Então, essas são outras discussões que não couberam no post original por uma limitação de caracteres, mas vamos lá 😅
Sempre que você vai armazenar um dado no banco de dados, você precisa entender a finalidade daquela dado na hora de projetar o MER (modelo de entidade-relacionamento).
Um dado como CPF pode ter diferentes aplicações em diferentes sistemas. Em um sistema ele pode ser usado para consulta, em outro não, etc. Mas acima de tudo a representação deste dado tem como característica a identificação única de um indivíduo.
Dentro do contexto de dados, a identificação única de um registro mais eficiente já o seu próprio ID (auto incrementado, por exemplo). O CPF, por exemplo, é a identificação do indivíduo e, em algum momento, assim como aconteceu com placas de carro, aconteceu com CNPJ, vai acontecer com o CPF: letras serão incluídas.
Quando você analisa a estrutura do dado, existem apenas 8 dígitos produtivos. Isso porque os três últimos dígitos fazem referência ao número do estado (em uma tabela de correspondência) e aos dígitos verificadores. Isso dá uma razão de 99 milhões de opções por grupo de estado. Parece muito, porém a Receita Federal ainda aplica um conjunto de regras para limitar essa combinação de números de modo a não gerar número em sequência de repetição alta, por exemplo.
Logo a natureza do dado em si nunca foi numérica, pois todos os dígitos formam esse dado. Os zeros à esquerda eliminados por uma coluna inteira, por exemplo, descaracterizam a entidade. Se eu precisar processar esses valores do lado do banco de dados, pode ter certeza que será uma dor de cabeça enorme. Mesmo para sistemas pequenos, não recomendaria a prática, ainda mais pelos poucos benefícios que você ganha com ela e, ainda, na camada da aplicação tem que: (1) converter para string; (2) preencher zeros a esquerda; (3) aplicar a formatação.
Sobre a outra discussão: devemos misturar dados? É outra coisa que depende do seu MER, quando você olha para o contexto e significado do CNPJ e CPF, estamos falando de pessoas diferentes. Uma é física, um indivíduo com nome, sobrenome, RG, etc. E a outra é jurídica, com razão social, nome fantasia, inscrição estadual, inscrição municipal, etc. E essa última ainda é composta de um quadro societário de pessoas físicas.
Em alguns sistemas, principalmente fiscais, essas separações lógicas são aplicadas no banco também, criando uma tabela para cada tipo de pessoa. Mas fora isso, existem muitas alternativas:
- Podemos criar uma tabela usuários e uma outra tabela de metadados desse usuário;
- Podemos criar uma única tabela com uma separação lógica por coluna.
Sobre o segundo caso que você mencionou sobre praticidade, por exemplo, é simples. Você irá precisar de três colunas para garantir uma consulta mais eficiente:
doc_type
: Um coluna do tipoENUM
comcpf, cnpj
e indexada. O custo dessa coluna tanto em tempos de processamento quanto armazenamento é insignificante, porque ela é armazenada como inteiro, mas com o benefício da fácil visualização e busca de dados porstring
;doc_number
: Uma coluna do tipoVARCHAR
com14
caracteres para armazenar o valor do documento sem formatação;doc_crc
: Uma coluna do tipoBIGINT
para armazenar os CRC32 do número do documento e indexada.
Quando você executar um WHERE
, o banco irá filtrar primeiro por doc_type
(menor índice), depois pelo doc_crc
e por fim o doc_number
. Não terá qualquer problema de ineficiência.
Agora, concordo que a estrutura acima só funciona para sistemas muito simples ou, geralmente, quando dados relacionados não são usados (nome completo, razão social, RG, inscrições federais, etc). Por exemplo, você tem um sistema de cadastro de usuário e você apenas quer saber se ele é pessoa física ou jurídica, junto com sua identificação. Nesse caso, a flag doc_type
se faz mais interessante. Contudo se você precisa, por exemplo, coletar dados fiscais dessas pessoas, geralmente você vai precisar separar, não só para organizar melhor os dados, mas também relacionar uma pessoa física a uma jurídica quando aplicável.
No fim se você trabalha com banco de dados, tem que entender de banco de dados. Entender sobre a construção do MER e, principalmente, desvendar as características e relações dos dados de modo a resolver um problema mais eficiente. Nesse caso, um número de documento jamais deveria ser interpretado como inteiro, mas muitos fazem e por suas razões.
Contudo, assim que CPF ganhar dígitos alfanuméricos, esteja prepara para atualizar todas as suas aplicações de pequeno porte.