BIT в MySQL. Введение
BIT — двоичный тип для хранения флагов и компактных булевых. Поддерживаются размеры 1..64, побитовые операции, агрегаты BIT_AND/BIT_OR. 100 примеров ниже.
Синтаксис
CREATE TABLE features (
id BIGINT PRIMARY KEY,
flags BIT(8) NOT NULL
);SELECT id, flags
FROM features
WHERE flags & b'00000100' <> 0;UPDATE features
SET flags = flags | b'00000001'
WHERE id=1;SELECT BIT_OR(flags) AS any_enabled
FROM features;Типовая конструкция
CREATE TABLE user_flags (
user_id BIGINT PRIMARY KEY,
flags BIT(16) NOT NULL DEFAULT b'0'
);
UPDATE user_flags
SET flags = flags | b'0000000000000100'
WHERE user_id=1001;100 примеров
Компактное хранение прав доступа в BIT(8)
CREATE TABLE access_flags (
user_id BIGINT PRIMARY KEY,
flags BIT(8) NOT NULL DEFAULT b'00000000'
);Несколько флагов функций в BIT(16)
CREATE TABLE feature_flags (
id BIGINT PRIMARY KEY,
flags BIT(16) NOT NULL
);Флаги статусов заказа в одном поле
CREATE TABLE order_flags (
order_id BIGINT PRIMARY KEY,
flags BIT(8) NOT NULL
);BIT(1) как булево значение
CREATE TABLE settings (
id BIGINT PRIMARY KEY,
is_active BIT(1) NOT NULL DEFAULT b'1'
);Установить флаг «подписка активна»
UPDATE settings
SET is_active = b'1'
WHERE id=10;Проверить, установлен ли флаг
SELECT id
FROM order_flags
WHERE (flags & b'00000010') <> b'0';Снять флаг «пауза»
UPDATE order_flags
SET flags = flags & ~b'00000100'
WHERE order_id=777;Переключить флаг уведомлений
UPDATE feature_flags
SET flags = flags ^ b'0000000000000010'
WHERE id=1;Сдвиг влево
UPDATE feature_flags
SET flags = (flags << 1)
WHERE id=1;Сдвиг вправо
UPDATE feature_flags
SET flags = (flags >> 1)
WHERE id=1;Фильтр пользователей по конкретной маске 10
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 11
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 12
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 13
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 14
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 15
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 16
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 17
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 18
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 19
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 20
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 21
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 22
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 23
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 24
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Ещё примеры
Фильтр пользователей по конкретной маске 25
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 26
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 27
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 28
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 29
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 30
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 31
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 32
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 33
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 34
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 35
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 36
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 37
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 38
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 39
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 40
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 41
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 42
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 43
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 44
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 45
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 46
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 47
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 48
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 49
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Ещё примеры
Фильтр пользователей по конкретной маске 50
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 51
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 52
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 53
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 54
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 55
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 56
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 57
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 58
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 59
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 60
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 61
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 62
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 63
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 64
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 65
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 66
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 67
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 68
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 69
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 70
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 71
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 72
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 73
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 74
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Ещё примеры
Фильтр пользователей по конкретной маске 75
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 76
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 77
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 78
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 79
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 80
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 81
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 82
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 83
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 84
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Фильтр пользователей по конкретной маске 85
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 86
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 87
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 88
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 89
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Ещё примеры
Фильтр пользователей по конкретной маске 90
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 91
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 92
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 93
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 94
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Ещё примеры
Фильтр пользователей по конкретной маске 95
SELECT user_id
FROM access_flags
WHERE (flags & b'00000111') = b'00000111';BIT_OR по проекту — есть ли активные флаги 96
SELECT project_id, BIT_OR(flags) AS any_on
FROM feature_flags
GROUP BY project_id;BIT_AND — одинаковы ли флаги у всех 97
SELECT project_id, BIT_AND(flags) AS all_same
FROM feature_flags
GROUP BY project_id;Подсчёт числа включённых битов 98
SELECT id, BIT_COUNT(flags) AS bits_on
FROM feature_flags;Индекс виртуального INT над BIT для поиска 99
ALTER TABLE feature_flags
ADD COLUMN flags_i BIGINT AS (CAST(flags AS UNSIGNED)) STORED,
ADD INDEX (flags_i);Типичные ошибки и советы по BIT
- Размер: задавайте точный размер (например, BIT(8)) и следите за переполнением.
- Операции: используйте побитовые операторы (&, |, ^, ~) и агрегаты BIT_AND/BIT_OR.
- Подсчёты: для количества включённых флагов используйте BIT_COUNT.
- Индексация: применяйте виртуальный числовой столбец для индекса по маске.
- Интероперабельность: для API конвертируйте BIT в число через CAST.
BIT в MySQL. Заключение
BIT экономит место и ускоряет проверки признаков. Придерживайтесь практик индексирования и агрегатов.