Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 将一个实体分散/分布到多个表中,而不是单个表中_Mysql_Database_Database Design_Query Optimization_Database Optimization - Fatal编程技术网

Mysql 将一个实体分散/分布到多个表中,而不是单个表中

Mysql 将一个实体分散/分布到多个表中,而不是单个表中,mysql,database,database-design,query-optimization,database-optimization,Mysql,Database,Database Design,Query Optimization,Database Optimization,为什么有人会通过执行以下操作将实体(例如用户)分发到多个表中: user(user_id, username) user_tel(user_id, tel_no) user_addr(user_id, addr) user_details(user_id, details) 这种DB设计有助于提高速度吗?这是非常违反直觉的,因为执行链式联接来检索数据似乎比使用选择投影糟糕得多 当然,如果只使用用户id和用户名执行其他查询,这是一种加速,但值得吗?那么,真正的优势在哪里?适合这种DB设计策略的兼

为什么有人会通过执行以下操作将实体(例如用户)分发到多个表中:

user(user_id, username)
user_tel(user_id, tel_no)
user_addr(user_id, addr)
user_details(user_id, details)
这种DB设计有助于提高速度吗?这是非常违反直觉的,因为执行链式联接来检索数据似乎比使用选择投影糟糕得多

当然,如果只使用用户id和用户名执行其他查询,这是一种加速,但值得吗?那么,真正的优势在哪里?适合这种DB设计策略的兼容工作场景是什么


稍后编辑:在这篇文章的详细信息中,请假设一个完整、唯一的实体,其属性在数量上没有变化(例如,一辆车只有一种颜色,而不是两种颜色,一个用户只有一个用户名/社会证号码/入学号码/家庭地址/电子邮件等。也就是说,我们处理的不是一对多关系,而是一对一、完全一致的实体描述。在上面的示例中,这只是一个表被“拆分”的情况。)以这种方式拆分用户,每个用户正好有一行,该行链接到用户电话、用户详细信息、用户地址中的0-n行

这反过来意味着这些可以被视为可选的,和/或每个用户可能有一个以上的电话号码链接到他们。总而言之,这是一个比硬编码更具适应性的解决方案,因此用户总是有最多一个地址,最多一个电话号码

另一种方法是使用,即
user.telephone1
user.telephone2
等,但是这种方法不符合3NF()-本质上,您引入了许多列来存储相同的信息

编辑

根据OP的附加编辑,假设每个用户将精确地拥有0或1个电话、地址、详细信息,并且不再有这些信息,那么将这些信息存储在单独的表中是过分的。更明智的做法是将这些信息存储在一个单用户表中,其中包含user\u id、username、tel\u no、addr、details列

如果内存可用,那么在3NF范围内就完全可以了。您说过这与正常形式无关,但是如果每个数据段都被认为与特定用户直接相关,那么将其放在表中就可以了

如果您后来将表扩展为包含电话1、电话2(例如),那么这将违反1NF。如果您有重复的字段(即多个用户共享一个地址,这是完全合理的),那么这将违反2NF,进而违反3NF


违反2NF的这一点很可能就是有人这么做的原因。

此设计的作者可能认为,在这样的“稀疏”结构中存储空值比在单个表中“串联”更有效。其想法可能是存储行,如
(1,“john”,NULL,NULL,NULL)
就像
(1,“john”)
用户
表中一样,在其他表中根本没有行。要做到这一点,空值必须大大超过非空值(并且必须以正确的方式“混合”),否则这种设计很快就会变得更昂贵

此外,如果您经常选择单个列,这可能会有一定的好处。通过将列拆分为单独的表,您可以从存储角度使它们“更窄”,并在这种特定情况下降低I/O(但不是一般情况)


在我看来,这种设计的问题远远超过了这些好处。

我应该说,它不是需要注意的第三种标准形式,让我们假设它本身就是一个实体,如果执行所有这些连接,最终得到的数据完全是1对1的,没有冗余。我同意,一次使用可能有0或更多1电话不,这是空的。因此,今天的RDMS中有一种机制可以帮助处理这个问题。您要求提供这种数据库设计的方案,所以我给了您一个。我不完全确定您在这一点上寻找的是什么作为回应。如果每个字段始终只有一条数据,那么不可能一秒钟的时间等,然后将行作为用户表中的列就足够了。一个可能的理由可能是有一个带有数字ID的VARCHAR表,然后通过n:m联接表链接到用户,但是很难建议这样做有好处的情况。总之,你的问题对于你的p来说太模糊了问题。谢谢你,我试着对它进行了一些编辑,消除了一些模糊。我最初担心的是,除了这种方法有意义的琐碎场景之外,在哪里可以找到其他场景。因此,如果NF3没有被破坏,那么将所有实体属性作为列保留在同一个表中会更容易、更健康,而且很少有机会找到这样的场景以这种方式“分裂”这些实体确实证明了性能奖金的合理性。例如,如果实体有许多属性,但其中没有一个在逻辑上与任何其他属性相连接(违反FN3规则!),则从实体中选择属性1、属性2是否成本高昂.Thnx!请参阅我的更新,如果不将这些特定的信息分割出去,它实际上是2NF,可能会被破坏。在我的示例中,地址与每个用户没有直接关系,因为在给定的地址中可能存在多个用户。但是,这可能是一个大问题,也可能不是一个大问题,如果没有关于预期pur的详细信息,很难给出建议为这些表设置姿势。这种类型的拆分在某些情况下成本更高,而在其他情况下则非常有利,它实际上取决于数据的长度、体积以及访问方式。