database - tipos - foreign key mysql ejemplo
Esquema de nombres de claves foráneas (9)
Estoy empezando a trabajar con claves externas por primera vez y me pregunto si hay un esquema de nombres estándar para usar para ellos.
Dadas estas tablas:
task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)
Donde las tareas tienen notas, las tareas son propiedad de los usuarios y las notas de los usuarios.
¿Cómo se nombrarían las tres claves externas en esta situación? O, como alternativa, ¿importa siquiera ?
Actualización : ¡Esta pregunta se trata de nombres de claves extranjeras, no de nombres de campos!
¿Qué tal FK_TABLENAME_COLUMNNAME
?
K eep I t S imple S tupid siempre que sea posible.
En función de las respuestas y los comentarios aquí, una convención de nomenclatura que incluya la tabla FK, el campo FK y la tabla PK (FK_FKTbl_FKCol_PKTbl) debe evitar 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
Esto es probablemente una muerte 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 para que el problema potencial sea durante una alerta prod-alert? Al 100% le encantaría conocer los pensamientos de la gente sobre esta convención de nombres.
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 da una vista "a simple vista" de qué tablas están involucradas en la clave, por lo que es más fácil ver en qué tablas depende una en particular (la primera llamada) (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 tanto de las tareas como de los usuarios.
Mi enfoque habitual es
FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference
O en otros términos
FK_ChildColumnName_ParentTableName_ParentColumnName
De esta forma, puedo nombrar dos claves externas que hacen referencia a la misma tabla, como una history_info table
con la column actionBy and actionTo
de la tabla users_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 que tiene sentido común, estoy en la tabla del niño así que puedo asumir fácilmente el nombre de la tabla del niño. El carácter total de la misma es 26 y se ajusta bien al límite de 30 caracteres del oráculo, que fue declarado por Charles Burns en un comentario here
Nota para los lectores: muchas de las mejores prácticas enumeradas a continuación no funcionan en Oracle debido a su límite 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
Por lo general, solo dejo mi ID con nombre de 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 camel-casing, porque algunas bases de datos descartan la distinción entre mayúsculas y minúsculas y simplemente devuelven todos los nombres de mayúsculas y minúsculas. En cualquier caso, así es como se vería mi versión de las 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 estoy persistiendo. Muchas de estas convenciones son preferencias personales. Sugeriría que es más importante elegir una convención y usarla siempre, que adoptar la convención de otra persona.
Si no estás haciendo referencia a tus FK tan seguido y usando MySQL (e InnoDB), entonces puedes dejar que MySQL nombre el FK por ti.
Más adelante, puede encontrar el nombre de FK que necesita ejecutando una consulta .
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 la dependencia en lugar de los términos convencionales de relación primaria / extranjera.
Al hacer referencia a la PRIMARY KEY de la tabla independiente (principal) por las columnas con nombre similar en la tabla dependiente (secundaria) , omito los nombres de columna (s):
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
Uso dos caracteres de subrayado como delimitador, es decir,
fk__ForeignKeyTable__PrimaryKeyTable
Esto se debe a que los nombres de tabla ocasionalmente contienen caracteres de subrayado. Esto sigue la convención de nomenclatura para 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))
...