Это не невозможно достичь этого, но это невозможно сделать это и не повредить систему на нескольких уровнях.
Хотя одна таблица поиска (как уже отмечалось) уже является действительно ужасной идеей, я скажу, что этот шаблон не требует отдельного поля PK или его автогенерации. Для этого требуется составная PK, состоящая из ([AppCodeCategory], [AppCode])
, а затем в таблице фактов должны присутствовать поля BOTH, которые должны иметь составной FK обоих полей обратно в PK. Опять же, это не одобрение этой конкретной конечной цели, просто техническая нота, что возможно иметь составные ПК и FK в других, более подходящих сценариях.
Основная проблема с этим типом подхода к константам состоит в том, что каждая константа поистине является своей собственной: Языки, страны, государства, Statii и т. Д. - все это совершенно разные сущности. Хотя структура из них в базе данных такая же (на сегодняшний день), данные внутри этой структуры не представляют одинаковые вещи. Вы были бы привязаны к модели, которая либо запрещает добавлять дополнительные поля поиска позже (например, коды ISO для языка и страны, но не другие, или что-то, что относится к государствам, которые не применимы к другим), или потребует добавления полей NULLable без каких-либо способов узнать, к какой категории они применимы (получать удовольствие от вопросов отладки, связанных с этим, и/или объяснять новому человеку - который был там в течение 2 дней и ему поручено написать новый отчет), что 3 Код страны ISO не применяется к статусу «Удалено»).
Этот подход также требует, чтобы вы сохраняли произвольное поле «Категория» во всех связанных таблицах. И это за поиск. Поэтому, если у вас есть CountryCode
, LanguageCode
и StateCode
в таблице фактов, каждый из этих FK получает соответствующее поле CategoryID, так что теперь это 6 полей вместо 3.Даже если вы смогли использовать TINYINT
для CategoryID, если ваша таблица фактов имеет даже 200 миллионов строк, то эти три дополнительных 1 байтовых поля теперь занимают 600 МБ, что отрицательно сказывается на производительности. И давайте не будем забывать, что резервное копирование займет больше времени и займет больше места, но диск дешевый, не так ли? О, и если резервное копирование займет больше времени, то восстановление также займет больше времени, не так ли? О, но таблица имеет ближе к 1 миллиарду строк? Даже лучше ;-).
В то время как этот подход выглядит, возможно, сейчас «более чистым» или «проще», в конечном счете, это более дорогостоящий, особенно с точки зрения потраченного времени на разработку, поскольку вы (и/или другие) в будущем попытаетесь для решения проблем, связанных с этим плохим выбором дизайна.
Кто-нибудь даже спросил у вашего менеджера проекта, что это за цель? Это разумный вопрос, если вы собираетесь потратить некоторое количество часов на внесение изменений в систему, чтобы заявленная выгода была потрачена на это время. Это, конечно же, не облегчает взаимодействие с данными, и на самом деле это станет сложнее, особенно если вы выберете строку для «Категории» вместо TINYINT
или, может быть, SMALLINT
.
Если ваш PM все еще нажимает на это изменение, то в качестве части этого проекта необходимо также соответствующим образом изменить любые enum
s в коде приложения, чтобы они соответствовали тому, что находится в базе данных. Поскольку база данных имеет свои значения, сгруппированные вместе, вы можете выполнить это на C# (если ваш код приложения находится на C#, если нет, то переведите на все, что подходит), установив значения enum
явно с образцом первых X цифр «категория», а остальные Y-цифры являются «значением». Например:
Предположим, что рабочий "Страна" категории == 1 и "Язык" == 2: категория, вы можете сделать:
enum AppCodes
{
// Countries
United States = 1000001,
Canada = 1000002,
Somewhere Else = 1000003,
// Languages
EnglishUS = 2000001,
EnglishUK = 2000002,
French = 2000003
};
Абсурд? Полностью. Но также аналогично запросу объединить все таблицы поиска в одну таблицу. Что хорошего для гуся, хорошо для гусака, верно?
a.k.a. «Один True Lookup Table», хорошо известный * anti- * pattern. Если вы не используете какой-то странный вариант SQL Server, за который вам приходится платить за каждую таблицу, здравомыслие простых внешних ключей и более простые запросы обычно более чем перевешивают любую воспринимаемую избыточность или неэффективность. –
См. [Пять простых ошибок проектирования баз данных, которые следует избегать] (https://www.simple-talk.com/sql/database-administration/five-simple--database-design-errors-you-should-avoid/) и посмотрите на пункт №1 - это именно то, что предлагает ваш премьер-министр, и его следует избегать **! –
Ваш первичный ключ должен быть сгенерированным значением ключа, и вам нужно будет создать составной уникальный ключ/ограничение вокруг кода, кода или бизнес-ключа. Как вы уже упоминали, у вас не может быть составной ключевой связи без какого-либо дополнительного уровня, обеспечивающего соблюдение логики. Короче говоря, это, вероятно, не очень хорошая идея, но вы видите, что это реализовано в других механизмах базы данных, таких как Intersystems Cache –