我有一个数据库表(称为Fields
),它有大约35列。其中11个总是包含大约每300.000行的相同常量值 - 并充当元数据。
这种结构的缺点是,当我需要更新这11列值时,我需要更新所有300.000行。
我可以将所有常用数据移动到另一个表中,并且只在一个地方更新一次,而不是300.000个地方。
但是,如果我这样做,当我显示字段时,我需要在两个表之间创建INNER JOIN's
,我知道这会使SELECT
语句变慢。
我必须说更新列比读取(显示)数据更少。
您如何建议我将数据存储在数据库中以获得最佳性能?
答案 0 :(得分:6)
我可以将所有常用数据移动到另一个表中,并且只在一个表中更新一次 地方,而不是300.000个地方。
即。理智的数据库设计和标准化。
这不是关于“许多空白字段”,它残酷地涉及大量冗余数据。你应该孤立的常数。单独的表。这也可能使事情变得更快 - 它允许数据库更有效地使用内存,因为您的数据库要小得多。
答案 1 :(得分:1)
我建议你去另外一张桌子,除非你隐瞒了一些重要的东西(当然最好尝试和测量,但我怀疑你已经知道了)。
你实际上也可以获得更快的选择:加入一个小桌子会比拿出300000次相同的数据更便宜。
答案 2 :(得分:0)
这是非规范化设计的典型例子。有时,非规范化是针对(SELECT)性能完成的,并且始终采用有意识的,可测量的方式。你真的测量过你是否获得了任何表现吗?
如果您的数据适合缓存,和/或JOIN非常昂贵 1 ,那么避免JOIN可能会带来一些性能优势。但是,非规范化数据更大并且会更快地推动缓存的限制,增加I / O并可能反转您从避免JOIN中获得的任何收益 - 实际上您可能失去表现。
当然,无论你能做多快,获取不正确的数据都是无用的。非规范化使您的数据库对数据不一致性 2 的抵抗力降低,并且性能差异必须非常显着才能证明这种风险。
1 这里的情况并非如此。
2 例如您是否考虑过并发环境中发生的情况,其中一个应用程序可能会修改现有行而另一个应用程序会插入一个新行但是使用旧值(因为第一个应用程序尚未提交,因此第二个应用程序无法知道有变化)?
答案 3 :(得分:0)
最好的方法是分离数据并用这11列形成第二个表,并将其称为一个MASTER DATA TABLE,它将具有主键。
此主键可以在第一个表中的30,000行中称为外键