使用循环引用设计关系数据库
Posted
技术标签:
【中文标题】使用循环引用设计关系数据库【英文标题】:Design relational database with circular reference 【发布时间】:2012-09-06 00:38:07 【问题描述】:想象一下面包店。我有一张产品表,该表与配方表具有一对多关系,而配方表又与成分具有一对多关系。问题是我有一个蛋糕,但其中一种成分是糖霜,它本身就是一种产品(你不能把糖霜分解成单独的部分,因为糖霜适用于很多东西,而且蛋糕上的糖霜量可能需要更改)。这种设置的桌子设计是什么?
【问题讨论】:
“公式”和“食谱”是一回事,对吧?同一个产品可以有多个配方吗? IE。如果你用不同的方式做蛋糕,它还应该被认为是同一个蛋糕吗?您的陈述:“与公式表具有一对多关系的产品” 似乎暗示了这一点,但我不确定您是在描述数据的基本属性,还是只是在描述当前的数据库设计(可能与数据的实际外观不同)。 【参考方案1】:成分表中的两列怎么样,一列用于实际成分,另一列将指向其他食谱。任何给定的行只会设置一个。
使用两列也可以强制执行参照完整性。
【讨论】:
【参考方案2】:您正在寻找的实际上是一种常见的数据库设计模式,称为材料清单。
这是一个很好的blog about bill of materials。
为了更轻松地使用此类设计所涉及的非层次树结构,您可以使用一种称为访问数的物理实现技术,我在对this question 的回答中对此进行了详细描述。
【讨论】:
【参考方案3】:您似乎只有两个对象:公式和东西。一个公式用其他东西来描述东西。一件东西可能是也可能不是产品。这是一个二元属性:第三个表。该方案将类似于:
Stuff
-----
id : integer
name : string
FormulaPairs
------------
stuff_described_id : integer
ingredient_id : integer
amount : float
Product
-------
stuff_id : integer
查询示例:
获取Apple Pie的所有成分ID:
select ingredient_id from Stuff s inner join FormulaPairs p
where s.id == p.stuff_described_id and s.name == 'Apple Pie'
获取所有产品名称:
select name from Stuff s inner join Product p where s.id == p.stuff_id
【讨论】:
以上是关于使用循环引用设计关系数据库的主要内容,如果未能解决你的问题,请参考以下文章