Quais são as desvantagens de usar UUID ou GUID como chave primária?

61

Eu gostaria de construir um sistema distribuído. Preciso armazenar dados em bancos de dados e seria útil usar um UUID ou um GUID como chave primária em algumas tabelas. Suponho que seja uma desvantagem desse design, pois o UUID / GUID é bastante grande e eles são quase aleatórios. A alternativa é usar um INT ou LONG incrementado automaticamente.

Quais são as desvantagens de usar UUID ou GUID como chave primária para minhas tabelas?

Provavelmente usarei o Derby / JavaDB (nos clientes) e o PostgreSQL (no servidor) como DBMS.

Jonas
fonte
Por que isso seria útil? Em que desvantagens você está mais focado? A resposta para cada pergunta do banco de dados que esta vaga é "depende". Você pode nos dar mais detalhes? Você está mais interessado em desempenho de leitura ou gravação? de que nível de distribuição estamos falando?
Brian Ballsun-Stanton
@Brian: os UUIDs nos sistemas distribuídos são úteis, pois você pode criar a chave primária nos clientes e depois carregar os dados de forma assíncrona no servidor. Estou pensando principalmente nas desvantagens do desempenho de leitura. Usar muitos JOINs em UUIDs talvez não seja tão bom? Por exemplo, um cliente adiciona um item (UUID, nome, fornecedor, criador) a um sistema de inventário e, em seguida, o banco de dados local é sincronizado com o banco de dados central no servidor.
Jonas
11
Eu acho que sem mais alguns comentários esclarecedores sobre isso, no máximo será "depende". Sem eles, eu vou para o VtC.
jcolebrand
Há um artigo que fala sobre o GUID versus o efeito não GUID nos índices em cluster no SQL Server que você pode achar interessante, embora esteja relacionado a um produto SQL diferente: x.co/Twpp
Jeff
Notei que o documento do Derby não lista o UUID como um tipo de dados. Você pode considerar uma alternativa, como o H2 Database Engine (um banco de dados Java puro como o Derby), que lista um tipo de dados UUID . Obviamente, o Postgres tem excelente suporte para armazenar , indexar e gerar valores UUID com eficiência .
Basil Bourque

Respostas:

29

Depende da sua função de geração e tamanho das mesas finais

Os GUIDs devem ser identificadores globalmente exclusivos . Como discutido na documentação do Postgres 8.3, não existem metodologias universalmente apropriadas para gerar esses identificadores, mas o postgreSQL é fornecido com alguns candidatos mais úteis.

No escopo do seu problema e na necessidade de gravações offline , você organizou com perfeição o uso de qualquer coisa, exceto um GUID, e, portanto, não há vantagens compensatórias de outros esquemas.

Do ponto de vista funcional, o comprimento da chave geralmente não é um problema em qualquer tipo de sistema moderno, dependendo do número de leituras e do tamanho da tabela. Como uma metodologia alternativa, os clientes offline podem agrupar novos registros sem uma chave primária e simplesmente inseri-los ao reconectar. Como o postgreSQL oferece o tipo de dados "Serial", os clientes nunca precisarão determinar o ID se puderem executar uma gravação simples no banco de dados.

Brian Ballsun-Stanton
fonte
3
Maldito seja, você foi embora e deixou Brian responder à pergunta. Sim, o requisito de "atualizações offline" mudou completamente todo o conceito.
jcolebrand
Muahahahaah! :: twirls bigode evilly ::
Brian Ballsun-Stanton
11
Mesmo com gravações offline, seria possível usar INTs. Por exemplo, usando duas colunas em {Node_ID, Item_ID}que cada nó tem um Node_IDe um Item_IDque é incrementado automaticamente por nó.
Jonas
@ Jonas ~ Sim, isso é viável. No entanto, um dos motivos pelos quais a maioria das pessoas ainda considera GUIDs é a replicação de conteúdo globalmente separada para outros bancos de dados. Quero dizer, o próprio termo é bastante QED lá.
jcolebrand
Com relação às arquiteturas master / slave ou clientes de conexão esparsa + arquiteturas de servidor principal, seria possível usar um global_id (SERIAL) no mestre e um global_id (BIGINT) + local_id (SERIAL) nos escravos. Os escravos realizam seu trabalho local usando local_id e se comprometem quando podem com o mestre, o mestre recebe os dados e concede a ele um global_id que retorna ao escravo, o escravo atualiza o campo global_id (para referência em conversação com o servidor ou com outros escravos).
Mihai Stancu
22

