Por que nomear a coluna da Chave Primária da tabela “Id” é considerada uma prática ruim? [fechadas]

201

Minha professora t-sql nos disse que nomear nossa coluna PK "Id" é considerada uma prática ruim sem maiores explicações.

Por que nomear uma tabela A coluna PK "Id" é considerada uma prática ruim?

    
por Jean-Philippe Leclerc 17.10.2011 / 19:22
fonte

19 respostas

238

Eu vou sair e dizer: não é uma prática ruim (e mesmo que seja, não é ruim ).

Você pode argumentar (como apontou Chad ) que ele pode mascarar erros como na consulta a seguir :

SELECT * 
    FROM cars car
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

mas isso pode ser facilmente atenuado por não usar aliases minúsculos para os nomes das tabelas:

SELECT * 
    FROM cars
    JOIN manufacturer
        ON manufacturer.Id = cars.ManufacturerId
    JOIN models
        ON models.Id = cars.ModelId
    JOIN colors
        ON manufacturer.Id = cars.ColorId

A prática de SEMPRE usar abreviações de três letras parece muito pior para mim do que usar o nome da coluna id . (Caso em questão: quem realmente abreviaria o nome da tabela cars com a abreviação car ? Que finalidade isso serve?)

O ponto é: ser consistente. Se sua empresa usa o ID e você costuma fazer o erro acima, adquira o hábito de usar nomes de tabela completos. Se sua empresa banir a coluna Id, acerte-a e use a convenção de nomenclatura que preferir.

Concentre-se em aprender coisas que são REALMENTE práticas ruins (como várias subconsultas correlacionadas aninhadas) em vez de refletir sobre problemas como esse. A questão de nomear suas colunas "ID" está mais perto de ser uma questão de gosto do que ser uma prática ruim.

UMA NOTA PARA OS EDITORES: O erro nesta consulta é intencional e está sendo usado para criar um ponto. Por favor, leia a resposta completa antes de editar.

    
por 12.04.2017 / 09:31
fonte
120

Porque quando você tem uma tabela com uma chave estrangeira você não pode nomear a chave estrangeira "Id". Você tem o nome da tabela, TableId

E então sua participação parece com

SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId

E, idealmente, sua condição deve ter o mesmo nome de campo em cada lado

SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId

Portanto, embora pareça redundante nomear o Id como ManufacturerId, é menos provável que você tenha erros em suas condições de associação, pois os erros se tornam óbvios.

Isso parece simples, mas quando você participa de várias tabelas, fica mais provável que você cometa um erro, encontre a que está abaixo ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

Considerando que, com a nomenclatura apropriada, o erro se destaca ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    JOIN models mod
        ON mod.ModelId = car.ModelId
    JOIN colors col
        ON mfg.ManufacturerId = car.ColorId

Outra razão para os nomear como Id é "ruim" é que quando você está consultando informações de várias tabelas, será necessário renomear as colunas Id para que você possa diferenciá-las.

SELECT   manufacturer.Id as 'ManufacturerId'
        ,cars.Id as 'CarId'
        --etc
    FROM cars 
    JOIN manufacturer
        ON manufacturer.Id = cars.Id

Com nomes precisos, isso é menos um problema

    
por 19.10.2011 / 15:21
fonte
63

A biblioteca ActiveRecord do Ruby e o GORM do Groovy usam "id" para a chave substituta por padrão. Eu gosto dessa prática. Duplicar o nome da tabela em cada nome de coluna é redundante, tedioso para escrever e mais entediante para ser lido.

    
por 20.10.2011 / 19:15
fonte
40

Nomes de coluna comuns ou chave como "Nome" ou "Id" devem ser prefixados com o nome da tabela.

Ele remove ambigüidade, mais fácil de procurar, significa muito menos aliases de coluna quando ambos os valores de "Id" são necessários.

Uma coluna de auditoria ou não-chave menos usada (digamos LastUpdatedDateTime) não importa

    
por 17.10.2011 / 18:48
fonte
28

Esse segmento está inativo, mas eu gostaria de acrescentar que o não IMO usando Id é uma prática ruim. A coluna Id é especial; é a chave primária . Qualquer tabela pode ter qualquer número de chaves estrangeiras, mas pode ter apenas uma chave que seja primária. Em um banco de dados em que todas as chaves primárias são chamadas Id , assim que você olha para a tabela, você sabe exatamente qual coluna é a chave primária.

