Структура таблиц БД: хранение списков значений наряду с обычными значениями
БД: MySQL. Задача: хранить словаревидные данные в виде id:int->value:string. Проблема: оказалось, что иногда нужно, чтобы одному id соответствовал список значений. При этом, если даже список состоит из одного элемента, все равно нужно отличать его от обычного значения.
Я вижу несколько вариантов решения, но ни один мне не нравится.
1) Хранить данные не в виде строки, а в каком-то формате: XML, JSON, etc. Тогда в одно строковое поле можно будет сохранить целый объект.
Вариант не нравится тем, что в итоге получаем денормализацию данных и проблемы, с ней связанные, например, невозможность оперировать значениями списка по отдельности стандартными средствами SQL. Чтение и изменение отдельных элементов прийдется реализовывать средствами приложения.
1.а) Хранить данные в одной строке с разделителем. Это частный случай варианта 1, и минусы те же самые.
2) Создать отдельную таблицу для значений списков.
Вариант не нравится тем, что прийдется делать запросы уже к двум таблицам как при чтении, так и при записи.
3) Хранить все данные в одной таблице, просто не делать id строки словаря уникальным ключом, тогда можно будет добавлять несколько записей для одного id.
Не нравится тем, что тогда сложно определить, является ли элемент обычным элементом, или же частью списка. Добавление специального поля-флага а-ля is_list_element — костыль.
Разрешите поинтересоваться, а как соотношение обычных элементов к списковым на что-то влияет?
Меня вот беспокоит другой вопрос. Я сейчас создал две таблицы по варианту №2, и у этих таблиц получилась идентичная структура, за исключением уникального индекса в первой таблице.
Т.е. имеем три поля: id, control_id, value.
В таблице с простыми элементами control_id нужно, чтобы поставить в соответствие запись в этой таблице и элемент страницы, в который данные будут попадать (textbox). Во второй таблице control_id выполняет ту же роль для dropdown-листов + по этому полю нужно будет группировать записи.
Все хорошо, но практически идентичная структура таблиц наводит на подозрения :)
Разрешите поинтересоваться, а как соотношение обычных элементов к списковым на что-то влияет?
Если у Вас всего 1% записей вида «список», и всего 1-2 дубля на каждую, то 99 раз из 100 Вы будете тратить 2 запроса вместо одного, и только 1 раз сэкономите на этом что-то. Стоит ли это того?
Это нечто сродни кэшированию. Если кэш долго строится… и у Вас 99% попаданий в кэш это хорошо, а если 1% попадание в кэш, то смысла в кэше в общем-то не много. С кэшем это как-то более очевидно:)
Все хорошо, но практически идентичная структура таблиц наводит на подозрения
Именно. Вы тут абсолютно правы.
Но окончательное решение зависит от Ваших реальных данных. Нормализация должна делаться во благо, не в последнюю очередь для уменьшения объема данных. А в случае почти полного дублирования…
То есть если у Вас по 10 в среднем значений на каждый ключ, и при этом 80% ключей имеют значения типа «список», то выбор 2-ого варианта однозначен. А если списки редки и невелики, то не однозначен как минимум.
Написано
Войдите на сайт
Чтобы задать вопрос и получить на него квалифицированный ответ.