Выбираете, где прикрепить внешний ключ между двумя таблицами? - PullRequest
1 голос
/ 14 декабря 2009

У меня есть таблица заказов на закупку и другая таблица, в которой содержатся элементы определенного заказа на закупку лекарств.

Пример:

PO_Table (POId, MainPharmacyID, SupplierID, PreparedBy)
PO_Items_Table (POItemID, ...)

У меня есть два варианта выбора таблицы для ссылки, и оба они кажутся действительными. я делал это несколько раз и делал так или иначе.

  • Я хотел бы знать, есть ли какие-нибудь правила, к которым прикреплять иностранца?
  • В моей ситуации, куда мне прикрепить свой внешний ключ?

Обновление:

Мои два варианта - поместить POItemID в PO_Table или поставить POId в PO_Items_Table.

Обновление 2:

Предполагая, что отношение между двумя таблицами является отношением один к одному

Ответы [ 4 ]

3 голосов
/ 14 декабря 2009

У вас нет двух вариантов. Ограничение внешнего ключа должно быть прикреплено к таблице (и к столбцу), в которой есть внешний ключ. И он должен ссылаться (или указывать на) Первичный ключ в другой таблице. Я не совсем понимаю, что вы имеете в виду, когда говорите, что делали это несколько раз в любом случае ... Каким другим способом?

3 голосов
/ 14 декабря 2009

Просто укажите на PRIMARY KEY указанной таблицы:

PO_Table (POId PRIMARY KEY, MainPharmacyID, SupplierID, PreparedBy)
PO_Items_Table (POItemID, POId FOREIGN KEY REFERENCES PO_Table (POId), ...)

На самом деле, в вашем PO_Table я не вижу другого ключа-кандидата, кроме POId, так что на данный момент это единственное доступное для меня решение.

Какие "два варианта" вы рассматриваете?

Обновление:

Поместить POItemID в PO_Table нельзя, если только вы не хотите, чтобы в ваших заказах было не более одного элемента.

Просто посмотрите на это: если у вас есть только один столбец, в котором хранится id заказанного товара в таблице заказов, где вы будете хранить другие предметы?

Обновление 2:

Если существует отношение один к одному, обычно вы просто объединяете таблицы: объединяете все поля из обеих таблиц в одну запись.

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

В этом случае вы создаете отдельное отношение для второго объекта и делаете его столбец PRIMARY KEY также FOREIGN KEY.

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

Pairs (PairID PRIMARY KEY, LockID UNIQUE, LockProductionDate, KeyId UNIQUE, KeyProductionDate)

Если для ключа нет ключа или нет ключа для ключа, мы просто помещаем NULLS в соответствующие поля.

Однако, если все ключи имеют блокировку, но ключи имеют только несколько замков, мы можем разделить таблицу:

Locks (LockID PRIMARY KEY, LockProductionDate, KeyID UNIQUE)
Keys (KeyID PRIMARY KEY, KeyProductionDate, FOREIGN KEY (KeyID) REFERENCES Locks (KeyID))

Как видите, KeyID - это PRIMARY KEY и FOREIGN KEY в таблице Keys.

Вы можете прочитать эту статью в моем блоге:

, который описывает некоторые способы отображения модели ER (сущности и отношения) в реляционную модель (таблицы и внешние ключи)

1 голос
/ 14 декабря 2009

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

0 голосов
/ 14 декабря 2009

Если PO означает «Заказы на покупку», а «PO Item» - отдельную позицию в заказе на покупку, тогда у вас есть только один способ настройки внешних ключей. Для каждого заказа на покупку может быть много товаров, но для каждого товара будет только один заказ на покупку. В этом случае Quassnoi дал правильный дизайн.

В качестве дополнительной информации, каждый раз, когда я проектировал базу данных заказов на покупку, у меня в таблице Предметов был составной первичный ключ, состоящий из POID и ItemID. Но ItemID не является уникальным среди всех предметов, а только предметов, которые принадлежат одному PO. Каждый раз, когда я начинаю новый заказ, я начинаю все сначала с ItemID, равным единице. Это позволяет мне позже восстановить заказ на поставку и получить элементы в том же порядке, в котором они были при создании заказа. Это тривиальный вопрос для большинства целей обработки данных, но он может свести с ума клиентов, если они потом посмотрят на ПО, а элементы не в порядке, как они воспринимают последовательность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...