Проектирование базы данных: использование сотен полей для небольших значений

#mysql #database-design

#mysql #проектирование базы данных

Вопрос:

Я планирую разработать веб-приложение на PHP, оно будет в основном использоваться зарегистрированными пользователями (сеансами)

Размышляя о дизайне базы данных, я размышлял о том, что для обеспечения наилучшего пользовательского интерфейса у пользователя будет множество вариантов активации, деактивации, указания и т.д.

Например:
— Параметры для каждого элемента макета, диалоговых окон, панели мониторинга, сетки и т.д.
— цвет, размер, оставаться видимым, невидимым, не спрашивать снова, показывать каждый раз, расширенный режим, простой режим и т.д.

Это дало бы примерно 100 полей в диапазоне от простых Да / Нет или от 1 до N значений … для каждого пользователя.

Итак, правильно ли использовать поле для каждого из этих параметров?
или как эти CRM, CMS или другие веб-приложения делают это для хранения большого количества значений длиной в 1-2 символа?

Группируют ли они их по текстовым полям, разделенным специальным символом, а затем «разбивают» их как массив для использования во время выполнения?

Спасибо

Комментарии:

1. Всегда думайте о удобочитаемости и ремонтопригодности для вас и других в будущем. Представьте систему с сотней полей, настройка которой занимает 4 часа. Звучит как много? Не совсем, если изменение какого-либо индивидуального поля или настройки будет несложным в будущем. Теперь представьте систему, которая извлекла все в ‘ключ, значение’. Некоторым может быть сложнее поддерживать работу под капотом. Все зависит от ваших потребностей в приложении (насколько оно большое, как долго длится его срок службы и т.д.)

2. Это также веб-приложение, и если вы не пишете Google V2 или facebook V2, я сомневаюсь, что выигрыш в скорости от таких вещей, как решения bit, будет стоить абстракции.

Ответ №1:

Как насчет чего-то подобного:

 CREATE TABLE settings (
    user_id INT,
    setting_name VARCHAR(255),
    setting_value CHAR(2)
)
  

Таким образом, чтобы сохранить параметр конфигурации для пользователя, вы можете сделать:

 INSERT INTO settings (user_id, setting_name, setting_value),
    VALUES (1, "timezone", " 8")
  

И когда вам нужно запросить настройку для конкретного пользователя, вы можете сделать:

 SELECT setting_value FROM settings
    WHERE user_id = 1 AND setting_name = "timezone"
  

Комментарии:

1. Хм …, мне нравится, как выглядит эта идея, она кажется универсальной и понятной. Таблица значений настроек, отлично, я вернусь через минуту, чтобы подробно проверить все ответы, спасибо.

2. 1. Иногда это называется entity-attribute-value (EAV) или «таблица таблиц» и многими людьми считается антишаблоном. Однако, на мой взгляд, другого разумного способа справиться с ситуацией такого типа не существует. Значения независимы и не имеют реляционной семантики. EAV имеет особое преимущество для этого сценария в том, что он намного более гибкий, если потребуются новые типы настроек. Никаких изменений схемы таблицы не требуется, только новые строки.

Ответ №2:

Я был бы абсолютно склонен иметь отдельные поля для каждого параметра. Мое эмпирическое правило заключается в том, что каждый столбец содержит ровно одну часть данных, когда это возможно. Ни больше, ни меньше. Как упоминалось ранее, простота обслуживания и возможность добавлять / удалять параметры в будущем намного перевешивают трудности с ее настройкой. Я бы, однако, немного подумал о том, как вы создаете таблицу (ы). Идея, упомянутая ранее, заключалась в том, чтобы создать таблицу настроек со 100 столбцами (по одному для каждой опции) и одной строкой для каждого пользователя. Это сработало бы, чтобы быть уверенным. На моем месте я бы был склонен разбить это немного подробнее. Конечно, вы начинаете с базовой пользовательской таблицы. Это содержало бы основы имени пользователя, пароля, идентификатора пользователя и т.д. Таким образом, вы можете использовать числовой идентификатор пользователя в качестве ключевого индекса для ваших таблиц настроек. Но после этого я бы попытался разбить настройки на более мелкие таблицы, основанные на логическом использовании. Например, если у вас есть 100 параметров, и 19 из них относятся к тому, как пользователь просматривает / является просмотренным / ведет себя в одной определенной части сайта, скажите что-нибудь вроде форума, затем выделите их в отдельную таблицу, то есть ForumSettings. Возможно, есть еще 12, которые относятся к настройкам электронной почты, но не будут использоваться в других областях сайта / приложения. Теперь у вас есть таблица EmailSettings. Это не только уменьшило бы количество столбцов в вашей общей таблице настроек, но и значительно упростило бы написание запросов для конкретных задач или областей приложения, немного ускорило бы производительность и значительно облегчило бы дальнейшее обслуживание. Некоторые могут не согласиться, поскольку с точки зрения строгого моделирования данных я почти уверен, что будет указана одна таблица настроек. Но с точки зрения реального мира, я никогда не ошибался, используя логические блоки, подобные этому.

Ответ №3:

С точки зрения чистой модели данных это был бы самый понятный дизайн (хотя и ужасно широкий). Некоторые могут попытаться замаскировать их в одно поле по соображениям предполагаемого пространства, но, на мой взгляд, логика кодирования / декодирования делает это нецелесообразным. Также вы теряете возможность индексировать их. Другой вариант (я только что видел опубликованный) — сохранить отдельную таблицу с FK обратно в таблицу user. Но затем вам придется перебирать результаты, чтобы получить значение, которое вы хотите проверить.

Комментарии:

1. Как отметил @George Edison, таблица «настройки» — это идея. И в своем запросе он показывает, что индексы могут работать и там, если вы хотите просто проверить, есть ли у этого пользователя определенные флаги с помощью запроса.