Pull to refresh

Comments 64

Правильное название: Битовая маска
мне кажется, битовая маска проще будет — у нас у поля может быть только два состояния, 0 и 1
возможно я не прав
SET в MySQL тоже хранится как битовая маска.
Чем это она проще? Необходимостью дописывать то, что уже было написано до вас?

Для подобных ситуаций используется либо дополнительная таблица, либо SET. Остальное — от лукавого :)
Как ничего? А приведённый в тексте код?
хм, как это реализуется при использовании SET?
Получить список меток — простая выборка, не нужно потом переводить в человеко-понятный вид.

Хотя в целом, что SET, что INT при использовании в этом контексте имеют кучу минусов. SET — это именнованные списки, реализованные как гибкий INT (размер поля зависит от количества элементов), и унаследовавший все его недостатки.
UFO just landed and posted this here
Как-то баловался таким-же способом хранения аттрибутов записи в блоге, появились проблемы с производительностью. Помоему в этом случае индексы не используются.
Ценное наблюдение, проверю по поводу индексов.
EXPLAIN в mysql говорит что possible keys null, однако в графе key стоит название используемого индекса, а также указана его длина.
Не совсем так. Индекс можно сделать, но он будет полезен при выборке записей с идентичными флагами. А, скажем, если надо выбрать записи, у которых установлен некий бит, а значения остальных не важно — тогда для каждой записи нужно выполнить операцию по выделению значения этого бита, а потом сравнение, что будет явно медленней поиска по индексу. В общем, как мне кажется, удобства от использования битовых масок сомнительные.
У нас так и сделано — проблема с индексацией есть, выявилась тогда, когда менять стало поздно. В следующей версии движка решили от такого откреститься.
вообще индекс использован не будет ибо: `services` & n высчитываемое значение, но похоже, что если поразмыслить, то можно эту операцию разбить на индексируемые, хотя не уверен.
а не проще было хранить строку с отмеченными id чекбоксов и разделяя их запятыми? ваш метод тоже конечно интересный, но вот тестировать легче со строкой.
В этом случае поиск придется вести LIKE '%, id,%', при этом не будут использоваться индексы.
если придется подобное делать, учту. спасибо :)
Можно ещё и через FIND_IN_SET(), только на счёт производительности ничего сказать не могу.
в данной реализации (field & n) индексы использоваться так же не будут
Мне кажется или что-то такое уже предлагали?
Поиском я не нашел, буду благодарен, если укажете мне на статью, в которой это уже предлагалось.
сравнивали скорость поиска и внесения изменений?
скорость извлечения?
какие результаты? — сколько процентов дискового пространства экономится применительно к базе, где это применялось и какой проигрыш(выигрыш?) в скорости? как увеличивается нагрузка на базу?
наитипичнейшая схема «многие ко многим». Со всеми вытекающими. В большинстве случаев отдельной таблицы связей достаточно.
что вы, нормализация нынче не в моде.
у себя в проекте не выпендривался и так и сделал, плюс от использования индексов очевиден, а на лишний гиг-два места наплевать.
А как же первая нормальная форма БД?
Ещё, средствами SQL просматривать таблички будет проблематично…
> Список услуг представляет собой набор чекбоксов, если услуга оказывается то чекбокс помечается, в противоположном случае отметка не ставится. Предположим количество услуг в каталоге равняется десяти(просто для определенности).

У вас уже грубейшая ошибка в проектировании. Услуг уже завтра будет 11, а верез неделю 15. И вы 2 недели потеряете на перекраивание приложения, которое работает с вашей базой.
полностью поддерживаю, единственное проблемы возникают не при увеличении а при уменьшении кол-ва услуг.
Кстати, чем не угодила дефакто используемая при таких операциях связь многие ко многим?
А не будет ли проще использовать для хранения настроек т.н. повернутые на 90 градусов таблицы?
Конечно пару байд дискового пространства потеряется, но переписывание кода, при введении нового параметра и изменение структуры БД отпадет совсем.
да да тока генератор SQL придется состряпать
Сэкономили пусть даже 15 байт за одну компанию, зато очень и очень потеряли в скорости обработки данных (как при выборке — полный просмотр, так и при вставке/редактировании — цикл). В общем, поменяли шило на мыло.
М… Это вы придумали битовые маски? Может и условный переход тоже ваших рук дело? ;)
Когда-то и я такой велосипед изобретал. Слава богу нашлись люди, которые сумели мне объяснить, почему так делать не надо ни в коем случае.
Было бы намного прекрасней, если бы вы объяснили почему так делать нельзя)))

