Не так давно я разговаривал со своим коллегой, и он определенно был против использования битовых масок, потому что трудно понять все значения, хранящиеся в базе данных. По моему мнению, это не всегда плохая идея использовать их, например, для определения ролей текущего пользователя. В противном случае вам нужно сохранить его в отдельной таблице, что приведет к еще одному JOIN. Подскажите пожалуйста, если я не прав? Любые другие побочные эффекты, преимущества / недостатки использования битовых масок?
database
patterns-and-practices
bit
advantages
Алекс Овечкин
источник
источник
Ответы:
Я работаю с приложением, которое использует битовые маски для хранения назначений ролей пользователей. Это боль в заднице. Если это делает меня предвзятым, виновным, как обвинение.
Если вы уже используете реляционную базу данных, это анти-паттерн, который нарушает большинство реляционных теорий и все правила нормализации. Когда вы создаете собственное хранилище данных, это может быть не такой уж плохой идеей.
Существует такая вещь, что объединяется слишком много таблиц, но реляционные базы данных созданы для этого. Многие из них имеют дополнительные функции, если производительность становится проблемой: индексы, индексированные представления и т. Д. Даже если искомые значения меняются не очень часто, что является преимуществом для Bitmask, накладные расходы на управление индексацией довольно легко в базе данных.
Хотя базы данных хорошо справляются с агрегацией данных, они могут стать вялыми, когда вы начнете вводить в наборы данных такие вещи, как сложные формулы или скалярные функции. Вы можете делать побитовое в своем приложении, но если все, что вы делаете, это получение связанных данных (поиск ролей пользователя), вы не пользуетесь преимуществами того, что лучше всего делает ваше хранилище данных.
Мой последний аргумент против этого будет простота для других разработчиков. У вас есть пользователи, роли и назначения. Это набор отношений «многие ко многим» (поскольку существует более одного отношения), который настолько распространен, что им легко управлять. Это просто CRUD материал.
источник
where some_bit_mask & 12 > 0
без построчного сканирования.user_role_map
илиuser_priv_map
столу.Вы уже назвали соответствующие плюсы и минусы:
Чтобы решить, что делать, нужно больше информации:
Так что вам нужно собрать факторы риска, а затем взвесить их, чтобы увидеть, перевешивают ли плюсы минусы.
источник
Если вы действительно, действительно , очень ограничены в доступе на диске, то вы можете рассмотреть растровые изображения для пользовательских разрешений. Если вы беспокоитесь о производительности, то забудьте о них совсем, потому что их разделение будет медленнее. Вы не можете индексировать растровое поле по смыслу, что приводит к сканированию таблиц базы данных, которые [почти] всегда снижают производительность.
Если вы не являетесь Amazon или Netflix, объем данных, связанных с разрешениями пользователей, будет незначительным по сравнению со всем, что у вас есть.
Любая серьезная СУБД может справиться с этим «дополнительным соединением», даже не моргнув.
источник
Назад, когда хранение было дорогим, благо с битовыми масками было то, что они экономили место. Во времена больших данных это не та проблема, которой когда-то была.
Возьмем пример, который вы привели: хранение ролей в виде битовой маски было бы чем-то вроде запаха кода с точки зрения дизайна базы данных, поскольку это нарушало бы первую нормальную форму . В этом смысле они анти-паттерн.
Все это, как говорится, не должно быть одно или другое. Вы можете сохранить данные в виде битовой маски, а затем получить представление, которое может «натянуть» роли пользователя на лету. Вы также сможете сразу же проверить, какие пользователи имеют одинаковые роли.
источник
Единственное преимущество использования битовых масок состоит в том, что значение битовых полей не является статическим. Реляционные таблицы работают хорошо только тогда, когда вы заранее знаете, что представляет собой каждое поле в записи: в
CREATE TABLE
конце концов, вы должны идентифицировать поля в выражении DDL.Если значение каждого битового поля настраивается во время выполнения или иным образом не известно заранее, тогда может иметь смысл хранить логические значения в виде битового поля. Даже тогда, можно определить таблицу с произвольными полями:
field_1
,field_2
и т.д. Это дает более чистый реляционный дизайн, хотя по- прежнему не идеальны. Является ли это преимуществом для битового поля, во многом зависит от мнения, поскольку ни одно из решений не является идеальным.Если вы знаете, что представляют собой биты во время разработки, создайте поля для каждого бита и дайте им осмысленные имена .
Просто будьте осторожны с эффектом внутренней платформы . Если вы в конечном итоге определяете произвольные, но хорошо типизированные поля, это одно, но если вы пойдете слишком далеко, вы будете заново изобретать реляционную базу данных ... внутри реляционной базы данных.
источник
Я амбивалентен в отношении битовых масок. Я считаю, что большинство их хулителей не понимают двоичные и шестнадцатеричные. Для наглядности используйте хорошую мнемонику.
Преимущество, не упомянутое выше, заключается в возможности добавления нового значения к битовым маскам без потенциально трудоемкого добавления нового столбца. Наши дизайнеры БД (которые предшествовали мне) хранят их в таблице, которая ежедневно получает 5 миллионов новых записей. Добавление нового столбца для представления нового поведения заняло бы много времени, в то время как определение нового бита (мы использовали 33 из 64) не требует перестройки таблицы.
Нет, битовые маски нельзя индексировать, но построение 33 индексов было бы нелепым и замедляло бы вставку в обход. При поиске в таблице используются индексы даты и записи «владельцев», поэтому индексы этой битовой маски, если это возможно, никогда не будут использоваться.
источник
Если цель состоит в том, чтобы просто сэкономить место на диске, я думаю, что это плохая идея:
Однако есть несколько случаев, которые могут оправдать использование битовых полей:
источник