Esquema de nomenclatura de clave externa

153

Recién estoy comenzando a trabajar con claves foráneas por primera vez y me pregunto si hay un esquema de nombres estándar para usar.

Dadas estas tablas:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)

Cuando las tareas tienen notas, las tareas son propiedad de los usuarios y las notas de los autores del usuario.

¿Cómo se nombrarían las tres claves foráneas en esta situación? O, alternativamente, ¿importa algo ?

Actualización : ¡Esta pregunta se trata de nombres de clave externa, no de nombres de campo!

nickf
fuente
66
Nota para los lectores: muchas de las mejores prácticas enumeradas a continuación no funcionan en Oracle debido a su límite de nombre de 30 caracteres. El nombre de una tabla o columna ya puede tener cerca de 30 caracteres, por lo que una convención que combine los dos en un solo nombre requiere un estándar de truncamiento u otros trucos.
Charles Burns

Respuestas:

180

La convención estándar en SQL Server es:

FK_ForeignKeyTable_PrimaryKeyTable

Entonces, por ejemplo, la clave entre notas y tareas sería:

FK_note_task

Y la clave entre tareas y usuarios sería:

FK_task_user

Esto le brinda una vista 'de un vistazo' de las tablas que están involucradas en la clave, por lo que es fácil ver de qué tablas depende una en particular (la primera nombrada) (la segunda nombrada). En este escenario, el conjunto completo de claves sería:

FK_task_user
FK_note_task
FK_note_user

Entonces puede ver que las tareas dependen de los usuarios, y las notas dependen de las tareas y los usuarios.

Greg Beech
fuente
1
Si la clave externa apunta a una clave candidata en la segunda tabla en lugar de una clave primaria, entonces probablemente usaría un tercer segmento para el nombre para calificar esto. Es una situación inusual, y no una que normalmente diseñarías desde cero, por lo que no incluí esto en la respuesta.
Greg Beech
44
Incluye el nombre de la tabla actual en la clave para mantenerlo distinto. Los nombres de FK se encuentran en el espacio de nombres global en SQL Server, por lo que no puede tener dos FK denominadas FK_PrimaryKeyTable adjuntas a dos tablas de claves externas diferentes. Las reglas pueden ser diferentes para otros servidores de bases de datos.
Greg Beech
De acuerdo ... Tengo diferentes espacios de nombres para cada tabla en Oracle, por lo que no necesito la auto referencia.
Steve Moyer,
29
Este parece ser el uso común, pero ¿qué hacen las personas cuando hay dos teclas externas que apuntan a la misma tabla? es decir, la messagetabla tiene una from_user_idy to_user_idambas se convertirían fk_message_user. Me parece mejor usar fk_tablename_columnname(fk_message_from_user_id en mi ejemplo) por este motivo y luego tratar de mantener los nombres de columna claros sobre la tabla de destino (es decir, to_user_id se refiere claramente a la tabla de usuario)
Code Commander
¿Qué pasa si tanto la tabla en sí tiene guiones bajos por ej. user_role y user_addresses? fk_user_addresses_user_role ¿no es confuso?
Govi S
38

Yo uso dos caracteres de subrayado como delimitador, es decir

fk__ForeignKeyTable__PrimaryKeyTable 

Esto se debe a que los nombres de las tablas ocasionalmente contienen caracteres de subrayado. Esto sigue la convención de nomenclatura para las restricciones en general porque los nombres de los elementos de datos con frecuencia contienen caracteres de subrayado, por ejemplo

CREATE TABLE NaturalPersons (
   ...
   person_death_date DATETIME, 
   person_death_reason VARCHAR(30) 
      CONSTRAINT person_death_reason__not_zero_length
         CHECK (DATALENGTH(person_death_reason) > 0), 
   CONSTRAINT person_death_date__person_death_reason__interaction
      CHECK ((person_death_date IS NULL AND person_death_reason IS NULL)
              OR (person_death_date IS NOT NULL AND person_death_reason IS NOT NULL))
        ...
un día cuando
fuente
3
Esta es absolutamente la mejor respuesta.
Frederik Krautwald
1
Acabo de crear Derby DB con una convención de nomenclatura muy específica y esta es la más fácil de leer y rastrear. Gracias
Anddo
17

¿Qué tal FK_TABLENAME_COLUMNNAME?

K eep I t S imple S tupid siempre que sea posible.

EvilTeach
fuente
20
Porque cuando tienes una gran base de datos con muchas claves y tablas y obtienes un error durante una actualización de esquema en tu software, es bastante difícil encontrar dónde se define la clave externa incluso sin buscar un script de creación de base de datos.
JohnC
1
@JohnC si los nombres de columna FK tienen el otro nombre de la tabla en el nombre de la columna, ¿no debería ser muy fácil saberlo? Le indica las dos tablas y el nombre de la columna en la que se define. Ej: FK_Animals_OwnerID—Animales y tabla de propietarios, definidos en la columna Id. De propietario
David Sherret
10

Una nota de Microsoft sobre SQL Server:

Una restricción FOREIGN KEY no tiene que estar vinculada solo a una restricción PRIMARY KEY en otra tabla; También se puede definir para hacer referencia a las columnas de una restricción ÚNICA en otra tabla.

entonces, usaré términos que describan dependencia en lugar de los términos convencionales de relación primaria / extranjera.

Al hacer referencia a la CLAVE PRIMARIA de la tabla independiente (principal) por la (s) columna (s) de nombre similar en la tabla dependiente (secundaria) , omito los nombres de columna:

FK_ChildTable_ParentTable

Al hacer referencia a otras columnas, o los nombres de las columnas varían entre las dos tablas, o simplemente para ser explícitos:

FK_ChildTable_childColumn_ParentTable_parentColumn
bvj
fuente
9

Por lo general, solo dejo mi ID con nombre PK, y luego concateno el nombre de mi tabla y el nombre de la columna clave al nombrar FK en otras tablas. Nunca me molesto con la carcasa de camello, porque algunas bases de datos descartan la distinción entre mayúsculas y minúsculas y simplemente devuelven todos los nombres en mayúsculas o minúsculas de todos modos. En cualquier caso, así es como se vería mi versión de sus tablas:

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);

