sql - tabla - Clave principal/convención de denominación de clave externa
integridad referencial sql server (13)
En nuestro grupo de desarrolladores, tenemos un debate sobre la convención de nombres para claves primarias y extranjeras. Básicamente hay dos escuelas de pensamiento en nuestro grupo:
1:
Primary Table (Employee)
Primary Key is called ID
Foreign table (Event)
Foreign key is called EmployeeID
o
2:
Primary Table (Employee)
Primary Key is called EmployeeID
Foreign table (Event)
Foreign key is called EmployeeID
Prefiero no duplicar el nombre de la tabla en ninguna de las columnas (así que prefiero la opción 1 anterior). Conceptualmente, es consistente con muchas de las prácticas recomendadas en otros idiomas, donde no se utiliza el nombre del objeto en sus nombres de propiedad. Creo que nombrar la clave externa EmployeeID
(o Employee_ID
podría ser mejor) le dice al lector que es la columna de ID
de la Tabla de Employee
.
Algunos otros prefieren la opción 2, donde nombra la clave principal con el prefijo de la tabla para que el nombre de la columna sea el mismo en toda la base de datos. Veo ese punto, pero ahora no se puede distinguir visualmente una clave principal de una clave externa.
Además, creo que es redundante tener el nombre de la tabla en el nombre de la columna, porque si piensas en la tabla como una entidad y una columna como una propiedad o atributo de esa entidad, piensas en ella como el atributo ID del Employee
, no el atributo EmployeeID
de un empleado. No voy a preguntarle a mi compañero de trabajo cuál es su PersonAge
o PersonGender
. Le pregunto cuál es su edad.
Así que, como dije, es un debate enardecido y lo seguimos y seguimos sin cesar. Estoy interesado en obtener algunas nuevas perspectivas.
"¿En qué parte del empleado? INNER JOIN order ON order.employee_id = employee.id" ¿hay alguna necesidad de cualificación adicional? ".
No hay necesidad de calificación adicional porque la calificación de la que hablé ya está allí.
"La razón por la que un usuario comercial hace referencia a ID de pedido o ID de empleado es proporcionar contexto, pero a nivel de dabase ya tiene contexto porque está haciendo referencia a la tabla".
Ora, dime, si la columna se llama ''ID'', entonces ¿cómo se hace exactamente ese "arbitraje [sic] en la mesa", a menos que califique esta referencia a la columna de ID exactamente en la forma en que hablé?
¿Has considerado lo siguiente?
Primary Table (Employee)
Primary Key is PK_Employee
Foreign table (Event)
Foreign key is called FK_Employee
¿Qué tal nombrar la clave externa?
Identificación del rol
donde rol es el rol que la entidad referenciada tiene en relación con la tabla en cuestión. Esto resuelve el problema de la referencia recursiva y múltiples fks en la misma tabla.
En muchos casos será idéntico al nombre de tabla referenciado. En estos casos, se vuelve idéntico a una de sus propuestas.
En cualquier caso, tener argumentos largos es una mala idea
Creo que depende de tu forma de armar tu aplicación. Si usa ORM o diseña sus tablas para representar objetos, entonces la opción 1 puede ser para usted.
Me gusta codificar la base de datos como su propia capa. Controlo todo y la aplicación solo llama a los procedimientos almacenados. Es bueno tener conjuntos de resultados con nombres de columna completos, especialmente cuando hay muchas tablas unidas y se devuelven muchas columnas. Con este estilo de aplicación, me gusta la opción 2. Me gusta mucho ver que los nombres de las columnas coincidan en las uniones. Trabajé en sistemas antiguos en los que no coincidían y era una pesadilla
Estoy de acuerdo en que hay poco para elegir entre ellos. Para mí, una cosa mucho más significativa sobre cualquiera de los estándares es la parte "estándar".
Si las personas comienzan a ''hacer lo que les corresponde'', deberían ser colgadas por sus entrañas. EN MI HUMILDE OPINIÓN :)
La convención que utilizamos donde trabajo es bastante cercana a A, con la excepción de que nombramos tablas en forma de plural (es decir, "empleados") y usamos guiones bajos entre la tabla y el nombre de la columna. El beneficio de esto es que para referirse a una columna, es "id. De empleados" o "empleados.id", dependiendo de cómo desee acceder a ella. Si necesita especificar de qué tabla proviene la columna, "employees.employees _id" es definitivamente redundante.
Me gusta la convención n. ° 2: al investigar este tema y al encontrar esta pregunta antes de publicar la mía, encontré el problema en el que:
Estoy seleccionando * de una tabla con un gran número de columnas y uniéndolo a una segunda tabla que de manera similar tiene una gran cantidad de columnas. Ambas tablas tienen una columna "id" como clave principal, y eso significa que tengo que seleccionar cada columna (hasta donde yo sé) para hacer que esos dos valores sean únicos en el resultado, es decir:
SELECT table1.id AS parent_id, table2.id AS child_id
Aunque el uso de la convención n. ° 2 significa que aún tendré algunas columnas en el resultado con el mismo nombre, ahora puedo especificar qué id necesito (principal o secundario) y, como sugirió Steven Huwig, la instrucción USING
simplifica aún más las cosas.
Ninguna de las convenciones funciona en todos los casos, entonces, ¿por qué tener una? Usa el sentido común...
por ejemplo, para la tabla de autorreferencia, cuando hay más de una columna FK que auto referencia el PK de la misma tabla, TIENE que violar ambos "estándares", ya que las dos columnas FK no pueden nombrarse del mismo modo ... por ejemplo , EmployeeTable con EmployeeId PK, SupervisorId FK, MentorId Fk, PartnerId FK, ...
Realmente no importa. Nunca me he encontrado con un sistema donde haya una diferencia real entre la opción 1 y la opción 2.
Jeff Atwood tuvo un excelente artículo hace un tiempo sobre este tema. Básicamente, las personas debaten y discuten con más furia aquellos temas sobre los que no se puede demostrar que están equivocados. O desde un ángulo diferente, aquellos temas que solo se pueden ganar a través de la resistencia al estilo filibustero basada en argumentos del último hombre.
Elija uno y dígales que se concentren en los problemas que realmente afectan su código.
EDITAR: si desea divertirse, pídales que especifiquen en detalle por qué su método es superior para referencias de tablas recursivas.
Si está mirando el código de la aplicación, no solo las consultas a la base de datos, algunas cosas me parecen claras:
Las definiciones de tabla generalmente se asignan directamente a una clase que describe un objeto, por lo que deben ser singulares. Para describir una colección de un objeto, generalmente agrego "Matriz" o "Lista" o "Colección" al nombre singular, ya que más claramente que el uso de plurales indica no solo que es una colección, sino qué tipo de colección es. En esa vista, veo un nombre de tabla no como el nombre de la colección, sino el nombre del tipo de objeto del que es una colección. Un DBA que no escribe el código de la aplicación puede perder este punto.
Los datos con los que trato a menudo usan "ID" para propósitos de identificación sin clave. Para eliminar la confusión entre las "ID" clave y las "ID" no clave, para el nombre de la clave primaria, usamos "Key" (eso es lo que es, ¿no?) Con el nombre de la tabla o una abreviatura de el nombre de la tabla. Este prefijo (y lo reservo solo para la clave primaria) hace que el nombre clave sea único, lo cual es especialmente importante porque usamos nombres de variables que son los mismos que los nombres de columna de la base de datos, y la mayoría de las clases tienen un padre identificado por el nombre la clave principal. Esto también es necesario para asegurarse de que no se trate de una palabra clave reservada, que es la "Clave" sola. Para facilitar la coherencia de los nombres de las variables clave y proporcionar los programas que realizan combinaciones naturales, las claves externas tienen el mismo nombre que se utiliza en la tabla en la que son la clave principal. En más de una ocasión, he encontrado programas que funcionan mucho mejor de esta manera con combinaciones naturales. En este último punto, admito un problema con las tablas de autorreferencia, que he usado. En este caso, haría una excepción a la regla de denominación de clave externa. Por ejemplo, usaré ManagerKey como clave externa en la tabla Empleado para señalar otro registro en esa tabla.
Si las dos columnas tienen el mismo nombre en ambas tablas (convención n. ° 2), puede usar la sintaxis de USING en SQL para guardar algunos tipeos y algunos ruidos repetitivos:
SELECT name, address, amount
FROM employees JOIN payroll USING (employee_id)
Otro argumento a favor de la convención n. ° 2 es que es la forma en que se diseñó el modelo relacional .
La importancia de cada columna se transmite parcialmente etiquetándola con el nombre del dominio correspondiente.
Siempre utilicé userId como PK en una tabla y userId en otra tabla como FK. Estoy pensando seriamente en usar userIdPK y userIdFK como nombres para identificar uno de otro. Me ayudará a identificar PK y FK rápidamente al mirar las tablas y parece que va a aclarar el código cuando se utiliza PHP / SQL para acceder a los datos, lo que facilita su comprensión. Especialmente cuando alguien más mira mi código.
Yo uso la convención n. ° 2. Estoy trabajando con un modelo de datos heredado ahora en el que no sé lo que representa en una tabla determinada. ¿Dónde está el daño de ser detallado?