#database #sqlite #tags #normalization #normalize
#База данных #sqlite #Теги #нормализация #нормализовать
Вопрос:
У меня есть таблица базы данных, в которой каждая строка (фильм) имеет пару числовых тегов (категории фильмов). В настоящее время я помещаю все эти теги в тот же столбец, что и строка, и ищу их, используя %LIKE% , что требует медленного полного сканирования таблицы, когда мне нужно найти все фильмы в определенной категории.
Я хочу ускорить поиск этих тегов, но единственное решение, которое я могу придумать, — это создать вторую таблицу с двумя целочисленными столбцами. Первый содержит одну категорию, а второй содержит идентификатор строки фильма.
Однако для этого потребуется гораздо больше вставок в базу данных. В строке в среднем содержится 10 тегов, поэтому вместо вставки одной строки я должен вставить 11 строк. Поскольку мое приложение выполняет гораздо больше вставок, чем запросов, производительность вставки имеет решающее значение.
Есть ли другой способ решить эту проблему, не жертвуя производительностью вставки? Или нет большой разницы между вставкой 1 строки с 10 столбцами и 10 строк с 2 столбцами?
Комментарии:
1. 1. Убедитесь, что используются транзакции (вставки выполняются относительно быстро, коммиты очень дороги ) 2. Используйте / попробуйте «стандартный» подход с нормализованными M-M тегами (также, возможно, используйте / попробуйте 1-M, позволяющий дублировать теги [менее нормализованные]: ключ в использовании индексов) 3. Сравните всеи снова оцените.
2. 1.) Я уже использую транзакции / прагму для вставок 2.) Подход M-M?
3. Я знал, что фильмы — это большой бизнес, но я понятия не имел, что они выпускаются с такой поразительной скоростью. Ваши люди, вводящие данные, должны быть потрясающими.
4. @Joshua M-M было бы похоже
movies (movie_id, movie_title) <- movies_tags (movie_id, tag_id) -> tags (tag_id, tag_text)
на то, что могло бы быть 1-Mmovies (movie_id, movie_title) <- tags (movie_id, tag_text)
(вроде как согласно сообщению; идентификатор [который на самом деле является FK] денормализуется как значение, и все становится размытым, если говорить о естественных PKS ;-). Я бы определенно сначала проверил обновления (я обновляю более 20 тыс. записей в секунду и не думаю дважды) — если это работает, это работает, и я подозреваю, что это будет работать просто отлично. Обязательно добавьте соответствующие индексы, поскольку они могут ускорить запросы.5. @ledorfier ЛОЛ 🙂 Я просто использовал фильмы / категории в качестве метафоры, это промышленные данные
Ответ №1:
У вас будет немного более низкая производительность вставки, потому что индексы необходимо обновить (по крайней мере, у него будет индекс по идентификатору строки, и вам нужен индекс по идентификатору категории, чтобы получить значительное ускорение). Сам размер данных тривиален.
Тем не менее, я бы ожидал, что это будет полностью затмено накладными расходами на транзакции (например, все вызовы fsync()
). SQLite ужасен для одновременных нагрузок с высокой нагрузкой на запись.
Если вы выполняете больше операций вставки, чем запросов, вам может потребоваться пересмотреть структуру данных.
Комментарии:
1. Там нет fsync, потому что я использую прагмы ‘synchronous = off’ и ‘journal-mode = off’. А также никаких синхронных записей, только один поток.