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 / 29116
Accepted
DamagedGoods
DamagedGoods
Asked: 2012-11-23 05:18:07 +0800 CST2012-11-23 05:18:07 +0800 CST 2012-11-23 05:18:07 +0800 CST

usando a coluna IDENTITY com incremento -1

  • 772

Eu preciso executar um banco de dados de log do servidor SQL com 2 tabelas principais em 2 datacenters separados gravando em ambos ao mesmo tempo.

Tive a ideia de restaurar o banco de dados para o novo datacenter e, em seguida, propagar novamente a coluna de identidade para -1 e definir o incremento para -1, dessa forma nunca haveria chance de duplicar id's quando os dados precisassem ser combinados. DATACENTRE1 seriam inteiros positivos, DATACENTRE2 inteiros negativos

um incremento de -1 causaria algum problema?

sql-server database-design
  • 6 6 respostas
  • 10769 Views

6 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2012-11-23T08:45:11+08:002012-11-23T08:45:11+08:00

    Voltar para trás parece errado para mim.

    Com apenas dois data centers, você também pode implementar intervalos de identidade. A menos que você percorra os valores de identidade em um ritmo alarmante, não há motivo para não ter:

    -- Data center 1
    CREATE TABLE dbo.Table
    (
      ID INT IDENTITY(1,1) PRIMARY KEY
      -- , ...
    );
    
    -- Data center 2
    CREATE TABLE dbo.Table
    (
      ID INT IDENTITY(1000000000,1) PRIMARY KEY
      -- , ...
    );
    

    Isso permitiria gerar 1 bilhão (bem, 999.999.999) valores no datacenter 1 antes que houvesse qualquer perigo de colisão com o datacenter 2. E você poderia adicionar uma restrição CHECK no datacenter 1 para evitar a sobreposição de valores, dependendo de como você prioriza erros versus duplicatas. Você também pode implementar um trabalho recorrente que verifica periodicamente o quão perto você está do limite inferior do outro centro de dados, se estiver preocupado em gerar mais de um bilhão de valores em qualquer centro de dados durante a vida útil do aplicativo (não importa Sua).

    Se ~1 bilhão não for suficiente, existem outras duas alternativas para dar mais espaço para respirar:

    -- Data center 1
      ID INT IDENTITY(-2147483648,1)
    
    -- Data center 2
      ID INT IDENTITY(1,1)
    

    Isso daria a cada centro de dados mais de 2 bilhões de valores não sobrepostos, sem perigo de colisão até que o centro de dados 1 se aproximasse de 0. E se isso ainda não for suficiente:

    -- Data center 1
      ID BIGINT IDENTITY(-9223372036854775808,1)
    
    -- Data center 2
      ID BIGINT IDENTITY(1,1)
    

    Ou, se você quiser manter todos os valores > 0, poderá dividir o intervalo positivo aproximadamente pela metade (você pode ser um pouco mais preciso do que isso se for mais pedante do que eu).

    -- Data center 1
      ID BIGINT IDENTITY(1,1)
    
    -- Data center 2
      ID BIGINT IDENTITY(4611600000000000000,1)
    

    Eu nem sei como dizer esse número, mas é gigantesco. E, na realidade, você teria que trabalhar muito duro em um computador muito rápido para usar todos esses valores no momento em que seu tataraneto se formar na faculdade. E se você estiver no Enterprise Edition, poderá usar a compactação de dados para não pagar o hit de todos os 8 bytes, pelo menos no data center 1, até ultrapassar 2 bilhões lá.


    Em um sistema que gerenciei, fiz isso de uma maneira um pouco diferente - tínhamos vários servidores da Web com instâncias do Express responsáveis ​​por gerar números de identificação que precisavam ser exclusivos na empresa. Portanto, apenas configuramos um gerador de sequência em cada máquina (eles não precisavam realmente armazenar o valor) usando uma coluna BIGINT IDENTITY. Tínhamos < 9 servidores, então todos eles foram semeados assim:

    -- WEBAPP0001
    ID BIGINT IDENTITY(10000000000,1)
    
    -- WEBAPP0002
    ID BIGINT IDENTITY(20000000000,1)
    
    -- WEBAPP0003
    ID BIGINT IDENTITY(30000000000,1)
    
    ...
    

    Quando os valores foram usados ​​e depois mesclados no sistema central, não apenas garantimos que não haveria duplicatas, mas também foi fácil reconhecer instantaneamente de qual servidor da Web eles vieram (o que às vezes era útil na depuração) sem introduzir nenhum composto principais requisitos. E não tínhamos preocupações de que qualquer servidor da Web pudesse gerar mais de 10 bilhões de valores.

    Muitas pessoas usariam um GUID nesse cenário, mas acho que há vários argumentos fortes contra essa abordagem.

    • 9
  2. Stuart Moore
    2012-11-23T05:37:14+08:002012-11-23T05:37:14+08:00

    Não causará problemas porque o SQL Server permite que você faça isso:

    
    create table decrement(
    id integer identity(0,-1),
    test int
    )
    
    insert into decrement (test) select number from numbers
    
    select top 10 id, test from decrement order by id asc
    go
    id  test
    ------------
    -5103   5110
    -5102   5109
    -5101   5108
    -5100   5107
    -5099   5106
    -5098   5105
    -5097   5104
    -5096   5103
    -5095   5102
    -5094   5101
    

    Mas uma boa ideia a longo prazo pode ser um problema diferente. Outros podem acabar confusos (ou seja, tive que pensar na ordem da consulta acima, pois está de cabeça para baixo ao normal). Ou o que acontece quando alguém restaura o banco de dados e propaga novamente da IDENTITYmaneira 'normal' e você tem IDs sobrepostos?

    É possível modificar seu esquema para que você tenha uma coluna 'site'? Em seguida, use o site e o ID como uma chave composta?

    • 7
  3. ypercubeᵀᴹ
    2012-11-23T07:12:58+08:002012-11-23T07:12:58+08:00

    Alguns problemas que podem surgir com esta configuração:

    Seguindo o link no comentário de @Martin Smith , valores negativos em uma coluna de identidade podem causar problemas com alguns aplicativos: Por que os designers de banco de dados não fazem as colunas de IDENTIDADE começarem com o valor mínimo em vez de 1?

    Outra questão não está relacionada aos valores serem negativos, mas decrescentes, e se a identidade também for a chave agrupada da tabela. As estruturas de árvore B são mais eficientes quando percorridas da esquerda para a direita (valores mais baixos para os mais altos) e quando as inserções são feitas no lado direito (mais alto), por exemplo, quando a chave é sempre crescente. Essa propriedade é cada vez mais importante para a chave agrupada da tabela. Veja esta postagem no blog de Kimberly Tripp sobre as melhores propriedades das chaves em cluster, especialmente sobre o número cada vez maior de .

    Com a tecla decrescente, você estará inserindo dados sempre do lado errado (esquerdo) do índice, causando a fragmentação do índice. Os efeitos podem não ser críticos para o seu caso, mas acho que você deve ter isso em mente se a identidade também for escolhida como a chave agrupada.

    Ou, como sugere @Martin, tenha o índice clusterizado também definido como DESCpara o datacenter (-1). Isso evitará qualquer um dos problemas acima com fragmentação.


    Outras opções para obter a mesma funcionalidade mantendo IDs crescentes é ter valores pares em um datacenter e ímpares no outro (ambos com incremento de +2) ou siteIDadicionado à chave primária como @Stuart sugeriu.

    • 7
  4. marc_s
    2012-11-23T05:35:19+08:002012-11-23T05:35:19+08:00

    Apenas tente! (e depois relatar aqui :-)).

    Não, não espero nenhum problema - afinal, INTo intervalo de dados do 's é de -2 bilhões a +2 bilhões - não vejo por que os números negativos devem se comportar de maneira diferente dos IDENTITYnúmeros positivos....

    • 3
  5. James Page
    2015-10-10T07:19:56+08:002015-10-10T07:19:56+08:00

    Isso soa como uma variação do particionamento de dados por chave. Um método alternativo é usar a semente e o incremento para que cada centro de dados gere valores que se intercalam, mas não colidem. Tente algo como:

    DC #1: IDENTITY (1, 2)
    DC #2: IDENTITY (2, 2)
    

    Os valores de identidade em cada tabela têm lacunas:

    DC #1 has values: 1, 3, 5, ...
    DC #2 has values: 2, 4, 6, ...
    

    Se você acha que pode ter DCs adicionais no futuro, defina o incremento para o número de DCs que você poderia ter (por exemplo, 4). Ao rolar, você teria:

    DC #1: IDENTITY ( 1, 4)
    DC #2: IDENTITY ( 2, 4)
    DC #3: IDENTITY ( 3, 4)
    DC #4: IDENTITY ( 4, 4)
    
    • 3
  6. BillThor
    2012-11-23T16:54:29+08:002012-11-23T16:54:29+08:00

    As abordagens que tenho usado são:

    • iniciar valores sequenciais para cada servidor e incrementar em um valor maior que o número previsto de servidores.
    • Use intervalos diferentes para cada servidor.
    • Use uma sequência comum para ambos os servidores.

    Cada solução tem prós e contras.

    • 1

relate perguntas

  • 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?

  • Quais são algumas maneiras de implementar um relacionamento muitos-para-muitos em um data warehouse?

  • 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

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 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

    Como selecionar a primeira linha de cada grupo?

    • 6 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +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