Mi profesor de t-sql nos dijo que nombrar nuestra columna PK "Id" se considera una mala práctica sin más explicaciones.
¿Por qué nombrar una columna PK de la tabla "Id" se considera una mala práctica?
Mi profesor de t-sql nos dijo que nombrar nuestra columna PK "Id" se considera una mala práctica sin más explicaciones.
¿Por qué nombrar una columna PK de la tabla "Id" se considera una mala práctica?
Respuestas:
Voy a salir y decirlo: no es realmente una mala práctica (e incluso si lo es, no es tan mala).
Podría argumentar (como señaló Chad ) que puede enmascarar errores como en la siguiente consulta:
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
pero esto se puede mitigar fácilmente al no usar pequeños alias para los nombres de su tabla:
SELECT *
FROM cars
JOIN manufacturer
ON manufacturer.Id = cars.ManufacturerId
JOIN models
ON models.Id = cars.ModelId
JOIN colors
ON manufacturer.Id = cars.ColorId
La práctica de SIEMPRE usando abreviaturas de 3 letras me parece mucho peor que usar el nombre de la columna id
. (Caso en cuestión: ¿quién realmente abreviaría el nombre de la tabla cars
con la abreviatura car
? ¿Para qué sirve eso?)
El punto es: ser consistente. Si su empresa usa Id y comúnmente comete el error anterior, entonces acostúmbrese a usar los nombres completos de las tablas. Si su empresa prohíbe la columna Id, tómela con calma y use la convención de nomenclatura que prefiera.
Concéntrese en aprender cosas que son REALMENTE malas prácticas (como múltiples subconsultas correlacionadas anidadas) en lugar de reflexionar sobre cuestiones como esta. La cuestión de nombrar las columnas "ID" está más cerca de ser una cuestión de gustos que de ser una mala práctica.
UNA NOTA PARA LOS EDITORES: El error en esta consulta es intencional y se está utilizando para hacer un punto. Lea la respuesta completa antes de editar.
cars
-> car
. Gracias a Dios, me salvaste los dedos). No leas demasiado profundamente.
cars
y manufacturer
. Uno es plural, el otro no. Si la gente quiere elegir en la base de datos, esa es la mala práctica que se debe elegir.
Porque cuando tienes una tabla con una clave foránea no puedes nombrar esa clave foránea "Id". Tienes el nombre de la tabla TableId
Y entonces tu unión parece
SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId
E idealmente, su condición debe tener el mismo nombre de campo en cada lado
SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId
Entonces, aunque parece redundante nombrar el Id como Id. De fabricante, hace que sea menos probable que tenga errores en las condiciones de unión, ya que los errores se vuelven obvios.
Esto parece simple, pero cuando une varias tablas, es más probable que cometa un error, encuentre la siguiente ...
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
Mientras que con un nombre adecuado, el error sobresale ...
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
Otra razón por la que nombrarlos Id es "incorrecta" es que cuando consulta información de varias tablas, deberá cambiar el nombre de las columnas Id para poder distinguirlas.
SELECT manufacturer.Id as 'ManufacturerId'
,cars.Id as 'CarId'
--etc
FROM cars
JOIN manufacturer
ON manufacturer.Id = cars.Id
Con nombres precisos, esto no es un problema
SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId
. Lo he usado id
durante años y nunca encontré lo que describiste como un problema real.
SELECT manufacturer.id FROM ...
. Cada dificultad resultante id
puede superarse muy fácilmente, por lo que es simplemente una cuestión de gustos.
La biblioteca ActiveRecord de Ruby y GORM de Groovy usan "id" para la clave sustituta por defecto. Me gusta esta practica. Duplicar el nombre de la tabla en el nombre de cada columna es redundante, tedioso de escribir y más tedioso de leer.
Los nombres de columna comunes o clave como "Nombre" o "Id" deben tener el prefijo TableName.
Elimina la ambigüedad, es más fácil de buscar, significa mucho menos alias de columna cuando se necesitan ambos valores "Id".
Una columna de menor uso o auditoría o no clave (por ejemplo, LastUpdatedDateTime) no importa
name
y id
? ¿Por qué no tener cada columna con el nombre de la tabla como prefijo? Parece arbitrario elegir esos dos nombres para ordenar un prefijo. Conceptualmente, debe tener la tabla para tener el contexto de una columna de todos modos. ¿Por qué no usar el nombre de la tabla para aclarar la consulta: Person.Name, Animal.Name, Part.Name, ...
Este hilo está muerto, pero me gustaría agregar que no usar IMO Id
es una mala práctica. La Id
columna es especial; Es la clave principal. Cualquier tabla puede tener cualquier número de claves externas, pero solo puede tener una clave primaria. En una base de datos donde se llaman todas las claves primarias Id
, tan pronto como mira la tabla, sabe exactamente qué columna es la clave primaria.
Créame, durante meses he pasado todo el día todos los días trabajando en muchas bases de datos grandes (Salesforce) y lo mejor que puedo decir sobre los esquemas es que cada tabla tiene una clave primaria llamada Id
. Les puedo asegurar que nunca me confundo acerca de unir una clave primaria a una clave externa porque se llama a la PK Id
. Otra cosa que la gente no ha mencionado es que las tablas pueden tener nombres largos y tontos como Table_ThatDoesGood_stuff__c
; ese nombre es bastante malo porque el arquitecto tuvo una resaca la mañana en que pensó en esa tabla, pero ahora me está diciendo que es una mala práctica no llamar a la clave principal Table_ThatDoesGood_stuff__cId
(recordando que los nombres de columna SQL no distinguen entre mayúsculas y minúsculas en general).
Para ser sincero, los problemas con la mayoría de las personas que enseñan programación de computadoras son que no han escrito una línea de código de producción en años, si es que alguna vez, y no tienen idea de lo que realmente hace un ingeniero de software en funcionamiento. Espere hasta que comience a trabajar y luego decida qué cree que es una buena idea o no.
No lo considero una mala práctica. La consistencia es el rey, como siempre.
Creo que todo se trata de contexto. En el contexto de la tabla en sí misma, "id" solo significa exactamente lo que espera, una etiqueta para ayudar a identificarlo de manera única frente a otros que de otro modo podrían ser (o parecer) idénticos.
En el contexto de las uniones, es su responsabilidad construir las uniones de tal manera que sean legibles para usted y su equipo. Del mismo modo que es posible hacer que las cosas parezcan difíciles con frases o nombres pobres, es igualmente posible construir una consulta significativa con el uso efectivo de alias e incluso comentarios.
De la misma manera que una clase Java llamada 'Foo' no tiene sus propiedades prefijadas por 'Foo', no se sienta obligado a prefijar sus ID de tabla con nombres de tabla. Por lo general, está claro en contexto a qué se refiere el ID.
BOOM, pregunta respondida.
Ahora ve a decirle a tu maestro que SO practica mal el diseño de la base de datos.
PostTypeId -> PostTypes.Id
; AcceptedAnswerId -> Answers.Id
; OwnerUserId -> Users.Id
. ¿Por qué una práctica que es así de fácil debe considerarse "mala"?
Hace que sea difícil (y confuso) realizar una unión natural en la mesa, por lo tanto, es malo, si no muy malo.
Natural Join es un antiguo artefacto de SQL Lore (es decir, álgebra relacional) que puede haber visto uno de estos: ⋈ en un libro de base de datos, tal vez. Lo que quiero decir es que Natrual Join no es una idea SQL nueva e incómoda, aunque pareciera que los DBMS tardaron una eternidad en implementarla, por lo tanto, no es una idea nueva e ingeniosa para que la implementen, incluso podría ser irracional ignorarla su existencia hoy en día.
Bueno, si nombra todas las ID de su clave principal, entonces pierde la facilidad y simplicidad de la unión natural. select * from dudes natural join cars
necesitará ser escrito select * from dudes inner join cars where cars.dudeid = dudes.id
o select * from dudes inner join cars where dudes.carid = cars.id
. Si puedes hacer una unión natural, puedes ignorar cuál es la relación, lo cual, creo, es bastante impresionante.
Hay una situación en la que pegar "ID" en cada tabla no es la mejor idea: la USING
palabra clave, si es compatible. Lo usamos a menudo en MySQL.
Por ejemplo, si tiene fooTable
una columna fooTableId
y barTable
una clave foránea fooTableId
, entonces sus consultas se pueden construir de la siguiente manera:
SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)
No solo guarda la escritura, sino que es mucho más legible en comparación con la alternativa:
SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)
USING
palabra clave es compatible con la base de datos postgres / mysql / sqlite, significa menos tipeo que algunas de las otras respuestas enumeran como una razón para usar id
, y finalmente en mi opinión subjetiva es más legible.
¿Por qué no solo le preguntas a tu maestro?
Piense en esto, cuando se nombran todas las columnas PK de sus tablas, es ID
una pesadilla usarlas como claves foráneas.
Los nombres de columna deben ser semánticamente significativos. ID
es genérico
id
solo no significa nada, especialmente en el contexto de una clave externa para otra tabla. Esto no tiene nada que ver con classes
todo y tiene que ver con un buen diseño básico básico de base de datos relacional.
table.id
es una forma perfectamente aceptable de referirse a un id
campo. Prefijar el nombre del campo con el nombre de la tabla es redundante.
La identificación es mala por las siguientes razones:
Si realiza muchas consultas de informes, siempre debe asignar un alias a las columnas si desea ver ambas. Entonces, para empezar, se convierte en una pérdida de tiempo cuando podrías nombrarlo correctamente. Estas consultas complejas son bastante difíciles (escribo consultas que pueden tener cientos de líneas de largo) sin la carga adicional de hacer un trabajo innecesario.
Está sujeto a causar errores de código. Si usa una base de datos que permite el uso de la unión natural (no creo que deba usarla alguna vez, pero cuando las características estén disponibles, alguien las usará), se unirá en lo incorrecto si obtiene un desarrollador que la use.
Si está copiando combinaciones para crear una consulta compleja, es fácil olvidarse de cambiar el alias al que desea y obtener una combinación incorrecta. Si cada identificación lleva el nombre de la tabla en la que se encuentra, generalmente obtendrá un error de sintaxis. También es más fácil detectar si la combinación en una consulta compleja es incorrecta si el nombre de pPK y el nombre de FK coinciden.
ID
no me convencen en absoluto.
Hay algunas respuestas que se acercan a lo que yo consideraría la razón más importante para no usar "id" como el nombre de la columna para la clave primaria en una tabla: es decir, consistencia y reducción de la ambigüedad.
Sin embargo, para mí, el programador de mantenimiento obtiene el beneficio clave, en particular uno que no participó en el desarrollo original. Si usó el nombre "PersonID" para la ID en la tabla Person y usó ese nombre como una clave foránea, es trivial escribir una consulta en el esquema para averiguar qué tablas tienen PersonID sin tener que inferir ese "PersonID" es el nombre usado cuando es una clave foránea. Recuerde, correcto o incorrecto, las relaciones de claves externas no siempre se aplican en todos los proyectos.
Hay un caso extremo en el que una tabla puede necesitar tener dos claves externas para la misma tabla, pero en tales casos pondría el nombre de la clave original como el nombre del sufijo para la columna, por lo que una coincidencia de comodín,% PersonID, podría encontrar fácilmente esas instancias también.
Sí, gran parte de esto podría lograrse mediante un estándar de tener "id" y saber usarlo siempre como "tableNameID", pero eso requiere tanto saber que la práctica está en su lugar y depender de los desarrolladores originales para seguir adelante con un menor Práctica estándar intuitiva.
Si bien algunas personas han señalado que requiere algunos golpes de tecla adicionales para escribir los nombres de columna más largos, diría que escribir el código es solo una pequeña fracción de la vida activa del programa. Si el objetivo era guardar las pulsaciones de teclas del desarrollador, los comentarios nunca deberían escribirse.
Como alguien que ha pasado muchos años manteniendo proyectos grandes con cientos de tablas, preferiría nombres consistentes para una clave en todas las tablas.
Companies
tabla tiene 2 claves foráneas para una Persons
tabla. Uno representa al presidente de la compañía; el otro representa al Tesorero de la compañía. ¿Realmente llamarías a las columnas PersonID1
y PersonID2
? Sería mucho más descriptivo llamarlos PresidentID
y TreasurerID
. Me resulta mucho más fácil de leer inner join Person AS Presidents ON Company.PresidentID = Presidents.ID
queinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
CompanyOfficer
o CompanyPerson
tabla que permita una relación de muchos a muchos entre Company
y Person
con información adicional sobre la naturaleza de la relación. Si Company
tuviera que implementarlo dentro de la tabla, usaría los nombres de columna PresidentPersonID
y TreasurerPersonID
para preservar la parte * PersonID del nombre al agregar el descriptor adicional. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
La práctica de usar Id como campo de clave principal conduce a la práctica donde se agrega id a cada tabla. Muchas tablas ya tienen información única que identifica de forma única un registro. Use ESO como clave principal y no como un campo de identificación que agregue a todas y cada una de las tablas. Esa es una de las bases de las bases de datos relacionales.
Y es por eso que usar id es una mala práctica: a menudo, id no es información, solo un aumento automático.
considere las siguientes tablas:
PK id | Countryid | Countryname
1 | 840 | United States
2 | 528 | the Netherlands
Lo que está mal con esta tabla es que permite al usuario agregar otra línea: Estados Unidos, con el código de país 840. Simplemente rompió la integridad relacional. Por supuesto, puede imponer la unicidad en columnas individuales, o simplemente puede usar una clave principal que ya está disponible:
PK Countryid | Countryname
840 | United States
528 | the Netherlands
De esa manera, utiliza la información que ya tiene como clave principal, que es el núcleo del diseño de la base de datos relacional.
No creo que sea una mala práctica si se usa correctamente. Es común tener un campo de ID de incremento automático llamado "ID" que nunca tiene que tocar, y usar un identificador más amigable para la aplicación. Escribir un código puede ser un poco engorroso, from tableA a inner join tableB b on a.id = b.a_id
pero ese código se puede guardar.
Como preferencia personal, tiendo a prefijar el Id con el nombre de la entidad, pero no veo un problema real con solo usarlo Id
si es manejado completamente por la base de datos.
La identificación es lo suficientemente común, que no creo que pueda confundir a nadie. Siempre vas a querer saber la mesa. Poner nombres de campos en el código de producción sin incluir una tabla / alias es una mala práctica. Si está demasiado preocupado por poder escribir rápidamente consultas ad hoc, está solo.
Solo espero que nadie desarrolle una base de datos SQL donde ID sea una palabra reservada.
CREATE TABLE CAR (ID);
Se encarga del nombre del campo, la clave primaria y los incrementos automáticos en 1, comenzando con 1 todo en un pequeño y agradable paquete de 2 caracteres. Ah, y lo habría llamado CARS, pero si vamos a ahorrar en la pulsación de teclas y ¿quién cree realmente que una mesa llamada CAR solo tendrá uno?
Car
representa un Table
donde cada uno Row
representa un solo Car
. Llamar Cars
cambia la semántica y muestra una completa falta de comprensión de los principios básicos de la teoría relacional formal. Rails es un excelente ejemplo de alguien que sabía lo suficiente como para ser peligroso .
Esta pregunta ha sido superada una y otra vez, pero pensé que yo también agregaría mi opinión.
Utilizo id para significar que ese es el identificador de cada tabla, por lo que cuando me uno a una tabla y necesito la clave primaria, automáticamente me uno a la clave primaria.
El campo id es un incremento automático, sin signo (lo que significa que nunca tengo que establecer su valor y no puede ser negativo)
Para las claves externas, uso tablenameid (nuevamente una cuestión de estilo), pero la clave principal a la que me uno es el campo id de la tabla, por lo que la coherencia significa que siempre puedo verificar las consultas fácilmente
la identificación es corta y dulce también
Convención adicional: utilice minúsculas para todos los nombres de tablas y columnas, de modo que no se encuentren problemas debido a mayúsculas y minúsculas
Otra cosa a considerar es que si el nombre de la clave primaria es diferente del nombre de la clave externa, entonces no es posible usar ciertas herramientas de terceros.
Por ejemplo, no podría cargar su esquema en una herramienta como Visio y hacer que produzca ERD precisos.
Encuentro que la gente aquí cubre casi todos los aspectos, pero quiero agregar que "id" no es y no debe leerse como "identificador", es más un "índice" y seguramente no establece ni describe la identidad de la fila. (Es posible que haya utilizado una redacción incorrecta aquí, corríjame si lo hice)
Es más o menos cómo las personas leen los datos de la tabla y cómo escriben su código. Personalmente y muy probablemente esta es la forma más popular que veo con más frecuencia es que los codificadores escriben la referencia completa como table.id
, incluso si no necesitan hacer uniones sindicales y / o unidas. Por ejemplo:
SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>
De esa manera, puede traducirlo al inglés como "Dame el color y el modelo de ese auto numerado como". y no como "Dame el color y el modelo de ese auto identificado como número". La identificación no representa el automóvil de ninguna manera, es solo el índice del automóvil, un número de serie si lo desea. Justo como cuando quieres tomar el tercer elemento de una matriz.
Entonces, para resumir, lo que quería agregar es que es solo una cuestión de preferencia y la forma descrita de leer SQL es la más popular.
Sin embargo, hay algunos casos en los que esto no se usa, como (un ejemplo mucho más raro) cuando la ID es una cadena que realmente describe. Por ejemplo id = "RedFordMustang1970"
o algo similar. Realmente espero poder explicar esto al menos para tener una idea.