代码之家  ›  专栏  ›  技术社区  ›  littlegreen

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

  •  23
  • littlegreen  · 技术社区  · 16 年前

    目前我正在为我们公司设计一个数据库。我们使用的是SQL Server 2008。数据库将保存从多个客户收集的数据。数据库的目标是获取多个客户的聚合基准数字。

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

    我的问题是,我们将来能处理这张桌子吗?还是把这张桌子分成几个小的桌子给每个顾客比较好?


    更新 experimenting with indexes 并决定在前两列(医院代码和科室代码)上使用聚集索引,如果使用企业版的话,我们就可以对表进行分区。正如Galwegian所预测的那样,直到最近,这种设置仍然运行良好,性能问题也层出不穷。重建索引需要很长时间,用户相互锁定,查询通常需要更长的时间,对于大多数查询来说,首先将数据的相关部分复制到临时表中,在临时表上创建索引并运行查询是值得的。这不是应该的。因此,我们正在考虑购买Enterprise Edition以使用分区表。如果购买无法通过,我计划使用 workaround to accomplish partitioning in Standard Edition .

    13 回复  |  直到 9 年前
        1
  •  17
  •   Galwegian    16 年前

    从一张大桌子开始,然后用2008年的 表分区 适当情况下的能力, .

        2
  •  7
  •   APC    16 年前

    数据仓库应该很大(线索就在名称中)。两千万行按仓储标准算是中等,不过六亿行可以算是大行。

    要记住的是,如此大的表有不同的物理,像黑洞。所以调整它们需要一套不同的技术。另一件事是,数据仓库的用户必须了解他们正在处理大量的数据,因此他们不能期望每一个查询都有亚秒(甚至亚分钟)的响应。

    分区是很有用的,特别是如果您有明确的界限,比如在您的案例中,客户。您必须知道分区可能会降低跨越分区键粒度的查询的性能。所以这不是一颗银弹。

        3
  •  6
  •   Sjoerd    16 年前

    分片 . 此外,数据库模式可以或多或少地规范化。规范化模式有单独的表,表之间有关系,并且数据不重复。

        4
  •  3
  •   Otávio Décio    16 年前

    我假设你的数据库正常化了。在SQLServer中,处理在单个表上引用的数据量应该不是问题;我认为你需要做的是检查你的索引。

        5
  •  3
  •   Ben    16 年前

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

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

        6
  •  3
  •   HLGEM    16 年前

    在一个正确设计的数据库中,这并不是一个庞大的记录量,SQLServer应该可以轻松处理。

    一张分开的桌子通常是最好的选择。试图维护独立的独立客户表在时间和精力上都是非常昂贵的,而且更容易出错。

    如果遇到性能问题,还可以检查当前查询。如果没有适当的索引(例如,是否索引了外键字段?),查询将很慢;如果没有可搜索的查询,则查询将很慢;如果使用相关子查询或游标,则查询将很慢。您返回的数据是否比striclty需要的多?如果您在生产代码中的任何地方都选择了*,那么就去掉它,只返回所需的字段。如果使用的视图调用调用视图的视图,或者使用的是EAV table,则会出现此级别的性能问题。如果您允许一个框架自动生成SQl代码,那么很可能查询性能很差。记住探查器是你的朋友。当然,你也可能有一个硬件问题,你需要一个相当大的专用服务器的数量记录。在你的网络服务器或一个小盒子上运行它是行不通的。

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

        7
  •  2
  •   Neil Knight    16 年前

    分道扬镳绝对是一件值得研究的事情。我有一个数据库,有两个表切分。每个表包含大约3000-3500万条记录。此后,我将其合并到一个大表中,并分配了一些好的索引。到目前为止,我还没有分区这个表,因为它的工作是一种享受,但我会记住分区。我注意到一件事,与数据被切分时相比,那就是数据导入。现在速度变慢了,但我可以接受,因为导入工具可以重新编写;(o)

        8
  •  1
  •   nvogel    16 年前

    我认为基于所提供的信息,使用NOLOCK的建议是不合理的。NOLOCK意味着您将从查询中得到不准确和不可靠的结果(脏读和虚读)。在使用NOLOCK之前,您需要确保这不会对您的客户造成问题。

        9
  •  1
  •   Cade Roux    16 年前

    这是一张单人平桌(没有特殊型号)吗?通常在数据仓库中,您要么有一个标准化的数据模型(至少是第三种标准形式-通常在实体关系模型中),要么有维度数据(Kimball方法或变体-通常是在一组星中具有关联维度表的事实表)。

    在这两种情况下,索引在很大程度上发挥了作用,分区也可以在让查询在非常大的数据集上执行方面发挥作用(但分区通常不是关于性能,而是关于能够快速添加和删除分区的维护),但这实际上取决于聚合的顺序和查询的类型。

        10
  •  0
  •   brien    16 年前

    一张桌子,然后担心性能。也就是说,假设您为每个客户收集完全相同的信息。这样,如果您必须添加/删除/修改列,那么您只能在一个位置进行操作。

        11
  •  0
  •   kragan    16 年前

        12
  •  0
  •   StuartLC    16 年前

    保留一个表—2000万行并不是很大,客户也不是那种可以轻松“归档”的表,搜索多个表以找到客户的做法并不值得(SQL在B树搜索方面可能比您自己的发明更有效)

        13
  •  0
  •   Jacob G    16 年前

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