Vantagens e desvantagens das chaves do banco de dados GUID / UUID

222

Eu trabalhei em vários sistemas de banco de dados no passado, onde mover entradas entre bancos de dados seria muito mais fácil se todas as chaves do banco de dados tivessem valores GUID / UUID . Eu considerei seguir esse caminho algumas vezes, mas sempre há um pouco de incerteza, principalmente em relação ao desempenho e aos URLs que não podem ser lidos por telefone.

Alguém já trabalhou extensivamente com GUIDs em um banco de dados? Que vantagens eu teria ao seguir esse caminho e quais são as possíveis armadilhas?

Matt Sheppard
fonte
1
Jeff tem um post sobre " Chaves Primárias: IDs versus GUIDs ".
jfs
1
Também é possível usar Hi-Lo para clientes remotos: stackoverflow.com/questions/282099/whats-the-hi-lo-algorithm
Neil McGuigan
Local atualizado para a postagem de Jeff Atwood sobre " Chaves Primárias: IDs versus GUIDs ". Obrigado a @jfs pela referência.
Adam Katz
@jfs Fazer a ligação mudou para blog.codinghorror.com/primary-keys-ids-versus-guids
cr0ss

Respostas:

229

Vantagens:

  • Pode gerá-los offline.
  • Torna a replicação trivial (em oposição aos int's, o que torna MUITO difícil)
  • ORM geralmente gostam deles
  • Exclusivo entre aplicativos. Então, podemos usar os PKs do nosso CMS (guid) em nosso aplicativo (também guid) e saber que NUNCA vamos entrar em conflito.

Desvantagens:

  • Maior uso do espaço, mas o espaço é barato (er)
  • Não é possível solicitar por ID para obter o pedido de inserção.
  • Pode parecer feio em uma URL, mas realmente, WTF você está colocando uma chave REAL DB em uma URL !? (Este ponto discutido nos comentários abaixo)
  • Mais difícil de depurar manualmente, mas não tão difícil.

Pessoalmente, eu os uso para a maioria dos PKs em qualquer sistema de tamanho decente, mas fui "treinado" em um sistema que foi replicado em todo o lugar, por isso tínhamos que tê-los. YMMV.

Eu acho que a coisa de dados duplicados é lixo - você pode obter dados duplicados como quiser. Chaves substitutas geralmente desaprovam onde quer que eu esteja trabalhando. No entanto, usamos o sistema semelhante ao WordPress:

  • ID exclusivo da linha (GUID / qualquer que seja). Nunca visível para o usuário.
  • o ID público é gerado UMA VEZ a partir de algum campo (por exemplo, o título - torne-o o título do artigo)

UPDATE: Portanto, este é marcado com +1, e pensei em apontar uma grande desvantagem dos PKs do GUID: índices agrupados.

Se você tiver muitos registros e um índice agrupado em um GUID, o desempenho da sua inserção será SUCOS, pois você obtém inserções em locais aleatórios na lista de itens (esse é o ponto), não no final (o que é rápido)

Portanto, se você precisar inserir desempenho, talvez use uma INT auto-inc e gere um GUID se quiser compartilhá-lo com outra pessoa (por exemplo, mostrá-lo a um usuário em um URL)

Nic Wise
fonte
184
[WTF você está colocando uma chave REAL DB em uma URL !?] Não sei por que isso a incomoda. O que mais você usaria? Veja o estouro de pilha ... Ele tem valores de IDENTITY na URL em todo o lugar e funciona muito bem. O uso de chaves de banco de dados em URLs não impede que você imponha segurança.
Euro Micelli 15/09/08
20
Não, não, mas coisas como SEO geralmente são melhores se não houver uma chave - especialmente algo contanto que um GUID. Obviamente, isso pode ser contornado com facilidade, então acho que isso foi um pouco exagerado
Nic Wise
7
Boa resposta, seria bom se você também adicionasse informações sobre as desvantagens de desempenho do uso de GUIDs; por exemplo, ingressar, classificar e indexar por eles serão mais lentos do que usar números inteiros. Os guias são fantásticos, mas têm um custo que pode ser uma dor quando o desempenho é crítico.
Doctor Jones
26
Lembre-se de uma coisa: as pessoas frequentemente mudam de página, pergunta e título do fórum. Para o SEO, é BOM ter algo como um pequeno ID no URL para que, se o título mudar, você ainda saiba para onde encaminhar as pessoas provenientes de um URL ANTIGO. example.com/35/old-and-bustedtornou-se apenas example.com/35/new-hotnesse você está aplicativo pode apenas verificar o título e encaminhar o usuário com um 301.
Xeoncross
9
A indexação de um GUID é cara e lenta, o que os torna realmente pobres candidatos a chaves primárias.
Matthew James Davis
14

@Matt Sheppard:

Digamos que você tenha uma mesa de clientes. Certamente você não deseja que um cliente exista na tabela mais de uma vez, ou muita confusão acontecerá nos departamentos de vendas e logística (especialmente se as várias linhas do cliente contiverem informações diferentes).

Portanto, você tem um identificador de cliente que o identifica exclusivamente e garante que o identificador seja conhecido pelo cliente (em faturas), para que o cliente e o pessoal do serviço de atendimento ao cliente tenham uma referência comum caso precisem se comunicar. Para garantir nenhum registro duplicado do cliente, adicione uma restrição de exclusividade à tabela, por meio de uma chave primária no identificador do cliente ou por meio de uma restrição NOT NULL + UNIQUE na coluna identificador do cliente.

Em seguida, por algum motivo (no qual não consigo pensar), você será solicitado a adicionar uma coluna GUID à tabela do cliente e tornar essa a chave primária. Se a coluna de identificação do cliente agora não tiver garantia de exclusividade, você estará solicitando problemas futuros em toda a organização porque os GUIDs sempre serão exclusivos.

Alguns "arquitetos" podem dizer que "ah, mas lidamos com a restrição real de exclusividade do cliente em nosso nível de aplicativo!". Certo. A moda com relação a essas linguagens de programação de uso geral e (especialmente) às estruturas da camada intermediária muda o tempo todo e, geralmente, nunca supera o seu banco de dados. E há uma chance muito boa de que você, em algum momento, precise acessar o banco de dados sem passar pelo aplicativo atual. == Problema. (Mas, felizmente, você e o "arquiteto" se foram há muito tempo, portanto você não estará lá para limpar a bagunça.) Em outras palavras: mantenha restrições óbvias no banco de dados (e em outras camadas também, se você tiver A Hora).

Em outras palavras: pode haver boas razões para adicionar colunas GUID às tabelas, mas não caia na tentação de diminuir as suas ambições de consistência nas informações reais (== não GUID).

Troels Arvin
fonte
1
Ouça ouça! Ame sua página de comparação SQL. Extremamente útil. A única coisa que sinto falta é um changelog.
Henrik Gustafsson
3
Eu acho que essa resposta precisa de alguns esclarecimentos: isso pressupõe que os UUIDs nunca sejam usados ​​como chaves primárias. Não sei de onde vem essa suposição, mas ainda não vi um sistema que não permita que você as use como tal. Sei que é uma resposta antiga, suponho que as vantagens do uso de UUIDs em sistemas distribuídos não eram tão amplamente compreendidas na época (?).
tne
12

Por que ninguém menciona desempenho? Quando você tem várias associações, todas baseadas nesses GUIDs desagradáveis, o desempenho passa pelo chão, e está lá :(

Andrei Rînea
fonte
1
Você pode elaborar isso como estou na situação em que preciso introduzir o UUID (ou similar), mas estou preocupado em usá-los como Chave Primária.
JoeTidee
1
UUIDs são apenas 4 vezes o tamanho de inteiros ... (se o seu banco de dados tem um tipo UUID)
Jasen
11

Os GUIDs podem causar muitos problemas no futuro se forem usados ​​como "uniqifiers", permitindo que dados duplicados entrem em suas tabelas. Se você deseja usar GUIDs, considere ainda manter restrições UNIQUE em outras colunas.

Troels Arvin
fonte
11
Este é o coração do problema: a introdução de um GUID torna qualquer linha exclusiva. Mas as partes não artificiais das linhas podem conter subitamente duplicatas (várias versões da verdade).
3011 Troels Arvin
8
+1 para compensar. Entendo o que você quer dizer, mas está mal expresso.
214 Stefano Borini
11

As principais vantagens são que você pode criar IDs exclusivos sem se conectar ao banco de dados. E os IDs são globalmente únicos, para que você possa facilmente combinar dados de diferentes bancos de dados. Essas parecem pequenas vantagens, mas me pouparam muito trabalho no passado.

As principais desvantagens são um pouco mais de armazenamento necessário (não é um problema em sistemas modernos) e os IDs não são realmente legíveis por humanos. Isso pode ser um problema ao depurar.

Existem alguns problemas de desempenho como fragmentação de índice. Mas esses são facilmente solucionáveis ​​(guias de jimmy nillson: http://www.informit.com/articles/article.aspx?p=25862 )

Editar mesclou minhas duas respostas a esta pergunta

@ Matt Sheppard Acho que ele significa que você pode duplicar linhas com diferentes GUIDs como chaves primárias. Esse é um problema com qualquer tipo de chave substituta, não apenas com GUIDs. E, como ele disse, é facilmente resolvido adicionando restrições únicas e significativas a colunas não-chave. A alternativa é usar uma chave natural e elas têm problemas reais.

Mendelt
fonte
Eu sei sobre guias de combinação e aqueles que ajudam a resolver problemas de indexação (desempenho de inserção). " principais desvantagens são um pouco mais de armazenamento necessárias " Isso afetará o desempenho devido ao grande tamanho do arquivo do banco de dados?
Amit Joshi
8

Um outro pequeno problema a considerar com o uso de GUIDS como chaves primárias, se você também estiver usando essa coluna como um índice em cluster (uma prática relativamente comum). Você será atingido na inserção por causa da natureza de um guia que não começa seqüencialmente de qualquer maneira, portanto, haverá divisões de página etc. quando você inserir. Apenas algo a considerar se o sistema tiver IO alto ...

WIDBA
fonte
6

IDs de chaves primárias versus guias

O custo dos GUIDs como chaves primárias (SQL Server 2000)

Mitos, GUID vs. incremento automático (MySQL 5)

Isto é realmente o que você quer.

Profissionais de UID

  • Exclusivo em todas as tabelas, bancos de dados e servidores
  • Permite mesclar facilmente registros de diferentes bancos de dados
  • Permite fácil distribuição de bancos de dados entre vários servidores
  • Você pode gerar IDs em qualquer lugar, em vez de precisar ir até o banco de dados
  • A maioria dos cenários de replicação requer colunas GUID de qualquer maneira

Contras do GUID

  • É impressionantemente 4 vezes maior que o valor tradicional do índice de 4 bytes; isso pode ter implicações sérias de desempenho e armazenamento, se você não tomar cuidado
  • Difícil de depurar (onde userid = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Os GUIDs gerados devem ser parcialmente seqüenciais para obter o melhor desempenho (por exemplo, newsequentialid () no SQL 2005) e para permitir o uso de índices em cluster
Wener
fonte
1

Há uma coisa que realmente não é abordada, ou seja, usar IDs aleatórios (UUIDv4) como chaves primárias prejudicará o desempenho do índice de chave primária . Isso acontecerá se sua tabela estiver ou não agrupada em torno da chave.

Os RDBMs geralmente garantem a exclusividade das chaves primárias e as pesquisas por uma chave, em uma estrutura chamada BTree, que é uma árvore de pesquisa com um grande fator de ramificação (uma árvore de pesquisa binária possui um fator de ramificação 2). Agora, um ID inteiro seqüencial faria com que as inserções ocorressem apenas um lado da árvore, deixando a maioria dos nós das folhas intocados. Adicionar UUIDs aleatórios fará com que as inserções dividam os nós das folhas em todo o índice.

Da mesma forma, se os dados armazenados são principalmente temporais, geralmente os dados mais recentes precisam ser acessados ​​e associados mais. Com UUIDs aleatórios, os padrões não se beneficiam com isso e atingem mais linhas de índice, necessitando assim de mais páginas de índice na memória. Com IDs seqüenciais, se os dados mais recentes forem necessários, as páginas de índice quentes exigiriam menos RAM.

Antti Haapala
fonte