Pergunta

Em leitura isto e isto e depois lendo isto (Quais referenciam os outros dois ironicamente) Eu me pergunto o tamanho da discussão deste tópico? Eu sou um cara do SQL Server e, portanto, tenho a tendência de usar uma identidade gerada automaticamente na forma de um int. No entanto, quando sei que precisarei de alguma forma de replicação entre servidor e servidor ou sincronização entre cliente e servidor, tendem a usar um GUID como minha chave.

Pergunta: Devo usar um GUID como minha chave primária em todas as tabelas o tempo todo, caso eu precise dessa possível escalabilidade no caminho? Isso torna meu esquema mais flexível, pois pode ser migrado entre plataformas o tempo todo? Isso me ajuda a manter a flexibilidade do meu ORM (independentemente do sabor) por não incorporar recursos específicos da plataforma?

Respostas:

@David Archer: Por seu comentário, atualizei minha postagem para não dizer "chave natural". Você está correto nessa chave natural é definida como tal. Obrigado pela correção.

Foi útil?

Solução

Costumo preferir teclas primárias geradas por aplicativos, normalmente usando o algoritmo LO/HI, implementado pelo Nibernate (quando o estou usando em um projeto). Caso contrário, os guids seqüenciais também funcionam. Este não é apenas o meu conselho, mas sim de várias pessoal quem têm Tenho feito toda essa coisa de desenvolvimento há muito mais tempo do que eu.

O problema que vejo com o uso de teclas primárias geradas por DB é que você deve atingir o banco de dados para obter esses valores de identidade em vez de configurar tudo antes de persistir no banco de dados. Normalmente, também quebra a unidade de padrão de trabalho no Nibernate devido a esse fato. Se você não estiver usando o padrão UOW em seu aplicativo, obviamente essa desvantagem não se aplica.

Se você estiver usando o GUIDS para o seu PK, definitivamente deseja usar GUIDs seqüenciais para eliminar a fragmentação do índice. Isso também fornece a "ordem de classificação aproximada" que outro pôster mencionou, embora eu normalmente tenha uma coluna DateInsert ou similar para esses tipos de coisas.

Juntando -se a uma coluna GUID foi mostrado Para ter uma sobrecarga de desempenho bastante mínima versus seu número inteiro de 4 bytes e eu me aventuraria a dizer que, para conjuntos de dados não grandes, a diferença de desempenho é trivial.

As chaves naturais são a desova do diabo. :)

Outras dicas

Você provavelmente não deve usar GUIDs brutos como sua chave primária. Fazer isso leva à fragmentação substancial de seus dados. O SQL Server tem um função Para fornecer um "GUID sequencial" para ajudar a mitigar esse problema. Há uma boa discussão sobre este tópico em profundidade aqui. Outra excelente discussão disso é aqui ...

Isso mostra que a quantidade de fragmentação para GUIDs aleatórios é muito significativa (é recomendado que "a fragmentação em porcentagem" deve estar o mais próximo possível de zero). O número de páginas usadas pelo GUID aleatório é 40% maior e a quantidade de espaço usada em cada página é menor; portanto, o espaço do disco necessário aumentará.

Eu evitaria o GUIDS para chaves primárias, a menos que você saiba que realmente precisará (ou seja, para sincronização multi-sistemas, etc.).

Na terra da replicação do SQL Server, um GUID é adicionado às linhas em tabelas replicadas para alcançar a singularidade, por isso é bem possível estabelecer esse design posteriormente se você tiver a necessidade.

Quanto à fragmentação, considere também o custo do seu espaço em disco. Se você vai ter menos de 10.000 linhas (em uma tabela), provavelmente não é um problema enorme, mas se o seu sistema precisar suportar acima de 10.000 linhas (em uma tabela), você encontrará desempenho e custo de armazenamento em disco (e fragmentação de índice) é melhor servido pelo uso de grandes ints (números inteiros grandes) + identidade (número automático) que escalam bem para o volume.

Eu evitaria as chaves naturais completamente - mesmo o risco de mudar a lógica em torno delas torna IMHO muito arriscado (por exemplo, se eles se tornarem de repente não unique).

Apoio a maioria das outras respostas ao dizer que você deve evitar o GUIDS como sua chave em cluster no SQL Server - se você realmente deseja, você pode usá -los como chave primária, mas não agrupe sua tabela.

A chave primária é o conceito lógico de uma chave para identificar exclusivamente cada linha - aqui, um GUID pode fazer sentido, pois é praticamente garantido ser único.

Mas a chave em cluster é um conceito físico que ordena fisicamente as linhas da tabela e aqui devido à sua natureza aleatória, os guids são mal adequados. Isso levará à fragmentação maciça do índice e, portanto, ao mau desempenho, mesmo se você continuar reorganizando seu índice (e, portanto, os dados da tabela) repetidamente.

Além disso, como a chave de índice em cluster está sendo usada como o valor da pesquisa para encontrar a linha na tabela, ela será adicionada a cada entrada de todo e qualquer índice não agrupado em sua tabela, e aqui o tamanho de O GUID (16 bytes) vs. Int (4 bytes) entra em jogo - você potencialmente desperdiça muito espaço apenas para acompanhar os valores de pesquisa.

A melhor discussão sobre índices e guids primários / agrupados que conheço é o casal de Kim Tripp, a rainha da indexação no SQL Server Land - confira!

Seus requisitos finais para um índice em cluster são: pequeno, estável, único e esperançosamente cada vez maior. GUID viola dois deles (pequeno e cada vez maior). Mesmo os GUIDs gerados pela função NewsequencialGuid () no SQL Server não são totalmente e verdadeiramente seqüenciais - então eu também não os usaria.

Marc

Fui queimado muitas vezes por "chaves naturais" mudando ou sendo duplicado para considerá -las usá -las. Minha decisão de usar sequências ou guids para chaves é determinada se espero ler ou falar um deles.

Não tive muita experiência com isso, mas usar um GUIDS para entrar me faz estremecer. 4 bytes versus 36 parece nojento.

No entanto, comecei a usar o GUIDS como identificadores públicos, e não os próprios campos de identidade. Dê uma olhada no URL acima, 1156712. Se, por algum motivo Google Stats também. Considerando que, se a maneira como todos os elementos fosse identificados publicamente foi através do uso de um GUID e as junções internas usavam os campos int ou bigint, você poderia ter o melhor dos dois mundos.

As mescladas ainda são possíveis também usando essa abordagem. Se um conflito for encontrado, um novo identificador interno poderá ser gerado em tempo real sem interromper o restante do aplicativo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top