Sei que esse tipo de pergunta surge muito, mas ainda não li argumentos convincentes para me ajudar a tomar essa decisão. Por favor, tenha paciência comigo!
Eu tenho um banco de dados enorme - cresce cerca de 10.000.000 de registros por dia. Os dados são relacionais e, por razões de desempenho, carrego a tabela com BULK COPY. Por esse motivo, preciso gerar chaves para as linhas e não posso confiar em uma coluna IDENTITY.
Um número inteiro de 64 bits - um bigint - é amplo o suficiente para eu usar, mas para garantir a exclusividade, preciso de um gerador centralizado para fazer meus IDs para mim. Atualmente, tenho um serviço desse gerador que permite que um serviço reserve números de sequência X e garanta que não haja colisões. No entanto, uma conseqüência disso é que todos os serviços que eu tenho dependem desse gerador centralizado e, portanto, sou limitado em como posso distribuir meu sistema e não estou satisfeito com as outras dependências (como exigir acesso à rede) impostas por este design. Este tem sido um problema na ocasião.
Agora estou pensando em usar GUIDs seqüenciais como minhas chaves primárias (geradas externamente para SQL). Tanto quanto pude verificar com meus próprios testes, a única desvantagem é a sobrecarga de espaço em disco de um tipo de dados mais amplo (que é exacerbado pelo uso em índices). Eu não testemunhei nenhuma desaceleração discernível no desempenho da consulta, em comparação com a alternativa bigint. Carregar a mesa com BULK COPY é um pouco mais lento, mas não muito. Meus índices baseados em GUID não estão se fragmentando graças à minha implementação sequencial de GUID.
Basicamente, o que eu quero saber é se existem outras considerações que eu possa ter esquecido. No momento, estou inclinado a dar o salto e começar a usar GUIDs. Como não sou especialista em banco de dados, gostaria muito de receber qualquer orientação.
fonte
Respostas:
Estou em uma mesma situação semelhante. Atualmente, estou usando a abordagem GUID seqüencial e não tenho fragmentação nem geração fácil de chaves.
Percebi duas desvantagens que me fizeram começar a migrar para o bigint:
(2) Foi o assassino para mim.
Agora vou gerar minhas chaves assim:
Eu usarei uma data inicial mais uma hora e ter uma parte seqüencial depois disso. Isso me permite consultar meus dados por data sem nenhum índice de adição. Este é um bom bônus para mim.
Gerarei a parte seqüencial do bigint usando um algoritmo HiLo que se presta bem à distribuição .
Espero que parte disso seja transferida para a sua situação. Definitivamente, recomendo usar bigint.
fonte
Com um tipo
INT
, começando em 1, você obtém mais de 2 bilhões de linhas possíveis - isso deve ser mais do que suficiente para a grande maioria dos casos. ComBIGINT
, você recebe aproximadamente 922 quatrilhões (922 com 15 zeros - 922'000 bilhões) - o suficiente para você?Se você usar uma
INT IDENTITY
partida em 1 e inserir uma linha a cada segundo, precisará de 66,5 anos antes de atingir o limite de 2 bilhões.Se você usar a
BIGINT IDENTITY
partir de 1 e inserir mil linhas por segundo, precisará de 292 milhões de anos antes de atingir o limite de 922 quatrilhões ...Usando seus 10 milhões de linhas por dia, você terá números suficientes para aproximadamente 1'844'674'407'370 dias ( 1844 bilhões de dias ou mais de 5 bilhões de anos ) de dados - isso é suficiente para suas necessidades ?
Leia mais sobre isso (com todas as opções disponíveis) nos Manuais Online do MSDN .
fonte
BIGINT
alcance tão rapidamente ...BIGINT IDENTITY
?Eu recomendo que você use o tipo de dados SEQUENCE of BIGINT no SQL 2012. Isso é muito mais flexível que o IDENTITY com opções como cache / nocache, você também pode atribuir um intervalo de sequência para sua operação em lote como sp_sequence_get_range.
fonte
É por isso que você não pode usar IDENTITY porque já existem relacionamentos de chave estrangeira entre tabelas separadas que você está carregando? E não há outra chave natural para você poder vinculá-las em uma operação de uma área intermediária para a área de produção? Por esse motivo, gostaria de saber um pouco mais sobre como eles estão atualmente "vinculados" no sistema de origem antes de você copiar em massa? Os sistemas de múltiplas fontes simplesmente usam suas próprias sequências e têm a possibilidade de sequências conflitantes quando trazidos para um banco de dados compartilhado?
A técnica COMB ID / GUID seqüencial é uma que eu conheço e é viável sempre que você precisar efetivamente da exclusividade global atribuída fora do banco de dados - é efetivamente uma identidade de linha utilizável dentro e fora do banco de dados. Por esse motivo, em ambientes altamente distribuídos ou em cenários desconectados, é uma boa opção
Exceto se você realmente não precisar, porque essa diferença de largura extra é significativa quando o tamanho dos dados aumenta e essas chaves estão em todos os índices e nos conjuntos de trabalho para muitas consultas.
Além disso, com a geração distribuída, se as linhas realmente não estiverem na ordem da coluna GUID, os problemas com o uso dessa chave de índice em cluster (estreita, estática, crescente) potencialmente causam alguma fragmentação em comparação com o cluster em uma IDENTITY ainda permanecer.
fonte
Em geral, é possível usar a
OUTPUT
cláusula deINSERT
comando para inserir dados nas duas tabelas e relacionados ao campo de identidade.O identificador baseado no registro de data e hora não deve ser considerado confiável - depende do relógio do sistema, que por sua vez depende de muitas coisas - do relógio do hardware aos serviços de sincronização de horário.
fonte