我正在重构数据库(SQL Server 2008)方案,并收集参数以将NCHAR(1)
列(保留Y|N
值)更改为BIT
。每个人都明白这是必要的,不知道它为什么会发生,但这种变化会影响生产数据库,因此需要重要的参数。表保留地址目录(最多1米的记录)。
我找到的第一个参数 - 每个nchar fields占用2个字节,每个8 bit fields - 1个字节(接下来的8个 - 另外1个字节)。
下一步是什么?也许某些索引的性能问题?
答案 0 :(得分:10)
除非你有充分的理由做出改变,否则我会毫不犹豫地为这种改变提供任何论据。也就是说,你必须平衡改变成本与你个人所做/喜欢的成本,实际实施成本和效益之间的平衡。
您是否检查过使用nchar(1)是否会影响性能,还是会陷入过早优化的陷阱?你这里只谈了100万条记录。
对于您认为会产生的次要存储/ IO成本,请考虑更改,重新测试和升级系统的总工时*每小时费率与仅购买更快磁盘的成本。我怀疑磁盘会更便宜 - 并且有益于系统的各个方面。
答案 1 :(得分:6)
找到NCHAR(1)而不是位的一个常见原因是Oracle不支持位类型。如果您有Oracle或Oracle培训的开发人员,或者曾经在Oracle上运行的数据库,那么您将会看到很多。在Sql Server中,确实没有必要这样做。
但是,我发现大多数我在真正想要的字段(或Oracle中的NCHAR(1))的地方是一个日期时间,表示没有那么多的值。旗帜,但确切地说它成为现实。这种情况并非总是如此,但是当我回想起我编写的旧代码时,我猜我曾经使用过一段时间的5次中有4次我应该使用日期时间。
答案 2 :(得分:5)
位字段通过自动强制执行当前隐含的业务规则来帮助您的逻辑(即,此列只能包含'Y'或'N')。如果您以编程方式强制执行该规则,则可以通过消除此开销来节省。由于基数较低,索引一个位列本身没什么价值,但它可以作为复合索引的一部分。
另见:
答案 3 :(得分:3)
创建位字段,添加一个模拟nchar(1)的计算列。
什么不使用nchar:
Y
vs y
vs unicode Y
Y
和N
是英文。 Ja / Nein,Oui / Non等你不应该对此进行索引,因此它归结为有效的存储和使用。位是
说,我们使用smalldatetime“WhenInactive”字段替代“IsActive”字段。 NULL =活动。
答案 4 :(得分:2)
如果您使用的是LINQ2SQL或实体框架,BIT
列将转换为bool
,但NCHAR(1)
会转换为string
。
答案 5 :(得分:1)
该字段是否广泛用于查询Where fld = 'Y'
?
如果是这样,我会考虑做一个测试,看看是否将它改为比特会影响性能。
现在更改它只是因为它应该是一个小字段,因为你在一个1m +记录的表上存储布尔值对我来说听起来不是一个好主意,我会选择@Andrew的答案。< / p>
答案 6 :(得分:1)
使用位:
意图的逻辑表示/表达 - 因为布尔状态并不总是一致地表达为Yes or No
,这意味着你需要在建模位中不一致,或者非直观,例如: True/False (T/F)
,On/Off (?O/F)
,Open/Closed(O/C)
等。
参照完整性 - 不可空位可以仅限于0 or 1
。除非您添加约束,否则*char(1)
可以是Y
,N
,X
或☺
。
Bits can be packed,因此可能会有较小的存储空间。
Re:性能:比特(或少数状态CHAR)列的索引通常是浪费,除非数据中有0或1的高选择性。在这种情况下,选择性值filtered index将是一个好主意。
(从deleted answer here迁移)
答案 7 :(得分:0)
我有几次我们想要一点点但不能确定在那个领域永远不需要第三或第四个值。因此,我们将其构造为包含Y或N的字符串字段。当然,我们仅在非常独特的情况下执行此操作。