我正在重构数据库(SQL Server 2008)方案并收集参数以进行更改 NCHAR(1) 列(保留 Y|N 值)到 BIT. 。每个人都知道这是必要的,但不知道为什么会发生,但这种变化会影响生产数据库,因此需要有分量的论据。表保存地址目录(最多 1m 条记录)。

我发现的第一个论点 - 每个 nchar 字段 占用2个字节,每个8个 位字段 - 1 个字节(接下来的 8 个字节 - 附加 1 个字节)。

下一步是什么?也许有些索引性能问题?

有帮助吗?

解决方案

位字段通过自动执行当前隐式业务规则(即该列只能包含“Y”或“N”)来帮助您的逻辑。如果您以编程方式强制执行该规则,则可以通过消除该开销来节省成本。由于基数较低,单独对位列进行索引几乎没有价值,但作为复合索引的一部分可能很有用。

也可以看看:

其他提示

我会毫不犹豫地为这种改变提供任何参数,除非你有一个很好的理由做出的改变。即你有一个变化的成本平衡你会亲自做过/喜欢什么,VS的实际执行它和补助费用。

你检查使用的nchar(1)的是否被损害性能,或者是你落入过早优化陷阱?您只谈论100万条记录在这里。

对于次要存储/ IO花费你认为你承担,考虑总工时来变化,复试和升级系统*每小时的速度VS的只是购买更快的磁盘成本。我怀疑磁盘会便宜得多。 - 以及受益于系统的每个方面

一个常见原因找到NCHAR(1)而不是位是Oracle不支持一个位类型。如果你有一个Oracle或Oracle训练的开发者,或者一个数据库,用于在Oracle运行,你会看到这个有很多。在SQL Server中,真的没有必要为此。

不过,我发现,在我(在Oracle或NCHAR(1))有位场最多的地方我的真正的要的是什么,表示的不是尽可能多的价值日期时间国旗,但具体什么时候成了真。这并不总是这种情况下,但是当我回想起关于旧的代码我写我猜4出5次我用了一下场我应该使用的日期时间。

创建位字段,添加一个暂时模拟 nchar(1) 的计算列。

不应该使用 nchar 的情况:

  • Yy 与一些 unicode Y
  • 检查 Y 或 N 的开销
  • 本身不是“true”或“false”(例如不会直接映射到 .net 布尔值)
  • YN 是英语。Ja/Nein、Oui/Non 等

无论如何,您都不应该对其建立索引,因此这取决于有效的存储和使用。位是

  • 较小
  • 数据类型安全(例如不需要检查)
  • 直接映射到客户含义
  • 独立于地区

也就是说,我们使用小日期时间“WhenInactive”字段来代替“IsActive”字段。NULL = 活动。

如果您使用的是LINQ2SQL或实体框架BIT柱将转化为一个bool,但NCHAR(1)将转化为一个string

该字段在查询中是否广泛使用 Where fld = 'Y'?

如果是这样,我会考虑进行测试,看看将其更改为位是否会影响性能。

现在更改它只是因为它应该是一个位字段,因为您将布尔值存储在 1m+ 记录的表上,这对我来说听起来也不是一个好主意,我会同意@Andrew的答案。

使用位:

  • 意图的逻辑表示/表达 - 因为布尔状态并不总是可以一致地表达为 Yes or No, ,这意味着您要么需要在建模位上不一致,要么需要不直观,例如 True/False (T/F), On/Off (?O/F), Open/Closed(O/C) ETC。

  • 参照完整性 - 不可空位只能被限制为 0 or 1. 。除非你添加约束,否则你的 *char(1) 可能 Y,N, X 或者 .

  • 可以打包位, ,因此可以有更小的存储空间。

  • 关于:表现 :位(或少状态 CHAR)列的索引通常是一种浪费,除非数据中 0 或 1 的选择性很高。在这种情况下,一个 过滤索引 关于选择性值将是一个好主意。

(迁移自 此处已删除答案)

我有几个场合我们需要一个位字段,但无法知道肯定永远不会有在该领域第三或第四值的需要。因此,我们把它作为含有Y或N.当然是一个字符串字段,我们只有在非常特殊情况这样做。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top