Начало работы над несколькими проектами с EF, но у меня возникли вопросы о таблицах соединений, ключах и т. Д. Допустим, у меня есть таблица приложений и таблица разрешений. Приложения имеют много разрешений, и каждое разрешение может принадлежать многим приложениям (многие ко многим).
Теперь таблицы Application и Permission просты:
Applications
--------------
PK ApplicationID
Name
Permissions
--------------
PK PermissionID
Name
Но какой ЛУЧШИЙ способ сделать таблицу соединений? У меня есть эти два варианта:
ApplicationPermissions
-----------------------
PK ApplicationPermissionID
CU ApplicationID
CU PermissionID
ИЛИ
ApplicationPermissions
-----------------------
CPK ApplicationID
CPK PermissionID
PK = Primary Key
CPK = Composite Primary Key
CU = Composite Unique Index
Вы когда-нибудь были обожжены, когда делали это так, как другие? это строго предпочтение? Мне пришло в голову, что многие из «различий» будут абстрагированы моим шаблоном репозитория (например, я бы почти никогда не создавал весь объект разрешений и не добавлял бы его в приложение, но делал бы это по ID или уникальному имени или что-то), но я думаю, я ищу ужасные истории, так или иначе.
источник
На протяжении многих лет я привык давать каждой таблице TableName автоматически генерируемый первичный ключ TableNameID, без каких-либо исключений, даже для соединительных таблиц. Я могу сказать, что никогда не сожалел об этом, потому что это облегчает многие вещи при создании универсального кода, который делает что-то для «всех таблиц» или «некоторых таблиц», или для «большого количества строк нескольких разных таблиц».
Например, если кто-то просит вас сохранить несколько строк разных таблиц (или ссылки на них) в файле или в памяти, например, для целей ведения журнала, это очень удобно, если вы заранее знаете, что вам просто нужно хранить ровно одну имя таблицы и ровно один целочисленный идентификатор, и вам не придется иметь дело с какими-либо «особыми случаями».
Другое дело, что когда вы начинаете с комбинированных PK, вы, вероятно, через некоторое время столкнетесь с необходимостью комбинированных внешних ключей (поскольку вы можете прийти к точке, когда вы захотите добавить ссылку FK на вашу
ApplicationPermissions
таблицу). Тогда следующее требование может состоять в том, чтобы этот FK был уникальным в сочетании с другими атрибутами или внешними ключами - что приведет к увеличению общей сложности. Конечно, нет ничего невозможного для большинства современных систем БД, но единое решение значительно облегчает жизнь программистам.И, наконец, оператор like
SELECT ... FROM TABLE WHERE TableNameID IN (id1,id2,...)
хорошо работает с одним столбцом в качестве первичного ключа, но я никогда не видел диалекта SQL, который позволял бы вам делать это с помощью комбинированных ключей. Если вы заранее знаете, что такой запрос вам никогда не понадобится, хорошо, но не удивляйтесь, если завтра вы получите требование, которое будет легче всего решить с помощью такого вида SQL.Конечно, когда вы ожидаете, что ваша
ApplicationPermissions
таблица будет содержать несколько сотен миллионов строк, вам следует избегать чего-то вроде aApplicationPermissionsID
.источник
Хотя ответ Майка хороший, вот причины, по которым я бы добавил отдельное поле идентификатора или нет.
Попробуйте использовать отдельное поле идентификатора для таблицы соединения / соединения, если она содержит поля, отличные от идентификатора . Это имеет тенденцию отмечать, что это первоклассная сущность.
Рассмотрите возможность использования отдельного поля идентификатора, если API или какая-либо существующая логика стремятся использовать отдельные поля для извлечения / редактирования объектов. Это может помочь другим людям следовать вашему коду в контексте более крупного проекта.
Не используйте его, если нет особой выгоды (KISS). EF знает, как обрабатывать этот тип таблицы, и иногда можно пропустить составное уникальное ограничение, когда другие люди пытаются понять этот тип отношений. Кроме того, при нормализации я стараюсь использовать наименьший возможный ключ, который однозначно определяет кортеж . Во втором примере у вас фактически есть 2 отдельных первичных ключа-кандидата.
источник
Не забудьте создать индекс и внешний ключ на обоих
PersonId
иAddressId
.Независимо от того, что другие считают «лучше» или «вам следует», это самый простой и легкий способ обеспечить правильное функционирование базы данных.
источник
PersonAddress
строки с одинаковыми ,PersonId
иAddressId
значениями.