Databases Reference
In-Depth Information
+------+-------+
| a | a + 0 |
+------+-------+
| 9 | 57 |
+------+-------+
This can be very confusing, so we recommend that you use BIT with caution. For
most applications, we think it is a better idea to avoid this type.
If you want to store a true/false value in a single bit of storage space, another option
is to create a nullable CHAR(0) column. This column is capable of storing either the
absence of a value (NULL) or a zero-length value (the empty string).
SET
If you need to store many true/false values, consider combining many columns into
one with MySQL's native SET data type, which MySQL represents internally as a
packed set of bits. It uses storage efficiently, and MySQL has functions such as
FIND_IN_SET() and FIELD() that make it easy to use in queries. The major drawback
is the cost of changing the column's definition: this requires an ALTER TABLE , which
is very expensive on large tables (but see the workaround later in this chapter). In
general, you also can't use indexes for lookups on SET columns.
Bitwise operations on integer columns
An alternative to SET is to use an integer as a packed set of bits. For example, you
can pack eight bits in a TINYINT and manipulate them with bitwise operators. You
can make this easier by defining named constants for each bit in your application
code.
The major advantage of this approach over SET is that you can change the “enu-
meration” the field represents without an ALTER TABLE . The drawback is that your
queries are harder to write and understand (what does it mean when bit 5 is set?).
Some people are comfortable with bitwise manipulations and some aren't, so
whether you'll want to try this technique is largely a matter of taste.
An example application for packed bits is an access control list (ACL) that stores per-
missions. Each bit or SET element represents a value such as CAN_READ , CAN_WRITE , or
CAN_DELETE . If you use a SET column, you'll let MySQL store the bit-to-value mapping
in the column definition; if you use an integer column, you'll store the mapping in your
application code. Here's what the queries would look like with a SET column:
mysql> CREATE TABLE acl (
-> perms SET('CAN_READ', 'CAN_WRITE', 'CAN_DELETE') NOT NULL
-> );
mysql> INSERT INTO acl(perms) VALUES ('CAN_READ,CAN_DELETE');
mysql> SELECT perms FROM acl WHERE FIND_IN_SET('AN_READ', perms);
+---------------------+
| perms |
+---------------------+
| CAN_READ,CAN_DELETE |
+---------------------+
If you used an integer, you could write that example as follows:
 
Search WWH ::




Custom Search