C# 在sql Server中使用sql_变量而不是varchar有什么好处吗?

C# 在sql Server中使用sql_变量而不是varchar有什么好处吗?,c#,performance,sql-server-2012,varchar,sql-variant,C#,Performance,Sql Server 2012,Varchar,Sql Variant,我目前的数据库表设置如下(EAV-业务原因有效): Id-int(PK) 键-唯一,varchar(15) 值-varchar(1000) 这允许我将混合值作为键/值对添加到数据库中。例如: 1 | 'Some Text' | 'Hello World' 2 | 'Some Number' | '123456' etc. 在我的C#代码中,我使用ADO.Net使用reader.GetString(2)以字符串形式检索值,然后让我的代码在其他地方根据需要进行转换,例如

我目前的数据库表设置如下(EAV-业务原因有效):

  • Id-int(PK)
  • 键-唯一,varchar(15)
  • 值-varchar(1000)
这允许我将混合值作为键/值对添加到数据库中。例如:

1   | 'Some Text'      | 'Hello World'
2   | 'Some Number'    | '123456'
etc.
在我的C#代码中,我使用ADO.Net使用
reader.GetString(2)
以字符串形式检索值,然后让我的代码在其他地方根据需要进行转换,例如<代码>Int32.ParseInt(myObj.Value)。我正在考虑通过可能将value列更改为
sql\u variant
datatype来增强我的表,但我不知道这样做的好处是什么?基本上,将我的值列设置为
sql\u variant
vs
varchar(1000)
,有什么好处吗



更清楚地说,我在某个地方读到sql_变量作为nvarchar(4000)返回给进行调用的客户机(哎哟)!但是,我不能在返回之前将其转换为它的类型吗?显然,我的代码必须进行调整,以将值存储为对象,而不是字符串值。我想,在我目前的情况下,使用
sql\u variant
与其他类型相比有哪些优点/缺点?哦,值得一提的是,我计划在value列中存储的是日期时间、字符串和数字类型(int、decimal等);我不打算存储blob或图像等。

如果将类型更改为
sql\u variant
,则必须使用该方法。它将一直保留该类型

因此,在.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\u variant
有趣的一种情况


当然,“关注SQLServer的家伙”(读作:DBA)一点也不喜欢:-)在SQLServer方面,
SQL\u variant
不太实用(如评论中所述),但如果您将其作为不透明的“东西”使用,并且不必在SQL过程代码中使用,我认为这是可以的。因此,它在.NET/OO编程方面更具优势。

正如Zarathos所描述的那样,sql_变量类型也有其局限性

我感到困惑的是,您提到了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。 在.NET中,从字符串到int的转换也比sql server快


希望这对您有所帮助。

sql variant的好处在于,您可以在一列中存储多个类型,并保留类型信息

在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
不幸的是,这有几个缺点:

  • 不是很快
  • ORM框架没有很好的支持

  • 我还没有看到有人提到它,所以我要提到解决这个问题的一个相当常见的方法是这样一个表:

    • Id-int(PK)
    • 键-唯一,varchar(15)
    • ValueType-整数(0-字符串,1-整数,3-浮点)(可选)
    • StringValue-varchar(1000)
    • IntValue-整数
    • 浮动值-双精度
    优点:

    • 数据以适当的形式保存(将整数存储为字符串会浪费很多位)
    • 您可以执行一些奇特的查询,如WHERE left(键,5)=“SHOES”和IntValue>5
    • ValueType列仅在键上使用前缀/后缀(用于检索键集)时有用,并且该集可以是混合类型。i、 e.其中左侧(键,4)=“大小”和ValueType=1
    缺点:

    • 在使用此表的任何地方,都必须确保您/获取/设置了正确的值列
    • 如果您决定需要/想要ValueType列,则必须确保正确获取/设置它

    As:根本不使用SQL变量-这不是一个好主意。不要用它。你没有得到任何好处,但有很多缺点……除了说sql_变体不好之外,你是否说varchar(1000)在我的情况下是正确的方法?你认为使用sql_变体将如何增强你的表?@PhilCarson:这正是我的问题。。。与varchar(1000)相比,优点和缺点是什么。哪个需要更多的磁盘空间?这两者对存储过程的读/写(非逻辑)是否有任何影响?通过网络发送哪个更好?在.NET中哪个更容易处理?等。我不知道,因此我问。通过一个
    ValueType
    列,并在填充
    StringValue
    IntValue
    FloatValue
    之间进行选择,您成功地重新发明了一个
    sql\u变体
    ,它使用起来工作量更大,功能更少。sql server中的ntext类型已被弃用: