假设我有两个表:来源和文章,我希望阅读具有特定细节的文章,我也可以 (1)对两个表使用join;要么 (2)将详细信息复制到文章记录中(这将使数据单元更大,但查询将非常简单)。 哪个更有效率?
答案 0 :(得分:3)
取决于数据。假设您有大量文章和小作者表。如果你想做很多查询,这些查询会得到一些文章数据和作者的名字(默认情况下在文章表中),那么你就可以对每个“作者”行进行简单的主键查找,并且表可能适合内存,因此在文章表中包含作者姓名不会带来巨大的性能提升。此外,这个denormalization也会使“文章”表格变得更大(每个作者的名字都会重复多次),因此它会占用更多的缓存。
另一方面,如果您想查询每个作者的文章数量,那么从两个表中获取这些数据意味着每次都会聚合很多行。但是如果你在“作者”表中包含这个数字,那么获取它只意味着一次查找,并且每个添加的文章都会增加。因此,如果你对这种结果感兴趣,非规范化可能是有意义的。
答案 1 :(得分:3)
会更有效率吗?
简单地说(也许太简单了):你正在为cpu周期交换内存 - 这可能会导致更糟糕的可缓存性并降低性能。
正确回答问题的唯一方法是您的环境并衡量效果。确保包含“正确”索引表。为数据库创建一个真实的负载 - 例如确保你没有反复敲击相同行的缓存。
提前问自己是否从性能提升(1%,10%,100%)开始非规范化是值得的。
答案 2 :(得分:2)
取决于,您想要数据库中的重复数据吗?然后,当您需要更新某些内容时,您必须在多个位置更新它。有时它可以有一些重复的数据,但是为了避免连接在一起可能会对你产生负面影响。
答案 3 :(得分:2)
这是一个设计决定,这意味着没有你分析的所有细节(目标,约束,用户要求等),而是我使用的一些经验法则;
1 /两个表之间的连接通常不是非常昂贵并且是一个容易调整的情况(例如,你说几乎没有更新,我认为没有广泛的插入/删除,并且大多数选择因此这很可能索引将加速的情况)
2 /在设计模式时,首先将其标准化为可能/合理的最高程度,然后当真实场景证明它是值得的时候,反规范化。 (并且通常决定对特定项目进行规范化然后非规范化工作相当好,未能正常化通常不会产生良好的结果。
3 /在一段时间内,标准化会为自己付出代价(在您尝试对系统进行一些更改的后几年,一个精心设计的基础会受到真正的欢迎和称赞)4 / Denormalising在我看来最适合报告将要使用adhoc查询的情况。或者换句话说,我看到反规范化的主要原因是让具有高查询 - 写入/使用率的报告编写者的生活更轻松
答案 4 :(得分:1)
如果优先考虑读取性能,则可以使用Materialized Views。由于MySQL不支持它们(我认为),你可以simulate them。
此解决方案可让您保持原始数据库的标准化,但您可以通过MV的简单查询获得性能。
答案 5 :(得分:0)
复制数据可能会带来更多性能。注意我写的可能是因为你会遇到缓存问题。另一方面,当复制数据时,您的系统更难以维护(顺便说一下,您违反了DB正常形式)。如果您需要支付的价格只是一个表加入,那么只需支付它。请确保您在要加入的列上有indexex,然后价格根本不会那么昂贵。
底线:除非是关键,否则永远不要复制数据。