哪种表结构被认为是更好的规范化?
例如
注意:idType告诉评论发生在哪个上,而subjectid是评论发生的项目的ID。
使用idType为subjectid的文本命名标识符。
commentid ---- subjectid ----- idType -------------------------------------- 1 22 post 2 26 photo 3 84 reply 4 36 post 5 22 status
与此相比。
commentid ---- postid ----- photoid-----replyid ----------------------------------------------- 1 22 NULL NULL 2 NULL 56 NULL 3 23 NULL NULL 4 NULL NULL 55 5 26 NULL NULL
我正在看他们两个,我不认为在第一个表格中我可以将它与外键约束相关联=(即如果帖子或照片被删除则注释被删除),其中第二个是可能的,你会如何处理类似的问题,记住数据库需要扩展加班和数据完整性也很重要=)。
由于
答案 0 :(得分:1)
如果稍微不完整,则第一个更规范化。您可以采取几种方法,最简单的(严格来说,最“正确”)将需要两个表,具有明显的FK约束。
commentid ---- subjectid ----- idType
--------------------------------------
1 22 post
2 26 photo
3 84 reply
4 36 post
5 22 status
idType
------
post
photo
reply
status
如果您愿意,可以使用char(1)或类似物来减少varchar对键/索引长度的影响,或者如果您打算使用ORM,则可以使用ORM。 NULL总是很麻烦,如果你开始看到它们出现在你的设计中,如果你能找到一种方便的方法来消除它们,你会更好。
第二种方法是我在处理超过1亿行时更喜欢的方法:
commentid ---- subjectid
------------------------
1 22
2 26
3 84
4 36
5 22
postIds ---- subjectid
----------------------
1 22
4 36
photoIds ---- subjectid
-----------------------
2 26
replyIds ---- subjectid
-----------------------
3 84
statusIds ---- subjectid
------------------------
5 22
当然还有(略微非规范化的)混合方法,我广泛使用大型数据集,因为它们往往很脏。只需为预定义的idTypes提供特化表,但在commentId表上保留一个adhoc idType列。
请注意,即使是混合方法也只需要2倍于非规范化表的空间;并通过idType提供简单的查询限制。然而,完整性约束不是直接的,是对类型表的派生UNION的FK约束。我的一般方法是在混合表或等效的可更新视图上使用触发器来提升对正确子类型表的更新。
简单方法和更复杂的子类表方法都可以工作;仍然,在大多数情况下,KISS适用,所以我怀疑你应该只是引入一个ID_TYPES表,相关的FK,并完成它。