web-dev-qa-db-ja.com

SQL ON DELETE CASCADE、削除はどのように行われますか?

データベースに2つの関係があるとします。

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

そして、私はこの2つの間に外部キーの関係を確立します。

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

これで、CourseリレーションのBookCourses属性がCodeリレーションのCourses属性を参照していることがわかります。

私の質問は、2つの関係のどちらかで削除が発生した場合です。削除はどのようにしてカスケードされますか? Coursesリレーション内のタプルを削除した場合、それはBookCoursesリレーション内の参照しているすべてのタプルを削除するのでしょうか。

146
Oliver Spryn

カスケードは、テーブルCourses上の何かを削除したときに機能します。テーブルBookCoursesを参照しているテーブルCoursesのレコードは自動的に削除されます。

しかし、テーブルBookCoursesを削除しようとすると、テーブル自体だけが影響を受け、Coursesは削除されません

フォローアップの質問:なぜあなたはテーブルCategoryに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;
175
John Woo

これはこの古い記事を掲げている他の人たちのための簡単な例ですが、質問の中の例と混同されます:

配達 - >パッケージ(一つ - >たくさん)

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)の参照エンティティとともに削除されます。

そのため、配信が削除されると、それを参照しているパッケージも削除されます。パッケージが削除された場合、配送には何も起こりません。

10