Acredite, por meses passei o dia todo trabalhando em grandes bancos de dados (Salesforce) e a melhor coisa que posso dizer sobre os esquemas é que cada tabela tem uma chave primária chamada Id . Posso garantir que eu absolutamente nunca me confundo sobre como unir uma chave primária a uma chave estrangeira porque o PK é chamado de Id . Outra coisa que as pessoas não mencionaram é que as tabelas podem ter nomes bobos longos como Table_ThatDoesGood_stuff__c ; esse nome é ruim o suficiente porque o arquiteto estava de ressaca na manhã em que pensou nessa tabela, mas agora você está me dizendo que é uma prática ruim não chamar a chave primária Table_ThatDoesGood_stuff__cId (lembrando que os nomes das colunas SQL não são em geral maiúsculas e minúsculas) sensível).

Para ser honesto, os problemas com a maioria das pessoas que ensinam programação de computadores são que eles não escreveram uma linha de código de produção em anos, e nunca fazem a menor ideia do que um engenheiro de software faz. Espere até você começar a trabalhar e depois decidir o que acha que é uma boa ideia ou não.

    
por 19.10.2011 / 21:34
fonte
23

Eu não considero isso uma prática ruim. Consistência é rei, como de costume.

Eu acho que é tudo sobre contexto. No contexto da tabela por si só, "id" significa exatamente o que você espera, um rótulo para ajudar a identificá-lo exclusivamente em relação a outros que, de outra forma, poderiam ser (ou parecer) idênticos.

No contexto das associações, é sua responsabilidade construir as associações de modo a torná-las legíveis para você e sua equipe. Assim como é possível fazer as coisas parecerem difíceis com frases ou nomenclaturas ruins, é igualmente possível construir uma consulta significativa com o uso efetivo de aliases e até mesmo comentários.

Da mesma forma que uma classe Java chamada 'Foo' não tem suas propriedades prefixadas por 'Foo', não se sinta obrigado a prefixar seus IDs de tabela com nomes de tabelas. Geralmente é claro no contexto para o qual o ID está sendo referido.

    
por 18.10.2011 / 01:10
fonte
22

Em data.stackexchange.com

BOOM, pergunta respondida.
Agora vá dizer ao seu professor que SO pratica um mau design de banco de dados.

    
por 17.04.2012 / 14:47
fonte
17

Torna difícil (e confuso) realizar uma junção natural na mesa, portanto, sim, é ruim, se não muito ruim.

Natural Join é um artefato antigo do SQL Lore (ou seja, álgebra relacional), você pode ter visto um destes: ⋈ em um livro de banco de dados, talvez. O que quero dizer é que o Natrual Join não é uma nova ideia de SQL, embora parecesse demorar uma eternidade para o DBMS implementá-lo, portanto, não é uma ideia nova para você implementá-lo, pode até ser irracional ignorar sua existência hoje em dia.

Bem, se você nomear toda a ID da sua chave primária, perderá a facilidade e a simplicidade da associação natural. select * from dudes natural join cars precisará ser escrito select * from dudes inner join cars where cars.dudeid = dudes.id ou select * from dudes inner join cars where dudes.carid = cars.id . Se você é capaz de fazer uma junção natural, você pode ignorar o que a relação realmente é, o que, acredito, é bastante impressionante.

    
por 17.10.2011 / 22:28
fonte
16

Existe uma situação em que colocar "ID" em todas as tabelas não é a melhor ideia: a palavra-chave USING , se for suportada. Nós usamos isso frequentemente no MySQL.

Por exemplo, se você tiver fooTable com coluna fooTableId e barTable com chave estrangeira fooTableId , suas consultas poderão ser construídas da seguinte forma:

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)

Ele não apenas salva a digitação, mas é muito mais legível em comparação com a alternativa:

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)
    
por 17.04.2012 / 17:40
fonte
11

Por que não basta perguntar ao seu professor?

Pense nisso, quando todas as colunas PK de suas tabelas são nomeadas ID , torna o uso delas como chaves estrangeiras um pesadelo.

