SQL ON DELETE CASCADE, Jalan Mana yang Dihapus?

156

Jika saya memiliki dua relasi dalam database, seperti ini:

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

dan saya membangun hubungan kunci asing antara keduanya, seperti ini:

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

Kemudian Anda dapat melihat bahwa Courseatribut dalam BookCoursesrelasi merujuk Codeatribut dalam Coursesrelasi.

Pertanyaan saya adalah kapan penghapusan terjadi di salah satu dari dua hubungan tersebut, ke arah mana penghapusan akan terjadi? Jika saya menghapus tuple dalam Coursesrelasi, apakah ini akan menghapus semua tupel referensi dalam BookCoursesrelasi, atau sebaliknya?

Oliver Spryn
sumber
11
Orang hanya bertanya-tanya mengapa Categoriestabel memiliki CourseIDsebagai Kunci Utama sementara Coursestabel memiliki EntryID. Anda serius perlu memikirkan kembali pilihan penamaan Anda.
ypercubeᵀᴹ
7
Silakan gunakan nama kolom yang tepat untuk menghindari kebingungan dan menghapus struktur DB.
Gunjan Shah

Jawaban:

185

Cascade akan berfungsi saat Anda menghapus sesuatu di atas meja Courses. Setiap catatan di atas meja BookCoursesyang memiliki referensi ke tabel Coursesakan dihapus secara otomatis.

Tetapi ketika Anda mencoba untuk menghapus di atas meja BookCourseshanya tabel itu sendiri yang terpengaruh dan bukan pada tabelCourses

pertanyaan tindak lanjut: mengapa Anda memiliki CourseIDKategori di atas meja?

Mungkin Anda harus menyusun kembali skema Anda menjadi ini,

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;
John Woo
sumber
5
Bagus! Terima kasih. jawaban lanjutan: Karena saya terlalu memikirkannya. Diperbaiki sekarang ... dan dalam DB saya
Oliver Spryn
59
Jawaban ini memiliki nama dan struktur tabel yang berbeda dari pertanyaan ... Menjadikannya jauh kurang berguna.
Daniel Beardsley
4
@DanielBeardsley, saya tidak setuju bahwa jawaban ini tidak berguna. Itu jika Anda membaca apa yang dikatakannya. Saya setuju, namun setuju bahwa jawabannya dapat diformat sehingga jelas apa yang merupakan bagian dari jawaban aktual dan apa yang merupakan diskusi lain. Skema yang disorot di atas terkait dengan pertanyaan tindak lanjut tetapi bukan jawaban untuk pertanyaan yang sebenarnya.
Baldur
26

Berikut adalah contoh sederhana untuk orang lain yang mengunjungi pos lama ini, tetapi bingung dengan contoh dalam pertanyaan:

Pengiriman -> Paket (Satu -> Banyak)

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
)

Entri dengan kunci asing Delivery_Id (Paket) dihapus dengan entitas yang dirujuk dalam hubungan FK (Pengiriman).

Jadi, ketika Pengiriman dihapus, Paket yang merujuknya juga akan dihapus. Jika Paket dihapus, tidak ada yang terjadi pada pengiriman apa pun.

Morten Holmgaard
sumber
Terima kasih atas contoh yang mudah dipahami!
Tom Spencer