Почему внешняя ключевая часть первичного ключа в идентифицирующих отношениях?

Хорошо, я надеюсь, что это подходящий вопрос для stackoverflow, поскольку я пытаюсь понять концепцию, а не исправлять фрагмент кода, который не будет работать.

Я возьму общий пример формы (родительская таблица) и поля формы (дочерняя таблица). Логически, это будет определяющее отношение, так как поле формы не может существовать без формы.

form and form_field tables

Это заставило бы меня подумать, что для перевода отношения логического в техническое отношение достаточно простого NOT NULL для поля form_id в таблице form_field, (см. левую часть выше).

Однако, когда я добавляю идентифицирующие отношения с помощью MySQL Workbench, form_id не только NOT NULL, но также и часть первичного ключа. (см. правую часть выше).
И когда я добавляю неидентифицирующее отношение, NOT NULL по-прежнему применяется так логически, что это действительно будет также идентифицирующее отношение.

Я думаю, это меня немного смущает, а также тот факт, что до сих пор я всегда просто использовал поле id в качестве первичного ключа.

Итак, я понимаю концепцию логической идентификации и неидентифицирующих отношений, но я не понимаю техническую часть . Почему, как этот ответ, говорится: "Правильный" способ сделать часть внешнего ключа дочернего первичного ключа?" В чем преимущество этих составных первичных ключей?

Ответ 1

Логически это будет определяющее отношение, так как поле формы не может существовать без формы.

Нет, идентифицирующая связь касается идентификации, а не существования.

Любое отношение X: Y, где X >= 1, гарантирует существование левой стороны, будь то идентификация или нет. В вашем случае соотношение 1: N гарантирует существование form для любого заданного form_field. Вы можете сделать его идентифицирующим или не идентифицирующим, и он все равно будет гарантировать то же самое.

Примечания:

  • Вы бы смоделировали идентифицирующую связь, сделав form_field.form_id часть ключа. Например, form_field PK может выглядеть так: {form_id, label}, что BTW было бы весьма полезно для правильных clustering ваших данных (таблицы InnoDB всегда кластеризован).
  • Просто сделать PK: {id, form_id} будет некорректным, так как этот суперкласс не является ключом-кандидатом (т.е. он не минимальный - мы могли бы удалить из него form_id и по-прежнему сохранить уникальность).
  • Вы могли бы моделировать отношения 0..1: N, сделав form_field.form_id NULL-способным (но тогда вы не смогли бы также идентифицировать его).

Существует два определения "идентифицирующего отношения":

  • Строгое определение: отношение, которое переносит родительский ключ в дочерний первичный ключ 1.
  • Свободное определение: отношение, которое переносит родительский ключ в дочерний ключ.

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

Большинство инструментов 2 похоже, используют строгое определение, поэтому, если вы отметите взаимосвязь как идентификацию, это автоматически сделает перенесенные атрибуты частью дочернего PK, и ни один из атрибутов PK не сможет NULL.


1 который затем либо полностью состоит из перенесенных атрибутов, либо представляет собой комбинацию перенесенных атрибутов и некоторых дополнительных атрибутов.

2 ERwin и Visio do. Я еще не использовал MySQL Workbench для моделирования, но ваше описание, похоже, предполагает, что оно ведет себя одинаково.

Ответ 2

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

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

В вашем примере, однако, ключи в двух таблицах НЕ совпадают. В первом случае идентификатор уникален в таблице form_field, а во втором случае, по-видимому, нет. Я ожидаю, что не то, что вы намеревались.