Fui ensinado a não usar o nome Id
da coluna de identidade de minhas tabelas, mas ultimamente apenas o uso de qualquer maneira, porque é simples, curto e muito descritivo sobre o que realmente são os dados.
Já vi pessoas sugerindo prefixar Id
o nome da tabela, mas isso parece funcionar mais 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 realmente nomeou todas as suas colunas de identidade Ident
apenas para evitar o uso Id
. No começo, pensei que eles fizeram 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, nem argumentos para usar uma convenção de nomenclatura sobre a outra. Eu só quero saber por que é recomendável 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 aplicativos pequenos 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 existem realmente boas razões para não fazer isso.
fonte
Respostas:
O prefixo do nome da tabela tem boas razões.
Considerar:
Queremos
DELETE
deTableA
registros que existem nas duas tabelas. Fácil, basta fazer umINNER JOIN
:.... e nós acabamos com tudo
TableA
. Inadvertidamente, comparamos o ID de B com ele próprio - 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 nenhum problema em usar o nome
id
em uma tabela, mas é realmente uma prática melhor precedê-lo com o nome da tabela (ou nome da entidade, se asTableA
pessoasPeopleId
funcionassem bem também) para evitar comparações acidentais com o campo errado e soprar alguma coisa.Isso também torna muito óbvio a origem dos campos em consultas longas com muitos
JOIN
s.fonte
begin transaction
ecommit transaction
seria melhor prática do que usar (IMO) um esquema de nomenclatura mais detestávelSELECT
para encontrar meus registros antes de executar oDELETE
e, uma vez executada a instrução, sempre verifico se a contagem de linhas é o que eu espero antes de confirmar.Principalmente é para impedir 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 no CustomerAddress. Como você não pode nomear o ID da coluna, obviamente, vá com customer_id.
Isso leva a alguns problemas. Primeiro, você deve se lembrar constantemente de quando chamar a coluna "id" e quando chamar "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 associações e não retornar nenhum dado, divirta-se jogando Where's Waldo e procurando esse 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 assim sejaON 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ê receberá um bom erro de compilação, em vez de resultados vazios e subsequentes estrabismo de código.É verdade que 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 "id" também não ajuda.
fonte
Aqui está um resumo de todas as respostas sobre as vantagens obtidas na 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 por engano uma consulta que se associa ao
B.Id = B.Id
invés deA.Id = B.Id
, porque os campos de identidade nunca serão nomeados exatamente iguais.Nomes de coluna mais claros.
Se você olhar para uma coluna chamada
CustomerId
, você saberá imediatamente quais dados estão nessa coluna. Se o nome da coluna fosse algo genéricoId
, será necessário conhecer o nome da tabela e saber quais dados a coluna contém.Evita aliases desnecessários de coluna
Agora você pode escrever a
SELECT CustomerId, ProductId
partir de uma consulta que se associaCustomers
aProducts
, em vez deSELECT Customer.Id as CustomerId, Products.Id as ProductId
Permite a
JOIN..USING
sintaxeVocê pode associar 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ê está 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 outras vantagens desta convenção de nomes, informe-me e adicionarei à lista.
Se você optar por usar nomes de colunas exclusivos ou idênticos para os campos de identidade, é com você, mas, independentemente do que você escolher, seja consistente :)
fonte
Para copiar minha resposta da pergunta vinculada:
Há uma situação em que colar "ID" em todas as tabelas não é a melhor idéia: a
USING
palavra - chave, se for suportada. Nós o usamos frequentemente no MySQL.Por exemplo, se você tiver
fooTable
uma colunafooTableId
ebarTable
uma chave estrangeirafooTableId
, suas consultas poderão ser construídas da seguinte forma:Ele não apenas salva a digitação, mas é muito mais legível em comparação com a alternativa:
fonte
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 (uma para uma, uma para muitas, muitas para muitas). 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 produziria duas tabelas:
Autor:
Postar
Aqui Author_Nickname seria uma chave primária para a tabela de autores e uma chave estrangeira na tabela de postagem. Mesmo que Author_Nickname apareça em duas tabelas, ele ainda corresponde a uma única unidade de informação, ou seja. o nome de cada coluna corresponde a um único campo .
Em muitos casos, não pode haver uma restrição exclusiva nos campos originais; portanto, um campo artificial numérico é usado como chave primária. Isso não altera o fato de que o nome de cada coluna ainda representa um único campo. No design tradicional do banco de dados, os nomes de colunas individuais correspondem a campos únicos, mesmo que não sejam chaves. (por exemplo, usaria part.partname e client.clientname em vez de part.name e client.name ). Esta é a razão para a existência do
INNER JOIN ... USING <key>
e asNATURAL JOIN
sintaxes.No entanto, hoje em dia, e com as camadas ORM prontamente disponíveis em muitos idiomas, os bancos de dados geralmente são projetados como uma camada de persistência para idiomas OO, na qual é natural que variáveis que tenham o mesmo papel em classes diferentes sejam chamadas de iguais ( part.name e client.name , não part.partname e client.clientname ). Nesse contexto, costumo usar 'ID' para minhas chaves primárias.
fonte
Usar "Ident" em vez de "Id" não resolve nada se o "Ident" acabar sendo usado em todas as suas 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, CustomerProductId e AgencyGroupAssignmentId fazem sentido usar. Sim, é bem detalhado. Você pode reduzi-lo, mas o ponto mais importante para se preocupar com isso é se o desenvolvedor que o segue ou não entenderá o que você quis dizer . Os IDs precedidos por nomes de tabela detalhados não devem deixar ambiguidade quanto ao que são. E (para mim) isso é mais importante do que salvar algumas teclas.
fonte
Nomeio minhas colunas como CustomerID em vez de ID, portanto, sempre que digito
O prompt SQL 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 maneira ou de outra.
fonte
É a mesma razão pela qual você não nomeará todos os seus campos varchar como "UserText" e "UserText1" ou por que você não usaria "UserDate" e "UserDate1".
Normalmente, se você tem um campo de identidade em uma tabela, é sua chave primária. Como você criaria uma tabela filho com uma chave estrangeira em uma tabela pai se a chave primária nas duas tabelas fosse id?
Nem todo mundo concorda com esse método, mas em meus bancos de dados atribuo uma abreviação exclusiva a cada tabela. O PK para essa tabela seria nomeado PK_ [abbrv] ID. Se isso for usado como um FK em qualquer lugar, eu usaria o FK_ [abbrv] ID. Agora, eu tenho zero trabalho de adivinhação para descobrir quais são os relacionamentos da tabela.
fonte
Basicamente, pelo mesmo motivo, você normalmente não nomeia os parâmetros parâmetro1, parâmetro2 ... é preciso, mas não descritivo. Se você vir o TableId, provavelmente poderá assumir com segurança que ele é usado para armazenar um pacote para a tabela, independentemente do contexto.
Quanto a quem usou o Ident, ele perdeu completamente o objetivo, dada a escolha entre Ident e Id usar o Id. Ident é ainda mais confuso que Id.
Fora do contexto, pode-se considerar que o ID é a chave principal de alguma tabela (não extremamente útil, a menos que o ID seja um guia), mas o Ident nem diz a você (ou pelo menos a mim) isso. Eu acabaria descobrindo que Ident é a abreviação de identidade (de uma maneira ou de outra), mas o tempo que gastei para descobrir isso seria desperdiçado.
fonte
Use um prefixo para que o mesmo nome possa ser usado nos contextos de chave primária e chave estrangeira, para que você possa executar
natural join
/join ... using
.fonte