В нашем приложении у нас есть список из примерно 150 пользовательских настроек. Ранее они были жестко закодированы. Жестко закодированная "таблица" выглядит так:
[ old settings ]
----------------
setting_key (string)
setting_label (string)
checked (0 / 1)
У каждого пользователя была запись в монго, которая была по существу гигантским массивом, содержащим эти значения. Поскольку пользователь может выбрать порядок, в котором отображаются настройки, порядок, который был установлен пользователем, был сохранен путем обновления структуры массива. Кроме того, если пользователь изменил setting_label
, он будет обновлен для их записи для этого setting_key
. Это просто позволило пользователю переименовать метки.
В настоящее время мы пытаемся реорганизовать все эти пользовательские настройки, чтобы уйти от жестких конфигураций гигантских настроек и обновить каждую отдельную информацию, когда пользователь может изменить только одну настройку. Для этого мы создаем следующую схему MySQL:
[ settings ] --> the master list of settings that each user has
------------
setting_id (int, auto-increment, primary key)
setting_key (varchar)
setting_label (varchar)
[ user_settings ] --> custom settings that override the default setting_id
-----------------
user_setting_id (int, auto-increment, primary key)
user_id (int)
setting_id (int, foreign key references settings.setting_id)
user_label (varchar)
Это работает, пока мы не осознаем, что нам все равно нужно как-то сохранить порядок настроек. И разрешите пользователю изменить этот порядок.
Мы подумали о создании таблицы settings_order
следующим образом:
[ settings_order ] --> user_id has settings in a specific order
-------------------
user_id (int)
setting_id (int, foreign key referencing settings.setting_id)
order_number (int)
Проблема в том, что если у меня есть 150 настроек по умолчанию, это означает, что order_number
будет order_number
между 0
и 150
и будет казаться жестко закодированным. И если пользователь переместил order_number
150
в order_number
1
, то все order_number
после 1
нужно было бы order_number
на учет для этого. В целом, кажется, немного сложно поддерживать.
Может ли кто-нибудь помочь мне понять, какой будет лучший тип схемы для этого? Или какие-либо идеи для способа сохранить порядок для списка настроек?
Это будет сводиться к тому, как ваше программное обеспечение должно взаимодействовать с данными. И, как обычно, в этих сценариях, спрашивающих о "лучшем" способе, ответ: "Это зависит! Подробности имеют значение". Вот три варианта, которые вы выбираете, должны зависеть от ваших потребностей в шаблонах использования:
"Правильный" метод, рассматривающий РСУБД и схему, действительно может привязывать значение упорядочения или ранжирование к каждой строке либо через вспомогательную таблицу, либо через дополнительный столбец. Это позволяет реализовать такие ограничения, как "никакие две строки не могут иметь одинаковое ранжирование (UNIQUE(...)
)", и вы можете использовать механизмы оптимизации и кэширования БД, чтобы сохранить некоторые детали в коде приложения. С другой стороны, это подразумевает ряд операций записи, когда пользователь переупорядочивает свои настройки. И тогда стандартный технический вопрос "эпсилон": имеет ли значение производительность? Конечно, неэффективно переписывать все эти строки, но если каждый пользователь делает это только один или два раза, действительно ли это проблема?
Тем временем вы можете попробовать другое предложение (@SloanThrasher избили нас до удара!), Который просто обновляет одну текстовую строку (назовите ее CSV или JSON или...) с заказом, когда это необходимо. Однако это переносит нагрузку от определения схемы на код приложения, чтобы убедиться, что вы никогда не оставляете устаревшие или неправильные ссылки (например, установка удалена, настройка обновлена, создаются новые настройки).
Другим вариантом, который я видел, был реализован с большим эффектом, является наличие столбца упорядочения или вспомогательной таблицы - в комплекте с данными ACID, обработанными схемой, - но ранжирование представляет собой сортированное двоичное дерево. В этом случае рейтинг постоянно и сильно обновлялся пользователями, поэтому дополнительное бремя, связанное с кодом приложения, связанным с оператором SELECT, считалось целесообразным.
Вы измеряете, платите свои деньги, делаете свой выбор и снова делаете меры. Хорошие лаки! ;-)
order_number
COLUMN в таблицу user_settings