Índice
Se você ainda não tem familiaridade com operadores binários, talvez o momento seja agora. Afinal, os benefícios de trabalhar com eles são vários. Mas antes de mais nada é essencial entender algumas definiçÕes. Mais conhecidos como operadores bitwise, operadores binários são aqueles que trabalham em cima da representação binária de números por meio de operações que permitem manipular grupos de bits. Além disso, são amplamente usados em sistemas onde performance é um fator decisivo, como por exemplo na gestão de permissões em sistemas de arquivo. Porém, antes de abordar a fundo o uso dos operadores em bancos de dados, devemos nos familiarizar com as terminologias usadas na definição de tipos de dados.
OBS: Para este artigo vamos considerar que o índice do bit será sempre representado da direita para a esquerda.
Bitwise AND (&)
A operação binária “E” (do inglês AND e também representada pelo caractere “&”) permite filtrar quais bits estão ativos em dois números diferentes. Por isso, ao utilizar o operador AND fornecemos duas entradas numéricas de mesmo tamanho binário. No exemplo abaixo veremos a operação AND sendo aplicada em dois bytes:
00100101
AND 00001111
= 00000101
Como podemos ver, o resultado da operação AND é composto apenas pelos bits que estavam presentes em ambos os dados de entrada. Na verdade, isso é bem útil quando queremos testar se determinado bit está ativo em uma entrada. Por exemplo, podemos usar a seguinte expressão para testar se o bit 3 está ativo:
var a = 00100101 # Valor a ser testado
const b = 00000100 # Apenas o bit 3
ativo = a & b == b
00100101
AND 00000100
= 00000100
Em outro cenário, podemos ver o que acontece quando o bit 3 não está ativo no dado de teste:
var a = 00100001 # Valor a ser testado
const b = 00000100 # Apenas o bit 3
ativo = a & b == b
00100001
AND 00000100
= 00000000
Portanto, ao testar uma entrada contra uma máscara contendo um ou mais bits desejados, sabemos que os bits estão ativados quando o retorno é igual à própria máscara.
Bitwise OR (|)
A operação binária “OU” (do Inglês “OR” também representada pelo caractere “|”) permite adicionar um bit a um número existente. Na verdade, o funcionamento inicial é parecido com o do AND. Por isso, a regra é a mesma: ao utilizar o operador OR fornecemos duas entradas numéricas de mesmo tamanho binário. No exemplo abaixo veremos a operação OR sendo usada para definir o bit 3 como ativo:
00100001
OR 00000100
= 00100101
Como podemos ver no resultado acima, basta que um bit esteja definido em apenas uma das entradas para que o resultado o contenha. Porém, em código, teríamos uma expressão parecida com esta:
var dados = 00100001
const flag = 00000100
resultado = dados | flag
Por que usar operadores binários no banco de dados?
Existem vários motivos para utilizá-los, sendo que todos visam melhoria de performance. Entretanto, os motivos principais que podem ser citados são: redução do espaço utilizado e velocidade das buscas aumentadas. Além disso, o uso desses operadores binários também trazem outros dois benefícios muito interessantes:
- Podemos usar operadores bitwise nas consultas, que são muito eficientes;
- E podemos ter um único índice na coluna de atributos, o que significa que todos eles ficarão mais rápidos na busca.
Como consultar os dados?
Mas e agora, depois de entender melhor o que são esses operadores binários, como é que encaixamos isto com os dados? Algumas database como o MySQL/Postgres oferecem funções e tipos de dados específicos para uso dos operadores. No entanto, podemos usar operadores binários em quase todos os bancos de dados. Para entender melhor como isso funciona na prática, confira a tabela a seguir, representando um restaurante, e o exemplo abaixo:
Posição do bit | Valor decimal | Nome do atributo | Expressão em base 2 |
00000001 | 1 | Estacionamento gratuito | 2ˆ0 |
00000010 | 2 | Área de fumantes | 2ˆ1 |
00000100 | 4 | Música ao vivo | 2ˆ2 |
00001000 | 8 | Opções vegetarianas | 2ˆ3 |
00010000 | 16 | Fast food | 2ˆ4 |
00100000 | 32 | Self service | 2ˆ5 |
A partir disso, digamos que queremos encontrar restaurantes que ofereçam ao mesmo tempo Estacionamento gratuito e Música ao vivo. Para isso, podemos usar o operador AND da seguinte forma:
SELECT *
FROM restaurants
WHERE attributes & 5 = 5;
Normalmente iremos compor o valor do campo usando bitwise na camada do back-end e passá-lo como argumento da consulta:
SELECT *
FROM restaurants
WHERE attributes & ? = ?;
A mesma lógica se aplica para inserir/atualizar dados, ou seja, tratamos sempre na camada da aplicação.
Mas vale a pena?
Como quase tudo na vida, a resposta é: depende. Afinal, é necessário verificar se a equipe responsável pela manutenção está familiarizada com o uso de operadores binários. Além disso, também depende da quantidade de campos booleanos envolvidos, da linguagem de programação e dos frameworks utilizados. E é claro que haverá ganho de performance em quase todos os cenários, mas ele só será perceptível em grandes bancos de dados com muitos campos booleanos sendo usados como filtro simultaneamente. No entanto, a composição das consultas sempre será melhor usando operadores binários.
Sem falar que é uma ótima maneira para iniciantes na área de programação se familiarizarem com o funcionamento dos operadores binários. Mas e aí, gostou desse conteúdo? Operadores binários podem ser um universo enorme na programação e a melhor forma de aprender é praticando e mantendo contato com outras pessoas do meio. Vale dar um pulo na Comunidade da Impulso no Discord, viu? Afinal, é no meio de comunidades assim que você pode criar networking e, claro, aprender.
Texto escrito por um Impulser Professional.
Se quiser, você também pode contribuir com artigos mandando um e-mail para blog@impulso.team