Eu tenho pesquisado recentemente o conceito de ROWGUID e me deparei com essa pergunta. Essa resposta deu uma ideia, mas me levou a uma toca de coelho diferente com a menção de alterar o valor da chave primária.
Sempre entendi que uma chave primária deve ser imutável, e minha pesquisa desde a leitura desta resposta forneceu apenas respostas que refletem o mesmo que a melhor prática.
Em que circunstâncias um valor da chave primária precisaria ser alterado após a criação do registro?
database-design
primary-key
5crammed
fonte
fonte
Respostas:
Se você estivesse usando o nome de uma pessoa como chave primária e o nome dela fosse alterado, seria necessário alterar a chave primária. Isto é o que
ON UPDATE CASCADE
é usado para uma vez que essencialmente cascatas a descer mudança a todas as tabelas relacionadas que têm relações-chave estrangeira para a chave primária.Por exemplo:
A
SELECT
em ambas as tabelas:Devoluções:
Se atualizarmos a
PersonKey
coluna e executar novamente oSELECT
:Nós vemos:
Observando o plano da
UPDATE
instrução acima , vemos claramente que ambas as tabelas são atualizadas por uma única instrução de atualização em virtude da chave estrangeira definida comoON UPDATE CASCADE
:clique na imagem acima para vê-la com mais clareza
Por fim, limparemos nossas tabelas temporárias:
O preferido 1 maneira de fazer isso usando chaves substitutas seria:
Para completar, o plano da instrução de atualização é muito simples e mostra uma vantagem em substituir as chaves, ou seja, apenas uma única linha precisa ser atualizada em oposição a todas as linhas que contêm a chave em um cenário de chave natural:
A saída das duas
SELECT
instruções acima são:Essencialmente, o resultado é aproximadamente o mesmo. Uma grande diferença é que a chave natural ampla não é repetida em todas as tabelas em que a chave estrangeira ocorre. No meu exemplo, estou usando uma
VARCHAR(200)
coluna para conter o nome da pessoa, o que exige o uso de um emVARCHAR(200)
qualquer lugar . Se houver muitas linhas e muitas tabelas contendo a chave estrangeira, isso adicionará muita memória desperdiçada. Observe que não estou falando de desperdício de espaço em disco, já que a maioria das pessoas diz que o espaço em disco é tão barato que é essencialmente gratuito. A memória, no entanto, é cara e merece ser valorizada. O uso de um número inteiro de 4 bytes para a chave economizará uma grande quantidade de memória quando você considerar o tamanho médio do nome em torno de 15 caracteres.Importante para a pergunta sobre como e por que as chaves podem mudar é a pergunta sobre por que escolher chaves naturais em vez de chaves substitutas, que é uma pergunta interessante e talvez mais importante, especialmente onde o desempenho é um objetivo do projeto. Veja minha pergunta aqui sobre isso.
1 - http://weblogs.sqlteam.com/mladenp/archive/2009/10/06/Why-I-prefer-surrogate-keys-instead-of-natural-keys-in.aspx
fonte
Embora você possa usar uma chave que seja natural e / ou mutável como sua PK, na minha experiência isso leva a problemas, que geralmente podem ser evitados pelo uso de uma PK que atenda a essas condições:
Por exemplo, muitas empresas nos EUA tentam usar os números de seguridade social como números de identificação pessoal (e PKs) em seus sistemas. Em seguida, eles se deparam com os seguintes problemas - erros de entrada de dados que levam a vários registros que precisam ser reparados, pessoas que não possuem um SSN, pessoas cujo SSN é alterado pelo governo, pessoas que possuem SSNs duplicados.
Eu já vi todos esses cenários. Também vi empresas que não queriam que seus clientes fossem "apenas um número", o que significava que seu PK acabou sendo 'primeiro + meio + último + DOB + zip' ou algo parecido. Embora eles adicionassem campos suficientes para quase garantir a exclusividade, suas consultas eram horríveis e a atualização de qualquer um desses campos significava procurar problemas de consistência de dados.
Na minha experiência, um PK gerado pelo próprio banco de dados é quase sempre uma solução melhor.
Eu recomendo este artigo para obter dicas adicionais: http://www.agiledata.org/essays/keys.html
fonte
A chave primária pode ser alterada quando a sincronização está envolvida. Esse pode ser o caso quando você tem um cliente desconectado e ele sincroniza os dados com o servidor em determinados intervalos.
Há alguns anos, trabalhei em um sistema em que todos os dados de eventos na máquina local tinham IDs de linha negativos, como -1, -2 etc. Quando os dados foram sincronizados com o servidor, o ID da linha no servidor foi aplicado ao cliente. Digamos que o ID da próxima linha no servidor seja 58. Então -1 se tornaria 58, -2 59 e assim por diante. Essa alteração do ID da linha seria conectada em cascata a todos os registros filho do FK na máquina local. O mecanismo também foi usado para determinar quais registros foram sincronizados anteriormente.
Não estou dizendo que esse foi um bom design, mas é um exemplo da chave primária sendo alterada ao longo do tempo.
fonte
Qualquer projeto que envolva mudanças
PRIMARY KEY
regulares é uma receita para o desastre. A única boa razão para alterá-lo seria uma fusão de dois bancos de dados separados anteriormente.Conforme apontado pelo @MaxVernon, mudanças ocasionais podem ocorrer - e use-as
ON UPDATE CASCADE
, embora a maioria dos sistemas hoje em dia use um ID como substitutoPRIMARY KEY
.Puristas como Joe Celko e Fabian Pascal (um site que vale a pena seguir) discordam do uso de chaves substitutas, mas acho que eles perderam essa batalha em particular.
fonte
A estabilidade é uma propriedade desejável para uma chave, mas é uma coisa relativa e não uma regra absoluta. Na prática, muitas vezes é útil alterar os valores das chaves. Em termos relacionais, os dados são identificáveis apenas por suas (super) chaves. Daqui resulta que, se houver apenas uma chave em uma determinada tabela, a distinção entre A) alterar um valor de chave ou B) substituir o conjunto de linhas em uma tabela por um conjunto de linhas semelhante ou diferente contendo outros valores de chave é essencialmente uma questão de semântica ao invés de lógica.
Um exemplo mais interessante é o caso de uma tabela com várias chaves em que os valores de uma ou mais dessas chaves talvez precisem mudar em relação a outros valores de chave. Veja o exemplo de uma tabela Employee com duas chaves: LoginName e Badge Number. Aqui está uma linha de amostra dessa tabela:
Se o ZoeS perder seu crachá, talvez ela receba um novo e obtenha um novo número de crachá:
Mais tarde, ela pode decidir alterar seu nome de login:
Os dois valores principais foram alterados - em relação um ao outro. Observe que não faz necessariamente nenhuma diferença qual deles é considerado "primário".
Na prática, a "imutabilidade", ou seja, absolutamente nunca alterando um valor, é inatingível ou pelo menos impossível de verificar. Na medida em que a mudança faz alguma diferença, o caminho mais seguro é provavelmente supor que qualquer chave (ou qualquer atributo) possa precisar ser alterada.
fonte
Curiosamente, a pergunta vinculada sobre o tipo ROWGUID fornece seu próprio caso de uso: quando você tem chaves primárias conflitantes nos bancos de dados que precisam ser sincronizados. Se você tiver dois bancos de dados que precisam ser reconciliados e usarem sequências para chaves primárias, desejará que uma das chaves mude para que permaneça única.
Em um mundo ideal, isso nunca aconteceria. Você usaria GUIDs para as chaves primárias, para começar. Realisticamente, porém, talvez você nem tenha um banco de dados distribuído ao começar a projetar, e convertê-lo em GUIDs pode ter sido um esforço que foi priorizado abaixo, tornando-o distribuído porque foi considerado de maior impacto do que a implementação da atualização principal. Isso pode acontecer se você tiver uma grande base de códigos que depende de chaves inteiras e exigiria uma revisão importante para converter em GUID. Há também o fato de que GUIDs esparsos (GUIDs que não são muito próximos um do outro, o que acontece se você os gerar aleatoriamente como deveria) também podem causar problemas para certos tipos de índices, o que significa que você deseja evitar o uso como chaves primárias (mencionadas por Byron Jones ).
fonte
Um cenário possível é, digamos, que você tem afiliados com ID exclusivo e sabe que eles não serão duplicados entre afiliados, pois possuem um caractere inicial exclusivo. Os afiliados carregam dados em uma tabela mestre. Os registros são processados e, em seguida, são atribuídos um ID mestre. Os usuários precisam acessar os registros assim que carregados, mesmo que ainda não tenham sido processados. Você deseja que o ID mestre seja baseado no pedido processado e nem sempre processará no pedido em que os registros foram carregados. Eu sei um pouco fabricado.
fonte
Imagine uma situação como quando alguém escolheu o NIN (National Insurance Number) como chave primária e, de alguma forma, um operador insere uma linha com o NIN errado. Após inserir o valor, há duas maneiras de corrigir o erro:
fonte