SQL ON DELETE CASCADE, ¿de qué manera se produce la eliminación?

156

Si tengo dos relaciones en una base de datos, así:

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

y establezco una relación de clave externa entre los dos, así:

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

Entonces puede ver que el Courseatributo en la BookCoursesrelación hace referencia al Codeatributo en la Coursesrelación.

Mi pregunta es cuando se produce una eliminación en cualquiera de las dos relaciones, ¿de qué manera la eliminación en cascada? Si elimino una tupla en la Coursesrelación, ¿eliminará todas las tuplas de referencia en la BookCoursesrelación, o es al revés?

Oliver Spryn
fuente
11
Uno solo se pregunta por qué la Categoriestabla tiene una CourseIDclave primaria mientras que la Coursestabla tiene la clave EntryID. Realmente necesita repensar sus opciones de nombres.
ypercubeᵀᴹ
77
Utilice los nombres de columna adecuados para evitar confusiones y borrar la estructura de la base de datos.
Gunjan Shah

Respuestas:

185

Cascade funcionará cuando elimine algo de la tabla Courses. Cualquier registro en la tabla BookCoursesque tenga referencia a la tabla Coursesse eliminará automáticamente.

Pero cuando intenta eliminar en la tabla, BookCoursessolo la tabla en sí se ve afectada y no en elCourses

pregunta de seguimiento: ¿por qué tienes CourseIDen la categoría de mesa?

Tal vez deberías reestructurar tu esquema en esto,

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
fuente
55
¡Excelente! Gracias. respuesta de seguimiento: Porque lo pensé demasiado. Reparado ahora ... y en mi DB
Oliver Spryn
59
Esta respuesta tiene diferentes nombres y estructuras de tabla que la pregunta ... Haciéndola mucho menos útil.
Daniel Beardsley
44
@DanielBeardsley, no estoy de acuerdo con que esta respuesta no sea útil. Eso es si lees lo que dice. Sí, sin embargo, estoy de acuerdo en que la respuesta podría formatearse para que quede claro qué es parte de la respuesta real y qué es otra discusión. El esquema resaltado anteriormente está relacionado con la pregunta de seguimiento pero no con la respuesta a la pregunta real.
Baldur
26

Aquí hay un ejemplo simple para otros que visitan esta publicación anterior, pero el ejemplo en la pregunta lo confunde:

Entrega -> Paquete (Uno -> Muchos)

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
)

La entrada con la clave foránea Delivery_Id (Paquete) se elimina con la entidad referenciada en la relación FK (Entrega).

Por lo tanto, cuando se elimina una entrega, los paquetes que hacen referencia también se eliminarán. Si se elimina un Paquete, no pasa nada en ninguna entrega.

Morten Holmgaard
fuente
¡Gracias por el ejemplo fácil de entender!
Tom Spencer