Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 表关系的最佳模式设计,可增强完整性_Database_Schema Design - Fatal编程技术网

Database 表关系的最佳模式设计,可增强完整性

Database 表关系的最佳模式设计,可增强完整性,database,schema-design,Database,Schema Design,给定一个模型“a”表,该表可以有多个子模型“B”,其中“B”将有一个或多个子模型“C”。。这听起来很简单,但是我需要强制每个“A”,任何“B”都必须有一个唯一的“C”集合。。例如,C不能是属于同一父级“a”的两个“B”的子级。。但是,如果每个“B”的父级“a”是不同的,那么“C”可以是多个“B”的子级 这有意义吗?还是我应该澄清我的情况?提前干杯 请注意,我知道此策略将在应用程序中强制执行,但我不认为数据库不可能处于无效状态 编辑:大家好,非常好的反馈,所以首先我必须感谢大家与我分享你们的知识

给定一个模型“a”表,该表可以有多个子模型“B”,其中“B”将有一个或多个子模型“C”。。这听起来很简单,但是我需要强制每个“A”,任何“B”都必须有一个唯一的“C”集合。。例如,C不能是属于同一父级“a”的两个“B”的子级。。但是,如果每个“B”的父级“a”是不同的,那么“C”可以是多个“B”的子级

这有意义吗?还是我应该澄清我的情况?提前干杯

请注意,我知道此策略将在应用程序中强制执行,但我不认为数据库不可能处于无效状态

编辑:大家好,非常好的反馈,所以首先我必须感谢大家与我分享你们的知识

为了澄清情况,我将解释场景,但这里有一些注释:

“A”有零个或多个“B”,A“B”隐式地与“A”关联,因此始终是一个“A”的子级C'是一个根实体,它与数据库中的许多B以及其他元素相关联


以下是真实的故事:

这是一个包含多个简报(a)和多个成员(C)的网站,简报可以包含多个提交(B),其中一个提交将始终包含一个或多个关联成员。其理念是,提交事实上可以是一种协作,每个成员都不比其他成员拥有更多的“权力”,但将有一个不同的系统来验证成员如何合作的政策

因此,根据简介,一个成员只能提交一个提交,一个提交可以有多个成员(合作者)

希望能有帮助,但我想你已经给了我很多帮助了


Steve。

将TableA的ID添加到TableB,并将其添加到主键,然后对TableB和TableC执行相同的操作

编辑:


我相信这个答案的第一部分将适用于A到B的约束。然而,我会在B和C之间放置一个链接表,其中也包含a的PK。这样,在a:B之间就有了1:N,然后强制执行约束。

我认为,使用简单的声明性引用完整性约束无法做到这一点。实施逻辑的最佳方法可能是使用触发器来实现业务约束,并回滚任何违反规则的插入或更新。

您拥有的是三元关系。您需要做的是在主键中有一个将a、B和C连接在一起的表。由于主键不能复制,这将强制每个A和每个B只有一个C。这将创建您要查找的唯一集合

您将获得以下表格结构:

A's({A_ID}, ...)
B's({B_ID}, ...)
C's({C_ID}, ...)
A_B_C_Relation({[A_ID], [B_ID], [C_ID]}, ...)
主键在大括号中,外键在括号中


寻找更多信息。

我想我已经在这里捕捉到了你的关系模型;如果不是,我投票赞成不混淆:

  • A[{AID},…]
  • B[{BID},AID,…]
  • C[{CID},…]
  • B_C_链接[{BID,CID},AID]
    • 上的附加唯一索引(AID、CID)

表示法使用{}主键指示符。因此,可以有多个B(通过在B上放置AID),B可以有C(通过使用多对多表B_C_链接),多个C不能属于同一个a(通过将AID添加到多对多表并强制(AID,CID)唯一性)基本上没有被实际的DBMS实现

所有答案都一致认为有三个主要表,分别称为TableA、TableB和TableC,每个表都包含自己的ID列:

TableA (A_ID PRIMARY KEY, ...)
TableB (B_ID PRIMARY KEY, ...)
TableC (C_ID PRIMARY KEY, ...)
从问题的描述中不清楚单个B值是否可以有多个a父项。很明显,单个C可以有多个B父项。如果a B与单个a关联,则表B的设计可以修改为:

TableB (B_ID, ..., A_ID REFERENCES TableA)
如果a B可以与多个不同的a相关联,则连接最好由连接表表示:

A_and_B (A_ID REFERENCES TableA,
         B_ID REFERENCES TableB,
         PRIMARY KEY (A_ID, B_ID)
        )
B_and_C (B_ID REFERENCES TableB,
         C_ID REFERENCES TableC,
         PRIMARY KEY (B_ID, C_ID)
        )
从描述中也不清楚与a B关联的C对于B关联的每个a是否必须相同,或者不同的a是否可以引用相同的B,并且对于A1与B关联的C的集合可以不同于对于A2与B关联的C的集合。(当然,如果一个B只能与一个a关联,那么这个问题就没有意义了。)

出于这个答案的目的,我将假设任何B都与单个a关联,因此TableB的结构包括a_ID作为外键。由于单个C可以与多个B关联,因此相关结构是一个新的连接表:

A_and_B (A_ID REFERENCES TableA,
         B_ID REFERENCES TableB,
         PRIMARY KEY (A_ID, B_ID)
        )
B_and_C (B_ID REFERENCES TableB,
         C_ID REFERENCES TableC,
         PRIMARY KEY (B_ID, C_ID)
        )
简化(通过省略关于延迟性和即时性的规则)断言如下所示:

CREATE ASSERTION assertion_name CHECK ( <search_condition> )
[修正:我认为这更准确:

CREATE ASSERTION only_one_instance_of_c_per_a CHECK
(
     NOT EXISTS (
         SELECT A_ID, C_ID, COUNT(*)
             FROM TableB JOIN B_and_C USING (C_ID)
             GROUP BY A_ID, C_ID
             HAVING COUNT(*) > 1
     )
)
]

连接条件集因表连接方式的其他规则而异,但总体约束结构保持不变-对于特定的a_ID,对给定C_ID的引用不得超过一个


在下面的注释中,meandmycode注释:

我觉得我的设计有一个缺陷。我的现实世界逻辑是a“B”总是至少有一个子“C”。考虑到“B”必须存在,才能连接它的子对象,这是没有意义的。
数据库目前允许将“B”附加到“a”而不需要至少一个“C”…子项,因此我将修改“B”,使其具有一个引用其主要子项“C”的字段,以及一个附加“C”的子集合,但现在我有了一个集合,该集合还可以包括“B”指定的主要“C”我错了


是否有一个db模式可以推断“一个或多个子项”规则,而不是零个或多个

我认为你的模型确实存在问题。如果必须已经存在一个C,那么很难创建一个B
SELECT s.brief_id, c.member_id, COUNT(*)
    FROM submissions AS s JOIN submission_collaborators AS c
         ON s.submission_id = c.submission_id
    GROUP BY s.brief_id, c.member_id
    HAVING COUNT(*) > 1