database tagdatabase Posso ter várias chaves primárias em uma única tabela?




runalways liquibase (10)

Boas respostas técnicas foram dadas da melhor maneira que eu posso fazer. Eu só posso adicionar a este tópico:

Se você quer algo que não é permitido / aceitável, é um bom motivo para dar um passo atrás.

  1. Entenda o núcleo do porque não é aceitável.
  2. Pesquisar mais em documentação / artigos de jornal / web e etc.
  3. Analise / revise o design atual e aponte as principais falhas.
  4. Considere e teste cada passo durante o novo design.
  5. Sempre olhe para frente e tente criar uma solução adaptativa.

Espero que ajude alguém.

Posso ter várias chaves primárias em uma única tabela?


Ter duas chaves primárias ao mesmo tempo não é possível. Mas (supondo que você não tenha bagunçado o caso com a chave composta), pode ser que você precise fazer um único atributo.

CREATE t1(
c1 int NOT NULL,
c2 int NOT NULL UNIQUE,
...,
PRIMARY KEY (c1)
);

No entanto, note que no banco de dados relacional uma 'superchave' é um subconjunto de atributos que identificam exclusivamente uma tupla ou linha em uma tabela. Uma 'chave' é uma 'superchave' que possui uma propriedade adicional que remover qualquer atributo da chave, torna essa chave não mais uma 'superchave' (ou simplesmente uma 'chave' é uma superchave mínima). Se houver mais chaves, todas elas são chaves candidatas. Selecionamos uma das chaves candidatas como chave primária. É por isso que falar sobre várias chaves primárias para uma relação ou tabela é um conflito.


Sim, é possível no SQL, mas não podemos definir mais de uma chave primária no MsAccess. Então, eu não sei sobre os outros bancos de dados.

CREATE TABLE CHAPTER (
    BOOK_ISBN VARCHAR(50) NOT NULL,
    IDX INT NOT NULL,
    TITLE VARCHAR(100) NOT NULL,
    NUM_OF_PAGES INT,
    PRIMARY KEY (BOOK_ISBN, IDX)
);

Como observado pelos outros, é possível ter chaves primárias com várias colunas. Deve-se notar, no entanto, que se você tem algumas dependências funcionais que não são introduzidas por uma chave, considere normalizing sua relação.

Exemplo:

Person(id, name, email, street, zip_code, area)

Pode haver uma dependência funcional entre id -> name,email, street, zip_code and area Mas muitas vezes um zip_code está associado a uma area e, portanto, há uma dependência funcional interna entre a zip_code -> area .

Assim, pode-se considerar dividi-lo em outra tabela:

Person(id, name, email, street, zip_code)
Area(zip_code, name)

De modo que é consistente com a terceira forma normal .


(Estive estudando muito isso)

Só pode haver 1 chave primária.
Mas você pode ter várias chaves alternativas.

Em simples este é o caso:

  • Pode haver várias chaves de Candidato (colunas mínimas, para identificar exclusivamente a linha) em uma tabela.
  • Uma das chaves candidatas é escolhida especificamente e é chamada de Chave Primária.
  • Todas as outras chaves candidatas são chamadas de chaves alternativas
  • Chave primária e alternativa podem ser chaves compostas (2 ou mais colunas)

Fontes:
https://en.wikipedia.org/wiki/Superkey
https://en.wikipedia.org/wiki/Candidate_key
https://en.wikipedia.org/wiki/Primary_key
https://en.wikipedia.org/wiki/Compound_key


Esta é a resposta tanto para a questão principal como para a questão do @ Kalmi sobre

Qual seria o sentido de ter várias colunas de geração automática?

Este código abaixo tem uma chave primária composta. Uma de suas colunas é incrementada automaticamente. Isso funcionará apenas no MyISAM. O InnoDB gerará um erro " ERROR 1075 (42000): Definição de tabela incorreta; pode haver apenas uma coluna automática e deve ser definida como uma chave ".

DROP TABLE IF EXISTS `test`.`animals`;
CREATE TABLE  `test`.`animals` (
  `grp` char(30) NOT NULL,
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `name` char(30) NOT NULL,
  PRIMARY KEY (`grp`,`id`)
) ENGINE=MyISAM;

INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');

SELECT * FROM animals ORDER BY grp,id;

