Uma chave primária deve ser imutável?

26

Uma pergunta recente sobre o stackoverflow provocou uma discussão sobre a imutabilidade das chaves primárias. Eu pensava que era um tipo de regra que as chaves primárias deveriam ser imutáveis. Se houver uma chance de algum dia uma chave primária ser atualizada, achei que você deveria usar uma chave substituta. No entanto, ele não está no padrão SQL e alguns recursos de "atualização em cascata" do RDBMS permitem que uma chave primária seja alterada.

Portanto, minha pergunta é: ainda é uma prática ruim ter uma chave primária que possa mudar? Quais são os contras, se houver, de ter uma chave primária mutável?

Vincent Malgrat
fonte

Respostas:

25

Você só precisa que a chave primária seja imutável se estiver vinculada a uma chave estrangeira ou se for usada como um identificador fora do banco de dados (por exemplo, em um URL que aponta para uma página do item).

Por outro lado, você só precisa ter uma chave mutável se ela tiver alguma informação que possa mudar. Eu sempre uso uma chave substituta se o registro não tiver um identificador simples e imutável que possa ser usado como chave.

Guffa
fonte
7
Por que você " precisa que a chave primária seja imutável se estiver vinculada a uma chave estrangeira"? Como o OP mencionado, a maioria dos RDBMSs possui o recurso de atualização "cascata".
Thanatos
1
@ A maioria dos Thanatos (na verdade, tudo que eu encontrei) rdbms não permitirá chaves primárias mutáveis, mas ainda possui atualizações em cascata. Uma chave primária, na sabedoria dba geralmente aceita, não deve conter informações, ser apenas um identificador de registro exclusivo (portanto, nem mesmo um carimbo de data / hora, intervalo de registros diferido, etc.).
jwenting
5
@jwenting: Estamos falando da mesma coisa? "a maioria dos rdbms não permitirá chaves primárias mutáveis" inclui o que? O MySQL e o PostgreSQL permitem chaves primárias mutáveis ​​e honram as atualizações em cascata ... como eu acho que o SQL padrão diz que deveria. Além disso, "sabedoria dba geralmente aceita"? Eu conheci muitos DBAs que argumentam contra chaves substitutas e muitos que argumentam contra chaves naturais.
Thanatos
2
@Thanatos Os argumentos a favor de "todas as tabelas devem ter substitutas" carecem de referências bibliográficas, eles citam "geralmente aceito dba sabedoria", mas nunca citam um livro. Os livros canônicos dizem que você deve usar substitutos se: A. não existir uma chave natural, B. a chave de várias colunas exceder 3 colunas ou C. Você estará alterando a chave o tempo todo. Então: natural quando eles se encaixam, substitutos quando os naturais não se encaixam.
Tulains Córdova
4
@ user61852: O que?
Guffa
15

Uma chave primária deve ser composta de todas as tuplas necessárias para determinar a exclusividade. Se os dados podem mudar ou não, é irrelevante. Somente a singularidade do registro é importante. Esse é o design conceitual do banco de dados.

Quando passamos ao domínio da implementação, a coisa mais segura a fazer é simplesmente usar uma chave substituta.

Chris Holmes
fonte
15

Sim, na minha opinião, uma chave primária deve ser imutável.

Mesmo se houver chaves candidatas óbvias, eu sempre uso uma chave substituta. Nas poucas ocasiões em que não fiz isso, quase sempre me arrependi. E não importa o quão imutável você pense que a chave é, você não pode se proteger contra erros de entrada de dados - dizendo aos usuários que eles não podem editar essa parte da informação porque é uma chave primária que não lava muito.

richeym
fonte
Bom ponto sobre erros de entrada de dados
Tim Goodman
Parece que você está argumentando por que as chaves NÃO devem ser imutáveis: os usuários podem querer alterá-las.
Nvogel 01/10
4
@dportas - meu argumento é que eu gosto que os PK sejam imutáveis, portanto sempre use chaves substitutas, mesmo que eu ache que exista uma chave óbvia que possa ser derivada dos dados da tabela (por exemplo, email, nome de usuário).
Richeym 9/10/10
2

Os mecanismos de armazenamento em cache entre o banco de dados e o usuário perderão a eficácia se as chaves primárias mudarem.

Spoulson
fonte
2

Por que não? Porque você deseja eliminar uma coluna?

