Подтвердить что ты не робот

Multitenant DB: зачем класть столбец TenantID в каждую таблицу?

В каждом учебном пособии, который я видел о моделях баз данных Multitenant, вы должны указывать TenantID в каждой отдельной таблице:

zoos
-------
id
zoo_name
tenant_id

animals
-------
id
zoo_id
animal_name
tenant_id

Однако это кажется лишним для меня. Почему бы не добавить столбец tenant_id только в таблицу zoos и использовать отношение внешнего ключа между zoos и animals?

Добавляете ли вы tenant_id к каждой таблице только для того, чтобы объединения не становились слишком сумасшедшими? Это защита от ошибок? Оценка эффективности?

4b9b3361

Ответ 1

Если у меня был идентификатор tenantID в верхней части иерархии (т.е. на уровне зоопарка), у вас есть несколько проблем для рассмотрения.

  • Верх иерархии никогда не может измениться, например, если вам нужно добавить node на дереве выше уровня зоопарка (например, регионы → зоопарки → животные), то он будет заставлять реорганизацию каждый раз.
  • Для определенных запросов вы будете вынуждены начинать вверху иерархии, то есть дать мне список всех доступных животных, заставив вас начать вверху дерева.
  • Почему бы не использовать схемы? Каждый арендатор изолирован в своей собственной схеме. Это также отлично отделяет наборы данных.

Ответ 2

Если одним из ключевых соображений дизайна является безопасность - в частности, один клиент не может ни каким образом не иметь доступа к другим данным клиента, а затем, в зависимости от того, как вы реализуете эту безопасность, придерживаться этого квалификационного столбца в каждой таблице может необходимо. Одна такая тактика, описанная здесь, требует создания представления для каждой таблицы; предполагая, что каждая таблица содержит столбец tenantId, тогда, если правильно настроено, каждое представление может содержать предложение WHERE tenantId = SUSER_SID() (и, конечно же, вы настраиваете базу данных, чтобы клиенты могли получать доступ только к представлениям).

Еще один фактор (как в моем текущем задании) - загрузка данных склада (ETL). Таблицы разделены на tenantId (мы используем разбиение на таблицы, но также выполняем секционированные представления), и данные могут быть легко загружены или выгружены для клиента без серьезного воздействия на любого другого клиента.

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

Ответ 3

Его там для удобства и производительности - с точки зрения нормализации вы абсолютно правы, нужно только входить наверху. Тогда проблема заключается в том, что для доступа к некоторым данным (например, zoo → animal → food → поставщик) у вас должно быть ужасно сложное объединение на то, что, по сути, очень простые запросы.

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

См. статью Возможно, нормализация не является нормальным - и ее заключение:

Как старая пословица идет, нормализуется, пока не болит, денормализовать, пока он не будет работать

как место для начала изучения предмета

Ответ 4

Первое, что приходит на ум, - это медленнее искать animals > zoos > tenants, чем просто animals > tenants. И, скорее всего, это поиск, который вы будете делать часто (например, "получить всех животных для определенного арендатора, независимо от зоопарка" ).

Для приложений малого и среднего размера вы можете уйти с более нормализованной структурой, но ради эффективности вы должны пойти с посторонними данными (и, вообще говоря, приложения для многозадачности невелики). Просто убедитесь, что он не выходит из строя, что представляет собой риск, связанный с избыточными данными.

Чтобы ответить на ваш последний абзац, причина - это производительность, чистая и простая. Соединения не плохие; они помогают вам хранить кусок данных в одном месте, а не в трех. Это определенно не для предотвращения ошибок. Добавление поля tenant_id в большее количество таблиц приведет к увеличению вероятности ошибок (хотя для идентификатора, который никогда не изменяется, это не будет проблемой).

Ответ 5

Ну, Боб может владеть жирафом в зоопарке №1, в то время как Джо может владеть львом в том же зоопарке. Они не должны смотреть на данные друг друга.

Ответ 6

Причина N1 для безопасности.

Безопасность должна быть сильной концепцией в многопользовательском приложении.

Предположим, что вы даете пользователю возможность изменять Animal. Вы создаете форму с выбором, который показывает зоопарк для текущего арендатора. Что произойдет, если пользователь взломает форму и передаст идентификатор зоопарка другого арендатора?

Животное будет перенесено в другой зоопарк другого арендатора!!

Это реальная боль в приложении для нескольких арендаторов!