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
Будь ласка, користувач належних імен стовпців, щоб уникнути плутанини та чіткої структури БД.
— Гунян Шах

Відповіді:


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 (Доставка).

Тож коли видалення буде видалено, вони також будуть видалені. Якщо пакет буде видалено, жодна доставка не відбувається.


Дякую за простий для розуміння приклад!
— Том Спенсер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.