我有一些数据,哪些列是动态的,列数据的数量可以随时增加/减少。所以我打算以行方式而不是列格式存储它们。
我放置了主列表,并指出了列使用的数据类型。我正在绘制下面的主表供您参考
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”
的表达式两者都有各自的缺点。有人可以指出哪种方式会让我在将来减少头痛。请记住,此表将在后期增加数百万条记录。
我感谢您的观点和时间。谢谢。
答案 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)。