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 / 6108
Accepted
Jack Douglas
Jack Douglas
Asked: 2011-09-24 13:25:40 +0800 CST2011-09-24 13:25:40 +0800 CST 2011-09-24 13:25:40 +0800 CST

Toda tabela deve ter uma chave primária substituta/artificial de campo único?

  • 772

Entendo um benefício das chaves substitutas/artificiais em geral - elas não mudam e isso pode ser muito conveniente. Isso é verdade, sejam campos únicos ou múltiplos - desde que sejam 'artificiais'.

No entanto, às vezes parece ser uma questão de política ter um campo inteiro de incremento automático como a chave primária de cada tabela. É sempre a melhor ideia ter uma chave de campo único e por que (ou por que não)?

Para ser claro, esta questão não é sobre artificial versus natural - mas sobre se todas as chaves artificiais devem ser de um único campo

database-design primary-key
  • 3 3 respostas
  • 6280 Views

3 respostas

  • Voted
  1. Joel Brown
    2011-09-24T17:25:26+08:002011-09-24T17:25:26+08:00

    Vou dizer que não, nem sempre, mas na maioria das vezes sim. .

    Estas são algumas circunstâncias em que você não precisa de uma chave substituta ou artificial:

    • Tabelas de interseção puras . Se não houver risco de a interseção ser o alvo de uma chave estrangeira e se houver pouco ou nenhum risco de a interseção atrair atributos independentes (ou seja, algo diferente de FK para as duas tabelas pai), você poderá usar a combinação de FKs como PK com razoável confiança.
    • Tabelas de consulta com chaves de negócios estáticas . Se você tiver uma
      tabela de pesquisa com uma chave de negócios exclusiva que é fixada externamente ao seu
      negócio e que tem chance zero de mudar para qualquer
      finalidade prática, usar a chave de negócios diretamente pode tornar
      as coisas mais simples. Um exemplo pode ser uma lista de códigos de estado ou província
      ou uma lista de números padrão ANSI, etc.
    • Tabelas contendo dados consolidados de várias fontes independentes . Se o seu sistema tiver muitas fontes de dados que devem ser agrupadas em uma única tabela, digamos na matriz, às vezes você precisará de uma chave composta que inclua o valor da chave do sistema de origem e um código indicando qual era o sistema de origem.

    Há também algumas situações em que a antiga chave substituta de número inteiro crescente monotonicamente não é ideal. Você pode ter chaves que são substitutos alfanuméricos. Estes podem incluir:

    • Situações em que você precisa mesclar dados de várias fontes independentes. Para evitar colisões de chaves, você pode usar GUIDs em vez de chaves IDENTITY.
    • Situações em que você é forçado a usar representações de teclas não numéricas. Digamos que você tenha um banco de dados de placas. Sua chave pode ser o valor alfanumérico em vez de um número puro.
    • Situações em que algum requisito externo força você a aplicar compactação ao seu valor de chave. Em vez de usar 10 dígitos para um int32, você pode usar seis dígitos de base 36.

    Por que na maioria das vezes sim? A resposta mais fundamental para essa pergunta é que é um inferno se você precisar modificar um valor de chave primária em qualquer tabela. Como quase tudo que um usuário pode ver ou tocar está sujeito a uma atualização em algum momento, usar um valor de chave visível é convidar o inferno. Usar uma chave substituta evitará que você caia nessa armadilha.

    Dito isso, lembre-se que há espaço para a YAGNI aplicar esse conceito. Você não precisa forçar tabelas de código com chaves de IDENTIDADE em todos os cantos do seu esquema, apenas no caso de alguém decidir que o símbolo de gênero masculino em sua tabela de funcionários precisa mudar de M para X ou algo bobo.

    • 29
  2. gbn
    2011-09-24T22:46:31+08:002011-09-24T22:46:31+08:00

    "depende"

    Sim: os campos substitutos IDENTITY/AUTONUMBER são bons quando a chave natural é ampla e não numérica. Nota: isso pressupõe a fusão de "PK" e índice clusterizado que ocorre por padrão no SQL Server e Sybase, etc.

    Não: muitas/muitas tabelas quando as 2 chaves pai são suficientes. Ou quando a chave natural é curta e de tamanho fixo, por exemplo, código da moeda

    Claro, um ORM inteligente (leia-se: (n)Hibernate) pode superar essas regras...

    Editar: lendo a pergunta novamente

    Uma tabela muitos/muitos com 2 chaves pai substitutas terá uma coluna PK múltipla.
    No entanto, não precisa de outra coluna substituta.

    Se uma tabela tiver uma chave substituta (IDENTITY, etc.), ela não precisará ser de várias colunas.

    Você pode ter uma superchave que inclua o substituto, mas isso seria para impor outras regras (por exemplo, subtipos )

    • 15
  3. Best Answer
    Jack Douglas
    2011-09-24T13:28:12+08:002011-09-24T13:28:12+08:00

    Não.

    Eu diria que certamente há casos em que as chaves de campo único são inferiores às chaves compostas, pelo menos para fins de chaves estrangeiras . Isso não quer dizer que você não deva ter uma chave substituta de campo único também, se preferir, mas eu pessoalmente prefiro que a chave que é usada com mais frequência como alvo de uma chave estrangeira seja chamada de chave primária

    Vou tentar ilustrar meu ponto nos seguintes exemplos, nos quais:

    • brandé marca de carro, por exemplo, Ford, Toyota etc
    • dealeré uma concessionária física, vinculada a uma marca (por exemplo, uma concessionária Ford que vende apenas Fords)
    • modelé o tipo de carro, por exemplo, Ford Focus, Ford Fiesta, etc.
    • stocké a contagem atual de carros no pátio para cada concessionária

    Se criarmos uma chave substituta de campo único para dealere modelda seguinte forma:

    create table brand( brand_id integer primary key );
    
    create table dealer( dealer_id integer primary key, 
                         brand_id integer references brand )
    
    create table model( model_id integer primary key, 
                        brand_id integer references brand )
    
    create table stock( model_id integer references model, 
                        dealer_id integer references dealer, 
                        quantity integer,
                          primary key(model_id, dealer_id) )
    

    então é possível inserir uma linha stockque liga um Ford dealera um modelo "Toyota". Adicionar brand_id references branda stockapenas piora o problema. Por outro lado, se mantivermos a chave estrangeira como parte da chave primária da seguinte forma:

    create table brand( brand_id integer primary key );
    
    create table dealer( brand_id integer references brand, 
                         dealer_id integer, 
                           primary key(brand_id, dealer_id) )
    
    create table model( brand_id integer references brand, 
                        model_id integer, 
                          primary key(brand_id, model_id) )
    
    create table stock( brand_id integer, 
                        model_id integer, 
                        dealer_id integer, 
                        quantity integer,
                          primary key(brand_id, model_id, dealer_id),
                          foreign key(brand_id, model_id) references model,
                          foreign key(brand_id, dealer_id) references dealer )
    

    agora, a regra de que as concessionárias "Ford" só podem estocar carros "Ford" é aplicada naturalmente pelo modelo.

    Observe que no exemplo 'chaves compostas', dealer_idpode ou não ser único, de acordo com a preferência. Não precisa ser único (ou seja, uma chave alternativa), mas muito pouco se perde ao fazê-lo (talvez um pouco de espaço de armazenamento) e pode ser muito útil, então é assim que costumo configurá-lo, por exemplo:

    create table dealer( brand_id integer references brand, 
                         dealer_id serial unique, 
                           primary key(brand_id, dealer_id) )
    
    • 12

relate perguntas

  • Quais são as desvantagens de usar UUID ou GUID como chave primária?

  • É melhor armazenar os valores calculados ou recalculá-los a pedido? [duplicado]

  • Armazenar vs calcular valores agregados

  • Chaves primárias de caractere x número inteiro

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

Sidebar

Stats

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

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

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

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

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 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
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +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
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +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
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +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