AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 232120
Accepted
igelr
igelr
Asked: 2019-03-15 03:22:10 +0800 CST2019-03-15 03:22:10 +0800 CST 2019-03-15 03:22:10 +0800 CST

Como gerar ids globalmente exclusivos para diferentes tabelas do mesmo banco de dados?

  • 772

Em um sistema de produção no SQL Server todos os ids (principalmente PKs) em todas as tabelas são gerados automaticamente e sou informado que eles são únicos globalmente. Quero dizer, não há 2 ids iguais no banco de dados, mesmo que as tabelas sejam diferentes. Eu quero saber como isso pode ser feito? Se houver várias maneiras, liste todas. Obrigado.

sql-server unique-constraint
  • 3 3 respostas
  • 7700 Views

3 respostas

  • Voted
  1. Best Answer
    Michael Green
    2019-03-15T03:34:52+08:002019-03-15T03:34:52+08:00

    Antigamente tínhamos IDmesa. Coluna única, linha única com um intvalor. Cada transação primeiro atualizava essa tabela para obter um novo valor, que era usado onde quer que fosse necessário. Isso foi, é claro, uma grande fonte de erros de simultaneidade.

    Mais tarde, as sequências foram introduzidas. Uma única sequência usada em todo o banco de dados mostraria o comportamento que você descreve. Há um exemplo na documentação que ilustra isso:

    CREATE TABLE Audit.ProcessEvents
    (
        EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different table
        <other columns>
    );
    
    CREATE TABLE Audit.ErrorEvents
    (
        EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different tables
        <other columns>
    );
    
    

    Editei o exemplo para destacar esse uso.

    Um resultado idêntico pode ser obtido gerando os números globalmente exclusivos no código do aplicativo, antes de serem passados ​​para o banco de dados. Se eu implementar isso, imagino que seria como um método estático de alguma classe de utilitário compilada no executável (embora outras implementações sejam possíveis). Digamos que o aplicativo precise gravar os detalhes de um cliente no banco de dados. Como ele está empacotando o nome do cliente, endereço, número de telefone, etc., ele também gera um novo ID global. O ID é passado para a instrução INSERT (ou procedimento armazenado) como apenas outro valor de parâmetro.

    Se os valores de ID são produzidos pela camada de arquitetura do aplicativo ou pela camada de banco de dados depende das considerações de design específicas. Se o aplicativo pode escalar horizontalmente, a coordenação entre instâncias se torna problemática. Depois que um aplicativo é reiniciado, o código deve descobrir o próximo valor a ser usado. O servidor de banco de dados tem esses recursos e outros já gravados nele.

    O que eu definitivamente não faria é fazer com que o aplicativo chamasse o banco de dados apenas para o próximo ID e, em seguida, empacotasse isso com os dados de negócios em um INSERT. São muitas viagens de ida e volta para o banco de dados quando apenas uma é necessária.

    • 13
  2. David Spillett
    2019-03-15T04:15:11+08:002019-03-15T04:15:11+08:00

    Para valores de ID exclusivos na mesma tabela, presumo que você esteja ciente da IDENTITYopção comumente usada, geralmente usando um valor de 32 bits a partir de 1 (portanto, para definir um PK dessa maneira, algo como ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY). É claro que você pode usar um ( BIGINT) maior se a tabela precisar de mais de 2.147.483.647 linhas.

    O SQL Server tem a opção de definir sua própria sequência que pode ser compartilhada entre várias tabelas, potencialmente todas elas. Consulte https://learn.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql para obter detalhes. Em seguida, você define cada coluna de ID como ID INTEGER DEFAULT NEXT VALUE FOR The_sequence_You_Defined PRIMARY KEY. Há algumas coisas para estar ciente aqui embora. Ao contrário de IDENTITYvocê, você não está impedido de inserir nenhum valor antigo (que ainda não esteja presente), pois o valor da sequência é aplicado por padrão somente se um não for fornecido explicitamente, o que pode ser problemático. Além disso, o uso de uma sequência é um pouco mais lento e pode se tornar um gargalo, pois todas as tabelas dependem do mesmo objeto, embora esses dois problemas sejam apenas uma preocupação se o banco de dados vir muita atividade de inserção em um curto espaço de tempo.NEXT VALUE FOR The_sequence_You_Definedpode ser usado em outro lugar também (ou seja SET @someVariable = NEXT VALUE FOR The_sequence_You_Defined;) o que significa que se você precisar que os IDs sejam gerados em outro lugar na lógica do seu aplicativo, você pode fazer isso dessa maneira (na verdade, eu vi isso usado mesmo para uma única identidade, não apenas compartilhando uma sequência entre vários objetos).

    Uma abordagem mais complicada poderia ser usar um BIGINTpara cada coluna de identidade e iniciar cada uma em um múltiplo diferente de (por exemplo) 4.000.000.000. Isso funcionará em outros bancos de dados e evita o problema do gargalo, mas dobra o tamanho da sua chave e pode causar um pesadelo de manutenção se você definir acidentalmente duas tabelas com IDs começando no mesmo ponto. Você pode querer adicionar restrições de verificação para garantir que um valor de identidade definido dessa maneira não possa transbordar para o espaço numérico de outro valor, o que adiciona novamente alguma preocupação de desempenho.

    Se você não se importa com a chave maior, os UUIDs são úteis e têm a vantagem adicional de serem exclusivos entre bancos de dados (todos os bancos de dados, como o nome sugere) e não apenas entre tabelas em um banco de dados. Assim como em uma sequência, eles são aplicados com uma restrição padrão, ou seja, ID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID(). No entanto, esses são valores de 128 bits, duas vezes o tamanho BITINTe quatro vezes o tamanho de um 32 bits "padrão" INTEGER. Se você está preocupado com o potencial de fragmentação extra causada pela aleatoriedade dos UUIDs v4, você pode usar NEWSEQUENTIALID()em vez do NEWID()que ainda deve ser único o suficiente (a chance de uma colisão durante a vida útil desta galáxia é muito pequena).

    • 7
  3. kovalensue
    2019-03-15T03:54:43+08:002019-03-15T03:54:43+08:00

    Antes de mais nada, devo mencionar que não trabalhei com SQL Server, portanto não posso apontar alguns recursos específicos.

    Eu tenho dois conceitos de como isso pode ser feito em minha mente:

    1. Uma sequência para governá-los todos: Este conceito é tão fácil quanto parece. Você tem uma sequência que é responsável por gerar IDs para cada linha inserida em qualquer tabela. No meu último trabalho, estávamos usando esse conceito. A implementação depende de muitas circunstâncias, então vou deixar você decidir. Mas uma maneira é ter algum procedimento armazenado que recuperará o próximo valor da sequência antes de qualquer inserção.
    2. Timestamp: Você pode de alguma forma incorporar timestamps em seus IDs

    No mundo do SQL Server, você pode consultar isto: Documentação NEWID() - newid é compatível com RFC4122

    • 3

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve