Как структурировать схему MySQL для пользовательских настроек, которые могут иметь произвольный порядок

0

В нашем приложении у нас есть список из примерно 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 на учет для этого. В целом, кажется, немного сложно поддерживать.

Может ли кто-нибудь помочь мне понять, какой будет лучший тип схемы для этого? Или какие-либо идеи для способа сохранить порядок для списка настроек?

  • 0
    Сохраните порядок настроек в строке JSON в одном столбце для каждого пользователя.
  • 0
    вместо добавления таблицы добавьте order_number COLUMN в таблицу user_settings
Теги:
schema

1 ответ

1

Это будет сводиться к тому, как ваше программное обеспечение должно взаимодействовать с данными. И, как обычно, в этих сценариях, спрашивающих о "лучшем" способе, ответ: "Это зависит! Подробности имеют значение". Вот три варианта, которые вы выбираете, должны зависеть от ваших потребностей в шаблонах использования:

  • "Правильный" метод, рассматривающий РСУБД и схему, действительно может привязывать значение упорядочения или ранжирование к каждой строке либо через вспомогательную таблицу, либо через дополнительный столбец. Это позволяет реализовать такие ограничения, как "никакие две строки не могут иметь одинаковое ранжирование (UNIQUE(...))", и вы можете использовать механизмы оптимизации и кэширования БД, чтобы сохранить некоторые детали в коде приложения. С другой стороны, это подразумевает ряд операций записи, когда пользователь переупорядочивает свои настройки. И тогда стандартный технический вопрос "эпсилон": имеет ли значение производительность? Конечно, неэффективно переписывать все эти строки, но если каждый пользователь делает это только один или два раза, действительно ли это проблема?

  • Тем временем вы можете попробовать другое предложение (@SloanThrasher избили нас до удара!), Который просто обновляет одну текстовую строку (назовите ее CSV или JSON или...) с заказом, когда это необходимо. Однако это переносит нагрузку от определения схемы на код приложения, чтобы убедиться, что вы никогда не оставляете устаревшие или неправильные ссылки (например, установка удалена, настройка обновлена, создаются новые настройки).

  • Другим вариантом, который я видел, был реализован с большим эффектом, является наличие столбца упорядочения или вспомогательной таблицы - в комплекте с данными ACID, обработанными схемой, - но ранжирование представляет собой сортированное двоичное дерево. В этом случае рейтинг постоянно и сильно обновлялся пользователями, поэтому дополнительное бремя, связанное с кодом приложения, связанным с оператором SELECT, считалось целесообразным.

Вы измеряете, платите свои деньги, делаете свой выбор и снова делаете меры. Хорошие лаки! ;-)

  • 0
    Спасибо за отличный ответ! Однако, у меня есть вопрос. В чем разница между первым решением (на основе столбцов) и вашим третьим решением? Похоже, как использовать схему и порядок? Меня смущает сортированное двоичное дерево в MySQL. Вы говорите, что на уровне приложения мы реализовали отсортированное двоичное дерево чисел? Или на реальном уровне MySQL? Или есть примеры этого?
  • 0
    Последний пункт ссылается на «фактическое двоичное дерево на основе схемы». Детали слишком сложны для комментирования и более глубоки, чем исходный вопрос «дайте мне советы». Управление иерархическими данными в MySQL должно дать вам необходимый толчок. Однако, прежде чем нырнуть в эту кроличью нору, я предлагаю рассмотреть реальное использование В целом, достаточно ли изменить порядок настроек для пользователей? Вы всегда можете выполнить рефакторинг после того, как это станет актуальной проблемой. Не предварительно оптимизируйте.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню