正如标题所描述的,我想要建立一种零或一到零或一的关系。
例如,假设我们有两个表Calls和Files。呼叫可能带有附加文件,反之亦然。但我有一个限制。我希望如果我删除一个呼叫,它的文件也会被删除,但是如果我删除它的文件呼叫应该保持原样。使用SQL Constraints(如
ON DELETE CASCADE
/ON DELETE SET NULL
)可以实现这样的事情吗?或者有什么办法,用 SQL 在数据库中实现这样的行为,而不使用触发器/事件?
我尝试了如下所示:
-- Create the 'files' table
CREATE TABLE files (
id SERIAL PRIMARY KEY, -- Primary key for the 'files' table
file_name TEXT NOT NULL -- Any additional fields for the 'files' table
);
-- Create the 'calls' table
CREATE TABLE calls (
id SERIAL PRIMARY KEY, -- Primary key for the 'calls' table
file_id INT UNIQUE, -- Foreign key referencing 'files' table (1-1 relationship)
call_description TEXT, -- Any additional fields for the 'calls' table
CONSTRAINT fk_file_id FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE SET NULL
);
-- Add an additional constraint on the 'files' table to enforce the cascading behavior
ALTER TABLE files
ADD CONSTRAINT fk_call_file
FOREIGN KEY (id)
REFERENCES calls(file_id)
ON DELETE CASCADE;
但它需要可推迟,因为约束是立即执行的。而且,这也不是我的本意。我希望存在一个调用/文件而不相互依赖。
在这种情况下应遵循哪些最佳实践?
我可以想到多种方法来做到这一点:
file
而不是 call
,文件就会级联到调用:delete from files where id = (select file_id from calls where id = :call)
with deleted_calls as (
delete from calls where id = :call
returning (file_id)
)
delete from files where id = (select file_id from deleted_calls);
请注意,
calls
表有 2 个查询。如果我们没有 FK,我们可以先删除