SQL:可选外键
我有以下表格...
“楼层”(有很多)“区域”(有很多)“资产”,
然后我有一个“任务”表。
“任务”可以分配给“区域”或“资产”;所以我在“任务”表中有两列,名为areaId和assetId,其中一列必须有一个值。
第一个问题:如何查询某个楼层发生的所有任务?
第二个问题:如何强制引用完整性?
第三个问题:这种方法值得推荐吗?如果没有的话欢迎任何建议。
非常感谢
ETFairfax提供的任何答案
I have the following tables....
"Floor" (which has many) "Area" (which has many) "Asset",
then I have a "Task" table.
A "Task" can be assigned to either an "Area" or an "Asset"; so I have two columns in the "Task" table named areaId and assetId, one of which must have a value.
1st question: How do I query all tasks which have occurred on a given floor?
2nd question: How do I enforce referential integrity?
3rd question: Is this approach recommended? Any suggestions welcome if not.
Many thanks for any answers given,
ETFairfax
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个问题:
应该告诉您您正在尝试构建的查询的形状。 (当然,如果你已经有了FloorID,你实际上不需要查询Floor表)
第二个问题:
或者,你也可以让AreaID不为空,在Asset表上添加一个唯一约束(AreaID,AssetID) ,然后使资产表的外键引用两列 - 这确保了如果提供了 AssetID,它会链接到属于正确 AreaID 的资产。 中总是有一个 AreaID,这也将简化问题 1 的答案
如果任务第三个问题
:如果不知道这一切将如何使用,则很难说。我不认为这是一个不合理的方法。
1st question:
should give you the shape of the query you're trying to build. (Of course, you don't actually need to query the Floor table if you already have a FloorID)
2nd question:
Or, alternatively, you can make AreaID not null, add a unique constraint on the Asset table across (AreaID,AssetID), and then make the foreign key to the Asset table reference both columns - this ensures that if an AssetID is supplied, it's linking to an Asset that belongs to the correct AreaID. This would also simplify the answer to Q1, if there's always an AreaID in Task
3rd question:
difficult to say without knowing how this is all going to be used. I don't think it's an un-reasonable approach.
让我们从问题 3 开始,这是一个有效的方法吗?如果它模拟现实的话那就是了。如果楼层、区域和资产是不同的事物,具有比共同属性更多的不同属性,并且如果对它们的操作往往不同,那么您的 3 表方法就很好。
对于第二个问题,只需将外键放在areaId和assetId上即可。外键中可以使用空值。
但是您需要一个表级约束,不允许它们都为空,也不允许它们都被填充。
最后,解决了模式和约束问题后,我们就可以进行查询了,这非常简单。这个想法是,一些任务通过资产通过区域连接到楼层,而其他任务则通过区域直接连接到楼层。为此,您需要将两个查询合并在一起:
这将返回正确的结果,但可能不是最快的。在每个子查询上放置一个 WHERE 子句来过滤掉 NULL/NOT NULL 可能会加快速度,您必须对此进行调查。
Let's start with question 3, is this a valid approach? It is if it models reality. If floors, areas, and assets are unlike things, with more distinct properties than properties in common, and if the operations on them tend to be different, then your 3 table approach is fine.
For the second question, simply put foreign keys onto both areaId and assetId. Null values are ok in foreign keys.
But you need a table level constraint that will not allow both of them to be null, nor allow both of them to be populated.
Finally, having settled the issue of schema and constraints, we can do the query, which is pretty straightforward. The idea is that some tasks join through asset through area to floor, while others join through area straight to floor. For that you need to union two queries together:
This will return the correct results but may not be the fastest. Putting a WHERE clause on each subquery to filter out NULL/NOT NULL may speed it up, that you would have to investigate.