想知道,将一个表分成三个表,每个表大约有 6 列并使用外键,还是使用一个表并有 15 列更好?
大多数字段都是 varchars,偶尔会有一些数字。数据库是MySQL。
通过更好,我最感兴趣的是插入和选择速度。
只是为了澄清这是该特定表的一对一案例,数据主要是用户数据,属性将是位置年龄活跃性别等仅与一个用户有关。是的,我正在尝试将热柱与冷柱隔离开来
想知道,将一个表分成三个表,每个表大约有 6 列并使用外键,还是使用一个表并有 15 列更好?
大多数字段都是 varchars,偶尔会有一些数字。数据库是MySQL。
通过更好,我最感兴趣的是插入和选择速度。
只是为了澄清这是该特定表的一对一案例,数据主要是用户数据,属性将是位置年龄活跃性别等仅与一个用户有关。是的,我正在尝试将热柱与冷柱隔离开来
如果表具有一对一的关系(表 1 中的每一行将与表 2 中的一行和表 3 中的一行相关联),那么
INSERT
andSELECT
语句可能会更慢(你有相同的数量要插入的数据,加上外键,以及插入时可能要更新的其他索引;选择时,您需要将表连接在一起的额外开销)。然而,大多数时候,在讨论这类事情时,Table2 和 Table3 中的每一行都将绑定到 Table 1 中的多行(或者,Table3 将绑定到 Table2 而不是 Table 1 中的多行)。例如,如果您有一个
employee
包含字段division
、division_address
、division_city
、division_state
和的表division_zip
,您可以将它们移动到一个division
表中;并且,假设每个员工都与一个部门相关,而每个部门可以有很多员工。在这种情况下,an
INSERT
可能更快(索引结构可能有所不同,但在大多数情况下,您将在每行中插入 6 列,而不是 15 列),而 aSELECT
可能更慢(必须将表连接在一起才能得到所有数据都涉及额外的工作;但是,在某些情况下,如果 Table2 或 Table3 上的索引提供更快的方法来缩小需要检查的总行数,查询可能会更快;即使在最坏的情况下,我们也应该减少处理查询时必须读入的数据量)。但是,不要忽视规范化的其他好处。通过只输入
division
一次信息(使用我上面的例子),我们避免了导致每个部门在员工表中有 7 个不同名称的拼写错误。我们使部门名称或地址的更新变得更加简单(并避免在发生这种情况时锁定员工表)。而且,我们(在大多数情况下)在数据库中存储的冗余数据要少得多,这也为我们节省了空间。但是,您问题的最佳答案可能是“试试看”。我们不知道您的数据,也不知道查询速度的差异(比如 2%)对您的环境是否至关重要。
一般来说,我会建议从一个更规范化的数据库开始(同样,就我的例子而言,拆分
employee
和division
),并且只有在性能不可接受时才进行非规范化(division
放回employee
),并且测试表明合并两个表将使性能恢复达到可接受的标准。这是因为为每个员工输入的部门数据并将其准确地组合到您的实际部门结构中(由于上述拼写错误等)比复制规范化division
数据并复制到employee
绑定到的每一行要困难得多它。这是一种常见的非规范化模式,称为“垂直分区”。
这可能有用的场景是当您的大多数查询仅覆盖表中的少量列时。如果不需要的列很大(例如 blob)。
通过“折叠”较少使用的列,您可以在每页中容纳更多行。还有更多在各种缓存中。
此外,假设较少使用的数据将从压缩中受益,但热数据不会。现在您已将它放在另一个表中,您可以在不影响另一个表的情况下对其进行压缩。
这样做的代价是插入和删除会变慢,因为必须进行额外的查询、参照完整性检查、获取额外的锁、维护外键的冗余索引。
对键列的更新将更加昂贵,因为必须级联到其他行及其索引。
跨多个表的读取必须合并,因此需要更长的时间。
更多的磁盘空间将被用作键列将被存储并为每个表建立索引。
数据库现在更复杂,更难维护。
与几乎所有优化一样,除非需要,否则不要这样做。
我建议在三种有限情况下进行垂直分区:
TEXT
某些文档或图像的列(在 a 中BLOB
)。即使这是可疑的,因为 InnoDB 会自动执行类似的操作。NULL
在主表中创建列集,而是LEFT JOIN
对辅助表使用 a 并在数据丢失时省略该行。这是否帮助大于伤害是值得怀疑的。进入垂直分区的一种意外方式是,当您需要为具有大量行的表添加一些新列,但无法承受添加列的停机时间时。相反,制作一个平行表来保存新列。但是请注意,
ALTER TABLE .. ALGORITHM=IMPLACE
大多数情况下不需要这种技术。40 列开始太多了;400太多了。也就是15本身不是问题。
至于性能,是的,如其他答案所述,任一方向都会存在一些性能问题。
如果您不是在谈论数百万行,请不要担心。
我的经验法则之一:如果我不能期望 10% 的改进,请花时间在其他地方寻找优化。
底线:做最适合你的事;担心以后优化。