鉴于Person
和Item
Person Item
------- ------
Id <-----. Id
Name `---- PersonId
Label
如果有人和Item.Label
可能需要很少的不同值,那么采用等效模式可能是有意义的:
Person List Item
-------- ------ ------
Id .--> Id <--. Id
ListId --` `-- ListId
Name Label
这样很多人可以共享同一个列表。
从第二个模式到第一个模式的迁移是微不足道的。我的问题是,如何从第一个架构迁移到第二个?
挑战在于为
的每个可能结果选择一个代表Person
SELECT Label FROM Item WHERE PersonId = ?
我能够通过使用MS SQL服务器中的FOR XML
来解决问题。也就是说,
SELECT P.Id, (SELECT Label FROM Item WHERE PersonId = P.Id FOR XML) list
FROM Person P
然后只需SELECT MIN(P.Id) FROM ... GROUP BY list
来收集代表。我对这种解决方法不满意,并希望找到更纯粹的解决方案。
修改
SELECT p.Id, q.Id FROM Person p, Person q
WHERE NOT EXISTS ( --symmetric difference between
(SELECT Label FROM Item WHERE PersonId = p.Id) --and
(SELECT Label FROM Item WHERE PersonId = q.id))
应该是人员的等同关系,需要找到代表。我仍然不知道如何完成,这似乎效率很低。
答案 0 :(得分:0)
这取决于!我建议你把你的模型贴在你的业务逻辑上。 如果人们拥有预先制作的物品集,那么他就会创造一个表来保持这种逻辑。
考虑人们可以拥有“家庭版”,“专业版”或“标准版”。 在Edition_Items之间创建关系表是有意义的,因为该版本可以包含项目(A,B),(A,B,C,D)和(A,C)等。
你可以在它拥有的People和Edition之间创建一个关系表。在您的场景中,如果版本是“自定义”版本,即使您有两个包含相同的项目集,您可以认为它们是不同的集合(仅仅因为它们由不同的人拥有)。
因此,“Assembled Set”表可用作人与物品之间的关系表。
修改:
OP评论强制执行我的上一次陈述。 因此,您的“列表”表可以是人物和物品之间的关系表。
|People | |List| |List_Item| |Item|
|-------| |----| |---------| |----|
|P1, L1 | | L1 | | L1, I1 | |I1 |
|P2, L2 | | L2 | | L1, I2 | |I2 |
| L3 | | L2, I1 | |I3 |
| L4 | | L2, I1 |
看到它你可以问,为什么要保留List表?如果List有一些属性,那就是使用full:isDeleted,Description,CreateTime等
最后一个问题是什么?我们在列表中列出人员列表或人员参考(或创建另一个关系表?)
它依赖于: 1)人员名单是1-1关系? 2)谁先来? (鸡蛋和鸡肉问题?) 这通常是更好的质疑:谁能在没有另一个的情况下存在。