Vamos supor que você tenha uma tabela groups
e uma tabela item
. Cada item pertence a exatamente um grupo. É uma parte inerente desse grupo. Um item não pode existir fora de um grupo e não pode ser movido para outro grupo.
Ao tentar decidir sobre uma chave primária para a item
tabela, o que devo usar?
Devo criar uma chave serial global artificial como esta:
CREATE TABLE items
(
item serial PRIMARY KEY,
group integer NOT NULL REFERENCES groups(group),
);
... ou devo usar uma chave composta e uma série de itens por grupo como esta:
CREATE TABLE items
(
group integer NOT NULL REFERENCES groups(group),
item integer NOT NULL,
PRIMARY KEY(group, item)
);
A razão pela qual estou mais inclinado para a segunda solução é que o URL da postagem sempre mostrará o grupo e o item, portanto, faz sentido ter os dois como a chave primária composta. No caso da primeira solução, a URL contém informações supérfluas porque o ID do grupo já pode ser deduzido apenas do ID do item. A estrutura da URL é fornecida, no entanto, e não pode ser alterada.
A desvantagem da segunda solução é que você precisa gerenciar uma série por grupo (ou seja, cada número inteiro de item deve começar em 0 para cada grupo).
O que é melhor em termos de melhores práticas, normalização e desempenho? Ou é simplesmente uma questão de gosto?
Muito disso é uma questão de gosto e estilo. E mais importante: requisitos específicos e convenções consistentes. No entanto, existem boas razões para este conselho genérico:
Se você tiver um
item_id
, é melhor torná-lo único e, idealmente, uma chave primária substituta sem nenhum significado específico para o próprio número. Isso é barato e versátil. Periódicos por grupo (nãoper-row
) são normalmente caros e um esforço inútil. Se você deseja uma numeração sem lacunas por grupo, adicione algum tipo de coluna de classificação ou userow_number()
em uma exibição. E não confie em uma numeração sem lacunas se puder evitá-la. Mais cedo ou mais tarde, você terá que excluir ou mover itens.É conveniente para a manutenção ter uma chave primária de coluna única que segue uma convenção de nomenclatura (a menos que você tenha um pk natural óbvio).
Não use
group
como identificador. É uma palavra reservada . Mesmo que sejam apenas nomes simbólicos.Se você tiver consultas por
grp_id
, adicione outro índice:Você pode querer torná-lo uma
UNIQUE INDEX
documentação, mas isso é redundante, pois jáitem_id
é exclusivo. Com duas colunas inteiras, um índice de várias colunas é tão grande quanto um índice apenasgrp_id
e parece haver casos de uso em que você precisa dessas duas colunas, portanto, há a chance de um índice de cobertura. Este deve ser o ideal. Mais justificativa aqui:um índice composto também é bom para consultas no primeiro campo?