Задать вопрос
venticello
@venticello
IT-направленный

Хранение и выборка булевых значений. Mysql

Есть 4 переключателя (вкл\выкл) по ним будет проводится выборка, пример, 1й включен 2й выключен 3й не важно 4й включен.
Как лучше организовать хранение данных, в голову сразу пришло решение 4 поля TINYINT, но как понимаю есть более грамотные решения? например, хранения в одном поле четырех значений (1101), вопрос как выбирать, через like? как эффективнее?
Какое лучше выбрать решение, ткните носом пожалуйста где почитать?
  • Вопрос задан
  • 4651 просмотр
Подписаться 3 Оценить Комментировать
Решения вопроса 1
Dzuba
@Dzuba
Я бы попробовал следующее: хранить все 4 бита совместно в одном индексированном поле (назовем его bits), имеющем тип TINYINT UNSIGNED (либо BIT(4), либо SET).
А запросы бы делал в виде:
SELECT * FROM table WHERE bits IN (...)
Где вместо многоточия должны быть перечислены те значения, которые удовлетворяют маске. Для маски, указанной вами в примере, запрос примет вид:
SELECT * FROM table WHERE bits IN (b'1001', b'1011')
На мой взгляд, при таком подходе и место экономится, и производительность будет наилучшей.
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
KEKSOV
@KEKSOV
Уверен, что для описанной задачи подойдет тип данных SET
Ответ написан
kutelev
@kutelev
Если строк будет не много, то я бы, возможно, сделал бы так:

CREATE TABLE `test`.`switches` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`switches` CHAR(4) NOT NULL,
PRIMARY KEY (`id`)
);

Тогда ваш пример (1 — включен, 2 — выключен, 3 — не важно, 4 — включен) превращается в запрос:

SELECT * FROM switches WHERE switches LIKE '10_1';
Ответ написан
Assorium
@Assorium
На Вашем месте использовал бы тип BOOLEAN (это синоним TINYINT но со значениями 0 или 1 только).
По ним можно выстроить индекс и поиск будет проводится гораздо быстрее, чем по строке с LIKE.
Также можно будет легко расширить систему, удалив или добавив новый переключатели.
Ответ написан
@eresik
Важна производительность? BOOLEAN
Важна экономия места? SET
Ответ написан
Dzuba
@Dzuba
Вы путаете. Никакой экономии по месту нет. И в моем решении, и в SET, все хранится в 1 байте. Компактнее некуда. А вот решение с 4 полями типа BOOLEAN занимает 4 байта.
Я убежден, что приведенное мной решение является также и самым производительным из предложенных.
Преимущество по скорости в нем достигается за счет использования индекса конструкцией WHERE IN (...). Точно такой же результат должен быть, если использовать эту конструкцию и с полем типа SET. Я даже изначально написал, что решение приемлемо для типов, цитирую:
TINYINT UNSIGNED (либо BIT(4), либо SET)
Это поскольку все они приводимы к целочисленному типу, и, при использовании каждого из них, фактически будут образовываться одинаковые значение в байте.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 дек. 2024, в 20:40
10000 руб./за проект
22 дек. 2024, в 20:34
3000 руб./за проект
22 дек. 2024, в 20:12
10000 руб./за проект