Transact SQL: как создать двусторонние ограничения внешнего ключа?

Скажем, у меня есть две таблицы: A и B

A имеет один столбец, который является первичным ключом для B, то есть внешним ключом, а B имеет один столбец, который является первичным ключом для A, то есть внешним ключом.

Так что я бы сделал

CREATE TABLE A(
 idA INT PRIMARY KEY,
 idB INT FOREIGN KEY REFERENCES B(idB)
);

CREATE TABLE B(
 idB INT PRIMARY KEY,
 idA INT FOREIGN KEY REFERENCES A(idA)
);

и ожидал, что это сработает; однако студия управления сервером sql дает мне следующую ошибку: Foreign key references invalid table for table B Если я поменяю их порядок, вместо этого ошибка будет в таблице A.

Как мне решить эту проблему, учитывая, что у меня двусторонние отношения, то есть A ссылки B и B ссылки A.

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

Brad 10.12.2020 19:28

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

user11107231 10.12.2020 19:29

Вы не можете ссылаться на таблицу, которую вы еще не создали (или Паттерсон на пакет). SQL является последовательным, поэтому вторая таблица не будет существовать при выполнении первого оператора. Создайте оба, затем используйте оператор ALTER TABLE, чтобы добавить оба ограничения с именем, отличным от значения по умолчанию.

Thom A 10.12.2020 19:29
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
3
345
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы должны сделать первое ограничение с отдельным ALTER TABLE, потому что справочная таблица еще не определена. В этом случае SQL не имеет понятия "прямая ссылка".

CREATE TABLE A (
 idA INT PRIMARY KEY,
 idB INT
);

CREATE TABLE B (
 idB INT PRIMARY KEY,
 idA INT FOREIGN KEY REFERENCES A(idA)

);

ALTER TABLE A
    ADD CONSTRAINT FK_A_B FOREIGN KEY (idB) REFERENCES B(idB);

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

Обычно они приходят к этому шаблону после добавления куда-то нового внешнего ключа и наблюдения за сбоем сценария из-за порядка объявлений таблицы.

Здесь db<>рабочий пример.

Если можно, что такое FK_B_A.

user11107231 10.12.2020 19:31

@ДуартеАррибас . . . Это имя ограничения. Вы обнаружите, что встроенные имена довольно непонятны.

Gordon Linoff 10.12.2020 19:32

Если это отвечает на вопрос @DuarteArribas, вы должны принять это как решение.

Thom A 10.12.2020 19:55

Итак, я вижу, что люди собираются ответить на этот вопрос, не задавая очевидного вопроса:

Почему круговая ссылка?

Возможно, есть какой-то блестящий дизайн, который мне не хватает, но идея, что вы FK PK на одном столе, а затем делаете обратное, кажется ДЕЙСТВИТЕЛЬНО плохим дизайном. Я открыт для обучения, но это звучит как катастрофа.

В общем:

  • При использовании «один ко многим» одна таблица является родительской или поисковой, а другая имеет FK для этой таблицы.
  • С один к одному вы обычно дублируете идентификатор (подкласс), поэтому в каждой таблице может быть только один. Или вы перепроектируете и создадите одну таблицу.
  • Вы можете ограничивать другими способами, но у вас все еще есть циклическая концепция в вашей схеме.

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

Задания, к сожалению/досадно/тупо/и т. д., часто выдвигают нереальные и произвольные требования. Я не удивлюсь, что это один из них.

Thom A 10.12.2020 22:33

@Larnu - Моя большая проблема, когда кто-то спрашивает: «Как мне разбить машину на скорости 90 миль в час без ремня безопасности и не умереть», и кто-то на самом деле отвечает на вопрос, а не спрашивает: «Чего ты пытаешься достичь?» Когда говорят: «Я хочу произвести впечатление на свою девушку», правильным ответом будет «купить ей цветы», а не «обложить себя подушками».

Gregory A Beamer 11.12.2020 20:07

Другие вопросы по теме