Tinyint vs Bit?

时间:2009-01-28 18:43:01

标签: sql mysql sql-server types

我不想在这里触发宗教战争,但似乎有两种思路可以在数据库中表示布尔值。有人说bit是适当的数据类型,而其他人认为tinyint更好。

我所知道的唯一区别是:

  • bit:存储大小为1位,可能的值为0或1
  • tinyint:存储大小为1个字节,可能的值为0-255

当您需要表示布尔值时,哪种数据类型更好? tinyint值得额外开销“以防万一”您需要值> 1?

16 个答案:

答案 0 :(得分:82)

当你向表中添加一个位列时,它将占用每个记录中的整个字节,而不仅仅是一个位。添加第二位列时,它将存储在同一个字节中。第九位列需要第二个存储字节。具有1位列的表将不会获得任何存储益处。

Tinyint和bit都可以使用,我已成功使用它们并没有强烈的偏好。

答案 1 :(得分:18)

比特......除非你是“真/假/未找到档案”的战队

In case you didn't get the reference...

对于Linq2SQL,bit使用true / false,这样可以更容易编程。两者都有优势。

还需要考虑编程维护。如果您(或初级实习生程序员)使用2,3,25,41,167,200等会怎样?记录在哪里? 比特是自我记录并且相当普遍。

答案 2 :(得分:14)

我在适当时使用位。除了它在语义上是正确的类型(语义计数!)之外,单行中的多个位字段(最多8个)(无论如何在SQL Server上)可以合并到单个存储字节中。在第八个之后,接下来的8个需要一个额外的字节,依此类推。

参考文献:

答案 3 :(得分:5)

答案 4 :(得分:3)

之前的StackOverflow帖子:What is the difference between BIT and TINYINT in MySQL?

当添加新的“BOOL”列时,MySQL实际上使用了TINYINT。

我只是坚持 BOOL (又名 TINYINT )并继续生活。

答案 5 :(得分:2)

根据定义,布尔值只允许两个值。为什么你需要的不仅仅是一点呢?如果您需要三个(或更多)状态逻辑,那么使用更大的数据类型,但我会(并且确实)坚持使用标准布尔逻辑的位字段。

答案 6 :(得分:2)

我使用bit是因为它节省了我必须使用检查约束,并且因为我的ORM会自动将位转换为可以为空的布尔值(C#),我非常感谢编码。

答案 7 :(得分:2)

所有这些理论上的讨论都很棒,但实际上,至少如果你使用的是MySQL,而且对于SQLServer也是如此,最好坚持使用非二进制数据为你的布尔值,原因很简单,因为它更容易工作当你输出数据,查询等时。如果您正在尝试实现MySQL和SQLServer之间的互操作性(即您在两者之间同步数据),这一点尤其重要,因为BIT数据类型的处理在两者中是不同的。因此,如果你坚持使用数值数据类型,那么在实践中你将会有更少的麻烦。我建议MySQL坚持BOOL或BOOLEAN,它存储为TINYINT(1)。即使MySQL Workbench和MySQL Administrator显示BIT数据类型的方式也不好(它是二进制数据的一个小符号)。所以要务实并为自己省去麻烦(不幸的是,我是从经验中说出来的)。

答案 8 :(得分:2)

虚假零空间

无论您的选择是什么,您都可以设置为NULL而不是0,它将占用无额外空间(因为数据库几乎总是有NULL每行的每个字段都有标志,只是坐在那里; more info here)。如果您还确保默认/最可能的值为false,则可以节省更多空间!

真实的空间

表示true的值需要字段类型定义的空间;使用BIT只会在表中有多个这样的列时节省空间,因为它每8个字段使用一个字节(而TINYINT每个字段使用一个字节)。

TINYINT的优点是允许您自定义8值bitmask而无需担心管理一堆额外的列,理论上搜索速度更快(单个整数字段与多个位字段相比) 。但是有一些缺点,例如排序速度慢,花哨的交叉索引,以及缺少字段名称。对我来说,这是最大的损失;你的数据库需要外部文档来记录哪些位做了哪些位掩码。

无论如何,避免使用TEXT字段来存储布尔值或其中的一组。通过文本搜索对于服务器来说是更多的工作,并且诸如“开,关,关”之类的任意命名方案可能会损害互操作性。

答案 9 :(得分:1)

我刚尝试分组(SQL Server 2k5),它对我来说很好。我喜欢为应用程序使用正确的数据类型。如果它是一个真/假字段,那么bit就是我用的......

答案 10 :(得分:1)

我认为我没有看到上面提到的那个,但是存在无法聚合BIT列(例如MIN,MAX,尤其是SUM)的问题。我刚刚使用2008测试,问题仍然存在。这是我最近使用tinyint的最大原因 - 另一个是我喜欢tinyint的缩放 - 当你的“双值”位标志突然需要更多可能的值时,总是很痛苦。

答案 11 :(得分:0)

我们使用int“vector”字段构建所有表。然后,我们将该字段用作32位的集合,我们可以为任何目的分配这些字段。 (可能使用一组位用于一组状态)。如果我们忘记,我们不得不继续添加标记字段。

答案 12 :(得分:0)

@Kevin:我相信你可以在位字段上使用group by(SQL Server 2005):

declare @t table (
    descr varchar(10),
    myBit1 bit, 
    myBit2 bit
)
insert into @t values ('test1', 0, 1)
insert into @t values ('test2', 1, 0)
insert into @t values ('test3', 1, 1)
insert into @t values ('test4', 0, 0)

select myBit1, count(myBit1) from @t group by myBit1
select myBit2, count(myBit1) from @t group by myBit2

结果:

myBit1 
------ -----------
0      2
1      2

myBit2 
------ -----------
0      2
1      2

答案 13 :(得分:0)

TinyInt是我的偏爱。然后,在对字段进行汇总计数时,无需强制转换。另外,某些前端语言对Bit的解释与其他语言不同,并且使用TinyInt可使验证检查对任何前端语言通用。

答案 14 :(得分:-1)

如果您使用的是MySQL,则不建议使用BIT数据类型 - http://www.xaprb.com/blog/2006/04/11/bit-values-in-mysql/

答案 15 :(得分:-2)

我喜欢使用带有'T'或'F'的char(1)。是的,它可以被其他值滥用,但至少在报表或其他比特或二进制值更难处理的地方很容易查看。