SQL ON DELETE CASCADE. Каким образом происходит удаление?

156

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

CREATE TABLE Courses (
  CourseID int NOT NULL PRIMARY KEY,
  Course VARCHAR(63) NOT NULL UNIQUE,
  Code CHAR(4) NOT NULL UNIQUE
);

CREATE TABLE BookCourses (
  EntryID int NOT NULL PRIMARY KEY,
  BookID int NOT NULL,
  Course CHAR(4) NOT NULL,
  CourseNum CHAR(3) NOT NULL,
  CourseSec CHAR(1) NOT NULL
);

и я устанавливаю отношения между внешними ключами, как это:

ALTER TABLE BookCourses
ADD FOREIGN KEY (Course)
REFERENCES Courses(Code)
ON DELETE CASCADE;

Затем вы можете увидеть, что Courseатрибут в BookCoursesотношении ссылается на Codeатрибут в Coursesотношении.

Мой вопрос: когда удаление происходит в одном из двух отношений, каким образом происходит каскад удаления? Если я удаляю кортеж в Coursesотношении, удалит ли он все ссылающиеся кортежи в BookCoursesотношении, или это наоборот?

Оливер Сприн
источник
11
Интересно только, почему у Categoriesтаблицы есть CourseIDпервичный ключ, а у Coursesтаблицы - EntryID. Вы серьезно должны пересмотреть свой выбор имен.
ypercubeᵀᴹ
7
Пожалуйста, используйте правильные имена столбцов, чтобы избежать путаницы и ясной структуры БД.
Gunjan Shah

Ответы:

185

Каскад будет работать, когда вы удалите что-то на столе Courses. Любая запись в таблице, BookCoursesкоторая имеет ссылку на таблицу, Coursesбудет автоматически удалена.

Но когда вы пытаетесь удалить BookCoursesтаблицу, это влияет только на саму таблицу, а не наCourses

дополнительный вопрос: почему у вас CourseIDна столе категория?

Может быть, вы должны реструктурировать свою схему в этом,

CREATE TABLE Categories 
(
  Code CHAR(4) NOT NULL PRIMARY KEY,
  CategoryName VARCHAR(63) NOT NULL UNIQUE
);

CREATE TABLE Courses 
(
  CourseID INT NOT NULL PRIMARY KEY,
  BookID INT NOT NULL,
  CatCode CHAR(4) NOT NULL,
  CourseNum CHAR(3) NOT NULL,
  CourseSec CHAR(1) NOT NULL,
);

ALTER TABLE Courses
ADD FOREIGN KEY (CatCode)
REFERENCES Categories(Code)
ON DELETE CASCADE;
Джон Ву
источник
5
Большой! Спасибо. Последующий ответ: потому что я слишком обдумал это. Исправлено сейчас ... и в моей БД
Оливер Сприн
59
Этот ответ имеет другие имена и структуры таблиц, чем вопрос ... Это делает его гораздо менее полезным.
Дэниэл Бердсли
4
@DanielBeardsley, я не согласен, что этот ответ не является полезным. Это если ты читаешь, что там написано. Однако я согласен с тем, что ответ можно отформатировать, чтобы было ясно, что является частью фактического ответа и что является другим обсуждением. Выделенная выше схема связана с последующим вопросом, но не с ответом на фактический вопрос.
Балдур
26

Вот простой пример для других, посещающих этот старый пост, но он смущен примером в вопросе:

Доставка -> Пакет (Один -> Много)

CREATE TABLE Delivery(
    Id INT IDENTITY PRIMARY KEY,
    NoteNumber NVARCHAR(255) NOT NULL
)

CREATE TABLE Package(
    Id INT IDENTITY PRIMARY KEY,
    Status INT NOT NULL DEFAULT 0,
    Delivery_Id INT NOT NULL,
    CONSTRAINT FK_Package_Delivery_Id FOREIGN KEY (Delivery_Id) REFERENCES Delivery (Id) ON DELETE CASCADE
)

Запись с внешним ключом Delivery_Id (Package) удаляется со ссылкой на объект в отношении FK (Delivery).

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

Мортен Холмгаард
источник
Спасибо за простой для понимания пример!
Том Спенсер