SQL ON DELETE CASCADE,删除是按哪种方式进行的?

160

如果我在数据库中有两个关系,如下所示:

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;

然后您可以看到,在 BookCourses 关系中,Course 属性引用了 Courses 关系中的 Code 属性。

我的问题是当两个关系中的任一一个发生删除操作时,删除会向哪个方向级联?如果我在 Courses 关系中删除一个元组,它是否会删除 BookCourses 关系中所有引用该元组的元组,还是反过来?


13
为什么“分类”表的主键是“课程ID”,而“课程”表的主键却是“条目ID”,这让人不禁想问。你需要认真重新考虑一下你的命名选择。 - ypercubeᵀᴹ
9
请使用正确的列名以避免混淆,并清晰数据库结构。 - Gunjan Shah
3个回答

191

如果您在表上删除某些内容,Cascade将起作用。任何一张与表相关联的BookCourses的记录都会被自动删除。

但是,当您尝试仅在表BookCourses上删除时,仅对该表本身产生影响,而不会对表产生影响。

跟进问题:为什么你在类别表上有?

也许您应该将架构重组成这样:

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;

63
答案中的表格名称和结构与问题不同,使其变得不太有用。 - Daniel Beardsley
5
@DanielBeardsley,我不同意这个答案没有用。只要你读懂它说的是什么,它就有用。但我确实同意答案可以进行格式化,以便清楚地显示哪些内容是实际答案的一部分,哪些是其他讨论的内容。上面突出显示的模式与“后续问题”有关,而不是实际问题的答案。 - Baldur

35

以下是一个简单的例子,供那些看到这篇旧帖子却对问题和其他答案感到困惑的人参考:

Delivery(交付) -> Package(包裹)(一对多关系)

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

因此,当Delivery被删除时,引用它的Packages也将被删除。如果删除Package,则不会对任何交付产生影响。


0
只需记住:关系型数据库都是关于一致性的。它们希望始终确保数据的一致性。

enter image description here

如果您有一个Author表和一个Book表,Book表可能会有一个author_id。假设author_id设置为on_delete=CASCADE

当删除作者时,数据库将变为活动状态。当删除作者时,Book表可能引用一个不再存在的ID。这意味着删除作者可能需要“级联”删除书籍。

有几种可能的值,但最重要的是:

  • CASCADE:如果删除作者,则删除作者的所有书籍。
  • PROTECT:如果您尝试删除仍有书籍的作者,请让删除请求失败。您需要先明确删除书籍。
  • SET_NULL:如果删除作者,则将作者ID设置为NULL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接