O que é uma maneira eficaz de rotular colunas em um banco de dados?

30

Eu costumava rotular colunas em meus bancos de dados como este:

user_id
user_name
user_password_hash

Para evitar conflitos ao ingressar em duas tabelas, aprendi um pouco mais sobre como aliasar tabelas e parei de fazer isso.

O que é uma maneira eficaz de rotular colunas em um banco de dados? Por quê?

Thomas O
fonte
Qual banco de dados? Como eu rotulo no Oracle é diferente da maioria dos outros bancos de dados, devido ao seu recurso de selecionar automaticamente colunas para basear as junções se os nomes corresponderem.
Joe
@ Joe, Bem, eu sempre usei MySQL e SQLite3, mas deve aplicar-se à maioria dos outros bancos de dados.
Thomas O
@joe nunca percebeu que o Oracle é diferente. Você pode dar um link?
bernd_k
@bernd_k: Adicionei alguns links à minha resposta abaixo
Joe

Respostas:

33

No seu caso, o usuário do prefixo é redundante. Nós (os desenvolvedores encarregados) sabemos que esse é o usuário da tabela; então, por que adicionar user_prefixo na frente de cada campo?

O que eu sugeriria é fazê-lo com uma abordagem mais natural.

Quais são as características de uma Pessoa: Sobrenome, Nome, Data de Nascimento, Nacionalidade, etc ...

Quais são as características de um carro: modelo, ano, cor, energia, etc ...

Sua coluna deve ter o nome o mais natural possível, isso tornaria o esquema mais claro para todos, para você e para os que vierem depois de você. Isso também é chamado de fase de manutenção, e tudo o que você pode fazer para facilitar a manutenção geralmente vale a pena.

Spredzy
fonte
11
Sim, isso me enfurece quando as pessoas fazem isso. Além disso, quando eles chamam toda a sua mesa de tbl_whatever.
Gaius
Isso também é relevante para o conceito de "Palavras de classe" e parece haver algum debate na comunidade quando as palavras de classe são e não são apropriadas. (uma palavra de classe é uma ferramenta para: Identificar uma categoria ou classificação distinta de dados, Delinear o tipo de dados que está sendo descrito pelo nome dos dados e Descrever a classificação principal de dados associada a um elemento de dados.)
Jon Schoning,
17

Além do comentário da Spredzy, rotule suas chaves primárias da mesma forma (ID) para que, ao escrever consultas em tempo real, você possa se lembrar facilmente (u.ID = c.ID) em vez de precisar procurar "Era o countryID , country_ID, countries_ID, countriesID,? "

David Hall
fonte
5
Certa vez, trabalhei em um banco de dados onde o DBA decidiu usar ID em algumas tabelas e id em outras e tínhamos o MySQL configurado para diferenciar maiúsculas de minúsculas ... momentos divertidos!
Toby
6
Geralmente usamos tablename.tablename_id. Por exemplo, car.car_id; person.person_id. Nomes singulares para tabelas.
glasnt
@glasnt decisão inteligente.
Garik
11
Essa é realmente uma péssima idéia e você perderá a capacidade de usar a USINGcláusula SQL (é contra as especificações).
Evan Carroll
9

Eu não poderia concordar mais com o adendo de David Hall à excelente resposta de Spredzy. Simples e natural é o caminho a percorrer. A confusão de tabelas não deve ser um problema se você nomear tabelas naturalmente também.

Não faz sentido ter users.user_id e cars.car_id quando você pode ter users.id e cars.id

bsoist
fonte
7

Eu diria que, em um esquema de banco de dados, cada coluna deve ter um nome exclusivo, entre tabelas. Há várias razões para isso:

  • Do ponto de vista da modelagem: você começa com uma sopa de atributos e a normaliza em tabelas. Com o tempo, você pode desnormalizar ou normalizar ainda mais ou introduzir visualizações ou visualizações materializadas ou introduzir novas tabelas. Isso nunca é um problema se todos os nomes de colunas forem exclusivos.

  • Você pode usar esta junção sintaxe: a JOIN b USING (a_id) JOIN c USING (a_id). Muito conveniente e também ajuda com o seguinte ponto.

  • Se você executar consultas com muitas associações ou criar visualizações materializadas SELECT *, nunca terá (bem, talvez raramente) um conflito. Pense sobre como ingressar person.name, product.name, country.name, etc. Urgh.

  • Em geral, se você tiver grandes consultas, é difícil acompanhar o que idsignifica em qualquer lugar.

Peter Eisentraut
fonte
Como você nomearia a coluna para um nome de funcionário e um nome de site, por exemplo? Como você evitaria a redundância da coluna do rótulo de nome?
Spredzy
@ Spredzy: Eu iria apenas com a redundância.
Peter Eisentraut
11
A resposta para essas preocupações: aliases.
Jon de Todos os Negócios
7

Vamos ver, com o seu exemplo, será algo como isto:

USERS
----
id
username,
password
registration_date

Eu uso o nome da tabela em maiúsculas. Isso me permite identificar a tabela facilmente. As colunas que acabei de nomear são cada uma para o que elas representam. Tento não usar números ou incluir qualquer prefixo ou sufixo. Isso tornará as consultas simples e bem diretas.

BTW, acho que você deve encontrar um estilo que você goste e ficar com ele. Se você alterá-lo com freqüência, terá um esquema de banco de dados mais confuso.

eiefai
fonte
+1 em "encontre um estilo que você goste e fique com ele". A consistência é melhor do que cumprir exatamente com um padrão específico (embora se você ainda não escolheu um padrão, alguns são melhores que outros).
Jon de Todos os Negócios
5

Como os outros, recomendo que você não inclua o nome da tabela como parte da coluna. A menos que você tenha centenas de tabelas, todas com nomes de colunas semelhantes: se você tiver várias dezenas de tabelas, todas com uma coluna denominada ID, prefira-as com o nome da tabela.

Recentemente, saí de uma empresa em que um dos desenvolvedores preferiu prefixar as colunas chave primária e chave estrangeira com pk e fk. Isso levou a algumas abominações nas quais as colunas começaram com pkfk (geralmente uma chave primária composta com base em 2 colunas, das quais uma coluna era uma chave estrangeira para outra tabela).

Tangurena
fonte
4
isso conta como um fk_cluster?
quer
5

Estou trabalhando em um ambiente em que cada nome de coluna começa com um prefixo derivado do nome da tabela, não é minha invenção, mas estou muito feliz com isso.

Idealmente, os nomes das colunas são exclusivos em todas as tabelas do banco de dados.

Algumas observações:

  • precisamos apenas de aliases de tabela, quando as tabelas são unidas várias vezes em uma instrução select
  • evita algumas falhas ao copiar trechos de código, porque os nomes das colunas devem ser adaptados ao nome da tabela
  • ajuda a mostrar para qual tabela uma coluna de chave estrangeira aponta

Idéias gerais: O mais importante é a consistência de cada uma das convenções de nomenclatura: - singular vs. plural (ok que se aplica a tabelas e não colunas) - identifique chaves primárias e estrangeiras (elas constroem a estrutura versus o conteúdo do banco de dados) - seja consistente quando você armazena strings e uma variante curta da mesma string - seja consistente com sinalizadores, status etc.

bernd_k
fonte
3

Concordo com a resposta de Spredzy, mas acrescentaria que, por uma questão de preferência, eu usaria camelCase em vez de under_score.

nome, sobrenome etc.

Toby
fonte
2
-1 porque o CamelCase não funciona em todos os sistemas de banco de dados e você não especificou um sistema de banco de dados. Por exemplo, suas más notícias para usar o CamelCase no Oracle (seria necessário o uso de aspas duplas para criá-lo, mas a partir de então, todos os que acessassem teriam que passar por bastidores para acessá-lo / usá-lo). Que pesadelo.
ScottCher
@ ScottCher - Eu não sabia que ele não funciona no Oracle, mas não sou um DBA do Oracle. Eu teria pensado que seria dado que os nomes das colunas precisam primeiro estar em conformidade com as regras estabelecidas pelo DBS em questão.
Toby
3

No caso do Oracle, convém não nomear as colunas 'id' ou 'name' ou qualquer coisa genérica.

O problema é que, por padrão, em versões mais antigas , o Oracle tentará ingressar em tabelas com base em nomes de colunas semelhantes; portanto, se eu nomeei tudo bem, também acabei especificando a cláusula de associação padrão entre minhas tabelas.

Mas mesmo que você não esteja usando o Oracle, não escolhendo nomes que aparecem em várias tabelas, também significa que você não precisará passar pelo problema de criar aliases toda vez que precisar fazer uma seleção em duas tabelas:

SELECT
  instrument.name as instrument_name,
  instrument.abbr as instrument_abbr,
  source.name     as source_name,
  source.abbr     as source_abbr,
  ...
FROM ...

Portanto, se a seleção de várias tabelas for a norma, os nomes mais longos das colunas economizarão a digitação. (se você estiver usando apenas uma tabela por vez ... você realmente precisa de um banco de dados relacional?)