Nomes de colunas precisam ser semanticamente significativos. ID é para genérico.

    
por 06.05.2015 / 21:45
fonte
7

O ID é ruim pelos seguintes motivos:

Se você fizer muitas consultas de relatórios, você sempre terá que aliasar as colunas se quiser ver as duas. Assim, torna-se uma perda de tempo quando você poderia nomeá-lo corretamente para começar. Essas consultas complexas são bastante difíceis (escrevo consultas que podem ter centenas de linhas) sem o fardo adicional de fazer um trabalho desnecessário.

Está sujeito a causar erros de código. Se você usar um banco de dados que permita o uso da junção natural (não que eu ache que você deva usar isso, mas quando houver recursos disponíveis, alguém os usará), você entrará na coisa errada se tiver um desenvolvedor que o use.

Se você estiver copiando associações para criar uma consulta complexa, será fácil esquecer de alterar o alias para o desejado e obter uma associação incorreta. Se cada id tiver o nome da tabela em que está, você receberá um erro de sintaxe. Também é mais fácil identificar se a junção em uma consulta complexa estiver incorreta se o nome do pPK e o nome do FK corresponderem.

    
por 19.04.2012 / 23:22
fonte
5

Existem algumas respostas que abordam o que eu consideraria a razão mais importante para não usar "id" como o nome da coluna para a chave primária em uma tabela: consistência e redução da ambigüidade.

No entanto, para mim, o principal benefício é percebido pelo programador de manutenção, em particular aquele que não estava envolvido com o desenvolvimento original. Se você usou o nome "PersonID" para o ID na tabela Person e usou consistentemente esse nome como uma chave estrangeira, é trivial gravar uma consulta no esquema para descobrir quais tabelas têm PersonID sem precisar inferir que "PersonID" é o nome usado quando é uma chave estrangeira. Lembre-se, certo ou errado, relações de chave estrangeira nem sempre são aplicadas em todos os projetos.

Há um caso extremo onde uma tabela pode precisar ter duas chaves estrangeiras na mesma tabela, mas nesses casos eu colocaria o nome da chave original como o nome do sufixo da coluna, portanto, uma correspondência de caractere curinga,% PersonID, poderia facilmente encontrar esses exemplos também.

Sim, muito disso poderia ser realizado por um padrão de "id" e sabendo sempre usá-lo como "tableNameID", mas isso exige que você saiba que a prática está em vigor e dependendo dos desenvolvedores originais para seguir com uma prática padrão menos intuitiva.

Embora algumas pessoas tenham apontado que são necessários alguns toques de teclas extras para escrever os nomes das colunas mais longos, eu diria que escrever o código é apenas uma pequena fração da vida ativa do programa. Se salvar as teclas digitadas no desenvolvedor era o objetivo, os comentários nunca deveriam ser escritos.

Como alguém que passou muitos anos mantendo projetos grandes com centenas de tabelas, prefiro strongmente nomes consistentes para uma chave em todas as tabelas.

    
por 18.10.2011 / 17:19
fonte
5

A prática de usar o Id como campo de chave primária leva à prática em que o id é adicionado a todas as tabelas. Muitas tabelas já possuem informações exclusivas que identificam exclusivamente um registro. Use isso como chave primária e não um campo de ID que você adiciona a cada tabela. Essa é uma das bases dos bancos de dados relacionais.

E é por isso que usar id é uma prática ruim: muitas vezes, id não é apenas um aumento automático de informações.

considere as seguintes tabelas:

PK id | Countryid   | Countryname
    1 |         840 | United States
    2 |         528 | the Netherlands

O que há de errado com esta tabela é que ela permite que o usuário adicione outra linha: Estados Unidos, com o código de país 840. Ela acabou de quebrar a integridade relacional. É claro que você pode impor exclusividade em colunas individuais ou usar apenas uma chave primária que já está disponível:

PK Countryid   | Countryname
           840 | United States
           528 | the Netherlands

Dessa forma, você usa as informações que você já tem como chave primária, que é o coração do design de banco de dados relacional.

    
por 20.10.2012 / 16:53
fonte
4

Eu sempre uso 'id' como o nome da coluna principal para cada tabela, simplesmente porque é a convenção dos frameworks que eu uso (Ruby on Rails, CakePHP), então eu não tenho que sobrescrevê-lo o tempo todo.

