Совет по схеме MySQL: непредсказуемые полевые дополнения - PullRequest
0 голосов
/ 07 февраля 2019

Небольшой обзор проблемы.

Допустим, у меня есть таблица с именем TableA с фиксированными свойствами, PropertyA, PropertyB, PropertyC.Этого было достаточно для нужд вашего собственного сайта, но вдруг у вас появились клиенты, которым нужны настраиваемые поля на вашем сайте.

ClientA хочет добавить PropertyD и PropertyE.ClientB хочет добавить PropertyF и PropertyG.

Смысл в том, что эти клиенты не хотят, чтобы поля друг друга.А теперь представьте, что если у вас будет больше клиентов, решение просто добавить пустые поля в TableA будет громоздким, и вы в конечном итоге получите беспорядок в таблице.Или, по крайней мере, я полагаю, что это так, не стесняйтесь поправлять меня.Будет ли лучше, если я просто сделаю это?

Теперь я подумал о двух решениях.Я спрашиваю, есть ли лучший способ сделать это, так как я не настолько уверен в компромиссах и их будущих результатах.

Предлагаемое решение # 1 Proposed Solution #1

data_id - это не совсем внешний ключ, но он хранит все соответствующие свойства клиента, присоединенные к строке таблицы A.Использование client_id в качестве единственного внешнего ключа, присутствующего как в таблице свойств, так и в таблице A.

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

Предлагаемое решение # 2 Proposed Solution #2

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

Properties
-------------
1 | PropertyD
2 | PropertyE
3 | PropertyF
4 | PropertyG

И всякий раз, когда я сохраняю какие-либо данные, я отмечаю все свойства, когда они доступны, вот так.В этом примере я хочу сохранить ClientA, хранящийся в таблице Clients под идентификатором 1.

Property_Mapping
--------------------------------------------------------
property_id | table_a_id | property_value   | client_id
--------------------------------------------------------
1           | 1          | PROPERTY_D_VALUE | 1
2           | 1          | PROPERTY_E_VALUE | 1

Существует очевидная возможная сложность запроса, я думаю, это скорее компромисс.Я предполагал, что client_id будет помещен в property_mapping на тот случай, если клиенты захотят те же поля.Любой совет?

1 Ответ

0 голосов
/ 07 февраля 2019

Вы обнаружили антипаттерн Entity-Attribute-Value .Это ужасная идея для реляционной базы данных.Это делает ваши запросы намного сложнее, и занимает в 4-10 раз больше места для хранения.

Я рассмотрел некоторые плюсы и минусы нескольких альтернатив в старом ответе по переполнению стека:

А в презентации:

КакПример проблемы, вызываемой EAV, подумайте, как бы вы отреагировали, если один из ваших клиентов скажет, что PropertyD должен быть обязательным (то есть эквивалент NOT NULL), а PropertyE должен быть UNIQUE.Между тем другой клиент говорит, что PropertyG должен быть ограничен конечным набором значений, поэтому вы должны либо использовать тип данных ENUM, либо использовать внешний ключ для таблицы допустимых значений.

Но выне удается реализовать ни одно из этих ограничений с помощью таблицы свойств, поскольку все значения всех свойств хранятся в одном столбце.

При использовании этого антипаттерна вы теряете свойства реляционных баз данных, такие как типы данных.и ограничения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...