Dim*_*ima 10 database-design sql-server
我正在设计一个将(可能)包含数千万条记录的项目表。某些项目在管理员“批准”之前将无法使用。“使用”是指这些项目在“批准”之前不会在任何其他表格中引用。在任何给定时间,多达 50% 的商品都可能“未获批准”。记录可能会被“批准”,但反之则不然。
我考虑了两种设计方案:
我认为第二种选择要好得多。位标志每行只占用一个字节,所以这不是问题。但是,如果我们在同一个表中有 100 万条已批准的记录和 100 万条未批准的记录 - 扫描时间会增加对已批准记录的操作。
问题是:我应该考虑第一个(位标志)选项吗?它在描述的情况下有什么好处吗?
将(可能)包含数千万条记录的项目表。
考虑到 SQL Server 可以有效处理的内容,这实际上并没有那么多。当然,我记得我早期的工作之一,其中一个最大的表(单实例系统)有 200 万行,这是我处理过的最多的表。然后下一个作业有 17 个生产实例,其中一些表有数亿行,所有这些都被聚合到一个数据仓库中,其中包含多个具有超过 10 亿行的事实表。不要误会我的意思,我并不是嘲笑几千万行,我只是强调,有了良好的数据模型和适当的索引(和索引维护),SQL Server 可以处理很多.
在任何给定时间,多达 50% 的商品都可能“未获批准”。
唔。这听起来不对。“批准”条目的比率将是获得新条目的比率的一半?每 2 个新条目,只有 1 个会被“批准”?在您的 200 万行示例中,“已批准”和“未批准”各 100 万行,几年后又有 1000 万个条目,您预计“已批准”和“未批准”各有 600 万行?还是说100万个“未通过”会保持一定的水平,这样1000万个新条目,就会有1100万个“通过”,还有100万个“未通过”?
记录可能会被“批准”,但反之则不然。
今天确实如此,但事情会随着时间的推移而发生变化,因此企业总是有可能决定允许“未批准”或其他状态,例如“存档”等。
那么,让我们看看选择:
标志(甚至可能是TINYINT
“状态”)
TINYINT
柱两张单独的表格(一张表“批准”,一张表“未批准”)
IDENTITY
列,而批准的表的 ID 列不是一个IDENTITY
(因为那里不需要)。因此,当记录在表之间移动时,ID 值保持一致。就我个人而言,我倾向于从带有StatusID
列的单个表开始。使用两个表似乎过于复杂,过早的优化。如果/当记录数达到数亿并且索引不提供任何性能提升时,可以讨论这种类型的优化。
您可以同时使用分区视图。
您为每个状态创建一个基础表,由约束强制执行,具有互斥的值。然后是将基础表联合在一起的视图。可以显式引用视图或每个基表。如果通过视图更新了一行的状态,DBMS 将从一个基表中删除它并将其插入到与新状态对应的表中。每个基表可以根据其使用模式独立索引。如果可以,优化器将解析对单个相应基表的索引引用。
好处是
a) 较浅的索引。但是,请对索引扇出进行数学计算。在这种规模和状态值之间的拆分下,拆分表上的索引可能与合并表上的深度相同。
b) 无需更改应用程序代码。数据继续作为一个连续的整体出现。
c) 可以通过添加带有约束的新基表并重新创建视图来包含未来的新状态值。
成本就是数据移动;为每个状态更新写入两个页面和相关索引。需要处理大量 IO。如此大的运动也会导致碎片化。