CPF e CNPJ

237 views
Skip to first unread message

Rodrigo Mendonça

unread,
Nov 1, 2010, 12:44:25 PM11/1/10
to rub...@googlegroups.com
Pessoal gostaria de levantar uma questão sobre o Brazilian Rails e a forma com que ele armazena CNPJ e CPF

Ele armazena os caracteres como: . / - (ponto, barra e hífen)

Acredito se guardasse somente os números estaríamos fazendo uso de uma boa prática. Se eu estiver errado não me crucifiquem... rs

Eu uso o brazilian rails como plugin e acho que consigo fazer essa pequena alteração.

Levando em conta que minha aplicação é grande e deve ser o mais robusta possível.

Alguém poderia me dizer se eu deixo como está ou se eu mudo o plugin... qualquer sugestão é bem vinda. Queria mesmo era discutir um pouco o assunto.

Abraço

--
Rodrigo Mendonça
(62) 8567-3142

Cássio Marques

unread,
Nov 1, 2010, 1:48:08 PM11/1/10
to rub...@googlegroups.com
Quando eu escrevi essa gem fiz para resolver um problema que eu tinha. Na época achei que faria mais sentido salvar formatado, pois em todos os locais onde eu fosse exibir, teria que ser formatado e eu não precisaria ficar repetindo esse processamento. Já o valor sem os caracteres de formatação eu só iria precisar na hora de fazer o cálculo para validação, ou seja, ao criar e atualizar o registro. 

De qualquer maneira, ele aceita os números em qualquer uma das duas formas quando um cpf ou cnpj é criado.

Enfim, o que vocês acham pessoal?

2010/11/1 Rodrigo Mendonça <den...@gmail.com>
--
Você recebeu esta mensagem porque está inscrito no Grupo "ruby-sp" em
Grupos do Google.
Para postar neste grupo, envie um e-mail para rub...@googlegroups.com
Para cancelar a sua inscrição neste grupo, envie um e-mail para
ruby-sp+u...@googlegroups.com
Para ver mais opções, visite este grupo em
http://groups.google.com.br/group/ruby-sp?hl=pt-BR



--
Cássio Marques

Blog: http://cassiomarques.wordpress.com

If you're writing code and you're not testing it, the code is wrong. I don't care if it does the right thing, and people need to understand this. If it works by accident, you're still wrong.
Bryan Liles - Ruby Hoedown 2008

Rodrigo Mendonça

unread,
Nov 1, 2010, 2:09:49 PM11/1/10
to rub...@googlegroups.com
Cássio valeu a resposta.

A princípio eu estou pensando em deixar como estar mesmo. Tudo isso para seguir o fluxo do famoso Rails Way.

Mas a pergunta que fica é o seguinte. Quais benefícios eu teria em guardar somente o valor. é bom pro banco de dados?? relatórios??? onde eu sairia ganhando??? Eu só gostaria de não ter problemas no futuro com isso.

Uma vez eu abri um tópico no forum rubyonbr levantando essa questão, mas não ficou claro ainda -> http://forum.rubyonbr.org/forums/1/topics/5966





2010/11/1 Cássio Marques <cass...@gmail.com>



--
Rodrigo Mendonça
(62) 8567-3142

Maurício Szabo

unread,
Nov 1, 2010, 2:25:21 PM11/1/10
to rub...@googlegroups.com
Sinceramente, tanto faz. Eu prefiro guardar sempre formatado, mas é uma prática minha. Em geral, não faz a menor diferença mesmo, o seu banco de dados não vai estourar de memória se você guardar o número formatado, não há diferença de performance, literalmente nada.

Eu prefiro guardar formatado também porque fica mais fácil para exibir na tela e emitir relatórios como o Cássio citou. E também, sobre "boas práticas", vai depender de quem você vai perguntar, uns vão dizer que é melhor guardar sem os pontos e traços e isso é uma "boa prática", outros vão dizer que guardar formatado é "boa prática", e ninguém vai chegar numa conclusão hahaha.

Abraços!

2010/11/1 Rodrigo Mendonça <den...@gmail.com>



--
A question that sometimes drives me hazy: am I or are the others crazy?

Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction.

I am a deeply religious nonbeliever - this is a somewhat new kind of religion.
(Albert Einstein)

Apenas peixes mortos nadam a favor da maré (Malcolm Muggeridge)

Cássio Marques

unread,
Nov 1, 2010, 2:27:07 PM11/1/10
to rub...@googlegroups.com
Como o pessoal falou no post que você colocou, a vantagem de guardar sem formatação é para fazer buscas. Eu realmente passei por isso e acabei criando um método que fazia a busca no PostgreSQL removendo os caracteres especiais antes de buscar, via SQL. 

