在MySQL中一对多的父子表循环关系hp

|| 我正面临这个问题: 我有一个父表和一个子表,一个父级可以有多个孩子,这是标准故事。 这些是约束: 每个父母必须至少有一个孩子, 每个父母必须有一个喜欢的孩子, 每个父母可以有一个最不喜欢的孩子 如何在SQL中进行设计? 由于循环关系,我不确定是否可以使用标准的父子表:
Parent table:
parentId
favouriteChildId NOT NULL
leastFavouriteChildId NULL

Child table:
childId
parentId
我当时在考虑使用桥表,但不确定如何对这些约束建模。 编辑:只是为了增加一些清晰度,这是问题上下文的一部分: 有价格表(子级)和价格组表(父级)。 PriceGroup具有多个价格,一个强制性mainPrice(favouriteChild),并且可以具有一个OfficialPrice(leastFavouriteChild)。 以下内容与问题无关,但可以使您对背景有所了解: 价格是根据它们所引用的产品进行分组的,一个产品可以具有多个价格-然后将这些价格分组为价格组,每个组都需要参考主价格和官方价格(如果有)。     
已邀请:
根据您给出的业务规则 每个父母必须至少有一个孩子, 每个父母必须有一个喜欢的孩子, 每个父母可以有一个最不喜欢的孩子 您的解决方案
Parent table:
parentId (PK)
favouriteChildId NOT NULL (FK)
leastFavouriteChildId NULL (FK)

Child table:
childId (PK)
parentId (FK)
满足2和3。 但它也满足1(因为favouriteChildId NOT NULL不允许创建没有子项的父记录)。 既然您已经有了上述内容,那么我将假设您真正的问题是如何使Child表中的parentId不为NULL。 通常,SQL中有规定,因此您可以执行以下操作
BEGIN TRANS
INSERT INTO TABLE1 (FK not checked yet)
INSERT INTO TABLE2 (FK not checked yet)
COMMIT (All integrity checked)
在这种情况下,“循环引用”将不是问题(请参阅DEFERRED) Mysql不支持它,因此您有以下选择 触发条件: 可以假设在插入父记录时已经知道一个喜欢的孩子,那么您可以拥有一个触发器,该触发器将在插入父表之前运行,并且 将喜欢的孩子插入子表以获取其ID 插入带有孩子ID的父记录 注意:问题在于这种方式可以正式满足条件,但是要首先插入子记录,您将不得不在父级中使用其他列,以便触发器可以知道子表中的其他字段或插入空白记录(在无论哪种情况,设计都不干净) 通过安全诚信 可以将以上内容实现为存储过程,而无需在父表级别上添加其他字段。但是,通常可以绕过存储过程,因此它不符合实际的完整性规则。 有一种通用的方法可以使通过存储过程实现的某些事情符合完整性规则-即删除这些表对所有常规用户(和应用程序)的写许可权,并仅允许通过存储过程更改数据。 编辑: 关于触发器,还有一种方法可以使用触发器来实现规则,即接受您必须单独插入记录,并且必须同时拥有破坏业务规则的数据。 在这种情况下,您可以为父记录设置STATUS属性(例如:COMPLETE与INCOMPLETE),并将favouriteChildId设置为NULLable FK,但是将状态更新为COMPLETE时,可以触发检查是否遵守完整性。 这需要附加的列,但可以使情况变得更加整洁(您实际上可以在此表上创建一个视图,该视图仅公开仅COMPLETE的记录,有效地使其看起来像具有FK NOT NULL的表)。     
您可以(在一定程度上)建模其他约束:
Parent Table
parentId (PK)

Child table:
childId  (PK)
parentId (FK)

Is Favorite table:
childID (PK)(FK)

Is Least Favourite table:
ChildID (PK)(FK)
总会在“最喜欢的孩子”中插入一行;仅当存在最不喜欢的孩子时,才会在“最不喜欢”中插入一个:在视图上由触发器完成的插入,更新,删除;在表上通过左联接进行选择。 这不涉及“收藏夹子关系”的强制性质-必须由插入/更新/删除触发器来处理。     
如果仅深一层:
Parents ( ParentID, Title, etc )
Children ( ChildID, ParentID, Title, etc )
每个
Child
必须始终精确地具有1个
Parent
,而
Parents
始终具有
>= 0 Children
。 (没有办法解决。) 如果深度较深(未知):
Items ( ItemID, ParentItemID NULL, Title, etc )
很简单:
Items.ParentItemID = Items.ItemID
编辑 如果您需要多个(未知)级别,则查询将是多个,并且缓存总结果将是一个非常非常好的主意。 (每个孩子都会有另一个查询来获取它的直接孩子等)。     

要回复问题请先登录注册