Isso não vai bater motivos acadêmicos para mim.

    
por 15.02.2012 / 12:39
fonte
2

Eu não acho que seja uma prática ruim se for usada corretamente. É comum ter um campo de ID com incremento automático chamado "ID" que você nunca precisa tocar e usar um identificador mais amigável para o aplicativo. Pode ser um pouco complicado escrever código como from tableA a inner join tableB b on a.id = b.a_id , mas esse código pode ser guardado.

Como uma preferência pessoal, tenho a tendência de prefixar o Id com o nome da entidade, mas não vejo um problema real em apenas usar Id se ele for manipulado inteiramente pelo banco de dados.

    
por 18.10.2011 / 18:07
fonte
2

ID é bastante comum, não acho que isso possa confundir ninguém. Você sempre vai querer conhecer a mesa. Colocar nomes de campos no código de produção sem incluir uma tabela / alias é uma prática ruim. Se você está excessivamente preocupado em poder digitar rapidamente consultas ad hoc, fica sozinho.

Só espero que ninguém desenvolva um banco de dados sql onde ID é uma palavra reservada.

CREATE TABLE CAR (ID);

Cuida do nome do campo, chave primária e incrementos automáticos de 1 começando com 1 tudo em um pacote de 2 caracteres. Ah, e eu teria chamado CARS, mas se nós vamos economizar em ataques e quem realmente acha que uma mesa chamada CAR terá apenas uma?

    
por 19.10.2011 / 16:26
fonte
2

Esta pergunta foi espancada repetidas vezes, mas eu pensei que eu também acrescentaria minha opinião.

  1. Eu uso o id para indicar que esse é o identificador de cada tabela, portanto, quando eu participo de uma tabela e preciso da chave primária, participo automaticamente da chave primária.

  2. O campo id é um incremento automático, não assinado (o que significa que eu nunca precisei definir seu valor e ele não pode ser negativo)

  3. Para chaves estrangeiras, eu uso tablenameid (novamente uma questão de estilo), mas a chave primária a que me associo é o campo id da tabela, então a consistência significa que eu sempre posso verificar as consultas facilmente

  4. id é curto e doce também

  5. Convenção adicional - use letras minúsculas para todos os nomes de tabelas e colunas, para que nenhum problema seja encontrado devido ao caso

por 17.04.2012 / 16:23
fonte
1

Outra coisa a considerar é que, se o nome da chave primária for diferente do nome da chave estrangeira, não será possível usar certas ferramentas de terceiros.

Por exemplo, você não conseguiria carregar seu esquema em uma ferramenta como o Visio e produzir um ERD preciso.

    
por 20.10.2012 / 14:36
fonte
1

Acho que as pessoas aqui cobrem praticamente todos os aspectos, mas quero acrescentar que "id" não é e não deve ser lido como "identificador", é mais um "índice" e certamente não declara ou descreve a identidade da linha . (Eu posso ter usado palavras erradas aqui, por favor corrija-me se eu fizesse)

É mais ou menos como as pessoas lêem os dados da tabela e como escrevem o código. Pessoalmente, e muito provavelmente, essa é a maneira mais popular que vejo com mais frequência: os codificadores escrevem a referência completa como table.id , mesmo que não precisem fazer união ou / e associações. Por exemplo:

SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>

Dessa forma, você pode traduzi-lo para o inglês como "Dê-me cor e modelo do carro que é numerado como". e não como "Dê-me cor e modelo daquele carro que é identificado como número". O ID não representa o carro de qualquer forma, é apenas o índice do carro, um número de série, se você quiser. Assim como quando você quer pegar o terceiro elemento de um array.

Então, para resumir o que eu queria adicionar é que é apenas uma questão de preferência e a maneira descrita de ler SQL é a mais popular.

No entanto, há alguns casos em que isso não é usado, como (um exemplo bem mais raro) quando o ID é uma string que realmente está descrevendo. Por exemplo, id = "RedFordMustang1970" ou algo semelhante. Eu realmente espero que eu possa explicar isso, pelo menos, para ter a idéia.

    
por 27.12.2012 / 19:09
fonte

Tags