将列数据存储为行MS SQL的最佳方法

时间:2013-07-25 05:57:31

标签: c# sql sql-server sql-server-2008

我有一些数据,哪些列是动态的,列数据的数量可以随时增加/减少。所以我打算以行方式而不是列格式存储它们。

我放置了主列表,并指出了列使用的数据类型。我正在绘制下面的主表供您参考

CID     Name          Type
1      Speed         Double
2      Input1        Bool
3      Message       String
.......
.......

现在我想到了存储这个动态列数据的两种方法 第一种方式是

CID      Data_bool       Data_String      Data_Double
1        NULL            NULL             12
2        True            NULL             NULL
3        NULL            test             NULL
1        NULL            NULL             5
1        NULL            NULL             15

第二种方法是有一个通用varchar列并将每个值存储为字符串,所以它看起来像

CID      Datas
1        12
2        True
3        test
1        5
1        15

如果从数据库规范化的角度来看,那么第二种方式似乎是好的。但我认为这可能会在数据检索中产生问题。因为我想过滤像“Speed> 10”这样的数据。所以,如果我采取第二种方式(我将所有值存储为字符串)我认为表达式需要更多时间来评估 如果我首先使用表达式,那么首先我需要确定我需要评估表达式的列。防爆。表达速度> 10,首先我必须检查Speed是哪种数据类型(字符串,bool等)然后再次执行“data_double> 10”

的表达式

两者都有各自的缺点。有人可以指出哪种方式会让我在将来减少头痛。请记住,此表将在后期增加数百万条记录。

我感谢您的观点和时间。谢谢。

4 个答案:

答案 0 :(得分:2)

我不确定您是如何访问数据的,SQL_Variant可能是SQL_VARIANT_PROPERTY可能与{{3}}结合使用的选项。

Declare @a table(id int, cont sql_variant)
insert into @a select 1,'test'
insert into @a select 1,Cast('20130101' as DateTime)
insert into @a select 1,Cast('20130201' as Datetime)
insert into @a select 1,Cast(1 as Bit)
insert into @a select 1,Cast(0 as Bit)
Select * from
(
Select *  from @a
where SQL_VARIANT_PROPERTY(cont,'BaseType')='datetime'
) x
Where cont>Cast('20130101' as DateTime)

答案 1 :(得分:1)

一种方法可能是为您感兴趣的每种数据类型使用一个表。这些表中的每一个都只有两个字段。用于存储数据的int型PK和相应类型的列。在主表中,你可以只有一个链接到特定类型表之一的int类型的FK和另一个tinyint类型的字段来决定FK属于哪个子表。

主表

ID int PK

ValueID int Not Null

输入tinyint Not Null

子表

ID int PK

值字符串不为空

ValueID是从Child表到Master表的FK。可以为其他类型创建类似的子表。

答案 2 :(得分:0)

我知道这并没有回答你关于这两个选项中哪一个更好的问题,但我希望无论如何它都会有用。

我不会选择这两个选项中的任何一个。我宁愿尝试看看我是否可以将它们放入列中(具有50或100甚至更多列的表格并不常见)和/或不同的表格。

我建议您安装TFS或Dynamics CRM,看看它们如何存储数据。他们构建了应用程序代码,以便能够在数据库中添加/删除列,并且它们有一组表来跟踪这些元数据。

如果确实存在与我尝试使用XML数据类型不同的值。

答案 3 :(得分:0)

我已经在很多场合看到并处理过这类问题,特别是在应用程序必须允许用户配置字段名称和数据类型的情况下。

这些情况下的解决方案是Key-Value(即2列)表,它们对所有键[显然]使用varchars,但也为所有值使用。

这是一个非常强大的解决方案,它简化了它的简单性!

虽然这是最简单和可扩展的选项,但它可能不是最高效的选项。为每种数据类型设置键值表可能有所帮助,但编程起来要困难一些。或者,在同一个表中包含Type字段和每个数据类型的列(但不是我最喜欢的,因为这会浪费空间)。

我使用的基于数据库的应用程序,使用varchar Value方法,执行时没有明显的缓慢;但是,他们实际上只使用简单的基于密钥的查找操作。您的情况可能会有所不同,特别是如果您对数据执行更复杂的查询。说明显而易见的,但是,将主键应用于Key字段将提高查找速度。

附加说明:

为回收我在各种论坛上阅读的内容而道歉,但我没有在我自己的数据库中使用变体类型。我读过:

1)在SQL Server 2005之后,使用变体类型而不是varchar类型 - 在本例中,对于Value列 - 将导致更快的操作,

2)它们不适用于WHERE子句中的LIKE,

3)OLE DB和ODBC提供程序自动将变体转换为nvarchar(4000)。