Estou no meio de um debate sobre se é melhor fazer um PRIMARY KEY
de um Identity Columns , ou de um UDF que gera explicitamente um id exclusivo.
- Estou defendendo a Coluna de Identidade.
- Meu sócio está defendendo a geração manual dos valores, ele alega
- colocando o UDF em outra tabela onde podemos ter um UDF
- bloquear o recurso
- incrementar uma tabela de ID com um campo chamado
ID_Value
por1
- use isso como um identificador exclusivo global
- Ou faça com que a tabela faça um
id+1
ao inserir - Que é mais simples mover dados entre servidores e/ou ambientes sem a restrição de identificação; mover de um banco de dados onde há dados para outro banco de dados semelhante com, digamos, dados de teste ou fictícios. Para testes em não produção, podemos extrair todos os registros de ontem para a preparação para teste.
- colocando o UDF em outra tabela onde podemos ter um UDF
Qual implementação faz mais sentido?
Seu colega é um idiota.
A solução não será escalável, o UDF não é concorrente ( mesmo motivo deste ). E como você lida com inserções de várias linhas: isso exigiria uma chamada UDF por linha
E migrar para outro RDBMS não acontece com frequência na vida real ... você também pode não usar o SQL Server agora e usar sequências no Oracle e esperar não migrar.
Editar:
Sua atualização afirma que mover dados é para atualizar bancos de dados de não produção.
Nesse caso, você ignora as colunas de identidade ao atualizar. Você não compromete sua implementação para facilitar o carregamento sem produção. Ou use tabelas temporárias para rastrear as alterações de valor de identidade.
Ou use processos: atualizamos nosso sistema de teste todas as noites desde a produção, o que evita totalmente o problema. (E garante que nosso backup de prod também possa ser restaurado)
Use um valor de identidade. Gerar sua própria tabela de sequência e valores de sequência exigirá muita sobrecarga e causará muitos travamentos e bloqueios ao tentar gerar números.
A identidade existe por uma razão, use-a.
Quando o SQL Denali for lançado, ele oferecerá suporte a sequências que serão mais eficientes que a identidade, mas você não pode criar algo mais eficiente sozinho.
Quanto à movimentação de registros de um ambiente para outro, ative IDENTITY_INSERT ON ao fazer a inserção ou marque a caixa no SSIS.
A coluna de identidade parece boa para mim. Não tenho certeza se sigo a lógica sobre por que é difícil mover dados entre servidores.
Se você deseja que cada linha tenha uma identidade globalmente exclusiva, pode usar um UUID, mas eu não faria isso, a menos que tenha certeza de que a exclusividade global é necessária - geralmente não é. O uso de UUIDs como IDs diminuirá o desempenho, aumentará os requisitos de espaço em disco e dificultará a depuração - devido ao tamanho, é difícil lembrar um UUID, contá-lo a alguém pelo telefone ou escrevê-lo no papel sem erros.
Para IDs numéricos simples, basta ir com a identidade e esquecer todos os problemas de gerá-los manualmente.
Você sempre pode criar uma "super tabela" que use uma identidade como PK e tenha uma coluna de tipo e qualquer outra informação. Quando você precisar de um novo ID (supondo que você quer dizer IDS exclusivo em tabelas diferentes), basta inserir nesta tabela e pegar
SCOPE_IDENTITY()
e inserir na tabela real que você precisa.Basicamente você cria uma tabela: MasterIDs com uma identidade PK, quando você precisa inserir uma linha em sua Table1,
INSERT INTO MasterIDs
e obter a identidade gerada por essa linha usandoSCOPE_IDENTITY()
e inserir na Table1 usando esse valor como PK.Table1 terá uma PK int sem identidade. Você faria o mesmo processo para inserir na Table2, etc. Deixe o SQL Server gerenciar os valores de identidade na tabela MasterIDs , que você pode usar em suas outras tabelas. MasterIDs podem conter outras tabelas, como tipo (para que você possa saber qual tabela, Tabela1 ou Tabela2, etc., usa esse valor de identidade.
Contanto que você esteja usando restrições de chave estrangeira corretamente (cascata, atualização, etc.), você estará bem usando um campo de identidade. Eu realmente não vejo uma vantagem para a outra solução neste caso.
A identidade foi feita para se adequar ao seu cenário. Você tem ferramentas como replicação para troca de dados de servidores/ambientes que mantêm tudo junto.
Acabei de terminar um trabalho em que substituí uma
identity
coluna do SQL Server por umint
campo normal e controlei a alocação de ID.Tenho visto ganhos de desempenho bastante impressionantes. Ao contrário do OP, não tenho UDF para gerar o id. Mas o princípio é praticamente o mesmo: existe uma parte do software que mantém um conjunto de id's. Quando eles acabam, ele recebe outro lote consultando o banco de dados para o próximo valor baixo e incrementa isso para o próximo alto .
Isso nos permite gerar ids e relacionar todas as entidades fora de uma transação em nosso ORM antes de enviarmos os lotes ao banco de dados e também enviar lotes maiores sem ida e volta extras para obter a identidade recém-inserida (exigida pelas colunas de identidade).
Na tabela de id que temos há mais de uma linha, o que nos permite usar intervalos específicos se desejarmos. ou seja, para reutilizar blocos excluídos e ids negativos.
Eu uso identidade há anos e considero seriamente substituir o número de identidade por UNIQUEIDENTIFIER. É um pesadelo quando você precisa alterar o tipo de dados se alguém o projetou para ser um banco de dados compacto e um pesadelo se você precisar adicionar identidade a uma coluna; além disso, você não pode atualizar a coluna de identidade. Imagine que você coloca um int e seu banco de dados cresce além de 2 bilhões de registros, novamente um pesadelo para mudar (considere os FKs)! Alterar qualquer coisa com identidade é um pesadelo e não é compatível com a escala, a menos que você coloque bigint! UNIQUEIDENTIFIER vs Identity = conveniência e robustez vs melhoria de desempenho talvez perceptível (não fiz o benchmark).
Atualização: depois de ver isso , definitivamente me inclino para UNIQUEIDENTIER. Isso não mostra nenhum benefício real da identidade bigint e vários benefícios para o UNIQUEIDENTIFIER! Diferentes versões do SQL Server podem ter um resultado diferente. Existe beleza em ter um id único em todos os bancos de dados e sistemas (robustez)! Mova, copie, transforme dados como quiser! https://www.mssqltips.com/sqlservertip/5105/sql-server-performance-comparison-int-versus-guid/