... e salvar a digitação nos leva a outro problema no Oracle - pelo menos no 8i (a versão atual quando participei dos cursos de Oracle SQL Tuning e Data Modeling), o cache dos planos de execução é baseado apenas nos primeiros tantos caracteres do consulta (não se lembra do valor exato ... 1024?), portanto, se você tiver consultas que variam apenas de alguma forma no final da cláusula where e uma lista realmente longa de colunas que você está extraindo, pode ter um desempenho atingido, pois não pode armazenar em cache o plano de execução corretamente.

A Oracle tinha um guia para selecionar o que eles afirmam ser bons nomes de tabelas e colunas, que é basicamente um guia para remover letras até que tenham entre 5 e 8 caracteres, mas eu nunca me importei muito com isso.

...

Como as coisas vão além disso:

  • as colunas são sempre singulares (as tabelas são sempre plurais)
  • todos os nomes são minúsculos, caso haja algo que diferencia maiúsculas de minúsculas
  • como resultado acima, use sublinhados em vez de estojo de camelo.

update : para aqueles que não estão familiarizados com o comportamento de junção do Oracle, consulte o último exemplo em Mastering Oracle SQL: Join Conditions , em que ele menciona:

O que aconteceu? O motivo está no fato de que, além de supplier_id, essas duas tabelas têm outro par de colunas com um nome comum. Essa coluna é o nome. Portanto, quando você solicita uma junção natural entre o fornecedor e as tabelas de peças, a junção ocorre não apenas igualando a coluna supplier_id das duas tabelas, mas também a coluna de nome das duas tabelas. Como nenhum nome de fornecedor é igual a um nome de peça desse mesmo fornecedor, nenhuma linha é retornada pela consulta.

Sob 'sintaxe de junção antiga' (8i e anterior), 'NATURAL JOIN' era o comportamento de junção padrão, e acredito que ainda será se você não especificar uma condição de junção. Uma vez que 'NATURAL JOIN' era uma opção oficial no 9i, a recomendação geral era não usá-lo , porque a má nomeação de colunas pode estragar tudo, o que eu estou defendendo por bons nomes de colunas.

Joe
fonte
4
Você está se referindo a "Junções naturais" no seu segundo parágrafo? Nesse caso, SHUDDER ... Sempre que possível, você deve especificar como deseja que seu sistema de banco de dados ingresse em suas tabelas. Deixar para o banco de dados decidir pode produzir resultados inesperados / inconsistentes. Além disso, as junções naturais são limitadas às junções entre duas tabelas e, portanto, são relativamente limitadas em sua usabilidade.
ScottCher 4/11/21
2
JOIN NATURAL nunca foi o padrão. Se nenhuma junção explícita for / foi fornecida, uma junção cartesiana seria feita (ou seja, cada linha de uma tabela unida a cada linha da outra tabela). Antes de as junções ANSI serem suportadas (ou seja, aquelas especificadas na cláusula FROM), as junções tinham que ser feitas na cláusula WHERE.
Gary
11
-1 para junções naturais. Quando uma mudança de esquema não relacionada pode interromper junções, ou pior ainda, alterá-las sem causar erros, você estará em um mundo de dor. Por favor, pense nas crianças e SEMPRE especifique seus campos de associação.
Jon de Todos os Negócios
2
@ ScottCher: "Deixando que o banco de dados decida" - primeiro, presumivelmente você quer dizer "DBMS" em vez de "banco de dados". Segundo, não há IA ou mecanismo antropomorfístico no Oracle; em vez disso, NATURAL JOINé determinista.
onedaywhen
11
@ Joe cross joiné, foi e sempre será o 'padrão'. A Oracle não emparelhadas no nome da coluna, a menos que natural joinfoi usado explicitamente
Jack Douglas
1
  1. Nunca use aspas duplas, "pois, ao fazer isso, você substitui a dobra nativa do banco de dados. A especificação SQL exige que todos os identificadores sejam dobrados para maiúsculas. Alguns bancos de dados, como o PostgreSQL, dobram-nos para minúsculas. Se nada for citado, ele funcionará em todos os bancos de dados e eles poderão dobrá-los para a especificação ou o padrão específico do rdbms.
  2. Use um under_score ( _), porque conforme descrito acima - você não deve usar camelCase.
  3. use {entity}_idpara identificações (e chaves estrangeiras apontando para essas identificações). Porque então você pode usar a USINGcláusula Os nomes de chave exclusivos globalmente usados ​​nas condições de junção são uma convenção estabelecida na especificação.

    SELECT *
    FROM employee
    INNER JOIN department
      USING (department_id);
    
      -- compare to
      ON employee.department_id = department.department_id;
Neil McGuigan
fonte
11
Eu atualizei isso para ser mais explícito.
Evan Carroll