Суррогатный ключ как внешний ключ над составными ключами
Я понимаю, что могут быть похожие вопросы, но я не мог найти тот, который был достаточно близок для руководства.
Учитывая эту спецификацию,
Site
---------------------------
SiteID int identity
Name varchar(50)
Series
---------------------
SiteID int
SeriesCode varchar(6)
...
--SeriesCode will be unique for every unique SiteID
Episode
----------------------
SiteID int
SeriesCode varchar(6)
EpisodeCode varchar(10)
...
мой предложенный дизайн / реализация
Site
----------------------------
SiteID int identity
Name varchar(50)
Series
-------------------------------------------
SeriesID int identity, surrogate key
SiteID int natural key
SeriesCode varchar(6) natural key
UNIQUE(SiteID, SeriesCode)
...
Episode
-------------------------------------------
EpisodeID int identity, surrogate key
SeriesID int foreign key
EpisodeCode varchar(6) natural key
...
Что-то не так с этим? Можно ли использовать здесь суррогат SeriesID в качестве внешнего * ключа? Я не уверен, что мне не хватает очевидных проблем, которые могут возникнуть. Или было бы лучше использовать составные натуральные ключи (SiteID+SeriesCode / SiteID+EpisodeCode)? По сути, это отделило бы таблицу Episode от таблицы Series, и это не подходит мне.
Стоит добавить, что SeriesCode выглядит как 'ABCD-1', а EpisodeCode как 'ABCD-1NMO9' в необработанных входных данных, которые будут заполнять эти таблицы, так что это еще одна вещь, которую можно изменить, я полагаю.
*: "виртуальный" внешний ключ, так как он был ранее решен вышестоящим руководством, мы не должны использовать фактические внешние ключи
3 ответа
Да, все выглядит хорошо. Единственное (второстепенное) замечание, которое я могу сделать, заключается в том, что если у вас нет еще 4-й дочерней таблицы, свисающей с Episode, вам, вероятно, не понадобится EpisodeId, поскольку Episode.EpisodeCode - это естественный ключ с одним атрибутом, достаточный для идентификации и определения местоположения строк в Episode. Конечно, не вредно оставлять его там, но, как правило, я добавляю суррогатные ключи, чтобы действовать в качестве целей для FK в дочерних таблицах, и пытаюсь добавить естественный ключ к каждой таблице, чтобы идентифицировать и контролировать избыточные строки данных... Поэтому, если у таблицы нет другой таблицы, на которую ссылается FK, (и никогда не будет), я иногда не буду включать в нее суррогатный ключ.
Мое предложение:
Используйте естественный / бизнес как первичный ключ, когда это возможно, за исключением следующих 3 ситуаций:
- Натуральный / бизнес-ключ неизвестен на момент вставки
- Натуральный / бизнес-ключ не хорош (он не уникален, он может часто меняться)
- Натуральный / бизнес-ключ состоит из более чем трех столбцов, и таблица будет иметь дочерние таблицы
В ситуациях 1 и 2 требуется суррогатный ключ.
В ситуации 3 настоятельно рекомендуется суррогатный ключ.
Что такое "виртуальный" внешний ключ? Решили ли руководители высшего звена не использовать ограничения внешнего ключа? В этом случае вы вообще не используете внешние ключи. Ты просто притворяешься.
И является ли Эпизод лучшим выбором для сущности? Разве это не означает "Шоу", "Подкаст" или что-то в этом роде, и просто сейчас всегда является частью серии? Если так, это изменится в будущем? Будет ли Эпизод со временем использоваться для показа за пределами Серии? В этом случае привязка Эпизода к Сайту через Серию может снова преследовать вас.
Учитывая все это, и предполагая, что вы как хрюканье, вероятно, не можете ничего изменить: если бы я был вами, я чувствовал бы себя более безопасным, используя естественные ключи везде, где это возможно. В отсутствие ограничений по внешнему ключу это облегчает распознавание неверных данных, и если позже вам придется прибегнуть к какой-то хитрости SeriesCode='EMPTY', то это проще сделать и с естественными ключами.