Skip to content

Instantly share code, notes, and snippets.

@danarrib
Last active May 16, 2024 18:04
Show Gist options
  • Save danarrib/b48423c55351764c59dee9a70365d1a0 to your computer and use it in GitHub Desktop.
Save danarrib/b48423c55351764c59dee9a70365d1a0 to your computer and use it in GitHub Desktop.
Test CPF Storage (BigInt vs Varchar) on Postgres
-- Cria duas tabelas: stringcpf e bigintcpf
drop table if exists stringcpf;
create table if not exists stringcpf (
cpf varchar(11) not null primary key
);
drop table if exists bigintcpf;
create table bigintcpf (
cpf bigint not null primary key
);
-- Cria uma função para calcular DV de CPF (para que os CPFs sejam válidos)
CREATE OR REPLACE FUNCTION calcular_dv_cpf(cpf_base VARCHAR)
RETURNS VARCHAR AS $$
DECLARE
cpf_base_numerico BIGINT;
soma_1 INT;
soma_2 INT;
digito_verificador_1 INT;
digito_verificador_2 INT;
BEGIN
-- Converte os primeiros 9 dígitos do CPF para um número inteiro
cpf_base_numerico := CAST(SUBSTRING(cpf_base FROM 1 FOR 9) AS BIGINT);
-- Cálculo do primeiro dígito verificador
soma_1 := 0;
FOR i IN 1..9 LOOP
soma_1 := soma_1 + (SUBSTRING(cpf_base FROM i FOR 1)::INT * (11 - i));
END LOOP;
digito_verificador_1 := (11 - (soma_1 % 11)) % 10;
-- Adiciona o primeiro dígito verificador ao CPF base
cpf_base := cpf_base || digito_verificador_1;
-- Cálculo do segundo dígito verificador
soma_2 := 0;
FOR i IN 1..10 LOOP
soma_2 := soma_2 + (SUBSTRING(cpf_base FROM i FOR 1)::INT * (12 - i));
END LOOP;
digito_verificador_2 := (11 - (soma_2 % 11)) % 10;
-- Retorna os dígitos verificadores
RETURN digito_verificador_1::text || digito_verificador_2::text;
END;
$$ LANGUAGE plpgsql;
-- Insere 10 milhões de CPFs na tabela "stringcpf" (limpar antes pra garantir que a tabela está vazia)
truncate table stringcpf;
insert into stringcpf
SELECT CONCAT(
LPAD(gs::text, 9, '0'),
calcular_dv_cpf(LPAD(gs::text, 9, '0'))
)
FROM generate_series(1, 10000000) gs;
-- Copiar os registros da tabela stringcpf para a tabela bigintcpf (limpar antes pra garantir que a tabela está vazia)
truncate table bigintcpf;
insert into bigintcpf
select cpf::bigint from stringcpf;
-- Obter o tamanho das tabelas no disco
SELECT
table_name,
pg_size_pretty(table_size) AS table_size,
pg_size_pretty(indexes_size) AS indexes_size,
pg_size_pretty(total_size) AS total_size
FROM (
SELECT
table_name,
pg_table_size(table_name) AS table_size,
pg_indexes_size(table_name) AS indexes_size,
pg_total_relation_size(table_name) AS total_size
FROM (
SELECT ('"' || table_schema || '"."' || table_name || '"') AS table_name
FROM information_schema.tables
where table_schema = 'public'
) AS all_tables
ORDER BY total_size DESC
) AS pretty_sizes;
explain select * from stringcpf where cpf = '00250000041';
explain select * from bigintcpf where cpf = 00250000041;
@danarrib
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment