Meu design atual de banco de dados utiliza uma chave primária de várias colunas para usar os dados existentes (que seriam únicos de qualquer maneira) em vez de criar uma coluna adicional atribuindo a cada entrada uma chave arbitrária. Eu sei que isso é permitido, mas estava me perguntando se essa é uma prática que eu gostaria de usar com cautela e possivelmente evitar (muito parecido com ir para C).
Então, quais são algumas das desvantagens que eu vejo nessa abordagem ou os motivos pelos quais desejo uma única chave de coluna?
database-design
Covar
fonte
fonte
Respostas:
Normalmente, quando você tem uma tabela com uma chave primária de várias colunas, é o resultado de uma tabela de junção (muitos para muitos) que se elevou para ser sua própria entidade (e, portanto, merece sua própria chave primária). Há muitos que argumentam que qualquer tabela de junção DEVE ser uma entidade por padrão, mas essa é uma discussão para outro dia.
Vejamos um relacionamento hipotético de muitos para muitos:
Aluno * --- * Classe
(um aluno pode estar em várias turmas, uma turma pode ter vários alunos).
Entre essas duas tabelas, haverá uma tabela de junção chamada StudentClass (ou ClassStudent, dependendo de como você a escreve). Às vezes, você deseja acompanhar coisas como quando o aluno estava na sala de aula. Então você o adicionará à tabela StudentClass. Neste ponto, StudentClass se tornou uma entidade única ... e deve receber um nome para reconhecê-lo como tal, por exemplo, Inscrição.
Aluno 1 --- * Inscrição * --- 1 Classe
(um aluno pode ter muitas matrículas, cada matrícula é para uma turma (ou seguindo o caminho oposto que uma turma pode ter muitas matrículas, cada matrícula é para um aluno).
Agora você pode consultar questões como, quantos alunos estavam matriculados na aula de Química 101 no ano passado? Ou em quais aulas o aluno que John Doe se matriculou enquanto cursava a Universidade Acme? Isso foi possível sem a chave primária separada, mas depois que você tiver uma chave primária para inscrição, uma consulta mais fácil será sobre essas inscrições (por ID), quantos alunos receberam uma nota de aprovação?
A determinação de se uma entidade merece uma PK se resume a quantas consultas (ou manipulação) você fará por essa entidade. Digamos, por exemplo, que você deseja anexar as tarefas concluídas para um aluno em uma classe. O local lógico para anexar esta entidade (atribuição) seria na entidade de inscrição. Dar à inscrição sua própria chave primária tornaria as consultas de atribuição mais simples.
fonte
Faz sentido ter uma coluna de identificação separada. Quando você deseja obter algo da sua tabela de banco de dados, é mais fácil:
que SELECT qualquer tabela FROM WHERE col1 = 'val1' AND col2 = 'val2' AND col3 = 'val3'
Por exemplo, em um aplicativo Web, ele se traduz em um URL parecido com este:
ou assim:
fonte
SELECT
consultas extras . E, B) , não tenho idéia de como isso realmente causa qualquer tipo de requisito de URL (a menos que você esteja trabalhando com uma estrutura incorreta). Meus URLs não possuem nenhuma sequência de consulta?id=13
, muito menos?col1=val1&col2=val2&col3=val3
.Basicamente, você está perguntando se deve usar chaves substitutas ou naturais (no seu caso, parece chaves naturais compostas ). Aqui está um ótimo artigo: http://www.agiledata.org/essays/keys.html
Prefiro chaves substitutas porque simplificam a administração ao longo da vida do DB (você nunca precisa se preocupar com a implicação da mudança de significado das chaves, o que nunca deve acontecer, mas ocorre em qualquer sistema real em que os humanos estejam envolvidos). Contudo , se houver muitas tabelas de "pesquisa" no banco de dados (ou seja, tabelas que são basicamente pares chave: valor), as chaves substitutas poderão ficar complicadas porque você precisará associar essas tabelas à consulta para obter resultados significativos.
Por exemplo, digamos que você tenha duas entidades: Endereço e País.
select * from Address where CountryCode = 'US'
select Address.* from Address join Country on Address.CountryID = Country.ID where Country.Code = 'US'
Fico confortável em exigir chaves naturais para tabelas de consulta e chaves substitutas para todo o resto, se tiver certeza de que as chaves naturais não serão alteradas com muita frequência, se é que alguma vez.
fonte
Depende de como você acessa os dados. Se você fizer muitas pesquisas de chave parcial (onde você seleciona registros com base em, digamos, apenas duas das três chaves), manterá as chaves com várias partes. OTOH, se você tem muitos relacionamentos 1: 1 com outras tabelas, provavelmente faz mais sentido ter uma chave substituta.
fonte
Eu gosto de ter sempre uma chave primária substituta para cada tabela. Mas não há muitas razões "difíceis" para reforçar isso que ouvi.
A única vez em que eu tive uma chave natural de várias colunas foi na ORM. Ocasionalmente, eu teria problemas com uma chave primária de várias colunas usando o Linq To Entities.
fonte
Nunca diga nunca, mas juntar-se a 4 colunas é uma dor. Quanto mais colunas você tiver com dados inteligentes, maior a chance desses valores mudarem. Os bancos de dados podem ser configurados para manter a integridade referencial com atualizações em cascata.
Você sempre pode criar outro índice para manipular os valores exclusivos.
O desempenho é provavelmente insignificante na maioria dos casos, mas você pode testar suas consultas com e sem a chave de substituição.
fonte
Acho difícil encontrar uma boa razão para exigir uma chave separada, mas, como você disse, muitas pessoas a colocam.
Não acho isso útil (especialmente com armazenamento) ao lidar com tabelas de fatos / detalhes. Exemplo canônico: uma tabela de fatos de vendas com uma (chave do cliente, chave da loja, chave do produto) com quantidade não faz muito sentido ter uma chave em nível de registro.
fonte
Ter o PK como um incremento automático int reduz o aborrecimento se você achar que sua chave composta pode, na realidade, ter duplicatas.
fonte
Há uma boa discussão desde 2002 em Ask Tom . É específico da Oracle, mas a discussão mais ampla é relevante, independentemente do banco de dados que você estiver usando.
fonte