Mais um conselho - nunca use GUIDs como parte do índice clusterizado. Os GUIDs não são seqüenciais; portanto, se eles fazem parte de um índice clusterizado, toda vez que você insere um novo registro, o banco de dados precisa reorganizar todas as suas páginas de memória para encontrar o local certo para inserção, no caso de incremento automático int (bigint), seria apenas a última página.

Agora, se olharmos para algumas realizações de banco de dados: 1.) MySQL - chaves primárias são agrupadas, sem opção de alterar o comportamento - a recomendação é não usar GUIDs aqui 2.) Postgres, MS-SQL - você pode criar GUID como chave primária sem cluster e use outro campo como índice clusterizado, por exemplo, autoincrement int.

Ross Ivantsiv
fonte
O que você propõe para o Postgres também pode ser feito no MySQL, com uma estrutura ligeiramente diferente - auto_increment PK (chave em cluster), GUID com índice exclusivo (sem cluster).
precisa saber é o seguinte
Isso nem sempre é verdade. Dependendo da taxa de transferência do sistema de disco, sincronizar o acesso à última página pode ser seu gargalo. blog.kejser.org/2011/10/05/…
mwilson
2
"Ao contrário do Microsoft SQL Server, o armazenamento em cluster em um índice no PostgreSQL não mantém essa ordem. É necessário reaplicar o processo CLUSTER para manter a ordem." Como o cluster em melhorar o desempenho do índice
bartolo-otrit
Uma versão mais resumida das informações @ bartolo-otrit vinculada a: stackoverflow.com/a/4796685/1394393 . Essa resposta realmente não parece relevante para mim, pois esta pergunta é sobre PG e parece assumir semelhanças com o SQL Server e MySQL que não existem.
Jpmc26
database would need to rearrange all its memory pages to find the right place for insertion=> Acho que não é o caso do Postgres, pois o agrupamento é opcional e as novas linhas são armazenadas sem ordem.
Flavien
3

Depende.

Sério, com tudo o que você deu até agora, isso é o mais longe que você pode ir.

Por que seria útil usar UUIDs? Por que você não usa INTs? Por que você não pode simplesmente indexar UUIDs mais tarde? Você entende o que significa ter uma lista classificada com a chave de um UUID e inserir um UUID aleatório (não sequencial) após alguns milhões de linhas?

Em que plataforma isso funcionará? Quantos discos? Quantos usuários? Quantos registros?

jcolebrand
fonte
7
Como escrevi no meu comentário, se eu usar o UUID, os clientes poderão adicionar linhas ao banco de dados sem uma conexão com o servidor e posteriormente sincronizar com o servidor. Não posso fazer isso se eu usar INTs para chave primária, porque vários clientes podem usar a mesma chave primária para itens diferentes. Bem, é inútil classificar a lista em uma coluna UUID, seria mais útil classificá-la em uma coluna de carimbo de data / hora. Não, não sei o que significa inserir um UUID não sequencial aleatório após alguns milhões de linhas, é por isso que faço essa pergunta.
Jonas
O aplicativo será escrito em Java e os clientes podem usar Windows, Mac ou Linux. Os clientes usarão computadores comuns que geralmente têm um disco. O número de usuários e registros depende de quantos clientes eu recebo, mas serão cerca de 5000 por cliente e cliente.
Jonas
11
O comentário offline mudou tudo. Veja o que mais detalhes faz?
jcolebrand