规范一个非常大的桌子

iCo*_*fee 9 sql sql-server normalization sql-server-2008 database-normalization

我面临以下问题.我有一张非常大的桌子.此表是以前参与该项目的人员的遗产.该表位于MS SQL Server中.

该表具有以下属性:

  1. 它有大约300列.它们都有"文本"类型,但其中一些最终应该代表其他类型(例如,整数或日期时间).因此,必须在使用它们之前将这些文本值转换为适当的类型
  2. 该表有超过100毫米的行.桌子的空间很快就会达到1TB
  3. 该表没有任何索引
  4. 该表没有任何实现的分区机制.

正如您可能猜到的,无法对此表运行任何合理的查询.现在人们只在表中插入新记录,但没有人使用它.所以我需要对其进行重组.我计划创建一个新结构,并使用旧表中的数据重新填充新结构.显然,我将实施分区,但这不是唯一要做的事情.

该表最重要的特征之一是那些纯文本字段(即它们不必转换成另一种类型)通常具有频繁重复的值.因此,给定列中实际值的变化范围为5-30个不同的值.这导致了进行规范化的想法:对于每个这样的文本列,我将创建一个附加表,其中包含可能出现在此列中的所有不同值的列表,然后我将在此附加表中创建一个(tinyint)主键,然后将在原始表中使用适当的外键,而不是将这些文本值保留在原始表中.然后我将在这个外键列上放一个索引.以这种方式处理的列数约为100.

它提出了以下问题:

  1. 这种标准化真的会增加这些100个领域中某些领域的条件速度吗?如果我们忘记了保留这些列所需的大小,那么由于初始文本列与tinyint-columns的替换,是否会增加性能?如果我不进行任何规范化并简单地在这些初始文本列上放置索引,那么性能是否与计划的tinyint-column上的索引相同?
  2. 如果我执行所描述的规范化,那么构建一个显示文本值的视图将需要将我的主表加入大约100个附加表.一个积极的时刻是我将为对"主键"="外键"进行那些连接.但是仍然应该加入相当多的表.这是一个问题:对此视图的查询性能是否与初始非规范化表的查询性能相比是否会更差?SQL Server Optimizer是否真的能够以允许规范化的优势的方式优化查询?

抱歉这么长的文字.

感谢您的评论!

PS我创建了一个关于加入100个表的相关问题; 加入100张桌子

Mic*_*son 6

除了针对它运行的查询的速度之外,你还会发现规范化数据的其他好处......例如大小和可维护性,这本身就足以证明它的正常化......

但是,它也可能提高查询速度; 当前包含300个文本列的单行是巨大的,并且几乎肯定超过了存储行数据页面8,060字节限制 ...而是存储在ROW_OVERFLOW_DATALOB_DATA分配单元中.

通过规范化减少每行的大小,例如用TINYINT外键替换冗余文本数据,以及还将不依赖于这个大表的主键的列移到另一个表中,数据不应再溢出,而你还可以在每页存储更多行.

至于通过执行JOIN获取规范化数据而增加的开销......如果正确索引表,则不应增加大量开销.但是,如果确实添加了不可接受的开销,则可以根据需要选择性地对数据进行反规范化.


Gor*_*off 5

这是否值得付出努力取决于值的长度。如果值是州缩写(2 个字符)或国家/地区代码(3 个字符),则生成的表格甚至会比现有表格更大。请记住,您需要包含引用表的主键。这通常是一个整数并占用四个字节。

这样做还有其他充分的理由。具有包含有效值列表的参考表可保持数据库的一致性。参考表可用于验证输入和报告目的。可以包含附加信息,例如“长名称”或类似的信息。

此外,SQL Server 会将 varchar 列溢出到其他页面上。它不会溢出其他类型。您只有 300 列,但最终您的记录数据可能会接近单页数据的 8k 限制。

而且,如果您决定继续,我建议您在列中寻找“主题”。可能有可以组合在一起的多组列。. . 详细的停止代码和停止类别、简短的企业名称和完整的企业名称。您正在走上数据建模之路(一件好事)。但是在非常低的级别(管理 100 个参考表)而不是识别一组合理的实体和关系时要谨慎。