如何在MYSQL中处理关联表和级联约束

时间:2017-06-06 21:10:58

标签: mysql foreign-keys relational-database

我认为这是一个常见问题,但我无法找到正确的关键字来在StackOverflow上执行搜索。

在mysql中,我有两个参与:组织和规模。 一个组织只能有一个规模,但规模可以属于许多组织。

所以我创建了第三个实体organization_scale。

例如:

organization
------------
org_id | name
     1 | Mickey
     2 | Donald
     3 | Dingo

scale
----------
 sc_id | name
     1 | miniScale
     2 | maxiScale 

organization_scale
--------------
org_id | sc_id
     1 | 1
     2 | 1
     3 | 2

organization_scale实体的两个字段都是外键+更新和删除时级联

问题如下:

如果我从org_id = 3的组织中删除,则organization_scale中的第三行被正确删除(因为org_id = 3不再存在)

但是

不删除sc_id = 2的比例。我不明白为什么。没有人参考这个比例,否则应该删除,大量的数据,很多" scale"将是orphean。

(如果我不使用额外的表,并且我直接在组织中添加scale_id列,则会发生同样的事情)

1 个答案:

答案 0 :(得分:0)

我认为问题是这样的:ON DELTE CASCADE表定义中的organization_scale仅适用于一个方向:删除scaleorganization中的内容时请求并删除organization_scale中的行。

但您似乎想要另一个方向:删除organization_scale中的内容时,如果没有对它的引用,请删除scale中的行。

这对我有用:我在organization添加了一个触发器。

DROP DATABASE IF EXISTS test;
CREATE DATABASE test;
USE test;


CREATE TABLE organization (org_id INT UNSIGNED PRIMARY KEY, name VARCHAR(255));
CREATE TABLE scale (sc_id INT UNSIGNED PRIMARY KEY, name VARCHAR(255));
CREATE TABLE organization_scale (org_id INT UNSIGNED, sc_id INT UNSIGNED,
    FOREIGN KEY (org_id)
        REFERENCES organization(org_id)
        ON UPDATE CASCADE ON DELETE CASCADE,
    FOREIGN KEY (sc_id)
        REFERENCES scale(sc_id)
        ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TRIGGER delete_unused_sc_id AFTER DELETE ON organization FOR EACH ROW DELETE FROM scale WHERE NOT EXISTS (SELECT * FROM organization_scale WHERE organization_scale.sc_id = scale.sc_id);

INSERT INTO organization VALUES
(1,"Mickey"),
(2,"Donald"),
(3,"Dingo");

INSERT INTO scale VALUES
(1,"miniScale"),
(2,"maxiScale");

INSERT INTO organization_scale VALUES
(1,1),
(2,1),
(3,2);

SELECT * FROM organization_scale;
SELECT * FROM scale;

DELETE FROM organization WHERE org_id=3;

SELECT * FROM organization_scale;
SELECT * FROM scale;


DROP DATABASE test;