Só porque os requisitos exigem que três colunas sejam exclusivas, não significa que ela tenha que ser a chave primária. Você pode pensar que essa regra durará para sempre (lembre-se durante a reunião em que o gerente do departamento de alfinetadas jurou que nunca mudaria? Você sabe, a que acabou de ser demitida.), Mas não.

Eu não sou pago por cada atualização em cascata que eu implemento e um bônus se eu mesmo codificá-lo.

O computador não requer nenhum significado para uma chave; IMHO, as chaves são para computadores, deixe as pessoas estragar o resto dos dados.

JeffO
fonte
1
"chaves são para computadores, deixe as pessoas estragar o resto dos dados." +1, legal.
2

Não é uma prática ruim ter uma chave cujos valores possam mudar.

As propriedades de uma boa chave incluem estabilidade. A imutabilidade é ideal, mas não é um pré-requisito. Introduzir uma chave artificial em prol da imutabilidade é uma má prática.

Veja o exemplo do número internacional padrão de livros (ISBN) . É muito estável, mas não imutável: em algum momento os editores de livros cometem erros e - horror! - números duplicados de ISBN podem ocorrer. Isso significa que o ISBN não deve ser aceito como uma chave candidata em um banco de dados computadorizado? Claro que não. Uma das vantagens do ISBN é que ele possui uma fonte confiável que resolverá problemas para todos os usuários globalmente.

Existem outras conveniências de uma boa chave que o ISBN possui que falta uma chave inteira com incremento automático sem sentido, por exemplo, familiaridade (todos os profissionais do ramo conhecem ou estão familiarizados com o ISBN), verificáveis ​​(o ISBN é impresso em todos os livros modernos), podem ser validado com referência ao DBMS (ISBN é de largura fixa e inclui uma soma de verificação), etc.

um dia quando
fonte
3
O ISBN tem largura fixa, exceto quando não está (consulte ISBN-10 vs ISBN-13).
um CVn
Então, como você recomendaria lidar com ISBNs duplicados? Em todos os RDBMSs que eu conheço, você precisaria ter uma restrição UNIQUE no campo para usá-lo como chave primária.
Curinga
1

Tudo o que pode ser imutável deveria ser. Isso ajuda a garantir a correção e ajuda quando você deseja tornar seu aplicativo multithread.

traço-tom-bang
fonte
1

Sim, uma chave primária deve ser imutável, além de ser nula e exclusiva. No entanto, ainda tenho que encontrar um banco de dados que imponha a imutabilidade das chaves primárias, para que você possa ir adiante e alterar os valores deles, se realmente quiser.

Bob Jarvis - Restabelecer Monica
fonte
0

Como alguns comentários já disseram, uma solução é usar uma nova chave primária

Por exemplo (seguindo o exemplo de @onedaywhen), digamos que exista a tabela Livros que armazenam uma lista de livros e "usamos" para determinar o ISBN como a chave primária. No entanto, alguns autores cometeram o erro de digitar um ISBN errado e, portanto, solicitaram a alteração do ISBN, envolvendo as próximas tarefas:

  • crie um novo registro na tabela Livros
  • aponte todas as referências do ISBN antigo para o novo ISBN. (*)
  • E, finalmente, exclua o registro antigo da tabela Livros.

(*) isso pode ser trivial para encontrar todas as referências para um modelo de banco de dados que use chaves estrangeiras, mas alguns modelos não possuem.

Table Books
ISBN  is the primary key
NAME is a simple field.
etc.

Nós mudamos isso como

Table Books
InternalBookId as the primary key
ISBN as a simple field or an indexed field.
NAME is a simple field.
etc.

Onde o novo InternalBookId poderia até ser um valor autonumérico.

Os contras sobre isso:

  • ele adiciona um novo campo que usa mais espaço / recurso.

  • isso poderia exigir a reescrita de todo o modelo.

  • o novo modelo poderia ser menos auto-explicado.

O profissional

  • Permite alterar a "chave primária".
  • Permite até mesmo soltar ou refatorar a "chave primária", por exemplo, alterar Livros para ISBN-13 é tão simples que soltar a coluna mais antiga e criar uma nova

Nova tabela:

Table Books
InternalBookId as the primary key
ISBN13 is a new field.
NAME is a simple field.
etc.
Magallanes
fonte