Я пытаюсь найти лучший способ справиться с вставкой/обновлением/удалением больших списков.
В частности, моим пользователям необходимо выбрать большие списки продуктов, и они получат отчеты по этим элементам каждую ночь.
Чтобы упростить его, вот модель данных (просто многие и многие)
~ 5000 records total
+----------+------------+
| user_id | user_name |
+----------+------------+
| 1 | Ralph |
| 2 | Bill |
| 3 | Joe |
| 4 | Mike |
| 5 | Brian |
| 6 | Jose |
+----------+------------+
~ 6000 records total
+------------+------------+
| product_id | product |
+------------+------------+
| 1 | Widget A |
| 2 | Widget B |
| 3 | Widget C |
| 4 | Widget D |
| 5 | Widget E |
| 6 | Widget F |
+------------+------------+
As many as 30 million total
+----------+------------+
| user_id | product_id |
+----------+------------+
| 1 | 1 |
| 1 | 4 |
| 1 | 6 |
| 2 | 2 |
| 2 | 4 |
| 2 | 5 |
+----------+------------+
Проблема заключается в том, что продукты выбираются навалом, поэтому, если пользователь нажимает кнопку выбора (что они часто делают), они выбирают приблизительно 6000 продуктов, которые приравниваются к большому запросу вставки.
Кроме того, они могут обновлять и удалять эти списки на основе множества разных критериев, таких как категории, в которые они входят, ценовые точки и т.д.
Каждый раз, когда они хотят обновить свой список, я должен получить выбранные продукты, удалить продукты, которые они выбрали, а затем вставить любые новые продукты.
Процесс кажется громоздким в лучшем случае, и я хотел бы знать, есть ли лучшее решение.
Я рассмотрел вместо хранения продуктов, которые хотят пользователи, сохранит только тот продукт, который пользователь не хочет, тем самым ограничивая накладные расходы частыми большими запросами на вставку/обновление. Таким образом, каждый пользователь получает доступ к каждому продукту по умолчанию.
Проблема с этим решением заключается в том, что при поступлении новых элементов пользователь может не захотеть этих элементов в отчете, поэтому мне придется вести отдельную таблицу, в которой указаны элементы по умолчанию.
Большое спасибо тому, кто может мне помочь.
Изменить: просто для уточнения, пользователи не ограничиваются только критериями выбора. Они также могут напрямую выбирать продукты и группы продуктов. Пользователи уникальны тем, что все они хорошо знакомы с продуктами (большинство из них знают почти все 6000 предметов).
Возможно, вы захотите попробовать сохранить критерии выбора вместо самих продуктов. Например, сохраните "price < 10 и category = 'sports" вместо того, чтобы хранить (возможно, длинный) список продуктов, соответствующих этим критериям. Затем вы можете воссоздать список, применив критерии выбора к текущему списку продуктов.
Вам нужно будет выяснить, какой синтаксис вы должны использовать для хранения критериев. Возможно, SQL будет работать, может быть, вам захочется что-то еще. Модификации могут быть сложными, вам нужно будет выполнить некоторую простую логику, чтобы смягчить это, например. критерии должны быть OR OF AND простых сравнений полей/значений.
Проблема с этим подходом заключается в том, что вам необходимо ограничить пользователей определенными критериями отбора, которые могут спуститься довольно быстро (многие пользователи просят вас реализовать свои собственные критерии), если вы не будете осторожны. Я не уверен, что рекомендую этот подход всем, но это еще один вариант.
Не могли бы вы добавить дополнительный столбец REPORT_ON
в свою таблицу сопоставлений? Строки в этой таблице будут оставаться более или менее статическими, и вам просто нужно будет обновлять отдельные строки и партии строк, когда пользователь будет активно изменять критерии.
Другая возможность заключается в разделении таблицы users-products. MySQL 5.1 добавлена поддержка разбиения таблиц:
http://dev.mysql.com/doc/refman/5.1/en/partitioning.html
Каждый раз, когда они хотят обновить свой список, я должен получить выбранные продукты, удалить продукты, которые они выбрали, а затем вставить любые новые продукты.
Я хотел бы указать, что я думаю, что в конечном итоге произойдет то, что фактические данные будут разбросаны по всему пространству хранения, потому что вы не удаляете все, а затем повторно добавляете его. Оптимизатор, вероятно, будет более эффективен для полного сканирования, чем случайный поиск по всему месту с помощью индексов. Я не знаю этого наверняка, хотя.