Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any difference between integer and bit(n) data types for a bitmask?

I am working with a table in a PostgreSQL database that has several boolean columns that determine some state (e.g. published, visible, etc.). I want to make a single status column that will store all these values as well as possible new ones in a form of a bitmask. Is there any difference between integer and bit(n) in this case?

This is going to be a rather big table, because it stores objects that users create via a web-interface. So I think I will have to use (partial) indexes for this column.

like image 468
Igor Zinov'yev Avatar asked Apr 03 '12 10:04

Igor Zinov'yev


People also ask

What is the difference between bit and integer?

For 32 bits of information, an integer still needs 4 bytes (+ padding), a bit string occupies 9 bytes for the same (5 + 4) and boolean columns occupy 32 bytes. To optimize disk space further you need to understand the storage mechanisms of PostgreSQL, especially data alignment. More in this related answer.

What is bit data type in PostgreSQL?

Bit strings are strings of 1's and 0's. They can be used to store or visualize bit masks. There are two SQL bit types: bit( n ) and bit varying( n ) , where n is a positive integer. bit type data must match the length n exactly; it is an error to attempt to store shorter or longer bit strings.

What is difference between bit and bool?

A boolean is a true-or-false quantity, but a bit is actually an integer, just like char or int, but only one bit wide. When converting to these types, you can get different results. In the boolean world, 0 is false and anything else is true.

What is the largest bit string?

The default length is 1 byte. The maximum length is 65,500 bytes (8192 bytes prior to V12). FairCom DB SQL interprets a character string as the character representation of a hexadecimal string. If the data inserted into a BINARY column is less than the length specified, FairCom DB SQL pads it with zeroes.


1 Answers

If you only have a few variables I would consider keeping separate boolean columns.

  • Indexing is easy. In particular also indexes on expressions and partial indexes.
  • Conditions for queries are easy to write and read and meaningful.
  • A boolean column occupies 1 byte (no alignment padding). For only a few variables this occupies the least space.
  • Unlike other options boolean columns allow NULL values for individual bits if you should need that. You can always define columns NOT NULL if you don't.

If you have more than a hand full variables but no more than 32, an integer column may serve best. (Or a bigint for up to 64 variables.)

  • Occupies 4 bytes on disk (may require alignment padding, depending on preceding columns).
  • Very fast indexing for exact matches ( = operator).
  • Handling individual values may be slower / less convenient than with varbit or boolean.

With even more variables, or if you want to manipulate the values a lot, or if you don't have huge tables or disk space / RAM is not an issue, or if you are not sure what to pick, I would consider bit(n) or bit varying(n) (short: varbit(n).

  • Occupies at least 5 bytes (or 8 for very long strings) plus 1 byte for each group of 8 bits (rounded up).
  • You can use bit string functions and operators directly, and some standard SQL functions as well.

For just 3 bits of information, individual boolean columns get by with 3 bytes, an integer needs 4 bytes (maybe additional alignment padding) and a bit string 6 bytes (5 + 1).

For 32 bits of information, an integer still needs 4 bytes (+ padding), a bit string occupies 9 bytes for the same (5 + 4) and boolean columns occupy 32 bytes.

To optimize disk space further you need to understand the storage mechanisms of PostgreSQL, especially data alignment. More in this related answer.

This answer on how to transform the types boolean, bit(n) and integer may be of help, too.

like image 122
Erwin Brandstetter Avatar answered Nov 14 '22 17:11

Erwin Brandstetter