Sql server 奥瓦尔) 选择案例 当@bah='true'时,则为1 其他0 终点 终点 其他的 开始 插入#测试(StringVal) 选择@bah 终点 终点 否则,如果下限(转换(货币,@bah))上限(转换(货币,@bah))--补偿对货币的数字解释 开始 插入#测试(FloatVal) 选择转换(浮动,转换(货币,@bah)) 终点 其他的 开始 插入#测试(IntVal) 选择转换(Int,@bah) 终点

Sql server 奥瓦尔) 选择案例 当@bah='true'时,则为1 其他0 终点 终点 其他的 开始 插入#测试(StringVal) 选择@bah 终点 终点 否则,如果下限(转换(货币,@bah))上限(转换(货币,@bah))--补偿对货币的数字解释 开始 插入#测试(FloatVal) 选择转换(浮动,转换(货币,@bah)) 终点 其他的 开始 插入#测试(IntVal) 选择转换(Int,@bah) 终点,sql-server,sql-server-2012,Sql Server,Sql Server 2012,仅值列的基线将是1字节一段,以允许为空值,1字节用于位列,4字节用于int列,4字节用于浮点,2字节用于varchar(用于可变长度存储),因此看起来您看到的基线是15字节 如果是位或整数(15个字节)将是您的存储需求,如果是双精度,则如果精度为25或更高,则可能会再增加4个字节,而varchar将增加相当于所存储记录长度的字节数。因此,如果改为使用不可为null的varchar,则每个记录最多可节省12个字节(对于可变长度存储,最小为2个字节,对于单个字符值,最小为1个字节)。因此,对于100

仅值列的基线将是1字节一段,以允许为空值,1字节用于位列,4字节用于int列,4字节用于浮点,2字节用于varchar(用于可变长度存储),因此看起来您看到的基线是15字节

如果是位或整数(15个字节)将是您的存储需求,如果是双精度,则如果精度为25或更高,则可能会再增加4个字节,而varchar将增加相当于所存储记录长度的字节数。因此,如果改为使用不可为null的varchar,则每个记录最多可节省12个字节(对于可变长度存储,最小为2个字节,对于单个字符值,最小为1个字节)。因此,对于1000000条记录,您需要额外存储11.5MB的数据


但是,如果您要根据这些值查找主键,那么使用此解决方案可能会更快,因为根据位进行查找会更快,int或float索引值在varchar上,因此,如果在进行查找时,您将知道要查找的数据类型,那么执行此路径将更快,因为只要您的列被索引,您就可以忽略在不同列中具有值的所有空值。如果要基于主键获取值,请使用单个varchar列,因为这样做的好处可以忽略不计。

是否会有如此多的设置和查询,以至于您非常关心吞吐量和延迟?对于设置表来说,这一切都无关紧要。true和false会被作为“true”和“false”或“0”和“1”传递吗?我估计设置表中会有1000万个值。我不明白为什么人们会投反对票。这可能是一个选项,使用新的XQuery来查询半构造数据,性能也同样不错。也许我应该多解释一点。是的,flup,一个简单的例子会很有帮助。从未对Xml列使用过Xml索引。这似乎过于复杂且难以使用,但我将进行一些测试,以确定此方法的性能是否与varchar列相同(或接近于varchar列)。添加了不带索引的简单示例,以及指向带索引的msdn示例的链接。@flup:这似乎是在一个字段中存储各种变量数据的一个很好的解决方案。给你和社区的两个问题:1。您真的认为这可以在与straight varchar()列类似的级别上执行吗?2.您提到了带有模式的Xml列?模式从何而来?是的,这就是我的想法。但是这个解决方案对数据表的大小有什么影响呢?现在,对于一个有数百万行的表,每个值有4个字段。如果我想要第五或第六种呢。我是否在破坏我的存储和效率?您将如何获取信息?你打算一次或一组翻出一张唱片吗?您是要基于值查找主键还是基于主键查找值?
/*
        Create  Table #test 
                (
                    tID         Int Identity, 
                    StringVal   Varchar(100), 
                    FloatVal    Float, 
                    BoolVal     Bit, 
                    IntVal      Int
                )
*/

Declare @bah Varchar(100)

Set     @bah = 'ValuesToTest'

If      IsNumeric(@bah) = 0
Begin
        If      @bah In ('true','false') --Went with this assumption otherwise you'd get confused between 1 bool and 1 int
        Begin
                Insert  #test (BoolVal)
                Select  Case
                        When    @bah = 'true' Then 1
                        Else    0
                        End
        End
        Else
        Begin
                Insert  #test (StringVal)
                Select  @bah
        End
End
Else    If Floor(Convert(Money,@bah)) <> Ceiling(Convert(Money,@bah)) --Compensate for IsNumeric interpretation of money
Begin
        Insert  #test (FloatVal)
        Select  Convert(Float,Convert(Money,@bah))
End
Else
Begin
        Insert  #test (IntVal)
        Select  Convert(Int,@bah)
End