多表之间的SQL映射
这是一个SQL设计问题。首先,设置。我有三个表:
- A,它是根据对链接服务器的查询自动填充的。该表中的数据不能更改;
- B,只有十几行,包含 As 集合的名称;
- AtoB,它是映射表,通过它将 As 组织成命名集合,两列上都有外键;
例如,A 包含:
- 长颈鹿
- 猫头鹰
- 老虎
且 B 包含:
- 西雅图动物园
- 圣何塞动物园
且 AtoB 包含:
1 ,1(西雅图的长颈鹿)
2,1(西雅图的猫头鹰)
3,1(西雅图的老虎)
2,2(圣何塞的猫头鹰)
现在,问题是:
我被要求在其中一些集合中包含 A 中找不到的项目。因此,我创建一个表 C,其标识和名称列与 A 相同,并填充它。与前面的示例保持一致,假设 C 包含:
- Dragon
问题是,如何在 AtoB 中包含 C 中的项目?如果我需要在西雅图动物园养一条龙怎么办?
我天真的第一直觉是创建一个包含 A 和 C 的并集的视图 V,并将 AtoB 修改为 VtoB。这就是我的天真得到回报的地方:人们无法为视图创建外键。
我怀疑存在一种标准、正确的方法将一个或多个 A 或 C 与 B 相关联。
This is a SQL design question. First, the setup. I have three tables:
- A, which is automatically populated based on a query against a linked server. The data in this table cannot be changed;
- B, which has just a dozen or so rows, containing the names for collections of As;
- AtoB, which is the mapping table by which As are organized into named collections, with foreign keys on both columns;
For example, A contains:
- Giraffe
- Owl
- Tiger
And B contains:
- Seattle Zoo
- San Jose Zoo
And AtoB contains:
1,1 (Giraffe in Seattle)
2,1 (Owl in Seattle)
3,1 (Tiger in Seattle)
2,2 (Owl in San Jose)
Now, the problem:
I've been asked to include in some of these collections items not found in A. So, I create a table, C, with the same identity and Name columns as A, and populate it. In keeping with the earlier example, let's say C contains:
- Dragon
The question is, how do I include items from C in AtoB? What if I need to include a Dragon in the Seattle Zoo?
My first instinct, being naive, was to create a view V containing the union of A and C, and modifying AtoB to be VtoB. That's where my naivety paid off: one cannot create a foreign key to a view.
I suspect that there's a standard, correct means of relating one or more A OR C with a B.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为了扩展 Arthur Thomas 的解决方案,这里有一个在子选择中没有 WHERE 的
union
,以便您可以创建通用视图:然后,您可以执行如下查询:
To expand on Arthur Thomas's solution here's a
union
without the WHERE in the subselects so that you can create a universal view:Then, you can perform a query like:
如果您不能将龙放入 A 中,那么您将需要创建另一个表和另一个链接表。问题是创建一个需要存储的唯一数据集(另一个表),该数据集不能与 A 相同。由于它不是同一集,因此您不能再使用具有外部数据的链接表(AtoB)确保链接是来自集合 A 的引用的键。因此,您可以创建如下表:
imaginary_creatures
imaginary_creatures_to_b
稍后,当您想要获取 a 中的所有生物时动物园你可以做一个联盟
可能有更好的写法,但它应该适合你的目的。
If you can't put a Dragon in A then you will need to create another table and another link table. The problem is creating a unique set of data that needs to be stored (another table) that cannot be the same set as A. Since it isn't the same set then you can no longer use the link table (AtoB) which has foreign keys that ensure that the link is a reference from set A. So you could create a tables like this:
imaginary_creatures
imaginary_creatures_to_b
Later when you want to get all creatures in a zoo you can do a UNION
There may be a better way of writing that, but it should work for your purposes.
Arthur Thomas 有一个很好的解决方案,另一个可能的解决方案是在链接表中添加一列,指示它与哪个表(A 或 C)相关。然后通过触发器而不是外键来加强关系。但事实上,亚瑟的解决方案是做这类事情的首选方法。
Arthur Thomas has a good solution, the other possible solution is to add a column to the link table indicating which table (A or C) it is related to. Then enforce the relationships through triggers rather than foreign keys. But really Arthur's solution is the preferred way of doing this sort of thing.
你想要做的是将 Dragon 放入 A 中,如果你想选择 A 中的所有记录,无论它们在 AtoB 中是否有匹配的记录,请执行 LEFT OUTER JOIN。像这样的事情:
编辑:只有当您可以将新记录添加到 A 时,这才有效。我错过了您不能这样做的事实。我认为亚瑟托马斯的解决方案就是你想要的。
What you want to do is put Dragon in A, and if you want to select ALL records from A regardless of if they have a matching record in AtoB, do a LEFT OUTER JOIN. Something like this:
Edit: This would only work if you could add your new records to A. I missed the fact that you are not able to. I think Arthur Thomas's solution is what you want.