大量行的表设计选项?

时间:2010-02-24 15:38:53

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

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

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

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

示例数据:

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

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

选项1:

我的第一个想法是使用值作为字符串的列,然后有一个查找表,列出在需要使用Cast进行使用时可能使用的数据类型。

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

虽然发送的数据不是用户生成的,但我知道在这种方法中某处必须存在问题。这样做的唯一原因是我们不知道哪个密钥:对将被发送(在日期和id之外)并且试图避免多个列。

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

选项2:

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

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

我在这里遗漏了什么 - 为表现创建此表的最佳方法是什么?

3 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:2)

实际上,您可能会合并到目前为止提供的建议:

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

答案 2 :(得分:1)

它应该足够简单来测试这两个想法,但选项1的变体看起来对我很有帮助。像SQL Server这样的RDBMS更喜欢长而窄的表(即列数较少但行数很多)。

我不会再进一步​​了,因为看来Charles已经打败了它,并提出了一个非常明智的建议。