为什么有人会通过执行以下操作将实体(例如用户)分发到多个表中:
user(user_id, username)
user_tel(user_id, tel_no)
user_addr(user_id, addr)
user_details(user_id, details)
您是否从此数据库设计中获得了任何加速奖励?这是非常反直觉的,因为看起来执行链接连接来检索数据听起来比使用选择投影更糟糕。
当然,如果通过仅使用user_id和用户名执行其他查询,那就是加速,但值得吗?那么,真正的优势在哪里,哪种兼容的工作方案适合这种数据库设计策略呢?
LATER EDIT:在这篇文章的详细信息中,请假设一个完整的,独特的实体,其属性的数量不变(例如,汽车只有一种颜色,而不是两种,用户有只有一个用户名/社交秒号码/预科号码/家庭住址/电子邮件/等等。也就是说,我们不是处理一对多的关系,而是一对一,完全一致的实体描述。在上面的示例中,这就是将单个表“拆分”为与其具有的非主键列一样多的表的情况。
答案 0 :(得分:1)
通过以这种方式拆分用户,每个用户只有1行用户,它在user_tel,user_details,user_addr
中分别链接到0-n行这反过来意味着这些可以被认为是可选的,和/或每个用户可以有多个链接到它们的电话号码。总而言之,这是一个比硬编码更具适应性的解决方案,因此用户总是拥有最多1个地址,最多1个电话号码。
替代方法是使用ie user.telephone1
user.telephone2
等,但这种方法与3NF(http://en.wikipedia.org/wiki/Third_normal_form)相反 - 基本上你引入了很多列来存储同一块信息
修改
基于OP的额外编辑,假设每个用户将具有正好0或1的每个电话,地址,详细信息和 NEVER ,然后将这些信息存储在单独的表中太过分了。使用列user_id,username,tel_no,addr,details存储在单个用户表中会更为明智。
如果内存服务,这在3NF内完全没问题。您说这不是关于正常形式,但是如果认为每个数据都与该特定用户直接相关,则可以将其放在表格中。
如果您稍后将表格扩展为具有telephone1,phone2(例如)则会违反1NF。如果您有重复的字段(即多个用户共享一个地址,这完全合理),那么违反了2NF,这反过来违反了3NF
关于违反2NF的这一点可能就是为什么有人这样做了。
答案 1 :(得分:1)
这个设计的作者或许认为在这样的“稀疏”结构中存储NULL可以比在单个表中“在线”更有效地实现。这个想法可能是将(1 , "john", NULL, NULL, NULL)
中的行存储为(1 , "john")
表中的user
,而其他表中根本不存储任何行。为此,NULL必须大大超过非NULL(并且必须以正确的方式“混合”),否则这种设计会变得更加昂贵。
此外,如果您不断选择单个列,这可能会有所帮助。通过将列拆分为单独的表,您可以从存储角度将它们“缩小”,并在此特定情况下降低I / O (但通常不会)。
在我看来,这种设计的问题远远超过了这些好处。