Tenga en cuenta que también nombro mis tablas en singular, porque una fila representa uno de los objetos que persisto. Muchas de estas convenciones son de preferencia personal. Sugeriría que es más importante elegir una convención y usarla siempre que adoptar una convención de otra persona.

Steve Moyer
fuente
je - este es el estilo exacto que estoy usando en realidad (pero con camelCase) - pensé que agregaría un poco de descripción adicional a los nombres para ilustrar sus vínculos.
nickf
Entonces, al menos podemos leer los esquemas de cada uno;) ... lo que es vergonzoso es no poder leer el suyo después de un par de años de ausencia. Usamos ERWin para diagramar nuestros esquemas, pero a menudo es conveniente tener una versión de texto y tener una convención le permite encontrar tablas y campos fácilmente.
Steve Moyer,
5

Esto probablemente sea una matanza excesiva, pero funciona para mí. Me ayuda mucho cuando trato con VLDB especialmente. Yo uso lo siguiente:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

Por supuesto, si por alguna razón no hace referencia a una clave principal, debe hacer referencia a una columna contenida en una restricción única, en este caso:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

¿Puede ser largo, sí? ¿Ha ayudado a mantener la información clara para los informes, o me ha dado un salto rápido sobre que el problema potencial es durante una alerta de producto? Al 100% le encantaría saber qué piensan las personas sobre esta convención de nomenclatura.

SSISPissesMeOff
fuente
1

Mi enfoque habitual es

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

O en otros términos

FK_ChildColumnName_ParentTableName_ParentColumnName

De esta manera puedo nombrar dos claves foráneas que hacen referencia a la misma tabla como history_info tablecon una tabla column actionBy and actionTofromusers_info

Será como

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

Tenga en cuenta que:

No incluí el nombre de la tabla secundaria porque me parece de sentido común, estoy en la tabla del niño para poder asumir fácilmente el nombre de la tabla del niño. El carácter total es de 26 y se ajusta bien al límite de oráculo de 30 caracteres que declaró Charles Burns en un comentario aquí.

Nota para los lectores: muchas de las mejores prácticas enumeradas a continuación no funcionan en Oracle debido a su límite de nombre de 30 caracteres. Un nombre de tabla o columna ya puede tener cerca de 30 caracteres, por lo que una convención que combine los dos en un solo nombre requiere un estándar de truncamiento u otros trucos. - Charles Burns

Cary Bondoc
fuente
La suya fallará si tiene una tercera tabla que tiene el punto FK a ParentTableName_ParentColumnName misma tabla por duplicado FK_Name
Tony Dong
0

Según las respuestas y los comentarios aquí, una convención de nomenclatura que incluye la tabla FK, el campo FK y la tabla PK (FK_FKTbl_FKCol_PKTbl) debe evitar las colisiones de nombres de restricciones FK.

Entonces, para las tablas dadas aquí:

fk_task_userid_user
fk_note_userid_user

Entonces, si agrega una columna para rastrear quién modificó por última vez una tarea o una nota ...

fk_task_modifiedby_user
fk_note_modifiedby_user
Chad Kieffer
fuente
-2

Si no hace referencia a sus FK con tanta frecuencia y usa MySQL (e InnoDB), puede dejar que MySQL nombre el FK por usted.

Más adelante, puede encontrar el nombre FK que necesita ejecutando una consulta .

usuario12345
fuente
44
Solo puedo explicar mi voto negativo. Casi todos los sistemas de bases de datos permiten que el sistema nombre restricciones, ¿te imaginas volver e intentar resolver rápidamente durante un problema de producción con una base de datos de 100 tablas, incluso, tratando de descifrar con qué relación se relaciona FK__123ee456ff? Es simple y simplemente pone una práctica HORRIBLE. Cuando construyes un índice en este FK, ¿entonces qué? nombres de sistema que también? Entonces, cuando el índice IX_007e373f5963 está 98% fragmentado, ¿cómo sabrá dónde buscar para descubrir por qué? Simplemente no debería hacerse.
SSISPissesMeOff
-3

Intente usar el UUID de la versión 4 en mayúsculas con el primer octeto reemplazado por FK y '_' (guión bajo) en lugar de '-' (guión).

P.ej

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

La justificación es la siguiente

  • Algoritmo de generación estricto => nombres uniformes ;
  • La longitud de la clave es inferior a 30 caracteres , que es la limitación de la longitud del nombre en Oracle (antes de 12c);
  • Si cambia el nombre de su entidad , no necesita cambiar el nombre de su FK como en el enfoque basado en el nombre de la entidad (si DB admite el operador de cambio de nombre de la tabla);
  • Raramente se usaría el nombre de la restricción de clave externa. Por ejemplo, la herramienta DB generalmente muestra a qué se aplica la restricción. No debe temer el aspecto críptico, porque puede evitar usarlo para el "descifrado".
serenidad fría
fuente