Sinceramente, pensando por esse lado não sei dizer qual das duas abordagens é melhor, ambas têm vantagens de desvantagens. Se você exibir na view, vai precisar de formatação. Se for exibir em um relatório, vai precisar de formatação. Mas se for fazer busca, a formatação pode atrapalhar. Não consigo me decidir :)

2010/11/1 Rodrigo Mendonça <den...@gmail.com>

Rodrigo Mendonça

unread,
Nov 1, 2010, 2:57:04 PM11/1/10
to rub...@googlegroups.com
Botei fé demais!!

Já li muito sobre essa questão de boas práticas. Já vi o rails quebrar algumas e nunca vi nada de mal acontecer. Esquema de pluralização, model, tabela, singular, plural... uns dizem que tabela de bd tem que ser no singular outros no plural.

Antes do Restful ser um sucesso era uma simples teoria de que alguém fez na faculdade e que não deveria ser aplicada na prática....

Então sei lá.. Esse conceito de boas práticas mudam conforme a tecnologia avança.

Dizem que é melhor guardar somente a informação, mas ninguém sabe dizer porque.

Enquanto essa resposta não chega, eu vou guardar no BD com formatação mesmo, até porque vou economizar algumas linhas.

Muito obrigado pessoal.

Bruno Coimbra

unread,
Nov 1, 2010, 7:10:44 PM11/1/10
to rub...@googlegroups.com

Se você precisar efetuar muitos (muitos mesmo) cálculos de CNPJ e CPF, tenho uma
Implantação que foi feita como extensão nativa. Se interessar:

gem install br-{cnpj,cpf}

No bash. Os fontes estão em github.com/bbcoimbra/br-{cnpj,cpf}.git

[]s,
Bruno Coimbra

Em 01/11/2010 15:58, "Rodrigo Mendonça" <den...@gmail.com>escreveu:

Botei fé demais!!

Já li muito sobre essa questão de boas práticas. Já vi o rails quebrar algumas e nunca vi nada de mal acontecer. Esquema de pluralização, model, tabela, singular, plural... uns dizem que tabela de bd tem que ser no singular outros no plural.

Antes do Restful ser um sucesso era uma simples teoria de que alguém fez na faculdade e que não deveria ser aplicada na prática....

Então sei lá.. Esse conceito de boas práticas mudam conforme a tecnologia avança.

Dizem que é melhor guardar somente a informação, mas ninguém sabe dizer porque.

Enquanto essa resposta não chega, eu vou guardar no BD com formatação mesmo, até porque vou economizar algumas linhas.

Muito obrigado pessoal.

Em 1 de novembro de 2010 16:25, Maurício Szabo <maurici...@gmail.com> escreveu:


>
> Sinceramente, tanto faz. Eu prefiro guardar sempre formatado, mas é uma prática minha. Em geral...






--
Rodrigo Mendonça
(62) 8567-3142


--
Você recebeu esta mensagem porque está inscrito no Grupo "ruby-sp" em
Grupos do Google.

Para po...

Nelson Minor Haraguchi Jr

unread,
Nov 1, 2010, 7:28:41 PM11/1/10
to rub...@googlegroups.com
Guardar o CPF e o CNPJ como big int no DB costuma ser menos custoso que guardar em varchar. Com varchar temos 14 Bytes pelo menos por CNPJ, com BIGINT temos 8 Bytes, consequentemente se vc terá uma base de mais de 1 milhao desses caras ou vai fazer muitas buscas com esse index vale bem mais a pena guardar como inteiro.

Mas com certeza não guarde com formatação... para fazer buscas depois da mais trabalho. 

Abs

Nelson Minor Haraguchi Junior
---
"Software é como sexo: é melhor quando é de graça!"
Twitter: http://twitter.com/nelsonmhjr
Gtalk: nelso...@gmail.com

Maurício Szabo

unread,
Nov 1, 2010, 7:53:20 PM11/1/10
to rub...@googlegroups.com
Olha, na minha opinião, JAMAIS deve-se guardar qualquer documento como inteiro. Se o documento começar com zero, dá uma confusão absurda, além de que para exibir formatado você vai sempre ter que converter para string, por erros de conversão você pode acabar com um 

2010/11/1 Nelson Minor Haraguchi Jr <nelso...@gmail.com>

Maurício Szabo

unread,
Nov 1, 2010, 8:00:18 PM11/1/10
to rub...@googlegroups.com
Olha, na minha opinião, JAMAIS deve-se guardar qualquer documento como inteiro. Se o documento começar com zero, dá uma confusão absurda, além de que para exibir formatado você vai sempre ter que converter para string, e para fazer buscas, até onde eu sei, você não vai poder usar o LIKE para buscar por pedaços de CPF/CNPJ.

Fora isso, 14 bytes para 8 bytes dá uma diferença de 6 bytes por registro. Com um milhão de registros a gente tem 6.000.000 bytes a mais, que dá 5,7 megabytes...

E mesmo a idéia da formatação para fazer buscas: aonde eu trabalho, é costume buscar por CPFs com a formatação, então pra gente funcionou muito bem.

2010/11/1 Nelson Minor Haraguchi Jr <nelso...@gmail.com>
Guardar o CPF e o CNPJ como big int no DB costuma ser menos custoso que guardar em varchar. Com varchar temos 14 Bytes pelo menos por CNPJ, com BIGINT temos 8 Bytes, consequentemente se vc terá uma base de mais de 1 milhao desses caras ou vai fazer muitas buscas com esse index vale bem mais a pena guardar como inteiro.

Douglas Drumond

unread,
Nov 1, 2010, 9:08:26 PM11/1/10
to rub...@googlegroups.com


2010/11/1 Maurício Szabo <maurici...@gmail.com>

Olha, na minha opinião, JAMAIS deve-se guardar qualquer documento como inteiro. Se o documento começar com zero, dá uma confusão absurda, além de que para exibir formatado você vai sempre ter que converter para string, e para fazer buscas, até onde eu sei, você não vai poder usar o LIKE para buscar por pedaços de CPF/CNPJ.


Sem contar que evita erros não previstos, dependendo do documento. Por exemplo, em MG, RG tem letra. Já tive que ignorar as letras do meu RG em site paulista que achou que o formato era o mesmo no Brasil todo.


Douglas Drumond

Bruno Grasselli

unread,
Nov 2, 2010, 7:29:11 AM11/2/10
to rub...@googlegroups.com
Nossa, não sabia dessa da letra

--
Você recebeu esta mensagem porque está inscrito no Grupo "ruby-sp" em
Grupos do Google.
Para postar neste grupo, envie um e-mail para rub...@googlegroups.com
Para cancelar a sua inscrição neste grupo, envie um e-mail para
ruby-sp+u...@googlegroups.com
Para ver mais opções, visite este grupo em
http://groups.google.com.br/group/ruby-sp?hl=pt-BR



--
Bruno Grasselli
Blog: http://brunograsselli.com.br
Twitter: http://twitter.com/grasselli

agaelebe

unread,
Nov 2, 2010, 1:13:32 PM11/2/10
to ruby-sp
Pelo que me lembro existem RGs com dígito X, mas acho que isso náo
acontece com CPFs.

On Nov 2, 9:29 am, Bruno Grasselli <bruno.grasse...@gmail.com> wrote:
> Nossa, não sabia dessa da letra
>
> Em 1 de novembro de 2010 23:08, Douglas Drumond
> <drumond.doug...@gmail.com>escreveu:
>
>
>
>
>
> > 2010/11/1 Maurício Szabo <mauricio.sz...@gmail.com>
>
> > Olha, na minha opinião, JAMAIS deve-se guardar qualquer documento como
> >> inteiro. Se o documento começar com zero, dá uma confusão absurda, além de
> >> que para exibir formatado você vai sempre ter que converter para string, e
> >> para fazer buscas, até onde eu sei, você não vai poder usar o LIKE para
> >> buscar por pedaços de CPF/CNPJ.
>
> > Sem contar que evita erros não previstos, dependendo do documento. Por
> > exemplo, em MG, RG tem letra. Já tive que ignorar as letras do meu RG em
> > site paulista que achou que o formato era o mesmo no Brasil todo.
>
> > Douglas Drumond
>
> >  --
> > Você recebeu esta mensagem porque está inscrito no Grupo "ruby-sp" em
> > Grupos do Google.
> > Para postar neste grupo, envie um e-mail para rub...@googlegroups.com
> > Para cancelar a sua inscrição neste grupo, envie um e-mail para
> > ruby-sp+u...@googlegroups.com<ruby-sp%2Bunsu...@googlegroups.com>

Nelson Minor Haraguchi Jr

unread,
Nov 1, 2010, 11:22:06 PM11/1/10
to rub...@googlegroups.com
Como fiquei na dúvida com o que o Maurício Szabo falou resolvi tirar a prova.

Criei duas tabelas (as duas com MYISAM) uma com chave primaria BIGINT e outra VARCHAR populadas com 400 mill linhas.

mysql> desc integer_cnpj;
+-------+------------------------------+------+-----+----------------+-------+
| Field | Type                         | Null | Key | Default        | Extra |
+-------+------------------------------+------+-----+----------------+-------+
| cnpj  | bigint(14) unsigned zerofill | NO   | PRI | 00000000000000 |       |
| nome  | varchar(50)                  | YES  |     | NULL           |       |
+-------+------------------------------+------+-----+----------------+-------+

