Моделирование отношений
1-к-многим Если отношения 1 родителем для многих детей (то есть тот же ребенок может принадлежать только одному и только одному из родителей), то стандартный подход моделирования является ссылаться на Родительская таблица из таблицы «Дети», через (один из) столбцов ключа родителя, обычно основной ключ родителя (ПК). В то же время, это также хорошая идея внешнего ключа (FK) ограничение на опорной колонке (child.PARENT_ID
) поощрять RDMBS для обеспечения referential integrity через отношения:
parent
-------------
PARENT_ID PRIMARY KEY, // PK for the parent table
OTHER_COL
...
child
-------------
CHILD_ID PRIMARY KEY, // PK for the Child Table
PARENT_ID // <-- Should this column be here? = Yes
CONSTRAINT FK_ChildParent FOREIGN KEY(PARENT_ID) REFERENCES parent(PARENT_ID)
Дополнительные много: многие таблицы parent_has_children
является избыточным, так как он будет иметь ровно одну строку на child
, и вскоре это станет обузой для синхронизации этой таблицы со строками, добавленными/удаленными из других таблиц (поскольку неспособность сохранить эту синхронизацию приведет к путанице/противоречию в целостность отношений).
Re: Как родители знают о своих детях?
дочерних записи для данного родителя можно найти с помощью простого запроса на столе ребенка фильтрованный на родительском столбца внешнего ключа:
SELECT ...
FROM child
WHERE PARENT_ID = myParentId;
Поскольку это, как правило, общий запрос, это всегда хорошо Идея обеспечить индексирование внешнего ключа child.PARENT_ID
- некоторые версии РСУБД делают это для всех внешних ключей по умолчанию.
CREATE INDEX IXFoo on child(PARENT_ID);
Если у вас есть модель сущности (например,для ORM) в приложении, представляющем эти таблицы, родительский объект обычно имеет коллекцию, содержащую ее экземпляры child
, а на дочернем объекте скалярный внешний ключ child.PARENT_ID
«столбец» либо полностью отбрасывается, либо заменяется ссылкой на экземпляр родителя:
class Parent
{
ParentId,
Child[] Children,
// ...
}
class Child
{
ChildId,
Parent Parent, // Optional, allows bidirectional navigation
// ...
}