А вообще побитовые оптимизации вещь известная и где-то точно применения находит, не уверен правда что тут — не представляю как MySql будет такое оптимизировать — смотрю чисто с точки зрения программиста.
Вы совершенно правы — MySQL никак не сможет оптимизировать.
Собственно по этому и не стоит так делать. Ведь все чекбоксы в дальнейшем используются в дальнейшем как фильтры по которым в дальнейшем будет строиться выборка, расчитываться статистика и прочее.
Единственное где можно использовать (по моему мнению) это в местах с узким каналом, например устройства передающие данные через GPRS.
Или при необходимости одновременного хранения большого числа объектов в оперативной памяти.
Но в таком случае можно/нужно делать параллельно хранение в БД для поиска и в записи для хранения и передачи.
Хранение нескольких переменных булевого типа в одной численно не нова. А вот в БД, как сказали выше, его применение нецелесообразно.
вы бы для наглядности показали что за биты-то такие.
слева двоичная система, справа — десятеричная.
00001 = 1 - первый флаг
00010 = 2 - второй
00100 = 4 - третий
01000 = 8 - четвёртый
10000 = 16 - пятный
и так далее
01011 = 1+2+8 = 11 - перый, второй и четвёртый
Пробовал как-то такую штуку для админки (отдельные задачи обозначал константами, в БД хранил сумму флагов) — больше так делать не буду, ибо нерасширяемо.
Лучше отдельной таблицы ничего не придумано?
UFO just landed and posted this here
Собирается на клиенте на раз два, представление — это его задача.
Экономия на спичках с неизвестными граблями сайд-эффектами.
Основной недостаток — при поиске. Ни один движок не сделает индекс по битовой маске.
Вы уточняйте: поиск бита в битовой маске.

Индекс то сделается, но зачем он тогда нужен, если все записи будут перебираться.

Но в процессе построения запросов, самое удивительное то,
что оптимизатор mysql сам всегда выбирает, какой индекс использовать, и в 99% случаев не ошибается.

Так вот, 99% того что оптимизатор сначала сделает «выборку» по другим удобным индексам и только потом начнет высчитывать поля с битовыми масками.

Вывод: если вы знатете что при выборке до манипуляций с битовыми полями у вас будет результат не очень большой, можете спокойно пользоваться битовыми масками, SUN не зря купили MySQL GmbH за миллиард.

Битовую маску можно использовать, только надо знать где… да вообще explain и оптимизации никто не отменял.
Учтите одно, если вы в запросе «высчитываете/просчитываете» поле битовой маски — забудьте про индексы при выборке, правда, если вы join выполнятете к выбранному результату и потом битовую маску считаете, то на скорости это не скажется, если конечно вы не используете поле битовой маске в ON.

Далее, например очень удобно хранить «доступ» по группам.
Конечно 32 бита — это 32 группы, но этого всегда вполне хватит (кто-то наблюдал более 32 групп в природе ;)?

Кстати mysql, да вообще все «языки» очень быстро выполняют битовые операции — не забывайте об этом!
кто-то наблюдал более 32 групп в природе ;)
Смотря где, если это какая-то (пардон за набившее оскомину слово) очередная «социальная сеть», то там будет всяко больше 30 групп. Но даже если это небольшой проект, то все равно иметь жесткое ограничение в 32 группы очень нехочется. Кто знает, что будет завтра — может вам жизненно потребуется 33-я группа, а сделать ее будет нереально без полной ломки приложения.
В соц. сети более 32 групп? ну возможно, пусть скажут например работающие в хабре, но я сомневаюсь,
Хотя всё может быть, но «новое веенье» — это не засывывать юзеров по мелким группам, а давать каждому юзеру — свои права.

И далее… Никто не мешает плугинсом добавить еще одно поле + 32 группы и еще одно и т.п.

При нормальной архитектуре — полной ломки приложения не надо. Всё спокойно делают плугинсы или (они же) модули
Все же зря вы отрицаете групповую раздачу прав. На мой взгляд, удобнее организовать пользователей в группы («Админы», «Менеджеры», «Техподдержка» и т.п.) и разом дать им права, чем возиться с каждым.

Если так добавлять поля, то потребуется менять структуру таблицы.
АХАХАХАХААААА =) я под столом просто.
coylone.habrahabr.ru/blog/37131/
За этот пост я лишился 10 пунктов кармы, а сам пост ушел в минус +)))))))

Для тех кто не понял — это идентичный пост, написанный ранее.
Поиском он не находился
Напишите пожалуйста, как лучше всего реализовать этто с помощью отдельной таблицы )
Уточните, пожалуйста, задачу. Вы хотите хранить битовые маски в отдельной таблице, или же просто права и(или) группы?
Chrome, я имею в виду поставленную в посте задачу.
Из комментариев я понял, что битовые маски — не самый удобный по скорости и удобству использования вариант реализации. Несколько раз в комментах прозвучало мнение, что лучше всего использовать отдельную таблицу для решения задачи.

Хотелось бы разобраться и найти оптимальный способ )
Sign up to leave a comment.

Articles