BIT в MySQL — 100 практических примеров 

100 приёмов BIT в MySQL: маски флагов, побитовые операции, BIT_OR/BIT_AND, BIT_COUNT, индексация.

🟢 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 экономит место и ускоряет проверки признаков. Придерживайтесь практик индексирования и агрегатов.


 

Понравилась статья? Поделиться с друзьями: