none
Campo CPF, CNPJ, CodigoInternto como int ou char(n)? RRS feed

  • Pergunta

  • Pessoal,

    Qual tipo de dados a ser utilizando em campos como CPF, CNPJ ou CodigoInternto... Int ou char?

    Alguns dizem que o armazenamento de inteiros é mais eficiente do que caracteres, assim, se estou buscando eficiência, deveria por estes campos como inteiro. Porém, não encontro uma referência segura para esta informação.

    segunda-feira, 27 de agosto de 2012 12:41

Respostas

  • Depende, o int trás melhor performance, mas vai depender da sua regra, se um dia quiserem colocar hífen, pontos ou barras no CPF/CNPJ/Código Interno? Se estiver como int não dará essa flexibilidade.

    Eu, particularmente acho que é uma melhor prática gravar como int mesmo, eu gravaria como int.

    Abraços!


    Thiago Coelho - Líder da Comunidade .NET Coders
    thiagocoelho.net | @thiagokoelho | Windows 8 Brasil

    Bom dia!

    Complementando a resposta do Thiago, eu criaria um codigo do tipo INT IDENTITY como PRIMARY KEY(clustered) e um outro atributo para armazenar o CPF/CNPJ do tipo VARCHAR e o promoveria a UNIQUE KEY.

    Faria referência a partir de outras tabelas utilizando o atributo código, que por ser clustered daria uma ganho em termos de performance, garantido com a unique que os dados não poderiam ser duplicados.

    Abçs




    • Editado _Juliano_Alves_ segunda-feira, 27 de agosto de 2012 13:18
    • Marcado como Resposta BrunoCosta.dsn segunda-feira, 27 de agosto de 2012 15:16
    segunda-feira, 27 de agosto de 2012 13:13
  • O int é mais performático que o char. Se tiver que aplicar máscara, deixe que o front-end se responsabilize por isso.

    E o int ocupa menos espaço também.


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    • Marcado como Resposta BrunoCosta.dsn segunda-feira, 27 de agosto de 2012 15:16
    segunda-feira, 27 de agosto de 2012 13:46
    Moderador
  • Bom dia

    Eu sinseramente prefiro usar int, o retorno de uma consulta em int é mais rápida do que uma char.

    [ ]'s

    • Marcado como Resposta BrunoCosta.dsn segunda-feira, 27 de agosto de 2012 15:16
    segunda-feira, 27 de agosto de 2012 12:44
  • Depende, o int trás melhor performance, mas vai depender da sua regra, se um dia quiserem colocar hífen, pontos ou barras no CPF/CNPJ/Código Interno? Se estiver como int não dará essa flexibilidade.

    Eu, particularmente acho que é uma melhor prática gravar como int mesmo, eu gravaria como int.

    Abraços!


    Thiago Coelho - Líder da Comunidade .NET Coders
    thiagocoelho.net | @thiagokoelho | Windows 8 Brasil

    • Marcado como Resposta BrunoCosta.dsn segunda-feira, 27 de agosto de 2012 15:16
    segunda-feira, 27 de agosto de 2012 13:07

Todas as Respostas

  • Bom dia

    Eu sinseramente prefiro usar int, o retorno de uma consulta em int é mais rápida do que uma char.

    [ ]'s

    • Marcado como Resposta BrunoCosta.dsn segunda-feira, 27 de agosto de 2012 15:16
    segunda-feira, 27 de agosto de 2012 12:44
  • Depende, o int trás melhor performance, mas vai depender da sua regra, se um dia quiserem colocar hífen, pontos ou barras no CPF/CNPJ/Código Interno? Se estiver como int não dará essa flexibilidade.

    Eu, particularmente acho que é uma melhor prática gravar como int mesmo, eu gravaria como int.

    Abraços!


    Thiago Coelho - Líder da Comunidade .NET Coders
    thiagocoelho.net | @thiagokoelho | Windows 8 Brasil

    • Marcado como Resposta BrunoCosta.dsn segunda-feira, 27 de agosto de 2012 15:16
    segunda-feira, 27 de agosto de 2012 13:07
  • Depende, o int trás melhor performance, mas vai depender da sua regra, se um dia quiserem colocar hífen, pontos ou barras no CPF/CNPJ/Código Interno? Se estiver como int não dará essa flexibilidade.

    Eu, particularmente acho que é uma melhor prática gravar como int mesmo, eu gravaria como int.

    Abraços!


    Thiago Coelho - Líder da Comunidade .NET Coders
    thiagocoelho.net | @thiagokoelho | Windows 8 Brasil

    Bom dia!

    Complementando a resposta do Thiago, eu criaria um codigo do tipo INT IDENTITY como PRIMARY KEY(clustered) e um outro atributo para armazenar o CPF/CNPJ do tipo VARCHAR e o promoveria a UNIQUE KEY.

    Faria referência a partir de outras tabelas utilizando o atributo código, que por ser clustered daria uma ganho em termos de performance, garantido com a unique que os dados não poderiam ser duplicados.

    Abçs




    • Editado _Juliano_Alves_ segunda-feira, 27 de agosto de 2012 13:18
    • Marcado como Resposta BrunoCosta.dsn segunda-feira, 27 de agosto de 2012 15:16
    segunda-feira, 27 de agosto de 2012 13:13
  • O int é mais performático que o char. Se tiver que aplicar máscara, deixe que o front-end se responsabilize por isso.

    E o int ocupa menos espaço também.


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    • Marcado como Resposta BrunoCosta.dsn segunda-feira, 27 de agosto de 2012 15:16
    segunda-feira, 27 de agosto de 2012 13:46
    Moderador
  • O int é mais performático que o char

    Não necessariamente.

    Primeiro que para o caso do Cpf/Cnpj o char não resolve, pois tem um tamanho de alocação de 1 byte (8 bits), ou seja de 0 a 255 no máximo.  

    O que você poderia utilizar é o int ou varchar(n), sendo n o tamanho máximo de alocação do campo.

    Considerando o pior cenário do Cnpj com 15 caracteres incluídos os sinais de máscara, então o tamanho máximo de alocação para este campo seria de 15 bytes

    O tipo int aloca 32 bytes.

    Conclusão: varchar(n) neste cenário seria no mínimo 50% mais performático.

    E tem outra, de nada adianta ganhar performance na base de dados se a aplicação também não tem a mesma preocupação.

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

    Tiago Saraiva Ferreira

    quinta-feira, 30 de agosto de 2012 22:21
  • O INT não serve pra armezar o CPF, o maximo de dígitos que ele consegue chegar é 10, e o cpf é 11, teria que ser o bigint, mas vc pagaria + 4 bytes só por causa de um caractere?

    Crie com um  varchar(11) e seja feliz.

    domingo, 2 de setembro de 2012 21:40
  • Boa Noite,

    Essa é uma questão bem interessante. Antes de dar a minha opinião, vamos há algumas considerações:

    - O INT consegue armazenar de -2.147.483.648 a 2.147.483.647 e isso não torna possível cadastrar nenhum CPF válido. Isso já merecia desmarcar metade das respostas consideradas corretas nesse post (mas deixo para o dono da dúvida fazer esse julgamento).
    - O BIGINT ocupa 8 bytes e ele sim, possibilitaria o armazenamento de CPFs
    - Utilizar um tipo texto para uma coluna CPF só faz sentido se for um CHAR(11). Utilizar uma coluna VARCHAR para um tipo CPF é um completo desperdício de espaço visto que todo CPF válido terá sempre 11 caracterés. Se usar o VARCHAR(11), além dos 11 caracterés utilizados, serão gastos mais dois bytes para controle o que tornará todo CPF com 13 caratéres (o que nesse caso é um desperdício).
    - É plenamente possível especificar a quantidade de caractéres de uma coluna CHAR de modo que acreditar que o CHAR ocupa 1 byte não é verdadeiro (pelo menos não para o SQL Server)
    - O tipo INT não aloca 32 bytes, mas apenas 4 bytes enquanto o BIGINT aloca 8 bytes. 32bytes é a representação de -2^255 a + (2^255 - 1). O SQL Server nem tem tipo nativo pra isso (e acho que nenhum banco de dados tem)

    Agora vamos às minhas avaliações:

    Até acho que usar o BIGINT para armazenar o CPF pareça ser um bom negócio já que ele ocupa apenas 8 bytes e isso economizará espaço nos dados (3 bytes por linha) e principalmente nos índices. Ainda assim, eis duas excelentes razões para armazená-lo como CHAR(11) ou CHAR(14)

    - Normalmente importações de arquivos utilizaram o tipo CPF como textual e portanto, ter o CPF como uma coluna numérica irá trazer problemas na hora da conversão. Você até pode utilizar o CONVERT, mas aí adeus índice, pois, bem sabemos que funções em cláusula WHERE ou JOIN são matadoras de índices
    - O BIGINT não permitirá o uso de máscara
    - Toda vez que você tiver um CPF que comece com 0, terá que formatá-lo para poder visualizá-lo corretamente. A aplicação até pode fazer, mas é um trabalho que poderia ser evitado.

    [ ]s,

    Gustavo Maia Aguiar
    Blog: http://gustavomaiaaguiar.wordpress.com
    Vídeos:http://www.youtube.com/user/gmasql


    Classifique as respostas. O seu feedback é imprescindível

    segunda-feira, 3 de setembro de 2012 03:18
  • Boa Noite,

    Essa é uma questão bem interessante. Antes de dar a minha opinião, vamos há algumas considerações:

    - O INT consegue armazenar de -2.147.483.648 a 2.147.483.647 e isso não torna possível cadastrar nenhum CPF válido. Isso já merecia desmarcar metade das respostas consideradas corretas nesse post (mas deixo para o dono da dúvida fazer esse julgamento).
    - O BIGINT ocupa 8 bytes e ele sim, possibilitaria o armazenamento de CPFs
    - Utilizar um tipo texto para uma coluna CPF só faz sentido se for um CHAR(11). Utilizar uma coluna VARCHAR para um tipo CPF é um completo desperdício de espaço visto que todo CPF válido terá sempre 11 caracterés. Se usar o VARCHAR(11), além dos 11 caracterés utilizados, serão gastos mais dois bytes para controle o que tornará todo CPF com 13 caratéres (o que nesse caso é um desperdício).
    - É plenamente possível especificar a quantidade de caractéres de uma coluna CHAR de modo que acreditar que o CHAR ocupa 1 byte não é verdadeiro (pelo menos não para o SQL Server)
    - O tipo INT não aloca 32 bytes, mas apenas 4 bytes enquanto o BIGINT aloca 8 bytes. 32bytes é a representação de -2^255 a + (2^255 - 1). O SQL Server nem tem tipo nativo pra isso (e acho que nenhum banco de dados tem)

    Agora vamos às minhas avaliações:

    Até acho que usar o BIGINT para armazenar o CPF pareça ser um bom negócio já que ele ocupa apenas 8 bytes e isso economizará espaço nos dados (3 bytes por linha) e principalmente nos índices. Ainda assim, eis duas excelentes razões para armazená-lo como CHAR(11) ou CHAR(14)

    - Normalmente importações de arquivos utilizaram o tipo CPF como textual e portanto, ter o CPF como uma coluna numérica irá trazer problemas na hora da conversão. Você até pode utilizar o CONVERT, mas aí adeus índice, pois, bem sabemos que funções em cláusula WHERE ou JOIN são matadoras de índices
    - O BIGINT não permitirá o uso de máscara
    - Toda vez que você tiver um CPF que comece com 0, terá que formatá-lo para poder visualizá-lo corretamente. A aplicação até pode fazer, mas é um trabalho que poderia ser evitado.

    [ ]s,

    Gustavo Maia Aguiar
    Blog: http://gustavomaiaaguiar.wordpress.com
    Vídeos:http://www.youtube.com/user/gmasql


    Classifique as respostas. O seu feedback é imprescindível

    Muito bem, Gustavo!

    Após ler algumas respostar, preocupei-me, achando que não sabia de nada sobre tipos de dados.

    Você esclareceu muito bem alguns colocações meio "estranhas".

    Obrigado!

    quinta-feira, 6 de novembro de 2014 19:51