Saudações, leitores, tudo certo?
Só uma pergunta: no seu sistema, existe a opção de pesquisa pela chave primária para encontrar um registro, como, por exemplo, pelo código do cliente?
Se a resposta for positiva, convido-o para ler este artigo sobre chaves primárias e chaves de negócio. Talvez você irá repensar os seus Selects, haha!
Introdução
Sabemos que atualmente é comum trabalhar com chaves primárias expostas para o usuário. Em uma tabela de produtos, o código, que é a chave primária, é exibido na tela de consulta como identificador do registro. Como efeito, usuários normalmente decoram a chave primária dos registros para agilizar o trabalho. Segue um exemplo clássico:
“João, qual é o código do produto XPTO?”
“568, José!”
Ótimo! Isso ajuda, e muito, na produtividade dos usuários.
Porém, tenho algo para revelar: esse não é o objetivo de uma chave primária. E acrescento: chaves primárias não deveriam ser exibidas para o usuário na aplicação.
Chaves primárias
Se você sabe o que é uma chave primária e qual o seu objetivo, irá compreender facilmente a minha objeção. Chaves primárias são (ou deveriam ser) exclusivamente utilizadas pelo motor do banco de dados para indexação e controle de registros únicos em uma tabela. Essas chaves são utilizadas para manipular registros, como alterações e exclusões, comportarem-se como Ãndices e também para fazer ligações entre tabelas (joins).
Chaves primárias não são manipuláveis pelo usuário. Geralmente são campos imutáveis na aplicação, já que não podem ser alterados para não quebrar a integridade dos dados. Em um cadastro de clientes, por exemplo, a chave primária (código ou ID) é o elemento de vÃnculo com outras tabelas, como pedidos, orçamentos, vendas, contas a pagar e contas a receber. O que aconteceria se o código do cliente fosse acidentalmente alterado e não houvesse um mecanismo confiável de atualização dos vÃnculos? Prefiro nem imaginar…
Mas qual o problema de disponibilizar a chave primária como um identificador?
Nenhum. 🙂
No entanto, sempre devemos pensar a longo prazo, certo? Suponha que a aplicação tenha um cadastro de clientes eficiente, no qual os usuários “decoraram” alguns códigos. Eis que, em um determinado momento, a empresa decide fazer a aquisição de uma concorrente que, por sua vez, também possui uma aplicação com um cadastro de clientes da mesma natureza. Chegaremos à seguinte situação:
- Na empresa matriz, o cliente nº 10 é “Beatriz Mayumi”;
- Já na empresa adquirida, o cliente nº 10 é “André Celestino”.
Ops! Como o código é chave primária, um dos registros deverá receber um número diferente durante a mesclagem de dados.
Ops! Os usuários da empresa adquirida já “decoraram” que o cliente nº 10 é o “André” e uma mudança poderá prejudicar o trabalho ou até mesmo gerar registros incorretos em tabelas vinculadas.
Ops! As vendas já realizadas para esse cliente também deverão ser atualizadas com o código novo. Caso contrário, a aplicação exibirá registros incorretos e causar transtornos.
Não me convenceu!
Ok, então imagine que a aplicação trabalhe com bancos de dados descentralizados, ou seja, cada filial possui uma base de dados separada e que, ao final do dia, essas bases são sincronizadas para que os clientes de uma filial fiquem visÃveis para as outras.
Este processo de sincronização inevitavelmente irá alterar os códigos de alguns registros, pois, durante o dia, a aplicação na filial 1 não tem conhecimento de quantos registros foram cadastrados na filial 5. A sincronização irá “empilhar” os códigos, atualizando-os conforme são gravadas. Mais uma vez: se houver um erro na sincronização, alguns clientes não serão gravados incorretamente, ou ficarão com códigos duplicados.
Para resolver essas situações de uma forma mais prudente, eu sugiro…
Chaves de negócio!
Assim como chaves primárias, também são chaves que não se repetem e comportam-se como identificadores, mas com uma diferença: são manipuláveis pelo usuário. Chaves de negócio podem ser expostas para os usuários da aplicação, uma vez que eles próprios mantêm o controle delas, e não o banco de dados. Dessa forma, caso seja necessário modificar uma chave de negócio por um motivo qualquer, a integridade dos dados não será prejudicada, já que a chave primária (internamente utilizada pelo banco de dados) sempre será a mesma.
Pensando em um cenário prático, a chave de negócio poderia ser, por exemplo, o CPF. É um valor único, que pode ser exposto para o usuário, utilizado em consultas e, talvez o mais importante, não é controlado pelo banco de dados, como em junções.
Em um cadastro de produtos, a chave de negócio pode ser um valor “amigável” para o usuário. Por exemplo, os produtos X e Y podem, respectivamente, receber os valores “PRD123” e “ABC456”, enquanto suas chaves primárias seriam 1 e 2. A diferença primordial é que as chaves primárias nunca serão exibidas para os usuários. Apenas as chaves de negócio. O resultado é a garantia da integridade do banco de dados, sem contar a facilidade de controle em ambientes de migração ou sincronização.
Bom, em suma, chaves primárias devem ser encapsuladas e utilizadas pelo banco de dados, enquanto chaves de negócio são manipuladas pelo usuário.
Hoje fico por aqui, pessoal!
Grande abraço!
Parabéns, concordo com você.
Opa, obrigado, Alexandre! 🙂
Muito bom o artigo!
Se todos os programadores seguissem essa dica, não terÃamos tantos problemas de integridade nos bancos de dados. rsrs.
Olá, Artur!
Concordo com você! As chaves de negócio representam uma prática que evitaria muitos problemas nos softwares atuais, rsrs.
Obrigado pelo comentário!
Olá André, tudo bem?
Mais um dos bons artigos, e eu concordo plenamente. Apesar de mostrar as chaves primarias, não permito a edição, oriento para aqueles que não tem um código próprio usarem como referência.
Olá, Gerson, quanto tempo!
Hoje é relativamente comum trabalhar com chaves primárias, bloqueando a edição. O conceito de chaves de negócio se tornou uma quebra de paradigmas.
Abraço!
Olá, André, estou sem tempo mas sempre venho dar uma olhada.
Estou trocando um programa instalado em uma empresa para o meu, mas quando fui importar os dados encontrei a situação comentada sobre as chaves primarias. Usam o CNPJ/CPF como chave para os clientes e fornecedores e o código de barras nos produtos. Isso evita a duplicação e também usam no relacionamento entre as tabelas.
Isso até mesmo resolve a situação que vc citou de uma empresa com varias lojas ter o mesmo cliente com chaves diferentes. Em uma loja a chave primária é 110 e na outra é 55. Como uso ela no relacionamento dificulta preparar um relatório das compras de um cliente em todas a lojas. Usando a chave de negócio no relacionamento aparentemente é mais fácil, mas nos dois casos temos que usar uma tabela temporária, certo?
Na minha opinião a única vantagem aparente desapareceu, e ainda tem o problema de como cadastrar um cliente que não quer fornecer o CPF, ou os produtos sem código de barras. Neste caso, é só colocar um código qualquer, afinal, não pode ficar em branco, aà o cliente monta uma tabelinha pra controlar os que já usou, rsrs. Essa é uma situação real.
Observa mais esse caso, em uma loja com 5 terminais de venda, a tabela de pedidos não tem uma chave primaria única. Cada terminal tem a sua sequência, então tem 5 pedidos (n° 1, 3, 4, e assim por diante). Para mim toda a estrutura do db está errada. Nunca vi alguma parecida. Estou comentando sobre esse caso porque é um bom exemplo de onde não aplicaram esses conceitos.
Não estou criticando quem criou a base e o programa, é que quando comecei a analisar lembrei imediatamente deste artigo.
Olá, Gerson, como vai?
Sempre costumo dizer que a qualidade de uma aplicação está intimamente relacionada com a qualidade da modelagem de dados. Assim como você, já encontrei vários sistemas que possuem falhas na estrutura de tabelas, relacionamentos e Ãndices. O resultado é o baixo desempenho, integridade de dados comprometida e dificuldade na manutenção.
Projetistas e desenvolvedores devem sempre pensar a longo prazo e elaborar modelagens robustas, capazes de comportar uma grande massa de dados no futuro. A utilização Chaves de negócio é um bom exemplo dessa ação. Além disso, devemos nos atentar também às consultas SQL. Toda otimização feita em Selects, como uma simples remoção de uma coluna desnecessária, pode trazer ganhos de desempenho em produção.
Abraço!
Excelente Artigo!
Obrigado, Filippe!
Abraço!