Fui ensinado a não usar o nome Id
para a coluna de identidade de minhas tabelas, mas ultimamente tenho usado de qualquer maneira porque é simples, curto e muito descritivo sobre o que os dados realmente são.
Já vi pessoas sugerirem prefixar Id
o nome da tabela, mas isso parece dar mais trabalho para a pessoa que escreve as consultas SQL (ou o programador, se você estiver usando um ORM como o Entity Framework), principalmente em nomes de tabela mais longos, como CustomerProductId
ouAgencyGroupAssignementId
Um fornecedor terceirizado que contratamos para criar algo para nós nomeou todas as suas colunas de identidade Ident
apenas para evitar o uso de Id
. A princípio, pensei que eles faziam isso porque Id
era uma palavra-chave, mas quando examinei, descobri que Id
não é uma palavra-chave no SQL Server 2005, que é o que estamos usando.
Então, por que as pessoas recomendam não usar o nome Id
para uma coluna de identidade?
Editar: Para esclarecer, não estou perguntando qual convenção de nomenclatura usar ou argumentos para usar uma convenção de nomenclatura sobre a outra. Eu só quero saber por que é recomendado não usar Id
para o nome da coluna de identidade.
Sou um único programador, não um dba, e para mim o banco de dados é apenas um local para armazenar meus dados. Como costumo criar pequenos aplicativos e normalmente uso um ORM para acesso a dados, é muito mais fácil trabalhar com um nome de campo comum para o campo de identidade. Quero saber o que estou perdendo ao fazer isso e se há algum motivo realmente bom para não fazer isso.
O prefixo do nome da tabela tem boas razões.
Considerar:
Queremos
DELETE
deTableA
registros que existem em ambas as tabelas. Fácil o suficiente, faremos apenas umINNER JOIN
:.... e acabamos de eliminar tudo
TableA
. Comparamos inadvertidamente o ID de B com ele mesmo - todos os registros correspondiam e todos os registros eram excluídos.Se os campos tivessem sido nomeados
TableAId
eTableBId
isso seria impossível (Invalid field name TableAid in TableB
).Pessoalmente, não tenho problemas em usar o nome
id
em uma tabela, mas é realmente uma prática melhor prefaciá-la com o nome da tabela (ou nome da entidade, seTableA
fossem pessoas,PeopleId
funcionaria bem também) para evitar a comparação acidental com o campo errado e explodir algo para cima.Isso também torna muito óbvio de onde vêm os campos em consultas longas com muitos
JOIN
s.Principalmente é para evitar que as chaves estrangeiras se tornem uma dor tremenda. Digamos que você tenha duas tabelas: Customer e CustomerAddress. A chave primária para ambos é uma coluna chamada id, que é uma coluna de identidade (int).
Agora você precisa ter o ID do cliente referenciado em CustomerAddress. Você não pode nomear o id da coluna, obviamente, então você vai com customer_id.
Isso leva a alguns problemas. Primeiro, você deve lembrar consistentemente quando chamar a coluna "id" e quando chamá-la de "customer_id". E se você estragar tudo, isso leva ao segundo problema. Se você tiver uma consulta grande com cerca de uma dúzia de junções e ela não retornar nenhum dado, divirta-se jogando Where's Waldo e caçando este erro de digitação:
Opa, deveria ter sido
ON c.id = ca.customer_id
. Ou, melhor ainda, nomeie suas colunas de identidade de forma descritiva, para que possam serON c.customer_id = ca.customer_id
. Então, se você acidentalmente usar o alias de tabela errado em algum lugar, customer_id não será uma coluna nessa tabela e você obterá um bom erro de compilação, em vez de resultados vazios e subseqüente estrabismo de código.Concedido, há casos em que isso não ajuda, como se você precisar de vários relacionamentos de chave estrangeira de uma tabela para outra tabela única, mas nomear todas as chaves primárias como "id" também não ajuda.
Aqui está um resumo de todas as respostas sobre as vantagens obtidas com a convenção de não usar um nome comum para todas as chaves primárias:
Menos erros, já que os campos de identidade não têm o mesmo nome
Você não pode escrever erroneamente uma consulta que se junta em
B.Id = B.Id
vez deA.Id = B.Id
, porque os campos de identidade nunca serão nomeados exatamente da mesma forma.Nomes de colunas mais claros.
Se você observar uma coluna chamada
CustomerId
, saberá imediatamente quais dados estão nessa coluna. Se o nome da coluna for algo genérico comoId
, você também precisará saber o nome da tabela para saber quais dados a coluna contém.Evita aliases de coluna desnecessários
Agora você pode escrever
SELECT CustomerId, ProductId
a partir de uma consulta que se juntaCustomers
aProducts
, em vez deSELECT Customer.Id as CustomerId, Products.Id as ProductId
Permite a
JOIN..USING
sintaxeVocê pode unir tabelas com a sintaxe
Customer JOIN Products USING (CustomerId)
, em vez deCustomer JOIN Products ON Customer.Id = Products.Id
A chave é mais fácil de encontrar nas pesquisas
Se você estiver procurando o campo de identidade de um cliente em uma solução grande, pesquisar
CustomerId
é muito mais útil do que pesquisarId
Se você puder pensar em qualquer outra vantagem que essa convenção de nomenclatura tenha, me avise e eu a adicionarei à lista.
A escolha de usar nomes de coluna exclusivos ou idênticos para campos de identidade depende de você, mas independentemente do que você escolher, seja consistente :)
Para copiar minha resposta da pergunta vinculada:
Há uma situação em que colocar "ID" em todas as tabelas não é a melhor ideia: a palavra-
USING
chave, se for suportada. Nós o usamos frequentemente no MySQL.Por exemplo, se você tiver
fooTable
com colunafooTableId
ebarTable
com chave estrangeirafooTableId
, suas consultas poderão ser construídas da seguinte forma:Ele não apenas economiza digitação, mas é muito mais legível em comparação com a alternativa:
Depois de normalizar um esquema de banco de dados para limitar a redundância, as tabelas são divididas em tabelas menores com relações estabelecidas (um para um, um para muitos, muitos para muitos). No processo, campos únicos na tabela original podem aparecer em várias tabelas normalizadas.
Por exemplo, um banco de dados para um blog pode se parecer com isso em sua forma não normalizada, assumindo uma restrição exclusiva no Author_Nickname.
A normalização resultaria em duas tabelas:
Autor:
Publicar
Aqui Author_Nickname seria uma chave primária para a tabela author e uma chave estrangeira na tabela post. Mesmo que Author_Nickname apareça em duas tabelas, ele ainda corresponde a uma única unidade de informação, ou seja. cada nome de coluna corresponde a um único campo .
Em muitos casos, não pode haver uma restrição exclusiva nos campos originais, portanto, um campo numérico artificial é usado como chave primária. Isso não muda o fato de que cada nome de coluna ainda representa um único campo. No design de banco de dados tradicional, nomes de colunas individuais correspondem a campos únicos, mesmo que não sejam chaves. (por exemplo, seria possível usar part.partname e client.clientname em vez de part.name e client.name ). Esta é a razão da existência do
INNER JOIN ... USING <key>
e dasNATURAL JOIN
sintaxes.No entanto, hoje em dia, e com camadas ORM prontamente disponíveis em muitas linguagens, os bancos de dados são frequentemente projetados como uma camada de persistência para linguagens OO, em que é natural que variáveis que tenham o mesmo papel em diferentes classes sejam chamadas da mesma forma ( part.name e client.name , não part.partname e client.clientname ). Nesse contexto, costumo usar 'ID' para minhas chaves primárias.
Usar "Ident" em vez de "Id" realmente não resolve nada se "Ident" acabar sendo usado em todas as tabelas.
Há um bom artigo sobre convenções de codificação SQL no site Drupal que indica uma boa prática para esta situação:
Desse ponto de vista, faz sentido usar CustomerProductId e AgencyGroupAssignmentId. Sim, é bastante detalhado. Você poderia encurtá-lo, mas o maior ponto a se preocupar é se o desenvolvedor que o segue entenderá ou não o que você quis dizer . Ids prefaciados com nomes de tabela detalhados não devem deixar ambigüidade quanto ao que são. E (para mim) isso é mais importante do que salvar algumas teclas.
Eu nomeio minhas colunas CustomerID em vez de ID, então sempre que eu digito
SQL Prompt sugere imediatamente o seguinte
Isso me poupa algumas teclas. No entanto, acho que as convenções de nomenclatura são muito subjetivas e, como tal, não tenho uma opinião forte de uma forma ou de outra.
É o mesmo motivo pelo qual você não nomearia todos os seus campos varchar como "UserText" e "UserText1" ou porque não usaria "UserDate" e "UserDate1".
Normalmente, se você tiver um campo de identidade em uma tabela, é sua chave primária. Como você construiria uma tabela filha com uma chave estrangeira para uma tabela pai se a chave primária em ambas as tabelas fosse id?
Nem todo mundo concorda com essa metodologia, mas em meus bancos de dados eu atribuo uma abreviação única a cada tabela. A PK dessa tabela seria denominada PK_[abbrv]ID. SE isso for usado como um FK em qualquer lugar, eu usaria FK_[abbrv]ID. Agora não tenho trabalho de adivinhação para descobrir quais são os relacionamentos da tabela.
Basicamente, pelo mesmo motivo, você normalmente não nomeia os parâmetros parâmetro1, parâmetro2 ... é preciso, mas não descritivo. Se você vir TableId, provavelmente poderá presumir com segurança que ele é usado para armazenar um pk para Table, independentemente do contexto.
Quanto a quem usou Ident, ele perde totalmente o ponto, podendo escolher entre Ident e Id use Id. Ident é ainda mais confuso do que Id.
Fora do contexto, Id pode ser considerado a chave primária para alguma tabela (não é extremamente útil, a menos que o id seja um guid), mas Ident nem mesmo diz isso a você (ou pelo menos a mim). Eu acabaria descobrindo que Ident é a abreviação de identidade (de uma forma ou de outra), mas o tempo que gastei descobrindo isso seria desperdiçado.
Use um prefixo para que o mesmo nome possa ser usado em contextos de chave primária e chave estrangeira, para que você possa executar
natural join
/join ... using
.