Há pouco tempo, conversei com meu colega e ele definitivamente era contra o uso de máscaras de bits, porque é difícil entender todos os valores armazenados no banco de dados. Na minha opinião, nem sempre é uma má idéia usá-los, por exemplo, para determinar os papéis do usuário atual. Caso contrário, você precisará armazená-lo em uma tabela separada, o que causará mais um JOIN. Você pode me dizer se estou errado? Quaisquer outros efeitos colaterais, vantagens / desvantagens do uso de máscaras de bits?
database
patterns-and-practices
bit
advantages
Alex Ovechkin
fonte
fonte
Respostas:
Trabalho com um aplicativo que usa máscaras para armazenar atribuições de função de usuário. É uma dor no traseiro. Se isso me torna tendencioso, culpado de acusado.
Se você já estiver usando um banco de dados relacional, é um antipadrão que viola a maioria das teorias relacionais e todas as regras de normalização. Quando você cria seu próprio armazenamento de dados, pode não ser uma má idéia.
Há muitas tabelas sendo juntadas, mas bancos de dados relacionais são criados para lidar com isso. Muitos possuem recursos adicionais se o desempenho se tornar um problema: índices, visualizações indexadas etc. Mesmo que os valores que você está pesquisando não sejam alterados com muita frequência, o que é uma vantagem para o Bitmask, a sobrecarga de ter que gerenciar a indexação é bastante fácil no banco de dados.
Embora o banco de dados faça um bom trabalho de agregação de dados, eles podem ficar lentos quando você começa a introduzir coisas como fórmulas complexas ou Funções Escalares nos conjuntos de dados. Você pode fazer o bit a bit no seu aplicativo, mas se tudo o que você está fazendo é obter dados relacionados (procurando as funções de um usuário), não está tirando proveito do que seu armazenamento de dados faz melhor.
Meu último argumento contra isso seria a simplicidade para outros desenvolvedores. Você tem usuários, funções e atribuições. É um conjunto de relações muitos-para-muitos (porque há mais de um relacionamento) que é tão comum que deve ser fácil de gerenciar. São apenas coisas CRUD.
fonte
where some_bit_mask & 12 > 0
sem uma verificação linha a linha.user_role_map
ouuser_priv_map
seria suficiente.Você já nomeou os prós e contras relevantes:
Decidir o que fazer requer mais informações:
Então, o que você precisa fazer é reunir os fatores de risco e ponderá- los, para ver se os profissionais superam os contras.
fonte
Se você está realmente, realmente , realmente precisando de espaço em disco, então você pode considerar bitmaps para permissões de usuário. Se o desempenho é a sua preocupação, esqueça-os completamente, porque separá-los será mais lento. Você não pode indexar um campo de bitmap significativamente, resultando em varreduras de tabela de banco de dados, que são quase sempre prejudiciais ao desempenho.
A menos que você seja Amazon ou Netflix, a quantidade de dados envolvidos nas permissões de usuário será desprezível em comparação com tudo o que você está mantendo.
Qualquer DBMS sério pode lidar com essa "junção extra" sem sequer piscar.
fonte
Quando o armazenamento era caro, o benefício com máscaras de bits era que eles economizavam espaço. Nos dias de big data, esse não era o problema que era antes.
Tomando o exemplo que você cita - ter funções armazenadas como uma máscara de bits seria uma espécie de cheiro de código do ponto de vista do design do banco de dados, pois violaria a primeira forma normal . Nesse sentido, eles são um anti-padrão.
Tudo isso dito, não precisa ser um ou outro. Você pode armazenar os dados como uma máscara de bits e, em seguida, ter uma visão que possa puxar as funções de usuário rapidamente. Você também terá o benefício de verificar rapidamente quais usuários têm as mesmas funções.
fonte
A única vantagem do uso de máscaras de bits é se o significado dos campos de bits não for estático. As tabelas relacionais só funcionam bem se você souber com antecedência o que cada campo está em um registro:
CREATE TABLE
afinal, é necessário identificar os campos na instrução DDL.Se o significado de cada campo de bits for configurável no tempo de execução ou não for conhecido antecipadamente, poderá fazer sentido armazenar booleanos como um campo de bits. Mesmo assim, é possível definir uma tabela com campos arbitrários:
field_1
,field_2
, etc. Isto dá-lhe um design relacional mais limpo, embora ainda não ideal. Se isso é preferencial a um campo de bits, é em grande parte uma questão de opinião, pois nenhuma solução é ideal.Se você souber o que os bits representam durante o desenvolvimento, crie campos para cada bit e atribua nomes significativos .
Apenas tome cuidado com o efeito da plataforma interna . Se você acabar definindo campos arbitrários, mas bem digitados, isso é uma coisa, mas se você for muito além, reinventará um banco de dados relacional ... dentro de um banco de dados relacional.
fonte
Eu sou ambivalente sobre máscaras de bits. Acho que a maioria de seus detratores não entende binário e hexadecimal. Para maior clareza, use boas mnemônicas.
Uma vantagem não mencionada acima é a capacidade de adicionar novo significado às máscaras de bits sem a adição potencialmente demorada de uma nova coluna. Nossos designers de banco de dados (que me precederam) os colocam em uma tabela que agora recebe 5 milhões de novos registros diariamente. Adicionar uma nova coluna para representar um novo comportamento levaria muito tempo, enquanto definir um novo bit (consumimos 33 de 64) não requer reconstrução da tabela.
Não, as máscaras de bits não podem ser indexadas, mas criar 33 índices seria ridículo e atrasaria as inserções em um rastreamento. As pesquisas de tabela usam os índices "proprietários" de datas e registros; portanto, os índices nessa máscara de bits, se possível, nunca seriam usados.
fonte
Se o objetivo é apenas economizar espaço em disco, acho uma má ideia:
No entanto, existem alguns casos que podem justificar o uso de campos de bits:
fonte