我有一个大致如下所示的模式:
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配合使用的解决方案。
我将需要对多个表执行此操作,因此多次复制/粘贴代码效率低下。
有没有办法做到这一点?
我研究了很多到很多的关系并删除了这些关系,但发现的只是提及使用触发器。但是,我对应该使用哪个触发器并没有真正的了解。
答案 0 :(得分:0)
该模式似乎是您的问题,基本上 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
);
然后您将标签绑定到帖子,如果删除了帖子,则该帖子的所有行将被删除,其他使用该标签的帖子将保留。如果删除了标签,则使用该标签的所有行都将被删除。
P.S。您可以删除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
;