情况:
一个公司有很多项目
一个项目有很多标签
一个项目仅属于一个公司
一个标签可以属于多个项目
一个公司必须有权访问自己的标签
范例1:
在第一个图像中,可通过projects / project_tag获得公司的所有标签。但是,如果所有项目都被删除,则该公司的标签将不再可用,因为project_tag和项目之间的链接已消失。即使没有项目,标签也应始终以某种方式链接到公司。
示例2(标签也链接到公司):
在第二个图像中,它应该起作用,但是现在这是一个“循环引用”吗?对于这样的问题,最好的解决方案是什么?那外键呢?
最后的问题是:如何针对这种情况正确设置数据库/数据模型?
在第二个示例中可能出错的示例:
companies:
id=1, name=MyCompany
id=2, name=OtherCompany
tags:
id=1, company_id=1, name=MyTag
id=2, company_id=2, name=OtherTag
projects:
id=1, company_id=1, name=MyProject
project_tag:
project_id=1, tag_id=1
project_id=1, tag_id=2 --> THIS ROW IS NOT VALID!
最后一个project_tag行无效,原因是:
项目1链接到company_id 1
tag_id 2链接到company_id 2
更新:谢谢大家提供的信息!
根据公认的答案,对PostgreSQL的CREATE查询将变为:
CREATE TABLE companies (
id SERIAL PRIMARY KEY NOT NULL,
name TEXT NOT NULL
);
CREATE TABLE projects (
id SERIAL PRIMARY KEY NOT NULL,
company_id INT NOT NULL,
name TEXT NOT NULL,
UNIQUE (id, company_id),
FOREIGN KEY (company_id) REFERENCES companies (id) ON DELETE RESTRICT ON UPDATE CASCADE
);
CREATE TABLE tags (
id SERIAL PRIMARY KEY NOT NULL,
company_id INT NOT NULL,
name TEXT NOT NULL,
UNIQUE (id, company_id),
FOREIGN KEY (company_id) REFERENCES companies (id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE project_tag (
id SERIAL PRIMARY KEY NOT NULL,
company_id INT NOT NULL,
project_id INT NOT NULL,
tag_id INT NOT NULL,
UNIQUE (company_id, project_id, tag_id),
FOREIGN KEY (company_id, project_id) REFERENCES projects (company_id, id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (company_id, tag_id) REFERENCES tags (company_id, id) ON DELETE CASCADE ON UPDATE CASCADE
);
已测试:
-在同一company_id上检查插入project_tag中的行(否则:被拒绝)
-无法在project_tag中插入重复的行
-如果删除了项目,则链接的project_tag行也被删除了
-如果删除了标签,则链接了project_tag行也被删除
-如果公司在有项目的同时被删除,则删除被拒绝(请参阅项目表:ON DELETE RESTRICT)
-如果公司(没有项目)被删除,则所有链接的标签也将被删除。
首先,您的第二个模型是绝对正确的,并且其中没有任何循环引用。
你应该发送Company_ID
的Company
为FK以Tags
和Project
,使其不为空。
然后,你应该传递TAG_ID
和Project_ID
为FK s转换Project_Tag
,使独特在一起。而且也没有必要发送Company_ID
的Project
和Tag
(我们在前面的段落传输)到Project_Tag
。
现在,关于最后一个问题,您的最终要求:
此行无效!
您无法通过ER捕获它。您应该编写一些函数,触发器或存储过程来捕获和控制它。
编辑:
基于@reaanb的评论和他在这里的出色回答:您可以通过这种方式控制此约束,并稍加冗余:
CREATE TABLE Project(
project_id INT NOT NULL,
company_id INT NOT NULL,
PRIMARY KEY (project_id),
FOREIGN KEY (company_id) REFERENCES Company (id),
UNIQUE KEY (project_id, company_id)
);
CREATE TABLE Tag(
tag_id INT NOT NULL,
company_id INT NOT NULL,
PRIMARY KEY (tag_id),
FOREIGN KEY (company_id) REFERENCES Company (id),
UNIQUE KEY (tag_id, company_id)
);
CREATE TABLE Project_Tags(
id INT NOT NULL,
company_id INT NOT NULL,
project_id INT NOT NULL,
tag_id INT NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (tag_id, project_id)
FOREIGN KEY (project_id, company_id) REFERENCES Project (project_id, company_id),
FOREIGN KEY (tag_id, company_id) REFERENCES Tag (tag_id, company_id),
);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句