例如,假设我有一个名为用户的实体和一个名为 profile_picture 的实体。用户可能没有或一张个人资料图片。
所以我想,我只想用这个字段创建一个名为“user”的表:
user:user_id,profile_picture_id (我离开了所有其他属性,如姓名,电子邮件等,以简化此事)
好的,所以如果用户没有profile_picture,那么我的关系模型中的id将为NULL。现在有人告诉我,我必须避免将任何内容设置为NULL,因为NULL是“坏”。
您如何看待这个?我是否必须从用户表中删除该profile_picture_id并使用user_id,profile_picture_id创建类似user__profile_picture的链接表?
在数据库设计中哪些被认为是“更好的做法”?
答案 0 :(得分:3)
这是一个非常合理的模型。是的,您可以采用为1:1关系创建连接表的方法(或者,更好一点,您可以将user_id
放在profile_picture
表中,但除非您认为用户很少会有个人资料图片,那可能是一个不必要的复杂情况。
可读性是关系设计的重要组成部分。您认为个人资料图片是用户的属性,还是用户是个人资料图片的属性?您从逻辑意义上开始,然后在您发现必要通过性能测试时优化直观设计。不要过早地优化。
答案 1 :(得分:3)
“NULL是坏的”是一个相当糟糕的借口,有理由做(或不做)某事。
也就是说,您可能希望将其建模为依赖表,其中user_id既是主键,也是现有表的外键。
这样的事情:
Users UserPicture Picture
---------------- -------------------- -------------------
| User_Id (PK) |__________| User_Id (PK, FK) |__________| Picture_Id (PK) |
| ... | | Picture_Id (FK) | | ... |
---------------- -------------------- -------------------
或者,如果图片是依赖对象(没有与用户无关的有意义的生命周期),请将UserPicture和Picture表合并为User_Id作为PK并丢弃Picture_Id。
实际上,再次查看它,这实际上并没有获得任何东西 - 你必须做一个左连接而不是一个空列,所以另一个场景(把User_Id放在Picture表中)或者只是离开“用户”表中的Picture_Id同样有意义。
答案 2 :(得分:3)
NULL不是“坏”。这意味着“我不知道。”您或您的架构承认它并没有错。
答案 3 :(得分:2)
您的user
表格不应该有一个名为profile_picture_id
的可空字段。最好在user_id
表中添加profile_picture
列。它当然应该是user
表的外键。
答案 4 :(得分:2)
因为什么时候可以为空的外键关系“不好?”老实说,在这里引入另一张表似乎有些愚蠢,因为没有可能有多张个人资料图片。您当前的架构超出了可接受范围。 “null is bad”这个论点在我的书中没有任何用处。
如果您正在寻找稍微好一点的架构,那么您可以执行类似操作,例如从users表中删除“profile_picture_id”列,然后在图片表中创建一个“user_id”列,并返回外键关系用户。然后,您甚至可以对user_id外键列强制执行UNIQUE约束,这样您就不能在该表中拥有多个user_id实例。
编辑:值得注意的是,如果您决定允许用户将来拥有多个个人资料图片,这种替代架构可能会更具前瞻性。你可以简单地在外键上删除UNIQUE约束,然后就完成了。
答案 5 :(得分:1)
确实不建议使用多个具有空值的列。我建议你使图片表成为用户表的弱实体,并在两者之间建立识别关系。图片表条目取决于用户ID。
答案 6 :(得分:1)
使个人资料图片成为用户桌面上可以为空的字段并完成。有时人们为了正常化而正常化。 Null非常好,在DB2中,NULL是值的第一类公民,其中NULL包含在索引中。
答案 7 :(得分:-6)
我同意NULL很糟糕。它不是关系数据库风格。
通过引入名为UserPictureIds的额外表来避免Null。它有两列,UserId和PictureId。如果没有,它就没有相应的行,而用户仍在Users表中。
由于同伴压力而进行编辑
这个答案不是关注为什么NULL是坏的 - 而是关于如何避免在数据库设计中使用NULL。
为了评估(NULL == NULL)==(NULL!= NULL),请参阅评论和谷歌。