有没有在SQL Server中使用SQL_VARIANT在VARCHAR什么好处?(Are ther

2019-08-03 21:28发布

我现在有一个数据库表设置如下(EAV - 商业上的原因是有效的):

  • ID - INT(PK)
  • 键 - 独特,VARCHAR(15)
  • 价值 - VARCHAR(1000)

这让我在混合值添加到我的DATABSE以键/值对。 例如:

1   | 'Some Text'      | 'Hello World'
2   | 'Some Number'    | '123456'
etc.

在我的C#代码,我用ADO.Net使用reader.GetString(2); 检索值作为一个字符串,然后让我的代码的其他地方将其转换为所需,例如... Int32.ParseInt(myObj.Value); 。 我期待在由可能改变值列到增强我的表sql_variant数据类型,但我不知道这样做的好处是什么呢? 基本上,它有什么优势具有我的列是sql_variant VS varchar(1000)


为了更清楚,我读的地方,SQL_VARIANT被返回的数据类型为nvarchar(4000)返回给客户端进行调用(哎哟)! 但是,我不能将它转换为它的类型返回之前? 显然,我的代码将不得不进行调整,以存储值作为一个对象,而不是一个字符串值。 我想,什么是使用的优势/劣势sql_variant与在我目前的状况一些其他类型的? 哦,这是值得一提的是所有我打算存储有日期时间,字符串和数值类型的值列(INT,小数等); 我不存储和BLOB或图像或计划等。

Answer 1:

有关SQL变种的好处是,你可以存储多种类型的列和你保持类型的信息。

INSERT INTO MySettings值( '名称', '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. 不是非常快
  2. 不能很好的ORM框架支持


Answer 2:

如果更改类型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不透明值,不使用的DbType。

EAV各种(标准)类型的值是一个情况下我个人认为sql_variant很有趣。

当然,“SQLServer的为重点的家伙”(读:数据库管理员)不喜欢它:-)在SQL Server端, sql_variant不太实际使用(如在评论中指出),但如果你把它作为不透明的“东西”,并没有在SQL程序代码中使用它,我认为这是好的。 因此,它是在.NET / OO编程方面更加具有优势。



Answer 3:

该SQL_VARIANT类型有其局限性如Zarathos描述良好。

我感到迷惑的是,你提到VARCHAR(1000),然后“哎哟”有关返回转换为nvarchar(4000)。

我会说,这是一件好事,对整个世界终于利用本地和有限的字符集,停止,决定全力以赴在Unicode和UTF-8开始,所以你应该更喜欢在为nvarchar的varchar和ntext文本上。

和返回类型为nvarchar(4000),而不是NCHAR(4000)。 不同的是,任何VARCHAR是 - 在大小可变的,而普通类型char被固定在尺寸。 CHAR(4000)的返回的元组将派出大量的空浪费,但VARCHAR,这不是一个问题。

好的。 但是,这将是一个正确的数据类型是你吗? 我会建议NTEXT。 什么是今天的1000可能是明天10000。 如果你有“大量的文字”你是不是索引,那么也许你的数据库不应该决定限制可能是什么。 这只是文字。

NTEXT也与.NET非常适合,因为它的字符串始终以Unicode。 从字符串到int转换也快于.NET比由SQL Server来完成。

希望这可以帮助



Answer 4:

我看不出它已经没有提到,所以我会提到这一问题相当普遍的做法是这样的一个表:

  • ID - INT(PK)
  • 键 - 独特,VARCHAR(15)
  • 值类型 - 整数(0 - 字符串,1 - 整数,3 - 浮动)(可选)
  • 的StringValue - VARCHAR(1000)
  • INTVALUE - 整数
  • 的floatValue - 双

好处:

  • 数据被保存在它的适当的形式(存储整数作为字符串浪费了大量的比特)
  • 你可以像WHERE左(键,5)=“鞋”,和INTVALUE> 5看中查询
  • 该值类型列只是您使用的是你的钥匙前缀/后缀有用的(以获取密钥组)和设定可能是混合型的。 即,其中左(键,4)=“尺寸”和值类型= 1

缺点:

  • 无处不在,你使用这个表,你必须保证你/获取/设置正确的值列
  • 如果你决定你需要/想要的值类型列,你必须确保你得到/设置正确。


文章来源: Are there any benefits to using sql_variant over varchar in SQL Server?