我有一个 SQL 结构,可以如下所示(简化): 零件、变型、机器、人员。每个都有不同的关系,例如;
我需要能够向这些表中的每个表中的每个条目添加注释。因此一个零件/变体/机器/人可以有很多评论。评论条目始终包含 user_id、时间戳、comment_text
我是否应该为每个评论制作一个表格,例如 Part_Comments、Variant_Comments 等。或者我可以/应该为所有评论制作一个表格并以某种方式包含表格 ID。因此,这些列将类似于:entry_id、table_id、user_id、timestamp、comment_text。
这有最佳实践吗? 谢谢
如果你做了一张像
(table name, foreign id, ...)
这样的表,你就会失去引用完整性和像on delete cascade
这样的重要事情。这些可以通过触发器来恢复,但这需要大量工作,而且很可能会出错。
您可以执行多个连接表,这可以工作并且具有引用完整性,但是如果您想找出谁写了评论,您必须搜索所有链接的表。这可以通过创建视图来缓解。
create view as commenters
select id, comment_id, 'parts' as table_name
from part_comments
union
select id, comment_id, 'persons' as table_name
from persons_comments;
select *
from commenters
where comment_id = $1
我一直在尝试第三个选项,创建一个名为“评论者”的实体。评论是由评论者完成的。
create table commenters (
id bigserial primary key,
-- this is for informational purposes
table_name text not null
);
create table comments (
commenter_id bigint not null references commenters on delete cascade,
body text not null
);
每个可以评论的表都有一个评论者。
create table parts (
id bigserial primary key,
commenter_id bigint not null references commenters on delete cascade
);
create table persons (
id bigserial primary key,
commenter_id bigint not null references commenters on delete cascade
);
为了确保评论者被删除,我们需要为每个表添加一个触发器。
create or replace function delete_associated_commenter()
returns trigger
language plpgsql
as $$
begin
delete from commenters where id = OLD.commenter_id;
return OLD;
end;
$$;
create trigger after_delete_parts_commenter_trigger
after delete on parts
for each row
execute function delete_associated_commenter();
create trigger after_delete_persons_commenter_trigger
after delete on persons
for each row
execute function delete_associated_commenter();
示范.
这比多个连接表有优势吗?我还不确定。