Проектирование отношений 1: 1 и 1: m в SQL Server - PullRequest
9 голосов
/ 25 февраля 2011

Как в SQL Server 2008 проектировать отношения 1: 1 и 1: m?

Ответы [ 3 ]

22 голосов
/ 25 февраля 2011

Любое отношение требует, чтобы у «родительской» таблицы (с одной стороны) был первичный (или уникальный) ключ (PK), который однозначно идентифицирует каждую строку, а у «дочерней» таблицы (с другой стороны) есть внешний ключ столбец или столбцы, которые должны заполняться значениями, которые совпадают с некоторыми существующими значениями [первичного ключа] в родительской таблице. Если вы хотите, чтобы отношение «один ко многим» (1-M), тогда внешний ключ должен быть обычным атрибутом (столбец или столбцы) в дочерней таблице, который может повторяться (может быть много строк с одинаковым значением)

Если вы хотите, чтобы отношение один к одному (1-1), тогда внешний ключ сам по себе должен быть первичным ключом или уникальным индексом в дочерней таблице, что гарантирует, что в дочерней таблице может быть не более одной строки с этим значением .

Отношение 1-1 эффективно разделяет атрибуты (столбцы) в таблице на две таблицы. Это называется вертикальной сегментацией. Это часто делается для подклассификации сущностей таблицы или, по другой причине, если шаблоны использования в столбцах таблицы указывают на то, что к нескольким столбцам нужно обращаться значительно чаще, чем к остальные столбцы. (Скажем, один или два столбца будут доступны 1000 раз в секунду, а остальные 40 столбцов будут доступны только один раз в месяц). Таким образом, разбиение таблицы таким образом оптимизирует схему хранения для этих двух разных запросов.

Sub-причислять . Вышеприведенное фактически создает отношение от 1 до 0 или одно, которое используется для того, что называется отношением подкласса или подтипа. Это происходит, когда у вас есть две разные сущности, которые имеют большое количество атрибутов, но одна из сущностей имеет дополнительные атрибуты, которые не нужны другой. Хорошим примером могут быть Сотрудники и SalariedEmployees . Таблица Employee будет иметь все атрибуты, которые имеют все сотрудники, а таблица SalariedEmployee будет существовать в (1-0 / 1) отношении с сотрудниками с дополнительными атрибутами ( Заработная плата , Ежегодный отпуск и т. Д.), Которые нужны только наемным работникам.

Если вы действительно хотите связь 1-1, то вам нужно добавить еще один механизм, чтобы гарантировать, что дочерняя таблица всегда будет иметь одну запись для каждой записи / строки в родительской таблице. Как правило, единственный способ сделать это - применить это в коде, используемом для вставки данных (в триггере, хранимой процедуре или в коде вне базы данных). Это связано с тем, что если вы добавили ограничения ссылочной целостности для двух таблиц, которые требуют, чтобы строки всегда были в обеих, было бы невозможно добавить строку в одну из них, не нарушая одно из ограничений, и вы не можете добавить строку в обе столы одновременно.

7 голосов
/ 25 февраля 2011

Индивидуальные отношения

Create Table ParentTable
    (
    PrimaryKeyCol ... not null Primary Key
    , ...
    )

Create Table ChildTable
    (
    , ForeignKeyCol ... [not] null [Primary Key, Unique]
    , ...
    , Constraint FK_ChildTable_ParentTable
        Foreign Key ( ForeignKeyCol )
        References ParentTable( PrimaryKeyCol )
    )

В этом случае у меня никогда не может быть более одной строки в ChildTable для данного значения первичного ключа ParentTable. Обратите внимание, что даже в отношении «один к одному» одна из таблиц является «родительской» таблицей. Отличие отношения «один-к-одному» от отношения «один-ко-многим» исключительно с точки зрения реализации заключается в том, имеет ли значение внешнего ключа ChildTable ограничение уникального или первичного ключа.

Отношения один-ко-многим

Create Table ParentTable
    (
    PrimaryKeyCol ... not null Primary Key
    , ...
    )

Create Table ChildTable
    (
    , ForeignKeyCol ... [not] null 
    , ...
    , Constraint FK_ChildTable_ParentTable
        Foreign Key ( PrimaryKeyCol )
        References ParentTable( PrimaryKeyCol )
    )

В этом сценарии у меня может быть несколько строк в ChildTable для данного значения первичного ключа ParentTable.

1 голос
/ 25 февраля 2011

Отношение 1: 1 существует, когда таблица A и таблица B существуют только один раз по отношению друг к другу. Пример: у студента есть 1 основная запись. Студентом будет таблица A, а запись в таблице B. Таблица B будет содержать внешний ключ к записи студента в таблице A (и, возможно, наоборот)

Отношение 1: m существует, когда на таблицу A можно ссылаться или ссылаться на множество записей в таблице B. Пример: студент может взять несколько книг из библиотеки. Студентом снова будет таблица A, а книгой может быть запись в таблице B. Запись в таблице B будет содержать внешний ключ для того, кто выписал книгу, и многие книги могут ссылаться на одного и того же студента.

...