Reputation: 70353
I don't want to touch-off a religious war here, but there seem to be two schools of thoughts in how to represent boolean values in a database. Some say bit
is the appropriate data type, while others argue tinyint
is better.
The only differences I'm aware of are these:
bit
: storage size is 1 bit, possible values are 0 or 1tinyint
: storage size is 1 byte, possible values are 0-255Which data type is better when you need to represent boolean values? Is tinyint
worth the extra overhead "just in case" you need to values > 1?
Upvotes: 91
Views: 59764
Reputation: 18572
For MySql users - Why you should not use BIT columns in MySQL
Edit: alternative link via archive.org
https://web.archive.org/web/20200825160258/http://www.xaprb.com/blog/2006/04/11/bit-values-in-mysql/
Upvotes: 6
Reputation: 157
TinyInt is my preference. Then, when doing aggregated counts against the field, you don't have to cast it. Also, some front-end languages interpret a Bit differently than others, and using a TinyInt makes validation checks universal for any front-end language.
Upvotes: 0
Reputation: 9408
Zero Space for False
Whatever your choice, you can set to NULL
instead of 0
and it will take up no extra space (since the database almost always has a NULL
flag for every field of every row, just sitting there; more info here). If you also make sure the default/most likely value is false
, you'll save even more space!
Some Space for True
The value to represent true
requires the space defined by the field type; using BIT
will only save space if a table has multiple such columns, since it uses one byte per 8 fields (versus TINYINT
which uses one byte per field).
TINYINT
has the advantage of allowing you to customize an 8-value bitmask without worrying about managing a bunch of extra columns, and searching is theoretically faster (a single integer field versus several bit fields). But there are some disadvantages such as slower ordering, fancy cross-indexing stuff, and lack of field names. Which to me, is the biggest loss; your database would require external documentation to note which bits did what in which bitmasks.
In any case, avoid the temptation to use TEXT
fields to store booleans or sets of them. Searching through text is a lot more work for the server, and arbitrary naming schemes like "on, off, off" can hurt interoperability.
Upvotes: 2
Reputation: 11
I don't think I saw it mentioned above, but there's the issue of not being able to aggregate BIT columns (e.g. MIN, MAX, and especially SUM). I just tested using 2008 and the issue is still there. That's the biggest reason I use tinyint lately - the other being I like how tinyint scales - it's always a pain when your "two-value" bit flag suddenly needs more possible values.
Upvotes: 1
Reputation: 1800
All these theorentical discussions are great, but in reality, at least if you're using MySQL and really for SQLServer as well, it's best to stick with non-binary data for your booleans for the simple reason that it's easier to work with when you're outputting the data, querying and so on. It is especially important if you're trying to achieve interoperability between MySQL and SQLServer (i.e. you sync data between the two), because the handling of BIT datatype is different in the two of them. SO in practice you will have a lot less hassles if you stick with a numeric datatype. I would recommend for MySQL to stick with BOOL or BOOLEAN which gets stored as TINYINT(1). Even the way MySQL Workbench and MySQL Administrator display the BIT datatype isn't nice (it's a little symbol for binary data). So be practical and save yourself the hassles (and unfortunately I'm speaking from experience).
Upvotes: 1
Reputation: 37858
I use bits when appropriate. Aside from it being semantically the correct type (semantics count!), multiple bit fields (up to 8) in a single row (on SQL Server, anyway) can be consolidated into a single byte of storage. After the eighth, an additional byte is needed for the next 8, and so on.
References:
Upvotes: 17
Reputation: 25159
Bit...unless you're of the "true / false / file not found" clan
In case you didn't get the reference...
And in the case of Linq2SQL, bit works with true/false which makes it easier to program for. There's advantages to both.
And there's also programming maintenance to consider. What happens if you (or a junior intern programmer) uses a 2, 3, 25, 41, 167, 200 etc? Where is that documented? Bits are self-documenting and pretty universal.
Upvotes: 20
Reputation: 171559
I use bit because it saves me having to use a check constraint, and because my ORM will automatically convert bit into a nullable boolean (C#), which I very much appreciate once coding.
Upvotes: 2
Reputation: 5231
I like using char(1) with 'T' or 'F'. Yes it can be abused with other values but at least it is easy to view in reports or other places where bit or binary values are harder to work with.
Upvotes: -3
Reputation: 8553
When you add a bit column to your table it will occupy a whole byte in each record, not just a single bit. When you add a second bit column it will be stored in the same byte. The ninth bit column will require a second byte of storage. Tables with 1 bit column will not gain any storage benefit.
Tinyint and bit can both be made to work, I have used both successfully and have no strong preference.
Upvotes: 101
Reputation: 8382
If you're using MySQL, then it's not recommended to use the BIT data type - http://www.xaprb.com/blog/2006/04/11/bit-values-in-mysql/
Upvotes: -1
Reputation: 532695
Boolean, by definition, allows only two values. Why would you need anything more than a single bit for this? if you need a three (or more) state logic, then use a bigger datatype, but I would (and do) stick with bit fields for standard boolean logic.
Upvotes: 3
Reputation: 3896
A previous StackOverflow post: What is the difference between BIT and TINYINT in MySQL?
When adding a new "BOOL" column, MySQL actually uses TINYINT.
I'd just stick with BOOL (aka TINYINT) and move on with life.
Upvotes: 3
Reputation: 70353
@Kevin: I believe you can use group by
on bit fields (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
Results:
myBit1
------ -----------
0 2
1 2
myBit2
------ -----------
0 2
1 2
Upvotes: 0
Reputation: 42666
We build all our tables with an int "vector" field. We then use that field as a collection of 32 bits that we can assign for any purpose. (Potentially using a group of bits for a set of states). Avoids us having to keep adding in flag fields if we forget.
Upvotes: 0
Reputation: 2110
I just tried grouping on bit (SQL Server 2k5) and it worked fine for me. I like using the correct data type for the application. If it's a true/false field, then bit is what i use...
Upvotes: 1