我目前有一个数据库表设置如下(EAV - 业务原因有效):
这允许我将混合值作为键/值对添加到我的数据库中。例如:
1 | 'Some Text' | 'Hello World'
2 | 'Some Number' | '123456'
etc.
在我的C#代码中,我使用reader.GetString(2);
使用ADO.Net将值作为字符串检索,然后让我的代码在其他地方根据需要进行转换,例如...... Int32.ParseInt(myObj.Value);
。我正在考虑通过将值列更改为sql_variant
数据类型来增强我的表,但我不知道这会带来什么好处?基本上,让我的值列属于sql_variant
vs varchar(1000)
是否有任何好处?
为了更清楚,我在某处读到sql_variant以nvarchar(4000)的形式返回给进行调用的客户端(ouch)!但是,在返回它之前,我不能把它转换成它的类型吗?显然,我的代码必须进行调整,以将值存储为对象而不是字符串值。我想,在我目前的情况下,使用sql_variant
与其他类型相比有哪些优点/缺点?哦,值得一提的是我计划存储的所有内容都是值列中的日期时间,字符串和数字类型(int,decimal等);我不计划存储和blob或图像等。
答案 0 :(得分:9)
关于sql变量的好处是你可以在一个列中存储多个类型,并保留类型信息。
插入MySettings值('Name','MyName');插入 MySettings值('ShouesNumber',45);插入MySettings值 ( 'MyDouble',31.32);
如果要检索类型:
select SQL_VARIANT_PROPERTY ( value , 'BaseType' ) as DataType,* from mysettings
你有:
Datatype Name Value
-----------------------------
varchar Name MyName
int ShoesNumber 45
numeric MyDouble 31.32
不幸的是,这有几个缺点:
答案 1 :(得分:7)
如果您将类型更改为sql_variant
,则必须使用IDataRecord.GetValue方法。它将一直保留类型。
所以在.NET中它允许你拥有这种代码:
// read an object of SQL underlying data type 'int' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.Int32
// read an object of SQL underlying data type '(n)varchar' or '(n)char' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.String
// read an object of SQL underlying data type 'datetime' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.DateTime
etc...
当然,它假设您在保存时也这样做。只需将SqlParameter.Value设置为opaque值,不要使用DbType。
具有各种(标准)类型作为价值的EAV是我个人认为sql_variant
很有趣的一个案例。
当然“以SQLServer为中心的人”(读取:DBA)根本不喜欢它:-)在SQL Server端,sql_variant
使用起来不太实际(如评论中所述) ,但如果你把它作为一个不透明的“东西”,并且不必在SQL过程代码中使用它,我认为没关系。因此,它在.NET / OO编程方面更具优势。
答案 2 :(得分:1)
sql_variant类型有其局限性,如Zarathos所述。
我觉得令人困惑的是你提到varchar(1000)然后'ouch'关于返回转换后的nvarchar(4000)。
我首先要说的是,整个世界终于停止使用本地和有限的字符集并且决定全部使用Unicode和UTF-8是一件好事,所以你应该更喜欢nvarchar而不是varchar和ntext而不是文本。
返回的是nvarchar(4000)而不是nchar(4000)。区别在于任何varchar的大小都是可变的,而普通类型的char的大小是固定的。返回char(4000)的元组将发送大量空浪费,但使用varchar这不是问题。
好。但是适合您的数据类型是什么?我推荐ntext。 今天的1000人明天可能是10'000。如果你有“很多文本”,你没有索引,那么你的数据库可能不应该决定限制。这只是文字。
ntext也适合.NET,因为它的字符串总是使用Unicode。 从字符串到int的转换在.NET中也比sql server更快。
希望这有帮助
答案 3 :(得分:1)
我没有看到它已被提及,所以我会提到这个问题的一个相当常见的方法就是这样一个表:
优点:
缺点: