ank*_*981 1 mysql database-design
这个问题是针对有经验的开发人员的。
我的朋友最近告诉我,他的雇主有一个遗留代码库,其 MySQL 数据库的大小现在已经增长到 800 GB 左右。有趣的是,很少有外键约束,导致一些重复的坏数据,但由于这不会损害任何东西(显然),没有人会过度担心。
现在我无法想象没有外键的生活,所以当我问他为什么没有这样的检查时,他回答说外键是数据库必须维护的另一个索引,占用更多空间。
是的,空间。所以这是我的问题:索引可以占用多少空间?10% 的数据库?20%?即使他的推理是错误的,不可否认外键会导致性能下降。作为一名开发人员,一旦数据库大小接近 1 TB,您会放弃外键,而是依靠代码来进行适当的内务处理吗?
Blr*_*rfl 11
...外键是数据库必须维护的另一个索引
我认为您的同事可能认为必须对包含外键的列进行索引,但情况并非总是如此。(请参阅下面 ypercube 的评论。)外键不是模式赋予特殊含义的值以外的任何东西。为此类列建立索引的决定与任何其他列的决定相同:如果它经常成为选择标准的主题(即,WHERE
子句的一部分),请根据您的 DBMS 的首选做法对其进行索引。
索引在父表的主键列中起作用,因为这些列满足上述条件。稍后会详细介绍。
...并占用更多空间。
这个领域的几乎所有东西都是空间/时间的权衡,索引就是其中之一:你在写入时消耗更多的存储空间,而在读取时消耗更少的时间。很难说向表添加索引不会消耗额外的空间,因为它确实如此。在没有整个模式的上下文的情况下做出这些类型的决策是见树不见林。
正如 Codd 所描述的那样,规范化是后来成为DRY 原则的一个非常早期的应用。非标准化数据本质上是重复的;标准化数据不是。子表中的引用(必然)是重复的,但优点是比原始表小。(标准化更多是为了保持完整性而不是空间,但这是另一个讨论。)
例如,1600 Pennsylvania Avenue
存储在非规范化表的一百万行中的一百万个字符串副本占用 25 MB。将该字符串移动到一个单独的地址表(它只存储一次),使用一个八字节的数字外键引用它一百万次,整个混乱占用 8 MB 加上实际字符串的 25 个字节。这节省了大约 67% 的空间。
如果地址表(父)由其主键索引,则此外键关系在性能方面可能会更好。该索引要小得多,因为规范化的 N:1 性质意味着,平均而言,要索引的行将更少,并且索引不需要经常更新。
没有看到架构很难说,但缺乏规范化可能是数据库最初增长到 800 GB 的原因。
索引可以占用多少空间?
笼统地说,这是一个很难回答的问题。大多数形式的索引背后的想法是允许遍历少量数据以在大型语料库中定位某些内容。一个副作用是用于表示它的数据结构往往会变得更小。也就是说,设计不当或选择不当的机制与病态数据相结合可能导致索引比原始数据大得多。相反,更常见的情况是索引是一小部分。我对全文索引器做了很多工作,发现它们往往会消化不到 5% 的原始数据。但这仅适用于我的用例,可能不适用于其他任何人。