mysql> desc varchar_cnpj;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| cnpj  | varchar(14) | NO   | PRI | NULL    |       |
| nome  | varchar(50) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

mysql> select count(*) from varchar_cnpj;
+----------+
| count(*) |
+----------+
|   400874 |
+----------+
1 row in set (0.00 sec)

mysql> select count(*) from integer_cnpj;
+----------+
| count(*) |
+----------+
|   400874 |
+----------+
1 row in set (0.00 sec)

Com as mesmas linhas.

Comparações com a query para retornar os registros que tenham cnpj iniciando por '00001%'

EXPLAIN SELECT * FROM integer_cnpj where cnpj like '00001%';
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table        | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | integer_cnpj | ALL  | PRIMARY       | NULL | NULL    | NULL | 400874 | Using where |
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+

EXPLAIN SELECT * FROM varchar_cnpj where cnpj like '00001%';
+----+-------------+--------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table        | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+--------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | varchar_cnpj | range | PRIMARY       | PRIMARY | 16      | NULL | 1006 | Using where |
+----+-------------+--------------+-------+---------------+---------+---------+------+------+-------------+


EXPLAIN SELECT * FROM integer_cnpj where cnpj between 1000000000 and 1999999999;
+----+-------------+--------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table        | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+--------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | integer_cnpj | range | PRIMARY       | PRIMARY | 8       | NULL | 1120 | Using where |
+----+-------------+--------------+-------+---------------+---------+---------+------+------+-------------+

EXPLAIN SELECT * FROM varchar_cnpj where cnpj between 1000000000 and 1999999999;
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table        | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | varchar_cnpj | ALL  | PRIMARY       | NULL | NULL    | NULL | 400874 | Using where |
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+

$ cat bench.txt | while read q; do sudo service mysql restart; echo "$q"; time mysql -uroot -e "FLUSH TABLES; $q" bench > /dev/null; done
mysql start/running, process 4385
SELECT * FROM integer_cnpj where cnpj like '00001%';

real 0m0.349s
user 0m0.004s
sys 0m0.004s
mysql start/running, process 4472
SELECT * FROM varchar_cnpj where cnpj like '00001%';

real 0m0.037s
user 0m0.008s
sys 0m0.008s
mysql start/running, process 4562
SELECT * FROM integer_cnpj where cnpj between 1000000000 and 1999999999;

real 0m0.035s
user 0m0.004s
sys 0m0.004s
mysql start/running, process 4619
SELECT * FROM varchar_cnpj where cnpj between 1000000000 and 1999999999;

real 0m0.290s
user 0m0.008s
sys 0m0.004s

----------------------------------------------------

Minha conclusão é que seja usando varchar ou integer na questão de busca não faz muita diferença desde que vc use a query correta.

O tamanho de chave talvez seja a maior diferença, o que só vai significar diferença mesmo com a base inteira de CNPJs ou de CPFs.

De qualquer forma é gasto a mais de leitura sendo que com integer seria gasto a mais de processamento.

Bom tem prós e contras, é questão de escolha.


Também sou a favor de guardar documentos como VARCHAR, mas se vc for buscar muito por esses valores começa a fazer mais sentido otimizar esses campos para garantir melhor performance.

Mas essa é a minha opinião o que acham?

[]'s

Nelson Minor Haraguchi Junior
---
"Software é como sexo: é melhor quando é de graça!"
Twitter: http://twitter.com/nelsonmhjr
Gtalk: nelso...@gmail.com


Em 1 de novembro de 2010 23:08, Douglas Drumond <drumond...@gmail.com> escreveu:
>
>

Rodrigo Mendonça

unread,
Nov 2, 2010, 1:35:09 PM11/2/10
to rub...@googlegroups.com
Nesse caso então acredito que a formatação faz parte da informação.
Varchar neles

Até porque esse tipo de coisa está sujeito a mudança... os telefones antes tinham 7 dígtos e hoje são 8
Rodrigo Mendonça
(62) 8567-3142

Douglas Drumond

unread,
Nov 2, 2010, 2:17:23 PM11/2/10
to rub...@googlegroups.com


2010/11/2 agaelebe <hugo....@gmail.com>

Pelo que me lembro existem RGs com dígito X, mas acho que isso náo
acontece com CPFs.


CPF é nacional, então é sussa. 11 dígitos sempre. 

O exemplo do RG foi por causa da ideia de armazenar como número ou string. Em MG, os RGs começam com letra, não é dígito X. O da minha mãe começa com M e logo após seguem os dígitos, o meu começa com MG e seguem os dígitos.


Douglas Drumond


Reply all
Reply to author
Forward
0 new messages