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é denominar una tabla a la columna PK "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é denominar una tabla a la columna PK "Id" se considera una mala práctica?
Voy a salir y decirlo: no es realmente una mala práctica (e incluso si lo es, no es tan malo).
Podría hacer el argumento (como Chad señaló) 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 alias diminutos para los nombres de sus tablas:
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 usar abreviaturas de 3 letras me parece mucho peor que usar el nombre de columna id
. (Caso en cuestión: ¿quién abreviaría realmente el nombre de la tabla cars
con la abreviatura car
? ¿Para qué sirve eso?)
El punto es: ser consistente. Si su empresa utiliza Id y comúnmente comete el error anterior, entonces adquiera el hábito de usar nombres completos de tablas. Si su empresa prohíbe la columna de identificación, tómela con calma y utilice la convención de nombres que prefiera.
Concéntrese en aprender cosas que son REALMENTE malas prácticas (como múltiples consultas secundarias relacionadas y anidadas) en lugar de reflexionar sobre temas como este. El tema de nombrar sus columnas "ID" es más una cuestión de gusto que de una mala práctica.
UNA NOTA A LOS REDACTORES: El error en esta consulta es intencional y se usa para hacer un punto. Por favor, lea la respuesta completa antes de editar.
Porque cuando tienes una tabla con una clave externa, no puedes nombrar esa clave externa "Id". Tienes el nombre de tabla it TableId
Y luego su unión se ve como
SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId
E idealmente, su condición debería tener el mismo nombre de campo en cada lado
SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId
Por lo tanto, aunque parece redundante nombrar a la Id como ManufacturerId, hace que sea menos probable que tenga errores en sus condiciones de unión, ya que los errores se vuelven obvios.
Esto parece simple, pero cuando te unes a varias mesas, es más probable que cometas un error, encuentra 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 el nombre correcto, 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 "malo" es que cuando consulta información de varias tablas, deberá cambiar el nombre de las columnas de Id para que pueda distinguirlas.
SELECT manufacturer.Id as 'ManufacturerId'
,cars.Id as 'CarId'
--etc
FROM cars
JOIN manufacturer
ON manufacturer.Id = cars.Id
Con nombres precisos, esto es un problema menor
La biblioteca ActiveRecord de Ruby y GORM de Groovy usan "id" para la clave sustituta de forma predeterminada. Me gusta esta práctica. Duplicar el nombre de la tabla en cada nombre de 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 un prefijo con TableName.
Elimina la ambigüedad, más fácil de buscar, significa mucho menos alias de columna cuando se necesitan ambos valores "Id".
Una columna o clave no utilizada o auditada menos (por ejemplo, LastUpdatedDateTime) no importa
Este hilo está muerto, pero me gustaría agregar que IMO no usando Id
es una mala práctica. La columna Id
es especial; es la clave principal . Cualquier tabla puede tener cualquier número de claves externas, pero solo puede tener una clave principal. En una base de datos donde todas las claves primarias se denominan Id
, tan pronto como mire la tabla, sabrá exactamente qué columna es la clave primaria.
Créame, hace meses que paso todo el día trabajando en muchas bases de datos grandes (Salesforce) y lo mejor que puedo decir sobre los esquemas es que cada tabla tiene una clave principal llamada Id
. Les puedo asegurar que nunca me confundiré acerca de unir una clave principal a una clave externa porque la PK se llama 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 lo suficientemente 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 las columnas SQL no son, en general, el caso) sensible).
Para ser honesto, 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 lo han hecho, y no tienen idea de lo que realmente hace un ingeniero de software. Espere hasta que empiece a trabajar y luego decida qué piensa que es una buena idea o no.
No lo considero una mala práctica. La consistencia es rey, como de costumbre.
Creo que se trata de contexto. En el contexto de la tabla por sí solo, "id" significa exactamente lo que usted espera, una etiqueta que lo ayude a identificarlo de manera única frente a otros que de otra manera podrían ser (o aparecer) 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. Así como es posible hacer que las cosas parezcan difíciles con una mala redacción o denominación, también es posible construir una consulta significativa con un 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 identificadores de tabla con nombres de tabla. Por lo general, está claro en contexto a qué se refiere la ID a la que se hace referencia.
BOOM, pregunta respondida.
Ahora ve y dile a tu profesor que SO practica un mal diseño de la base de datos.
Hace que sea difícil (y confuso) realizar una unión natural en la mesa, por lo tanto, sí, es malo o no muy malo.
Natural Join es un antiguo artefacto de SQL Lore (es decir, álgebra relacional) que quizás hayas visto en uno de estos: ⋈ en un libro de base de datos. Lo que quiero decir es que Natrual Join no es una nueva idea de SQL fangled, a pesar de que pareció que los DBMS tardaron una eternidad en implementarla, por lo que no es una nueva idea de Fangled para que la implementes, incluso puede que no sea razonable ignorarla Su existencia hoy en día.
Bueno, si nombra todas las ID de su clave principal, perderá la facilidad y simplicidad de la combinación natural. select * from dudes natural join cars
tendrá que estar 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 eres capaz de hacer una unión natural, puedes ignorar lo que realmente 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 palabra clave USING
, si es compatible. Lo usamos a menudo en MySQL.
Por ejemplo, si tiene fooTable
con las columnas fooTableId
y barTable
con la clave foránea fooTableId
, entonces sus consultas se pueden construir como tales:
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)
¿Por qué no le preguntas a tu profesor?
Piensa en esto, cuando todas las columnas de tus tablas PK se denominan ID
hace que usarlas como claves externas sea una pesadilla.
Los nombres de columnas deben ser semánticamente significativos. ID
es genérico.
La identificación es mala por las siguientes razones:
Si haces muchas consultas de informes, siempre tienes que asignar un alias a las columnas si quieres ver ambas. Así que se convierte en una pérdida de tiempo cuando podría nombrarlo correctamente para empezar. Estas consultas complejas son lo suficientemente difíciles (escribo consultas que pueden tener cientos de líneas de longitud) 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 combinación natural (no creo que deba usarla alguna vez, pero cuando las funciones están disponibles, alguien las usará), se unirá a la empresa incorrecta si obtiene un desarrollador que la use.
Si está copiando uniones para crear una consulta compleja, es fácil olvidarse de cambiar el alias al que desea y obtener una unión incorrecta. Si cada ID lleva el nombre de la tabla en la que está, entonces generalmente obtendrá un error de sintaxis. También es más fácil detectar si la unión en una consulta compleja es incorrecta si el nombre pPK y el nombre FK coinciden.
Hay algunas respuestas que se aproximan a lo que consideraría la razón más importante para no usar "id" como el nombre de columna para la clave principal en una tabla: es decir, coherencia y ambigüedad reducida.
Sin embargo, para mí, el programador de mantenimiento obtiene un beneficio clave, en particular uno que no estuvo involucrado con el desarrollo original. Si usó el nombre "PersonID" para el ID en la tabla de Persona y usó ese nombre de manera consistente como una clave foránea, es trivial escribir una consulta en el esquema para averiguar qué tablas tienen PersonID sin tener que inferir que "PersonID" es el nombre que se usa cuando se trata de una clave externa. Recuerde, correcto o incorrecto, las relaciones de clave externa no siempre se aplican en todos los proyectos.
Hay un caso de borde en el que una tabla puede necesitar tener dos claves externas a la misma tabla, pero en esos casos pondría el nombre de clave original como el nombre de sufijo para la columna, por lo que un comodín coincide,% PersonID, Fácilmente podría encontrar esos casos también.
Sí, mucho de esto podría lograrse con un estándar de tener "id" y saber usarlo siempre como "tableNameID", pero eso requiere que ambos sepan que la práctica está en su lugar y que dependan de los desarrolladores originales. Con una práctica estándar menos intuitiva.
Si bien algunas personas han señalado que se requieren algunos golpes de tecla adicionales para escribir los nombres de las columnas más largas, yo 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 del desarrollador, los comentarios nunca deben escribirse.
Como alguien que ha pasado muchos años manteniendo grandes proyectos con cientos de tablas, preferiría nombres consistentes para una clave en todas las tablas.
La práctica de usar Id como campo de clave principal conduce a la práctica en donde id se agrega a cada tabla. Muchas tablas ya tienen información única que identifica de forma única un registro. Utilice ESA como clave principal y no 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 sino 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 le permite al usuario agregar otra línea: Estados Unidos, con código de país 840. Acaba de romper la integridad relacional. Por supuesto, puede imponer la exclusividad 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.
Siempre uso 'id' como el nombre de la columna principal para cada tabla simplemente porque es la convención de los marcos que uso (Ruby on Rails, CakePHP), así que no tengo que anularlo todo el tiempo.
Eso no superará las razones académicas para mí.
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 debe tocar, y usar un identificador más amigable para la aplicación. Escribir código como from tableA a inner join tableB b on a.id = b.a_id
puede ser un poco incómodo, pero ese código puede estar oculto.
Como preferencia personal, tiendo a prefijar el Id con el nombre de la entidad, pero no veo un problema real con solo usar Id
si es manejado por completo por la base de datos.
La identificación es lo suficientemente común, que no creo que confundiría a nadie. Siempre vas a querer conocer la mesa. Poner los nombres de los 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 principal y los incrementos automáticos en 1, comenzando con 1, todo en un paquete de 2 caracteres. Ah, y lo habría llamado CARS, pero si vamos a ahorrar en teclas y ¿quién realmente cree que una tabla llamada CAR solo tendrá una?
Esta pregunta ha sido superada una y otra vez, pero pensé que yo también agregaría mi opinión.
Utilizo id para indicar que ese es el identificador de cada tabla, por lo que cuando me uno a una tabla y necesito la clave principal, me uno automáticamente a la clave principal.
El campo id es un autoincremento, sin signo (lo que significa que nunca tengo que establecer su valor y no puede ser negativo)
Para las claves foráneas, uso tablenameid (de nuevo, es una cuestión de estilo), pero la clave principal a la que me uno es el campo de identificación de la tabla, por lo que la consistencia significa que siempre puedo consultar las consultas fácilmente
la identificación también es corta y dulce
Convención adicional: use minúsculas para todos los nombres de tablas y columnas, por lo que no se pueden encontrar problemas debido al caso
Otra cosa a considerar es que si el nombre de la clave principal 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 lo más probable es que esta es la forma más popular que veo con más frecuencia es que los programadores escriben la referencia completa como table.id
, incluso si no necesitan hacer uniones de unión o unión. Por ejemplo:
SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>
De esa manera puedes traducirlo al inglés como "Dame el color y el modelo de ese auto que está numerado como". y no como "Dame el color y el modelo de ese auto que se identifica como número". La identificación no representa al automóvil de ninguna manera, es solo el índice del automóvil, un número de serie, por así decirlo. Al igual que cuando desea tomar el tercer elemento de una matriz.
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 no se usa, como (un ejemplo mucho más raro) cuando el ID es una cadena que realmente describe. Por ejemplo, id = "RedFordMustang1970"
o algo similar. Realmente espero poder explicarlo al menos para tener una idea.