tagdatabase - runalways liquibase




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

(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

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


Algumas pessoas usam o termo "chave primária" para significar exatamente uma coluna inteira que obtém seus valores gerados por algum mecanismo automático. Por exemplo, AUTO_INCREMENT no MySQL ou IDENTITY no Microsoft SQL Server. Você está usando a chave primária nesse sentido?

Se assim for, a resposta depende da marca do banco de dados que você está usando. No MySQL, você não pode fazer isso, você recebe um erro:

mysql> create table foo (
  id int primary key auto_increment, 
  id2 int auto_increment
);
ERROR 1075 (42000): Incorrect table definition; 
there can be only one auto column and it must be defined as a key

Em algumas outras marcas de banco de dados, você pode definir mais de uma coluna de geração automática em uma tabela.


Chave Primária é uma notação muito infeliz, devido à conotação de "Primária" e a associação subconsciente em conseqüência com o Modelo Lógico. Evito, assim, usá-lo. Em vez disso, refiro-me à Chave Substituta do Modelo Físico e à (s) Chave (s) Natural (ais) do Modelo Lógico.

É importante que o Modelo Lógico de cada Entidade tenha pelo menos um conjunto de "atributos de negócios" que compreendem uma Chave para a entidade. Boyce, Codd, Date et al referem-se a estes no Modelo Relacional como Chaves Candidatas. Quando, então, construímos tabelas para essas Entidades, suas Chaves Candidatas se tornam Chaves Naturais nessas tabelas. É somente através dessas chaves naturais que os usuários são capazes de identificar exclusivamente as linhas nas tabelas; como chaves substitutas sempre devem ser ocultadas dos usuários. Isso ocorre porque as Chaves Substitutas não têm significado comercial.

No entanto, o Modelo Físico de nossas tabelas será, em muitos casos, ineficiente sem uma Chave Substituta. Lembre-se de que colunas não abrangidas por um índice não clusterizado só podem ser encontradas (em geral) por meio de uma pesquisa de chave no índice clusterizado (ignorar tabelas implementadas como heaps por um momento). Quando a (s) chave (s) natural (is) natural (is) estão (ão) largas, isso (1) aumenta a largura de nossos nós de folha não agrupados, aumentando os requisitos de armazenamento e acessos de leitura para buscas e varreduras desse índice não agrupado; e (2) reduz o fan-out de nosso índice clusterizado, aumentando a altura do índice e o tamanho do índice, novamente aumentando as exigências de leitura e armazenamento para nossos índices clusterizados; e (3) aumenta os requisitos de cache para nossos índices clusterizados. perseguindo outros índices e dados fora do cache.

É aí que uma pequena Chave Substituta, designada para o RDBMS como "Chave Primária", é benéfica. Quando configurada como chave de armazenamento em cluster, de modo a ser usada para pesquisas de chave no índice clusterizado a partir de índices não agrupados e pesquisas de chave estrangeira a partir de tabelas relacionadas, todas essas desvantagens desaparecem. Nossas expansões de índice agrupadas aumentam novamente para reduzir a altura e o tamanho do índice clusterizado, reduzir a carga de cache para nossos índices clusterizados, diminuir as leituras ao acessar dados por meio de qualquer mecanismo (pesquisa de índice, busca de índice, pesquisa de chave não agrupada ou pesquisa de chave estrangeira) e diminuir os requisitos de armazenamento para os índices clusterizados e não clusterizados de nossas tabelas.

Observe que esses benefícios ocorrem apenas quando a chave substituta é pequena e a chave de cluster. Se um GUID for usado como a chave de cluster, a situação geralmente será pior do que se a menor chave natural disponível tivesse sido usada. Se a tabela estiver organizada como um heap, o RowID de 8 bytes (heap) será usado para pesquisas de chave, o que é melhor do que um GUID de 16 bytes, mas com um desempenho menor do que um inteiro de 4 bytes.

Se um GUID precisar ser usado devido a restrições de negócios, a busca por uma chave de cluster melhor vale a pena. Se, por exemplo, um identificador de site pequeno e um "número de sequência de sites" de 4 bytes for viável, esse design poderá fornecer um desempenho melhor do que um GUID como Chave substituta.

Se as conseqüências de um heap (hash join talvez) fizerem com que o armazenamento preferencial, em seguida, os custos de uma chave de cluster mais ampla precisam ser equilibrados na análise de trade-off.

Considere este exemplo ::

ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

onde a tupla " (P_Id, LastName) " requer uma restrição de exclusividade e pode ser um longo Unicode LastName mais um inteiro de 4 bytes, seria desejável para (1) declarativamente aplicar essa restrição como " ADICIONAR CONSTRAINT pk_PersonID UNIQUE NONCLUSTERED (P_Id , LastName) "e (2) declaram separadamente uma pequena Chave substituta como sendo a" Chave primária "de um índice clusterizado. Vale a pena notar que Anita possivelmente só deseja adicionar o Sobrenome a esta restrição, a fim de tornar esse campo coberto, o que é desnecessário em um índice clusterizado, porque TODOS os campos são cobertos por ele.

A capacidade do SQL Server de designar uma Chave Primária como não clusterizada é uma circunstância histórica infeliz, devido a uma conflação do significado "chave natural ou candidata preferida" (do Modelo Lógico) com o significado "chave de pesquisa no armazenamento" do Físico Modelo. Meu entendimento é que, originalmente, o SYBASE SQL Server sempre usava um RowID de 4 bytes, fosse em um heap ou em um índice clusterizado, como a "chave de consulta no armazenamento" do Modelo Físico.


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 .


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)
);

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.


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.


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.







composite-primary-key