O MySQL/MariaDB possuem nativamente a função CRC32
, logo conseguem calcular em tempo real para inserir, atualizar ou selecionar. Demais bancos não possuem essa função, embora a maioria deles possuam a geração de colunas calculadas em tempo real.
De todo modo é necessário entender que CRC32 (hexadecimal) pode ser convertido para um número inteiro e armazenado dessa forma sem perder as características dos dados. Logo, significa que você pode fazer isso do lado da aplicação (e na maioria das vezes é melhor que seja feito). No caso dos testes, a coluna calculada em tempo real é um facilitador.
Em todos os bancos o índice de uma coluna numérica será expressivamente menor e mais eficiente do que uma coluna alfa-numérica. Então o desempenho seria parecido, no caso do PostgreSQL ainda mais eficiente.
Então basicamente na hora de fazer uma inserção seria INSERT INTO cpfs_data (cpf, crc) VALUES (%s, %s)
e na aplicação você executaria crc32(cpf)
, já adicionando calculado no banco de dados. Na hora de ler, o mesmo processo SELECT * FROM cpfs_data WHERE crc = %s AND cpf %s
, executando novamente na aplicação crc32(cpf)
.
Todas as linguagens tem implementações. Exemplo abaixo com NodeJS:
const mysql = require('mysql2/promise');
const crc = require('crc');
const connectionConfig = {
host: 'localhost',
user: 'user',
password: 'pass',
database: 'database',
};
async function insertData(cpf) {
const crcValue = crc.crc32(cpf); // Calcula o CRC32 como um inteiro
const connection = await mysql.createConnection(connectionConfig);
try {
const query = `INSERT INTO cpfs_data (cpf, crc) VALUES (?, ?)`;
await connection.execute(query, [cpf, crcValue]);
console.log('CPF inserido com sucesso!');
} catch (error) {
console.error('Erro ao inserir CPF:', error);
} finally {
await connection.end();
}
}
async function getData(cpf) {
const crcValue = crc.crc32(cpf); // Calcula o CRC32 como um inteiro para a busca
const connection = await mysql.createConnection(connectionConfig);
try {
const query = `SELECT * FROM cpfs_data WHERE crc = ? AND cpf = ?`;
const [rows] = await connection.execute(query, [crcValue, cpf]);
if (rows.length > 0) {
console.log('CPF encontrado:', rows[0]);
} else {
console.log('CPF não encontrado.');
}
} catch (error) {
console.error('Erro ao buscar CPF:', error);
} finally {
await connection.end();
}
}
O código acima poderia funcionar da mesma forma em qualquer banco pois tudo que você precisa na verdade é:
- Uma coluna inteira indexada que irá armazenar o CRC32 calculado, encurtando o processo de busca substâncialmente;
- Uma coluna para armazenar a string do CPF.
Digo mais, você poderia armazenar o CPF até formatado (teria que buscar por ele formatado também) que não faria diferença. O CRC32 vai sintetizar o primeiro dado independente do que ele seja e diminuirá bastante o número de dados que serão lidos pelo banco.
Outro exemplo é, você poderia ter uma coluna public_id
com um uuid
e usar a mesma técnica. Veja que um uuid
tem 36
caracteres. Mas ao adicionar o CRC32 você poderia buscar tranquilamente por qualquer public_id
no banco.