Escolha do tipo de chave primária

votos
0

Eu tenho uma tabela que potencialmente terá elevado número de inserções por segundo, e eu estou tentando escolher um tipo de chave primária que eu quero usar. Para fins ilustrativos, digamos, é tabela de usuários. Eu estou tentando escolher entre usar GUID e BIGINT como chave primária e, finalmente, como UserID em todo o aplicativo. Se eu usar GUID, eu salvar uma viagem ao banco de dados para gerar um novo ID, mas GUID não é user-friendly e não é possível particionar a tabela por este ID (que eu estou planejando fazer). Usando BIGINT é muito mais conveniente, mas gerá-la é um problema - eu não posso usar a identidade (há uma razão fro isso), então minha única opção é ter alguma tabela auxiliar que deverá conter último ID utilizado e, em seguida, eu chamo isso proc armazenado:

create proc GetNewID @ID BIGINT OUTPUT
as
begin
update HelperIDTable set @ID=id, id = id + 1 
end

para obter o novo id. Mas, então, esta tabela auxiliar é um gargalo óbvio e eu estou preocupado com quantas atualizações por segundo que pode fazer.

Eu realmente gosto da idéia de usar BIGINT como pk, mas o problema gargalo me preocupa - há uma maneira de estimar aproximadamente quantos de id poderia produzir por segundo? Eu percebo que depende altamente de hardware, mas existem limitações físicas e qual o grau que estamos olhando? 100 do / s? 1000 / seg?

Todas as ideias sobre a forma de abordar o problema são muito apreciados! Este problema não me deixa dormir por muitos noite agora!

Obrigado! Andrey

Publicado 26/08/2009 em 22:16
fonte usuário
Em outras línguas...                            


5 respostas

votos
2

GUID parece ser uma escolha natural - e se você realmente deve, provavelmente você poderia argumentar usá-lo para a chave primária da tabela - o valor único que identifica exclusivamente a linha no banco de dados.

O que eu recomendo fortemente não fazer é usar a coluna GUID como a chave de cluster, que SQL Server faz por padrão, a menos que você especificamente dizer que não.

Como Kimberly Tripp - a Rainha de Indexação - e outros declarou muitas vezes - um GUID como a chave de cluster não é o ideal, uma vez que, devido à sua aleatoriedade, ele irá levar a página de massa e fragmentação do índice e geralmente mau desempenho.

Sim, eu sei - não há newsequentialid()no SQL Server 2005 e para cima -, mas mesmo isso não é verdadeira e totalmente seqüencial e, portanto, também sofre com os mesmos problemas que o GUID - apenas um pouco menos destaque lo.

Depois, há outra questão a considerar: a chave de cluster em uma tabela será adicionado a cada entrada em cada índice não agrupado em sua mesa, bem como - assim você realmente quer ter certeza que é tão pequeno quanto possível. Normalmente, um INT com 2+ bilhões de linhas deve ser suficiente para a grande maioria das mesas - e em comparação com um GUID como a chave de cluster, você pode salvar centenas de megabytes de armazenamento em disco e na memória do servidor.

Então, para resumir: a menos que tenha uma razão muito boa, eu sempre recomendo um INT IDENTITYcampo como chave primária / agrupado em sua mesa.

bagaço

Respondeu 26/08/2009 em 22:28
fonte usuário

votos
1

Você quer uma chave primária, por motivos de negócios, ou uma chave clustred, por preocupações de armazenamento? Veja stackoverflow.com/questions/1151625/int-vs-unique-identifier-for-id-field-in-database para um posto mais elaborado sobre o tema da PK chave cluster vs..

Você realmente tem que elaborar porque você não pode usar a identidade. Gerando as IDs manualmente, e especialmente no servidor com um rountrip extra e uma atualização apenas para gerar cada ID para a inserção não irá escalar. Você seria a sorte de chegar 100s mais baixos por segundo. O problema não é apenas o tempo rountrip e atualização, mas principalmente a partir da interação de atualização geração de ID com a inserção de lotes: a transação de lotes inserção serializará geração ID. O woraround é separar a geração de ID em sessão separada para que ele possa autocommit, mas, em seguida, a inserção de lotes é inútil porque o genartion ID não é batched: ela temesperar para descarga de log após cada ID genrated para cometer. Comparado a isto uuid será executado círculos em torno de sua geração ID manual. Mas uuid são a escolha horrível para chave clustred por causa da fragmentação.

Respondeu 26/08/2009 em 22:32
fonte usuário

votos
1

Eu tento usar PKs GUID para todas as tabelas, exceto pequenas tabelas de pesquisa. O conceito GUID garante que a identidade do objeto pode seguramente ser criado em memeory sem uma ida e volta ao banco de dados e salvar mais tarde, sem alterar a identidade.

Quando você precisa de um ID de "legível", você pode usar um incremento int auto quando salvo. Para particionar você também pode criar os valores BIGINT mais tarde por uma programação de banco de dados para muitos usuários em um único tiro.

Respondeu 26/08/2009 em 22:26
fonte usuário

votos
0

Uma ideia que requer testes sério: tente criar (inserir) novas linhas em lotes - digamos 1000 por hora (10.000 1M?). Você poderia ter uma tabela mestre (aka gargalo) listando o próximo a usar, ou você pode ter uma consulta que faz algo parecido

 select min(id) where (name = '')

Gerar um novo lote de linhas emtpy na parte da manhã, a cada hora, ou sempre que você está para baixo a um certo número de versões livres. Isso só aborda a questão da geração de novas IDs, mas se esse é o principal gargalo que poderia ajudar.

A opção de particionamento de tabela: Assumindo uma coluna ID bigint, como você está definindo a partição? Se você está permitindo linhas 1g por dia, você pode configurar a nova partição à noite (day1 = 1000000000 através 1999999999, day2 = 2000000000 através 2999999999, etc.) e depois trocá-lo quando ele está pronto. Está claro limitada a 1000 partições, portanto, com valores BIGINT você vai esgotar as partições antes de executar fora de IDs.

Respondeu 26/08/2009 em 23:05
fonte usuário

votos
0

tentar bater o seu db com um script, talvez com o uso de jmeter para simular acessos simultâneos. Talvez então você pode apenas medir-se quanta carga você pode manipular. Também o seu DB poderia causar um gargalo de garrafa. Qual deles é? Eu prefure PostgreSQL para carga pesada, como Yahoo e Skype também fazer

Respondeu 26/08/2009 em 22:24
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more