如果我的实体与另一个实体有(0-1):1的关系,我将如何在数据库中对其进行建模?

时间:2009-12-29 14:39:30

标签: database database-design

例如,假设我有一个名为用户的实体和一个名为 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的链接表?

在数据库设计中哪些被认为是“更好的做法”?

8 个答案:

答案 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),请参阅评论和谷歌。