SQL ON DELETE CASCADE, w jaki sposób następuje usunięcie?


156

Jeśli mam dwie relacje w bazie danych, na przykład:

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
);

i ustalam relację klucza obcego między nimi, na przykład:

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

Wtedy możesz zobaczyć, że Courseatrybut w BookCoursesrelacji odwołuje się do Codeatrybutu w Coursesrelacji.

Moje pytanie brzmi: kiedy następuje usunięcie w którejkolwiek z dwóch relacji, w jaki sposób przebiega kaskada usuwania? Jeśli usunę krotkę w Coursesrelacji, czy spowoduje to usunięcie wszystkich odwołujących się krotek w BookCoursesrelacji, czy też jest odwrotnie?


11
Można się tylko zastanawiać, dlaczego Categoriestabela ma CourseIDjako klucz podstawowy, podczas gdy Coursesstół ma EntryID. Musisz poważnie przemyśleć swoje wybory dotyczące nazewnictwa.
— ypercubeᵀᴹ

7
Proszę używać odpowiednich nazw kolumn, aby uniknąć nieporozumień i przejrzystej struktury bazy danych.
— Gunjan Shah

Odpowiedzi:


185

Kaskada zadziała, gdy usuniesz coś ze stołu Courses. Każdy rekord w tabeli, BookCoursesktóry ma odniesienie do tabeli, Courseszostanie automatycznie usunięty.

Ale kiedy próbujesz usunąć z tabeli, dotyczy to BookCoursestylko samej tabeli, a nieCourses

pytanie uzupełniające: dlaczego masz CourseIDkategorię tabeli?

Może powinieneś zmienić swój schemat w ten sposób,

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
Wspaniały! Dziękuję Ci. następna odpowiedź: Ponieważ przemyślałem to. Naprawiono teraz ... iw moim DB
— Oliver Spryn

59
Ta odpowiedź ma inne nazwy i struktury tabel niż pytanie ... Co czyni ją znacznie mniej użyteczną.
— Daniel Beardsley

4
@DanielBeardsley, nie zgadzam się, że ta odpowiedź jest nieprzydatna. To znaczy, jeśli przeczytasz, co mówi. Zgadzam się jednak, że odpowiedź może być sformatowana, aby było jasne, co jest częścią rzeczywistej odpowiedzi, a co jest inną dyskusją. Schemat wyróżniony powyżej odnosi się do pytania uzupełniającego, ale nie dotyczy odpowiedzi na pytanie rzeczywiste.
— Baldur

26

Oto prosty przykład dla innych odwiedzających ten stary post, ale jest zdezorientowany przykładem w pytaniu:

Dostawa -> Pakiet (jeden -> wiele)

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
)

Wpis z kluczem obcym Delivery_Id (pakiet) jest usuwany z przywoływaną jednostką w relacji FK (dostawa).

W związku z tym, gdy przesyłka zostanie usunięta, związane z nią paczki również zostaną usunięte. Jeśli paczka zostanie usunięta, nic się nie stanie z żadną dostawą.


Dziękuję za łatwy do zrozumienia przykład!
— Tom Spencer
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.