SQLite在最后一次引用共享行时删除该行

SQLite delete shared row when last reference to it deleted

本文关键字:删除 共享 最后一次 引用 SQLite      更新时间:2023-10-16

我阅读了级联删除的文档,但有一件事我不清楚,是否可以设置一个数据库,使子行可以由多个父行共享,并且只有在删除最后一个引用的父行时才能删除子行?

(基本上,我想要像std::shared_ptr一样的外键。)

如果内置的CASCADE DELETE设置不可能做到这一点,可以用触发器完成吗?那会是什么样子?

我的最后一个选择是,尽管在我正在编写的库中创建这种共享引用情况是可能的,但当尝试构建这样的东西时,我可以简单地让它抛出异常。

具体来说,我有一个自引用表,它存储一些类似于抽象语法树的东西。每个节点都有一个操作和两个子节点。在我使用数据库的C++程序中,表示该表中行的对象具有重载运算符,这些运算符返回的值同时导致在表中创建行。例如,"a<<b"将返回一个临时值"c",数据库将有一行,如:(c_id,'<<',a_id,b_id)。但是,您可以调用"a<<x",在这种情况下,数据库将包含引用"a"的两行。

编写C++类是为了在其构造函数中插入表行,并在其析构函数中删除表行。从本质上讲,我希望C++代码中临时对象的创建和销毁在数据库的状态中得到镜像。但是,如果子行仍被其他父行引用,我希望禁止删除它。

这可以通过触发器实现。

当没有父母留下相同的孩子时,删除孩子:

CREATE TRIGGER t
AFTER DELETE ON Parent
WHEN NOT EXISTS (SELECT 1 FROM Parent WHERE ChildID = OLD.ChildID)
BEGIN
    DELETE FROM Child WHERE ID = OLD.ChildID;
END;