Tinyint vs Bit?

SqlMysqlSql ServerTypes

Sql Problem Overview


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 1
  • tinyint: storage size is 1 byte, possible values are 0-255

Which 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?

Sql Solutions


Solution 1 - Sql

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.

Solution 2 - Sql

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.

Solution 3 - Sql

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:

Solution 4 - Sql

Solution 5 - Sql

A previous StackOverflow post: https://stackoverflow.com/questions/290223/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.

Solution 6 - Sql

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.

Solution 7 - Sql

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.

Solution 8 - Sql

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.

Solution 9 - Sql

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...

Solution 10 - Sql

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).

Solution 11 - Sql

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.

Solution 12 - Sql

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.

Solution 13 - Sql

@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

Solution 14 - Sql

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.

Solution 15 - Sql

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/

Solution 16 - Sql

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSeibarView Question on Stackoverflow
Solution 1 - SqlScottSView Answer on Stackoverflow
Solution 2 - SqlMike RobinsonView Answer on Stackoverflow
Solution 3 - SqlJohn RudyView Answer on Stackoverflow
Solution 4 - SqlarmandinoView Answer on Stackoverflow
Solution 5 - SqlMattView Answer on Stackoverflow
Solution 6 - SqltvanfossonView Answer on Stackoverflow
Solution 7 - SqlD'Arcy RittichView Answer on Stackoverflow
Solution 8 - SqlBeejorView Answer on Stackoverflow
Solution 9 - SqlRobView Answer on Stackoverflow
Solution 10 - SqlSheldmanduView Answer on Stackoverflow
Solution 11 - SqlsaldagView Answer on Stackoverflow
Solution 12 - SqlJoeView Answer on Stackoverflow
Solution 13 - SqlSeibarView Answer on Stackoverflow
Solution 14 - SqlGregory HartView Answer on Stackoverflow
Solution 15 - SqlBrynJView Answer on Stackoverflow
Solution 16 - SqlDarryl BraatenView Answer on Stackoverflow