数据库设计:一个巨大的表还是单独的表?

时间:2010-05-04 14:49:30

标签: sql-server sql-server-2008 database-design data-warehouse

目前我正在设计一个供我们公司使用的数据库。我们正在使用SQL Server 2008.该数据库将保存从多个客户收集的数据。该数据库的目标是获得多个客户的总基准数。

最近,我特别担心一张桌子会变得非常大。每个客户拥有大约20.000.000行数据,数据库中很快就会有30个客户(如果不是更多)。将在此表上进行大量查询。我已经注意到性能问题和暂时被锁定的用户。

我的问题是,我们将来能够处理这个表,还是将这个表拆分成每个客户的小表更好?


更新:自我们第一次创建表格以来,现在已经有半年了。按照下面的建议,我创建了一些巨大的表格。从那时起,我一直experimenting with indexes并决定在前两列(医院代码和部门代码)上的聚集索引,如果我们有企业版,我们将在该列上对表进行分区。直到最近,这种设置工作正常,正如Galwegian预测的那样,性能问题正在兴起。重建索引需要很长时间,用户互相锁定,查询经常花费的时间超过应有的时间,对于大多数查询,首先将相关部分数据复制到临时表,在临时表上创建索引并运行查询。这不是应该的样子。因此,我们正在考虑购买企业版以使用分区表。如果购买无法完成,我计划使用workaround to accomplish partitioning in Standard Edition

13 个答案:

答案 0 :(得分:16)

从一个大表开始,然后在适当情况下应用2008的表分区功能,如果性能成为问题

答案 1 :(得分:7)

数据仓库应该很大(线索在名称中)。根据仓储标准,有二千万行是中等的,尽管六亿可以被认为很大。

要记住的是,这样的大桌子有不同的物理特性,比如黑洞。因此调整它们需要一组不同的技术。另一方面,数据仓库的用户必须明白他们正在处理大量数据,因此他们不能指望每个查询的亚秒响应(或者实际上是亚分钟)。

分区可能很有用,特别是如果您有明确的分界线,例如,在您的情况下,CUSTOMER。您必须意识到,分区会降低跨越分区键的粒度的查询的性能。所以它不是一颗银弹。

答案 2 :(得分:6)

出于性能原因拆分表称为 sharding 。此外,数据库模式可以或多或少地标准化。规范化模式具有单独的表,它们之间具有关系,并且数据不会重复。

答案 3 :(得分:3)

我假设您已正确规范化数据库。处理在SQL Server中的单个表上引用的数据量应该不是问题;我认为您需要做的是检查索引。

答案 4 :(得分:3)

由于您已将问题标记为“数据仓库”,因此我假设您了解有关该主题的一些信息。根据您的目标,您可以选择星型模式(具有事实和维度表的多维模型)。将所有快速更改数据存储在1个表(每个主题)中,将慢速数据存储在另一个维度/“雪花”表中。

另一个选项是Dan Lindstedt的DataVault方法。这有点复杂,但为您提供了充分的灵活性。

http://danlinstedt.com/category/datavault/

答案 5 :(得分:3)

在设计合理的数据库中,这不是一个巨大的记录,SQl服务器应该可以轻松处理。

分手单桌通常是最好的方式。试图维护单独的个人客户表在时间和精力方面非常昂贵,并且更容易出错。

如果遇到性能问题,请检查当前查询。如果您没有正确的索引(例如索引外键字段吗?)查询会很慢,如果您没有可搜索的查询,如果使用相关子查询或游标,它们会很慢,它们会很慢。您是否返回了比严格需要更多的数据?如果您在生产代码中的任何位置选择*,请删除它并仅返回您需要的字段。如果您使用调用视图的视图来调用视图,或者您使用了EAV表,那么您将在此级别具有性能提升。如果您允许框架自动生成SQl代码,那么您可能会非常有效地执行查询。记住Profiler是你的朋友。当然,您也可能遇到硬件问题,您需要一个相当大的专用服务器来存储该数量的记录。在您的网络服务器或小盒子上运行它是行不通的。

我建议您需要聘请具有性能调优经验的专业dba。这是非常复杂的东西。应用程序员设计的数据库在获得真实数量的用户和记录时通常表现不佳。数据库必须在设计时考虑到数据完整性,性能和安全性。如果你没有这样做,那么拥有它们的变化确实很小。

答案 6 :(得分:2)

分区绝对是值得关注的事情。我有一个有2个表分片的数据库。每张表包含大约3000万至3500万条记录。我已经将它合并为一个大表并分配了一些好的索引。到目前为止,我没有必要对此表进行分区,因为它正在进行处理,但我仍然在考虑分区。与数据分片时相比,我注意到的一件事是数据导入。它现在变慢了,但我可以忍受,因为可以重写导入工具; o)

答案 7 :(得分:1)

一个表并使用表分区。

根据给出的信息,我认为使用NOLOCK的建议是不合理的。 NOLOCK意味着您将从查询中获得不准确且不可靠的结果(脏读和幻像读取)。在使用NOLOCK之前,您需要确保对您的客户不会有任何问题。

答案 8 :(得分:1)

这是一张单人平台(没有特定型号)吗?通常在数据仓库中,您要么具有规范化数据模型(至少是第三范式 - 通常在实体 - 关系模型中),要么您有维度数据(Kimball方法或变体 - 通常是一组中包含关联维度表的事实表)分)。

在这两种情况下,索引都占很大比例,并且分区也可以在获取查询的过程中发挥作用(但分区通常不是关于性能,而是关于维护能够快速添加和删除分区)而非大型数据集 - 但它实际上取决于聚合的顺序和查询的类型。

答案 9 :(得分:0)

一张表,然后担心性能。也就是说,假设您正在为每个客户收集完全相同的信息。这样,如果你必须添加/删除/修改一个列,你只能在一个地方进行。

答案 10 :(得分:0)

如果您使用的是MS SQL服务器,并且希望保留单个表,那么表分区可能就是一个解决方案。

答案 11 :(得分:0)

保留一个表--20万行不是很大,客户并不是那种你可以轻松“存档”的表格,并且搜索多个表来寻找客户的共同点是不值得的(在BTree搜索中SQL可能比您自己的发明更有效)

然而,您需要查看性能和锁定问题 - 这将阻止您的数据库扩展。

答案 12 :(得分:0)

如果存在常见查询,您还可以创建包含已计算的历史信息详细信息的补充表。