【问题标题】:Table design options for large number of rows?大量行的表格设计选项?
【发布时间】:2010-02-24 23:56:47
【问题描述】:

我有一个基于用户交互(不是用户输入)发送数据的应用程序。发送的数据可以是整数、字符串、日期或布尔值。有 140 个键。我们一次可以得到从 1 个键值对到全部 140 个键值对。

我们希望存储所有内容,但只会使用应用程序中 140 个键中的 20 个。剩下的将用于稍后的审计跟踪 - 所以我们仍然需要存储它们。

应用程序使用此数据来决定用户需要去哪里,因此它需要通过学生 ID 访问记录并在几毫秒内提取 20 个左右的选项。可能有数十亿行数据(这是对拥有超过 20,000 个用户的现有应用程序的升级),因此性能至关重要。用户每次访问应用程序时都会生成一个新行。

示例数据:

Score:1
ID:3212
IsLast:False
Action:Completed

关于如何做到这一点,我有 2 个想法,并正在寻求一些帮助,哪个是最好的,或者第三个选项是更好的选择。

选项 1:

我的第一个想法是使用一列作为字符串的值,然后在需要转换值以供使用时使用可能的数据类型的查找表。

value       | dataType
-----------------------
"1"         | int
"Completed" | string

虽然发送的数据不是用户生成的,但我知道这个方法中一定有一个陷阱。这样做的唯一原因是我们不知道将发送什么 key:pair(在日期和 id 之外)并试图避免超过几列。

SO 问题 How to Handle Unknown Data Type in one Table 使用了类似的想法。

选项 2:

另一种解决方案是设置 140 列 - 每个键对应一个列。但是,生成的数据量非常大(数十亿行),因此调用这些数据的速度不够快 - 我不认为。

技术细节: 这是使用 SQL Server 2008 - 而不是带有 DotNet C# 和 Reporting Services 的 R2。

我在这里遗漏了什么 - 创建此表以提高性能的最佳方法是什么?

【问题讨论】:

  • 第三个选项:以 XML 格式获取数据,存储在 NVARCHAR(max) 数据类型中。
  • 生成报告时这不会降低 Reporting Services 的速度。
  • 我会把它放在一个 XML 中
  • 键值表对性能来说很糟糕,我永远不会在性能是关键组件的关系数据库中考虑它们。听听 Charles Bretana,他有最好的设计选择。
  • 不要放在 XML 中。这将减慢访问速度并使检索数据更加复杂。充分利用数据库已经提供的数据结构。选择选项 1 以在速度、可扩展性和可读性之间取得良好平衡。

标签: sql sql-server tsql sql-server-2008


【解决方案1】:

垂直分割您的数据。将导航控制所需的 20 个键放在一张表中,所有 20 个放在一行中,并带有标识用户交互的 PK(Callit 说,InteractionId)。将其他 120 个值放在另一个表中,使用复合主键,基于第一个表的 PK(InteractionId,加上KeyTypeId,标识该值用于 120 个可能的键值对中的哪一个。存储所有值在第二个表中作为字符串。在名为KeyTypes 的第三个查找表中,存储KeyTypeIdKeyTypeNameKeyValueDataType,以使您的代码知道如何转换字符串值以正确输出它作为字符串、日期时间、整数或十进制值或其他任何值...

第一个表将被更频繁地访问,因此它只包含应用程序的导航功能需要更频繁访问的那些值,使行更窄,这允许每页有更多行,并最大限度地减少磁盘 IO。将所有 20 个值放在一行中将使行数更小(约 1/20 大),最小化每次访问需要执行的索引查找的深度。

具有所有其他 120 个键值的其他表将不会被频繁访问,因此它的结构可能会针对逻辑简单性而不是性能进行优化。

【讨论】:

    【解决方案2】:

    实际上,您可以合并目前提供的建议:

    创建一个表,其中包含导航控制所需的 20 个键、一列用于主键、一列是 XML 数据类型以存储其余可能的数据。然后,您可以创建一个 DTD 来处理每个键的数据类型,并根据需要对某些键加上约束。

    【讨论】:

      【解决方案3】:

      嗯,测试这两个想法应该足够简单,但选项 1 的变体对我来说似乎更受欢迎。像 SQL Server 这样的 RDBMS 更喜欢长而窄的表(即列少但行多)。

      我不会再进一步​​了,因为看起来查尔斯已经击败了它,提出了一个非常明智的建议。

      【讨论】:

        猜你喜欢
        • 2018-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 2013-01-25
        • 1970-01-01
        • 2013-04-08
        相关资源
        最近更新 更多