Ao projetar tabelas, desenvolvi o hábito de ter uma coluna única e que eu crio a chave primária. Isso é alcançado de três maneiras, dependendo dos requisitos:
- Coluna de número inteiro de identidade que é incrementada automaticamente.
- Identificador exclusivo (GUID)
- Uma coluna de caracteres curtos (x) ou número inteiro (ou outro tipo numérico relativamente pequeno) que pode servir como uma coluna identificadora de linha
O número 3 seria usado para pesquisas bastante pequenas, principalmente tabelas de leitura que podem ter um código estático exclusivo de cadeia de comprimento ou um valor numérico, como um ano ou outro número.
Na maioria das vezes, todas as outras tabelas terão um número inteiro com auto incremento ou chave primária de identificador exclusivo.
A questão :-)
Recentemente, comecei a trabalhar com bancos de dados que não possuem identificador de linha consistente e as chaves primárias estão atualmente agrupadas em várias colunas. Alguns exemplos:
- data / hora / caractere
- datetime / inteiro
- datetime / varchar
- char / nvarchar / nvarchar
Existe um caso válido para isso? Eu sempre teria definido uma coluna de identidade ou identificador exclusivo para esses casos.
Além disso, existem muitas tabelas sem chaves primárias. Quais são os motivos válidos, se houver, para isso?
Estou tentando entender por que as tabelas foram projetadas como eram e me parece uma grande bagunça, mas talvez houvesse boas razões para isso.
Uma terceira pergunta para me ajudar a decifrar as respostas: nos casos em que várias colunas são usadas para compor a chave primária composta, existe uma vantagem específica para esse método versus uma chave substituta / artificial? Estou pensando principalmente em desempenho, manutenção, administração, etc.?
fonte
Respostas:
Sigo algumas regras:
Em substituto vs chave natural, refiro-me às regras acima. Se a chave natural for pequena e nunca for alterada, poderá ser usada como chave primária. Se a chave natural for grande ou provável que eu mude, uso chaves substitutas. Se não houver chave primária, eu ainda faço uma chave substituta porque a experiência mostra que você sempre adiciona tabelas ao seu esquema e deseja que você coloque uma chave primária no lugar.
fonte
Int
sVersos naturais chaves artificiais é um tipo de debate religioso entre a comunidade de bancos de dados - veja este artigo e outros com os quais ele vincula. Não sou a favor de sempre ter chaves artificiais, nem de nunca tê-las. Eu decidiria caso a caso, por exemplo:
Onde quer que chaves artificiais sejam usadas, você também deve sempre declarar restrições exclusivas nas chaves naturais. Por exemplo, use state_id, se necessário, mas é melhor declarar uma restrição exclusiva em state_code; caso contrário, você certamente terá:
fonte
Apenas um comentário extra sobre algo que geralmente é esquecido. Às vezes, não usar uma chave substituta traz benefícios nas tabelas filho. Digamos que tenhamos um design que permita executar várias empresas no mesmo banco de dados (talvez seja uma solução hospedada ou o que for).
Digamos que temos essas tabelas e colunas:
Caso esse último bit não faça sentido, faça
Invoice.CompanyId
parte de duas chaves estrangeiras, uma na tabela CostCentre e outra na tabela CostElement . A chave primária é ( InvoiceId , CompanyId ).Nesse modelo, não é possível errar e referenciar um CostElement de uma empresa e um CostCentre de outra empresa. Se uma chave substituta foi usada nos CostElement e mesas CostCentre , que seria.
Quanto menos chances de estragar, melhor.
fonte
Evito usar chaves naturais por uma simples razão - erro humano. Embora frequentemente estejam disponíveis identificadores exclusivos naturais (SSN, VIN, número da conta etc.), eles exigem que um ser humano os insira corretamente. Se você estiver usando SSNs como chave primária, alguém transporá alguns números durante a entrada de dados e o erro não será descoberto imediatamente, você terá que alterar sua chave primária.
Minhas chaves primárias são todas tratadas pelo programa de banco de dados em segundo plano e o usuário nunca as conhece.
fonte
Não há problema em criar sua chave primária a partir de vários campos, é uma chave natural .
Você pode usar uma coluna Identidade (associada a um índice exclusivo nos campos candidatos) para criar uma Chave de Substituição .
Essa é uma discussão antiga. Prefiro chaves substitutas na maioria das situações.
Mas não há desculpa para a falta de uma chave.
RE: EDIT
Sim, há muita controvérsia sobre isso: D
Não vejo nenhuma vantagem óbvia nas chaves naturais, além do fato de serem a escolha natural. Você sempre pensará em Nome, Número Social - ou algo assim - em vez de idPerson .
Chaves substitutas são a resposta para alguns dos problemas que as chaves naturais têm (propagando alterações, por exemplo).
À medida que você se acostuma a substitutos, parece mais limpo e gerenciável.
Mas no final, você descobrirá que é apenas uma questão de gosto - ou mentalidade -. As pessoas "pensam melhor" com chaves naturais e outras não.
fonte
As tabelas devem ter uma chave primária o tempo todo. Quando isso não acontecer, deveria ter sido um campo de AutoIncremento.
Às vezes, as pessoas omitem a chave primária porque transferem muitos dados e isso pode retardar (dependendo do banco de dados) o processo. MAS, deve ser adicionado depois.
Algum comentário sobre a tabela de links , isso é correto, é uma exceção, mas os campos devem ser FK para manter a integridade e, em alguns casos, esses campos também podem ser chaves primárias se a duplicação de links não for autorizada ... forma simples, porque a exceção é algo frequentemente na programação, a chave primária deve estar presente para manter a integridade dos seus dados.
fonte
Além de todas essas boas respostas, só quero compartilhar um bom artigo que acabei de ler: O grande debate sobre chaves primárias .
Apenas para citar alguns pontos:
O desenvolvedor deve aplicar algumas regras ao escolher uma chave primária para cada tabela:
Chaves naturais (tendem a) violam as regras. Chaves substitutas cumprem as regras. (É melhor você ler esse artigo, vale a pena!)
fonte
O que há de especial na chave primária?
Qual é o objetivo de uma tabela em um esquema? Qual é o propósito de uma chave de uma tabela? O que há de especial na chave primária? As discussões em torno das chaves primárias parecem não entender o ponto em que a chave primária faz parte de uma tabela e essa tabela faz parte de um esquema. O que é melhor para a tabela e os relacionamentos da tabela deve orientar a chave usada.
As tabelas (e os relacionamentos das tabelas) contêm fatos sobre as informações que você deseja registrar. Esses fatos devem ser independentes, significativos, facilmente compreendidos e não contraditórios. Da perspectiva do design, outras tabelas adicionadas ou removidas de um esquema não devem impactar a tabela em questão. Deve haver um objetivo de armazenar os dados relacionados apenas às informações em si. Entender o que é armazenado em uma tabela não deve exigir a realização de um projeto de pesquisa científica. Nenhum fato armazenado para a mesma finalidade deve ser armazenado mais de uma vez. As chaves são uma parte ou parte das informações que estão sendo registradas, únicas, e a chave primária é a chave especialmente designada que deve ser o ponto de acesso principal da tabela (ou seja, deve ser escolhida para consistência e uso dos dados, não apenas inserir desempenho).
Dizia-se que as chaves primárias deveriam ser tão pequenas quanto necessárias. Eu diria que as chaves devem ter apenas o tamanho necessário. A adição aleatória de campos sem sentido a uma tabela deve ser evitada. É ainda pior criar uma chave de um campo sem sentido adicionado aleatoriamente, especialmente quando ela destrói a dependência de junção de outra tabela na chave não primária. Isso é razoável apenas se não houver boas chaves candidatas na tabela, mas essa ocorrência certamente é um sinal de um design de esquema ruim se usado para todas as tabelas.
Também foi dito que as chaves primárias nunca deveriam mudar, pois a atualização de uma chave primária sempre deveria estar fora de questão. Mas atualização é o mesmo que excluir, seguido de inserção. Por essa lógica, você nunca deve excluir um registro de uma tabela com uma chave e adicionar outro registro com uma segunda chave. Adicionar a chave primária substituta não remove o fato de que a outra chave na tabela existe. A atualização de uma chave não primária de uma tabela pode destruir o significado dos dados se outras tabelas dependem desse significado por meio de uma chave substituta (por exemplo, uma tabela de status com uma chave substituta cuja descrição do status foi alterada de 'Processado' para 'Cancelado definitivamente corromperia os dados). O que sempre deve estar fora de questão é destruir o significado dos dados.
Dito isso, sou grato pelos muitos bancos de dados mal projetados que existem hoje nas empresas (gigantes sem sentido-substitutos-com-dados-corrompidos-1NF), porque isso significa que há uma quantidade infinita de trabalho para pessoas que entendem o design adequado do banco de dados . Mas, no lado triste, às vezes me faz sentir como Sísifo, mas aposto que ele tinha um total de 401k (antes do acidente). Fique longe de blogs e sites para perguntas importantes sobre o design do banco de dados. Se você estiver projetando bancos de dados, procure Data CJ. Você também pode fazer referência ao Celko para SQL Server, mas apenas se segurar o nariz primeiro. No lado do Oracle, consulte Tom Kyte.
fonte
Uma chave natural, se disponível, geralmente é a melhor. Portanto, se datetime / char identifica exclusivamente a linha e as duas partes são significativas para a linha, isso é ótimo.
Se apenas a data e o horário forem significativos e o caractere for adornado para torná-lo único, você pode também optar por um campo de identificação.
fonte
Aqui está minha regra de ouro em que me decidi após mais de 25 anos de experiência em desenvolvimento.
A chave primária é usada pelo banco de dados para fins de otimização e não deve ser usada pelo seu aplicativo para nada além de identificar uma entidade específica ou relacionada a uma entidade específica.
Sempre ter uma chave primária de valor único torna a execução de UPSERTs muito simples.
Use índices adicionais para suportar chaves com várias colunas que tenham significado no seu aplicativo.
fonte
Chaves naturais versus chaves artificiais para mim são uma questão de quanto da lógica de negócios você deseja em seu banco de dados. O número do Seguro Social (SSN) é um ótimo exemplo.
"Cada cliente no meu banco de dados terá e deve ter um SSN." Bam, pronto, faça dela a chave primária e pronto. Lembre-se de quando as regras da sua empresa mudam, você está queimado.
Eu não gosto de chaves naturais, devido à minha experiência em alterar as regras de negócios. Mas se você tem certeza de que não vai mudar, isso pode impedir algumas associações críticas.
fonte
Suspeito que a terapia de jornal enrolada de Steven A. Lowe seja necessária para o designer da estrutura de dados original.
Como um aparte, os GUIDs como chave primária podem ser prejudiciais ao desempenho. Eu não recomendaria.
fonte
Você deve usar uma chave primária 'composta' ou 'composta' que compreende vários campos.
Esta é uma solução perfeitamente aceitável, clique aqui para obter mais informações :)
fonte
Eu também sempre uso uma coluna de ID numérica. No oracle, eu uso o número (18,0) sem motivo real acima do número (12,0) (ou seja, um int e não um longo), talvez eu não queira me preocupar em obter alguns bilhões de linhas em o db!
Também incluo uma coluna criada e modificada (tipo timestamp) para rastreamento básico, onde parece útil.
Não me importo de definir restrições exclusivas em outras combinações de colunas, mas gosto muito do meu id, criado, modificado pelos requisitos da linha de base.
fonte
Eu procuro chaves primárias naturais e as uso sempre que posso.
Se nenhuma chave natural puder ser encontrada, prefiro um GUID a um INT ++ porque o SQL Server usa árvores e é ruim sempre adicionar chaves ao final nas árvores.
Nas tabelas que são acoplamentos muitos para muitos, uso uma chave primária composta das chaves estrangeiras.
Como tenho a sorte de usar o SQL Server, posso estudar os planos e estatísticas de execução com o criador de perfil e o analisador de consultas e descobrir como minhas chaves estão executando com muita facilidade.
fonte
Eu sempre uso um número automático ou um campo de identidade.
Eu trabalhei para um cliente que usava o SSN como chave primária e, por causa dos regulamentos da HIPAA, fui forçado a mudar para um "MemberID" e isso causou muitos problemas ao atualizar as chaves estrangeiras nas tabelas relacionadas. Manter um padrão consistente de uma coluna de identidade me ajudou a evitar um problema semelhante em todos os meus projetos.
fonte
Todas as tabelas devem ter uma chave primária. Caso contrário, o que você tem é um HEAP - isso, em algumas situações, pode ser o que você deseja (carga pesada de inserção quando os dados são replicados por meio de um broker de serviço para outro banco de dados ou tabela, por exemplo).
Para tabelas de pesquisa com um baixo volume de linhas, você pode usar um código 3 CHAR como chave primária, pois isso ocupa menos espaço que um INT, mas a diferença de desempenho é insignificante. Fora isso, eu sempre usaria uma INT, a menos que você tenha uma tabela de referência que talvez tenha uma chave primária composta composta de chaves estrangeiras de tabelas associadas.
fonte
Se você realmente quiser ler todas as idas e vindas deste debate antigo, faça uma pesquisa por "chave natural" no Stack Overflow. Você deve receber páginas de resultados.
fonte
Os GUIDs podem ser usados como uma chave primária, mas você precisa criar o tipo certo de GUID para que ele funcione bem.
Você precisa gerar GUIDs COMB. Um bom artigo sobre isso e as estatísticas de desempenho são O custo dos GUIDs como chaves primárias .
Também algum código na criação de GUIDs COMB no SQL está em Uniqueidentifier vs identity ( archive ) .
fonte
Fazemos muitas junções e as chaves primárias compostas acabaram de se tornar um problema de desempenho. Um simples int ou long resolve muitos problemas, mesmo que você esteja introduzindo uma segunda chave candidata, mas é muito mais fácil e compreensível ingressar em um campo do que em três.
fonte
Serei sincero sobre minha preferência por chaves naturais - use-as sempre que possível, pois elas facilitarão muito sua vida na administração de bancos de dados. Estabeleci em nossa empresa um padrão de que todas as tabelas têm as seguintes colunas:
SUSER_SNAME()
em T-SQL))O ID da linha possui uma chave exclusiva por tabela e, em qualquer caso, é gerado automaticamente por linha (e as permissões impedem qualquer pessoa de editá-lo) e é razoavelmente garantido para ser exclusivo em todas as tabelas e bancos de dados. Se algum sistema ORM precisar de uma única chave de ID, essa é a única a ser usada.
Enquanto isso, o PK real é, se possível, uma chave natural. Minhas regras internas são algo como:
EventId, AttendeeId
)Então, idealmente, você acaba com um PK natural, legível por humanos e memorável, e um GUID de uma ID por tabela amigável para ORM.
Advertência: os bancos de dados que mantenho tendem a 100.000s de registros em vez de milhões ou bilhões; portanto, se você tiver experiência em sistemas maiores que contraindiquem meus conselhos, fique à vontade para me ignorar!
fonte
GUID
eINT
SKs para tabelas sem chave natural forte?