Существует другой хороший прием, который можно использовать для значительного улучшения вида представленного различного HTML. Хотя это не полностью решает начальную проблему, это будет иметь значительное значение в появлении Вашего представленного HTML diffs.
Бок о бок представленный HTML сделает очень трудным для Вашей разности выстроиться в линию вертикально. Выравнивание по вертикали крайне важно для сравнения бок о бок diffs. Для улучшения выравнивания по вертикали бок о бок разность, можно вставить невидимые элементы HTML в каждую версию разности в "контрольных точках", где разность должна быть вертикально выровненная. Тогда можно использовать немного клиентского JavaScript для добавления пространства по вертикали вокруг контрольной точки, пока стороны не выстраиваются в линию вертикально.
Объясненный в немного большем количестве деталей:
, Если Вы хотите использовать эту технику, выполните свой различный алгоритм и вставьте набор visibility:hidden
<span>
с или крошечный <div>
с везде, где Ваш бок о бок присваивают версию, должен совпасть, согласно различному. Тогда выполните JavaScript, который находит каждую контрольную точку (и ее бок о бок сосед) и добавляет пространство по вертикали к контрольной точке, которая является большой шишкой (более мелкой) на странице. Теперь Ваша представленная разность HTML будет вертикально выровненная до той контрольной точки, и можно продолжить восстанавливать выравнивание по вертикали вниз остальная часть Вашего бок о бок страница.
Если бы у меня был tenantID на вершине иерархии (то есть на уровне зоопарка), у вас есть несколько проблем, которые следует учитывать.
Если одним из ваших ключевых соображений при проектировании является безопасность - в частности, один клиент не может ни как не получить доступ к данным другого клиента - тогда, в зависимости от того, как вы реализуете эту безопасность, придерживайтесь этого квалификационная колонка в каждой таблице может быть необходима. Одна из таких тактик, описанная здесь , требует построения представления для каждой таблицы; предполагая, что каждая таблица содержит столбец tenantId, тогда при правильной настройке каждое представление может содержать предложение «WHERE tenantId = SUSER_SID ()» (и, конечно, вы настраиваете базу данных так, чтобы клиенты могли получать доступ только к представлениям).
Другой фактор ( как в моей текущей работе) загружает данные хранилища (ETL). Таблицы секционируются по tenantId (мы используем секционирование таблиц, но секционированные представления также будут работать), и данные могут быть легко загружены или выгружены для клиента, не оказывая серьезного воздействия на других клиентов.
Но, как всегда, здесь задействовано много «зависит от обстоятельств». Если нет явной и текущей потребности, и очень низкая вероятность будущей потребности, то нормализуйте этот столбец. Просто поймите, что это скорее физическая реализация, чем концептуальный или логический дизайн базы данных.
Он нужен для удобства и производительности - с точки зрения нормализации вы абсолютно правы, нужно только указать наверху. Тогда проблема заключается в том, что для доступа к некоторым данным (например, зоопарк -> животное -> еда -> поставщик) вам нужно иметь ужасно сложные соединения по теоретически очень простым запросам.
Так что в реальном мире нужно идти на компромисс. - тогда возникает вопрос, где и в какой степени.
См. эту статью Может быть, нормализация - это не нормально - и ее вывод:
Как старая пословица идет, нормализуется, пока не станет больно, денормализовать, пока он не сработает
как место для начала исследования предмета
Что ж, у Боба может быть жираф в зоопарке №1, а у Джо может быть лев в том же зоопарке. Они не должны просматривать данные друг друга.
Первое, что приходит на ум, это то, что он медленнее найдите животных> зоопарков> арендаторов
, чем просто животных> арендаторов
. И, скорее всего, это поиск, который вы будете часто выполнять (например, «получить всех животных для определенного арендатора, независимо от зоопарка»).
Для приложений малого и среднего размера можно обойтись с более нормализованной структурой, но для эффективности следует использовать посторонние данные (да и вообще мультитенантные приложения не маленькие). Просто убедитесь, что он не «рассинхронизируется», что представляет собой риск, связанный с наличием избыточных данных.
Чтобы ответить на ваш последний абзац, Причина в производительности, чистой и простой. Соединения - это не плохо; они помогают хранить часть данных в одном месте, а не в трех. Это точно не для предотвращения ошибок. Добавление поля tenant_id
к большему количеству таблиц увеличит риск ошибок (хотя для идентификатора, который никогда не меняется, это не будет такой большой проблемой).