【问题标题】:cascade deletions in many-to-many relationships when no related items are present当不存在相关项目时,多对多关系中的级联删除
【发布时间】:2019-04-27 10:30:00
【问题描述】:

我的架构大致如下所示:

CREATE TABLE posts(
    id INTEGER PRIMARY KEY,
    txt TEXT,
);
CREATE TABLE tags(
    id INTEGER PRIMARY KEY,
    tag TEXT
);

CREATE TABLE posts_tags(
    id INTEGER PRIMARY KEY,
    tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE
);

我想删除具有指定 ID 的帖子,但我也想删除与该帖子相关但没有任何其他帖子关联的所有标签。

所以,假设只有一篇关于编程的帖子,那么当该帖子被删除时,"programming" 标签应该会消失。但是,如果有多个关于sports 的帖子,删除一个应该保持标签完整,并且只从posts_tags 表中删除适当的关系(我假设这是通过级联自动完成的)。

我知道我可以选择所有标签,使用我选择的编程语言循环它们,验证它们是否只有一个关联的帖子并删除它们,但我正在寻找一种更简单的与 SQL 一起使用的解决方案。

我需要为多个表执行此操作,因此多次复制/粘贴代码效率低下。

有没有办法做到这一点?

我研究了多对多的关系并删除,但我发现的只是提到使用触发器。但是,我真的不知道应该使用什么触发器。

【问题讨论】:

  • 您的post_tags 表不应该有一列是引用posts(id) 的外键吗?特别是如果您希望在发布帖子时自动删除行?这不会像现在这样发生。

标签: sql sqlite triggers cascading-deletes


【解决方案1】:

架构似乎是您的问题,基本上 post_tags 表似乎没有用,但是有一个用于引用/关联/映射到帖子的列,它变得非常有用映射/参考/关系表。

我想你会想要这样的架构:-

CREATE TABLE posts(
    id INTEGER PRIMARY KEY,
    txt TEXT,
);
CREATE TABLE tags(
    id INTEGER PRIMARY KEY,
    tag TEXT
);

CREATE TABLE posts_tags(
    id INTEGER PRIMARY KEY,
    tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
    post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE
);

然后您将标签绑定到帖子,如果删除帖子,则该帖子的所有行都将被删除,使用该标签的其他帖子将保留。如果一个标签被删除,那么所有使用该标签的行都将被删除。

附:您可以取消 id 列,然后您可能希望将 PRIMARY KEY 作为两列的组合,从而消除无用/令人困惑的重复行。

所以也许可以使用(与其他拖车桌一起使用):-

CREATE TABLE posts_tags(
    tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
    post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
    PRIMARY KEY (tag_id,post_id)
);

或者如果sqlite的版本支持它(3.8.2+):-

CREATE TABLE  posts_tags(
        tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
        post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
        PRIMARY KEY (tag_id,post_id) 
        )
    WITHOUT ROWID
    ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多