Which returns:

+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+

Você só pode ter uma chave primária, mas pode ter várias colunas em sua chave primária.

Você também pode ter Índices Exclusivos em sua tabela, que funcionará um pouco como uma chave primária, pois eles aplicarão valores exclusivos e acelerará a consulta desses valores.


Uma Tabela pode ter uma Chave Primária Composta, que é uma chave primária feita de duas ou mais colunas. Por exemplo:

CREATE TABLE userdata (
  userid INT,
  userdataid INT,
  info char(200),
  primary key (userid, userdataid)
);

Atualização: aqui está um link com uma descrição mais detalhada das chaves primárias compostas.


Uma tabela pode ter várias chaves candidatas. Cada chave candidata é uma coluna ou conjunto de colunas que são UNIQUE, juntas e também NOT NULL. Assim, a especificação de valores para todas as colunas de qualquer chave candidata é suficiente para determinar que há uma linha que atenda aos critérios ou nenhuma linha.

Chaves candidatas são um conceito fundamental no modelo de dados relacionais.

É prática comum, se várias chaves estiverem presentes em uma tabela, designar uma das chaves candidatas como chave primária. Também é prática comum fazer com que qualquer chave estrangeira da tabela faça referência à chave primária, em vez de a qualquer outra chave candidata.

Eu recomendo essas práticas, mas não há nada no modelo relacional que requer a seleção de uma chave primária entre as chaves candidatas.


Uma chave primária é a chave que identifica exclusivamente um registro e é usada em todos os índices. É por isso que você não pode ter mais de um. Também é geralmente a chave usada na junção a tabelas filho, mas isso não é um requisito. O propósito real de uma PK é certificar-se de que algo permite identificar exclusivamente um registro, de modo que as alterações de dados afetem o registro correto e para que os índices possam ser criados.

No entanto, você pode colocar vários campos em uma chave primária (um PK composto). Isso fará com que suas junções sejam mais lentas (especialmente se forem campos maiores do tipo string) e seus índices maiores, mas pode remover a necessidade de fazer junções em algumas das tabelas filho, portanto, na medida em que desempenho e design, caso base. Quando você faz isso, cada campo em si não é exclusivo, mas a combinação deles é. Se um ou mais dos campos em uma chave composta também devem ser exclusivos, você precisará de um índice exclusivo. É provável, entretanto, que se um campo é único, este é um candidato melhor para o PK.

Agora, às vezes, você tem mais de um candidato para o PK. Nesse caso, você escolhe um como PK ou usa uma chave substituta (eu pessoalmente prefiro chaves substitutas para essa instância). E (isso é crítico!) Você adiciona índices exclusivos a cada uma das chaves candidatas que não foram escolhidas como PK. Se os dados precisarem ser exclusivos, ele precisará de um índice exclusivo, seja ele PK ou não. Este é um problema de integridade de dados. (Observe que isso também é verdade sempre que você usa uma chave substituta; as pessoas se envolvem em problemas com chaves substitutas porque se esquecem de criar índices exclusivos nas chaves candidatas.)

Ocasionalmente, há ocasiões em que você quer mais de uma chave substituta (que geralmente são o PK, se você as tiver). Nesse caso, o que você quer não é mais PK, é mais campos com chaves geradas automaticamente. A maioria dos bancos de dados não permite isso, mas existem maneiras de contornar isso. Primeiro, considere se o segundo campo poderia ser calculado com base na primeira chave gerada automaticamente (Field1 * -1, por exemplo) ou talvez a necessidade de uma segunda chave gerada automaticamente realmente significa que você deve criar uma tabela relacionada. Tabelas relacionadas podem estar em um relacionamento um-para-um. Você aplicaria isso adicionando o PK da tabela pai à tabela filha e, em seguida, adicionando o novo campo gerado automaticamente à tabela e, em seguida, quaisquer campos apropriados para essa tabela. Em seguida, escolha uma das duas chaves como PK e coloque um índice exclusivo na outra (o campo gerado automaticamente não precisa ser um PK). E certifique-se de adicionar o FK ao campo que está na tabela pai. Em geral, se você não tiver campos adicionais para a tabela filho, precisará examinar por que acha que precisa de dois campos gerados automaticamente.





composite-primary-key