¿Son realmente necesarias las claves externas en el diseño de una base de datos?

109

Hasta donde yo sé, las claves externas (FK) se utilizan para ayudar al programador a manipular los datos de la manera correcta. Supongamos que un programador ya está haciendo esto de la manera correcta, entonces ¿realmente necesitamos el concepto de claves externas?

¿Existen otros usos para las claves externas? ¿Me estoy perdiendo de algo?

Niyaz
fuente
2
Esto surge a menudo por aquí. Culpo Joel Spolsky :-). Aquí hay muchas buenas respuestas; en lugar de volver a escribir el mío, solo le daré un enlace: stackoverflow.com/questions/83147/whats-wrong-with-foreign-keys
SquareCog
70
"Supongamos que un programador ya está haciendo esto de la manera correcta"; ni siquiera puedo imaginar tal escenario.
recursivo
11
"Foreign Key" es una idea, no una tecnología. Es una regla relacional. Su pregunta es realmente sobre si debe intentar hacer cumplir la regla en su código o dejar que la base de datos lo ayude. Cuando se trata de simultaneidad, es mejor dejar que el motor de la base de datos haga cumplir la regla, ya que es consciente de TODO lo que sucede en la base de datos, mientras que su código no puede ser consciente.
Triynko
5
@lubos & cdeszaq. En realidad, ES una regla relacional ... es un subconjunto de la regla 10 de los "Twleve Commandments" de Codd ... "Integrity Independence", que básicamente dice que la integridad relacional del RDBMS debe mantenerse independientemente de cualquier aplicación que acceda a él, lo que es exactamente lo que estaba explicando de una manera fácil de entender. Esta regla se implementa, entre otras cosas, mediante restricciones de clave externa. Entonces, sí, la idea de una clave externa es "una" regla relacional.
Triynko
1
@lubos: Para aclarar, estás hablando de si vas a usar o no una función en particular, pero estoy hablando de si la presencia de esa función es necesaria para tener un RDBMS completo y completamente funcional. Las restricciones de referencia, siempre y cuando elija usarlas, es algo que debe aplicarse dentro del RDBMS (en lugar de la aplicación), por lo que es una característica que debe estar allí, y en ese sentido es un requisito del modelo relacional si vas a desarrollar un RDBMS completo.
Triynko

Respuestas:

102

Las claves externas ayudan a reforzar la integridad referencial a nivel de datos. También mejoran el rendimiento porque normalmente están indexados de forma predeterminada.

John Topley
fuente
52
Si necesita un índice, cree uno, esta no debería ser una razón principal para FK. (De hecho, en ciertas circunstancias (más inserciones que selecciones, por ejemplo) mantener un FK podría ser más lento.)
Robert
7
Esa es una respuesta horrible Los FK generalmente pueden agregar gastos generales adicionales, no mejorar el rendimiento.
Jedi ágil
En SQL-Server, no están indexados por defecto ni en el árbitro ni en el referente. sqlskills.com/blogs/kimberly/…
user420667
1
Ni en Oracle; tienes que crear índices (en las columnas FK) tú mismo.
Littlefoot
58

Las claves externas también pueden ayudar al programador a escribir menos código usando cosas como ON DELETE CASCADE. Esto significa que si tiene una tabla que contiene usuarios y otra que contiene pedidos o algo así, eliminar un usuario podría eliminar automáticamente todos los pedidos que apuntan a ese usuario.

Greg Hewgill
fuente
3
@Greg Hewgill Esto podría conducir potencialmente a muchos problemas. Debe tener mucho cuidado con pensamientos como BORRAR CASCADA, ya que en muchos casos, querrá conservar las órdenes creadas por un usuario al eliminar al usuario.
Kibbee
8
Aunque esto probablemente debería manejarse en la capa de lógica empresarial. Decidir si mantener o no registros secundarios relacionados no es lo mismo que asegurarse de que ningún valor viole las relaciones de clave externa.
Codewerks
5
El otro problema es la auditoría, si la auditoría no se realiza a nivel de la base de datos, las actualizaciones o eliminaciones en cascada invalidarán su pista de auditoría.
si618
@Codewerks: la lógica empresarial puede estar en la base de datos.
Fantius
44

No puedo imaginarme diseñando una base de datos sin claves externas. Sin ellos, eventualmente está obligado a cometer un error y corromper la integridad de sus datos.

No son necesarios , estrictamente hablando, pero los beneficios son enormes.

Estoy bastante seguro de que FogBugz no tiene restricciones de clave externa en la base de datos. Me interesaría saber cómo el equipo de Fog Creek Software estructura su código para garantizar que nunca introducirán una inconsistencia.

Eric Z Barba
fuente
43
Joel: "Hasta ahora nunca hemos tenido un problema". Hasta ahora, nunca he chocado contra un poste de luz. Pero sigo pensando que es una buena idea usar cinturones de seguridad ;-)
Tony Andrews
2
Puede que nunca hayas VISTO el problema, pero puede que esté ahí ... La mayoría de las bases de datos utilizan una convención como id_xxx que es exactamente la misma que ixXXX
FerranB
1
@Joel: ¿Convenciones de nomenclatura en lugar de la aplicación de las reglas? También podría acabar con la tipografía mientras lo hace.
jcollum
8
@Eric: Aquí tienes a Fog Creek como una especie de avatar del desarrollo de software. Si dijera "Una empresa en la ciudad de Nueva York no tiene claves extranjeras en su base de datos ...", todos diríamos "¿Y?"
jcollum
3
Eric: FogBugz usa una convención de nomenclatura para claves externas. Por ejemplo, se entiende que ixBug es un índice de la clave principal de la tabla Bug. Hasta ahora nunca hemos tenido ningún problema. - Joel Spolsky
Sam Saffron
40

Un esquema de base de datos sin restricciones FK es como conducir sin cinturón de seguridad.

Algún día te arrepentirás. No gastar ese poco de tiempo extra en los fundamentos del diseño y la integridad de los datos es una forma segura de asegurar dolores de cabeza más adelante.

¿Aceptarías un código en tu aplicación que fuera tan descuidado? Eso accedió directamente a los objetos miembros y modificó las estructuras de datos directamente.

¿Por qué cree que esto se ha vuelto difícil e incluso inaceptable en los lenguajes modernos?

Chico
fuente
2
+1 para una buena analogía entre encapsulación y relaciones FK / PK.
jcollum
21

Si.

  1. Te mantienen honesto
  2. Mantienen honestos a los nuevos desarrolladores
  3. Tu puedes hacer ON DELETE CASCADE
  4. Te ayudan a generar bonitos diagramas que explican por sí mismos los vínculos entre tablas.
csmba
fuente
1
¿A qué te refieres con honestidad?
dspacejs
Honesto con la concepción, supongo. Le impide hacer trampa con los datos haciendo una programación rápida y poco convincente.
Oreste Viron
13

Supongamos que un programador ya está haciendo esto de la manera correcta.

Hacer tal suposición me parece una muy mala idea; en general, el software tiene errores fenomenales.

Y ese es el punto, de verdad. Los desarrolladores no pueden hacer las cosas bien, por lo que asegurarse de que la base de datos no se pueda llenar con datos incorrectos es algo bueno.

Aunque en un mundo ideal, las uniones naturales usarían relaciones (es decir, restricciones FK) en lugar de hacer coincidir los nombres de las columnas. Esto haría que los FK fueran aún más útiles.

DrPizza
fuente
2
Buen punto, sería bueno unir dos tablas con "ON [Relación]" o alguna otra palabra clave y dejar que la base de datos descubra qué columnas están involucradas. Realmente parece bastante razonable.
jcollum
13

Personalmente, estoy a favor de las claves externas porque formaliza la relación entre las tablas. Me doy cuenta de que su pregunta presupone que el programador no está introduciendo datos que violarían la integridad referencial, pero he visto demasiados casos en los que se viola la integridad referencial de los datos, ¡a pesar de las mejores intenciones!

Restricciones de claves preexternas (también conocidas como integridad referencial declarativa o DRI) se dedicó mucho tiempo a implementar estas relaciones mediante disparadores. El hecho de que podamos formalizar la relación mediante una restricción declarativa es muy poderoso.

@John: otras bases de datos pueden crear automáticamente índices para claves externas, pero SQL Server no. En SQL Server, las relaciones de clave externa son solo restricciones. Debe definir su índice en claves externas por separado (lo que puede ser beneficioso).

Editar: Me gustaría agregar que, en mi opinión, el uso de claves externas en apoyo de ON DELETE o ON UPDATE CASCADE no es necesariamente algo bueno. En la práctica, he descubierto que la cascada de eliminación debe considerarse cuidadosamente en función de la relación de los datos; por ejemplo, ¿tiene un padre-hijo natural donde esto puede estar bien o la tabla relacionada es un conjunto de valores de búsqueda? El uso de actualizaciones en cascada implica que está permitiendo que se modifique la clave principal de una tabla. En ese caso, tengo un desacuerdo filosófico general en que la clave principal de una mesa no debería cambiar. Las claves deben ser inherentemente constantes.

Peter Meyer
fuente
9

Sin una clave externa, ¿cómo se sabe que dos registros en tablas diferentes están relacionados?

Creo que a lo que te refieres es a la integridad referencial, donde no se permite crear el registro secundario sin un registro principal existente, etc. A menudo se conocen como restricciones de clave externa, pero no deben confundirse con la existencia de claves externas en El primer lugar.

Samjudson
fuente
8

¿Existe algún beneficio por no tener claves externas? A menos que esté utilizando una base de datos de mala calidad, los FK no son tan difíciles de configurar. Entonces, ¿por qué tendría la política de evitarlos? Una cosa es tener una convención de nomenclatura que diga que una columna hace referencia a otra, y otra es saber que la base de datos realmente verifica esa relación por usted.

Tundey
fuente
8

Supongo que está hablando de restricciones de clave externa impuestas por la base de datos . Probablemente ya esté utilizando claves externas, pero no se lo ha dicho a la base de datos.

Supongamos que un programador ya está haciendo esto de la manera correcta, entonces ¿realmente necesitamos el concepto de claves externas?

Teóricamente no. Sin embargo, nunca ha habido un software sin errores.

Los errores en el código de la aplicación generalmente no son tan peligrosos: usted identifica el error y lo corrige, y luego la aplicación se ejecuta sin problemas nuevamente. Pero si un error permite que los datos corruptos ingresen a la base de datos, ¡se quedará atascado! Es muy difícil recuperarse de datos corruptos en la base de datos.

Considere si un error sutil en FogBugz permitió que se escribiera una clave externa corrupta en la base de datos. Puede ser fácil corregir el error y enviar rápidamente la solución a los clientes en una versión de corrección de errores. Sin embargo, ¿cómo se deberían corregir los datos corruptos en decenas de bases de datos? El código correcto ahora podría romperse repentinamente porque las suposiciones sobre la integridad de las claves externas ya no se mantienen.

En las aplicaciones web, normalmente solo tiene un programa hablando con la base de datos, por lo que solo hay un lugar donde los errores pueden dañar los datos. En una aplicación empresarial, puede haber varias aplicaciones independientes hablando con la misma base de datos (sin mencionar a las personas que trabajan directamente con el shell de la base de datos). No hay forma de estar seguro de que todas las aplicaciones sigan los mismos supuestos sin errores, siempre y para siempre.

Si las restricciones están codificadas en la base de datos, lo peor que puede suceder con los errores es que se muestre al usuario un mensaje de error desagradable sobre alguna restricción SQL no satisfecha. Esto es mucho mejor que permitir que los datos corruptos entren en la base de datos de su empresa, donde a su vez romperá todas sus aplicaciones o simplemente dará lugar a todo tipo de resultados incorrectos o engañosos.

Ah, y las restricciones de clave externa también mejoran el rendimiento porque están indexadas de forma predeterminada. No puedo pensar en ninguna razón para no usar restricciones de clave externa.

JacquesB
fuente
7

Los FK son muy importantes y siempre deben existir en su esquema, a menos que sea eBay .

Cherouvim
fuente
2
Ese enlace es realmente fascinante ... Realmente me gustaría saber más detalles y estoy algo asustado de usar eBay ahora. para otras personas: haga clic en la cuarta pregunta para ver qué dice sobre su estructura de base de datos. Sin embargo, vale la pena ver toda la entrevista. también ...unibrow
gloomy.penguin
6

Creo que una sola cosa en algún momento debe ser responsable de asegurar relaciones válidas.

Por ejemplo, Ruby on Rails no usa claves externas, pero valida todas las relaciones por sí mismo. Si solo accede a su base de datos desde esa aplicación Ruby on Rails, está bien.

Sin embargo, si tiene otros clientes que están escribiendo en la base de datos, entonces sin claves externas necesitan implementar su propia validación. Luego tiene dos copias del código de validación que probablemente sean diferentes, lo que cualquier programador debería poder decir que es un pecado capital.

En ese punto, las claves externas son realmente necesarias, ya que le permiten mover la responsabilidad a un solo punto nuevamente.

Orion Edwards
fuente
2
Es como una cebolla. Los FK son la última capa de defensa. A menos que sea una base de datos local incorporada, las aplicaciones que intentan hacer integridad referencial siempre son una mala idea.
Fabricio Araujo
5

Las claves externas permiten que alguien que no haya visto su base de datos antes determine la relación entre tablas.

Puede que todo esté bien ahora, pero piense en lo que sucederá cuando su programador se vaya y alguien más tenga que hacerse cargo.

Las claves externas les permitirán comprender la estructura de la base de datos sin tener que rastrear miles de líneas de código.

Craig
fuente
5

Hasta donde yo sé, las claves externas se utilizan para ayudar al programador a manipular los datos de la manera correcta.

Los FK permiten que el DBA proteja la integridad de los datos de los errores de los usuarios cuando el programador no lo hace y, a veces, protege contra los errores de los programadores.

Supongamos que un programador ya está haciendo esto de la manera correcta, entonces ¿realmente necesitamos el concepto de claves externas?

Los programadores son mortales y falibles. Los FK son declarativos, lo que los hace más difíciles de arruinar .

¿Existen otros usos para las claves externas? ¿Me estoy perdiendo de algo?

Aunque esta no es la razón por la que se crearon, los FK proporcionan pistas sólidas y fiables para las herramientas de diagramación y para los constructores de consultas. Esto se transmite a los usuarios finales, que necesitan desesperadamente pistas sólidas y fiables.

Peter Wone
fuente
Esta es una respuesta genial.
Dan Lugg
4

No son estrictamente necesarios, de la misma forma que los cinturones de seguridad no son estrictamente necesarios. Pero realmente pueden evitar que hagas algo estúpido que arruine tu base de datos.

Es mucho más agradable depurar un error de restricción FK que tener que reconstruir una eliminación que rompió su aplicación.

Mark Harrison
fuente
4

Son importantes porque su aplicación no es la única forma en que se pueden manipular los datos en la base de datos. Su aplicación puede manejar la integridad referencial tan honestamente como quiera, pero todo lo que necesita es un bozo con los privilegios adecuados para venir y emitir un comando de inserción, eliminación o actualización en el nivel de la base de datos, y se omite todo el cumplimiento de la integridad referencial de su aplicación. Poner restricciones FK en el nivel de la base de datos significa que, salvo que este bozo elija deshabilitar la restricción FK antes de emitir su comando, la restricción FK hará que una declaración de inserción / actualización / eliminación incorrecta falle con una violación de integridad referencial.

Mike McAllister
fuente
3

Lo pienso en términos de costo / beneficio ... En MySQL , agregar una restricción es una sola línea adicional de DDL . Es solo un puñado de palabras clave y un par de segundos de pensamiento. Ese es el único "costo" en mi opinión ...

Las herramientas aman las claves externas. Las claves externas evitan los datos incorrectos (es decir, filas huérfanas) que pueden no afectar la lógica o la funcionalidad del negocio y, por lo tanto, pasan desapercibidas y se acumulan. También evita que los desarrolladores que no están familiarizados con el esquema implementen partes enteras de trabajo sin darse cuenta de que les falta una relación. Quizás todo sea genial dentro del alcance de su aplicación actual, pero si se perdió algo y algún día se agrega algo inesperado (piense en informes sofisticados), es posible que se encuentre en un lugar en el que tenga que limpiar manualmente los datos incorrectos que se han estado acumulando desde el inicio. del esquema sin una verificación obligatoria de la base de datos.

El poco tiempo que se necesita para codificar lo que ya está en su cabeza cuando está armando las cosas podría ahorrarle a usted oa otra persona un montón de dolor meses o años en el futuro.

La pregunta:

¿Existen otros usos para las claves externas? ¿Me estoy perdiendo de algo?

Está un poco cargado. Inserta comentarios, sangría o nombres de variables en lugar de "claves externas" ... Si ya entiendes perfectamente la cosa en cuestión, no te sirve de nada.

danb
fuente
2

Reducción de entropía. Reducir la posibilidad de que se produzcan escenarios caóticos en la base de datos. Lo estamos pasando mal ya que está considerando todas las posibilidades por lo que, en mi opinión, la reducción de la entropía es clave para el mantenimiento de cualquier sistema.

Cuando hacemos una suposición, por ejemplo: cada pedido tiene un cliente, esa suposición debe ser impuesta por algo . En las bases de datos ese "algo" son claves foráneas.

Creo que vale la pena sacrificar la velocidad del desarrollo. Claro, puede codificar más rápido sin ellos y esta es probablemente la razón por la que algunas personas no los usan. Personalmente, he matado varias horas con NHibernate y alguna restricción de clave externa que se enoja cuando realizo alguna operación. SIN EMBARGO, sé cuál es el problema, por lo que es un problema menor. Estoy usando herramientas normales y hay recursos para ayudarme a solucionar esto, ¡posiblemente incluso personas que me ayuden!

La alternativa es permitir que un error se filtre en el sistema (y si se le da el tiempo suficiente, lo hará) donde no se establece una clave externa y sus datos se vuelven inconsistentes. Luego, obtienes un informe de error inusual, investiga y "OH". La base de datos está jodida. ¿Cuánto tiempo va a tardar en solucionarse?

Quisquilloso
fuente
1

Puede ver las claves externas como una restricción que,

  • Ayude a mantener la integridad de los datos
  • Muestre cómo se relacionan los datos entre sí (lo que puede ayudar a hacer cumplir la lógica y las reglas comerciales)
  • Si se usa correctamente, puede ayudar a aumentar la eficiencia con la que se obtienen los datos de las tablas.
Pascal
fuente
1

Actualmente no usamos claves externas. Y en su mayor parte no nos arrepentimos.

Dicho esto, es probable que comencemos a usarlos mucho más en el futuro cercano por varias razones, ambas por razones similares:

  1. Diagramación. Es mucho más fácil producir un diagrama de una base de datos si se utilizan correctamente relaciones de clave externa.

  2. Soporte de herramientas. Es mucho más fácil crear modelos de datos con Visual Studio 2008 que se pueden usar para LINQ to SQL si existen relaciones de clave externa adecuadas.

Así que supongo que mi punto es que hemos descubierto que si estamos haciendo mucho trabajo SQL manual (construir consulta, ejecutar consulta, blahblahblah), las claves externas no son necesariamente esenciales. Sin embargo, una vez que comienzas a usar herramientas, se vuelven mucho más útiles.

John Christensen
fuente
1
Trabajo en sistemas que no los usan. Y lo lamento con regularidad. He visto más casos que puedo contar de datos sin sentido que habrían sido prevenidos por las restricciones adecuadas.
recursivo
Y después de haber estado trabajando con claves externas en nuestro proyecto actual durante casi seis meses, estoy totalmente de acuerdo con este comentario.
John Christensen
1

Lo mejor de las restricciones de clave externa (y las restricciones en general, en realidad) es que puede confiar en ellas al escribir sus consultas. Muchas consultas pueden volverse mucho más complicadas si no puede confiar en que el modelo de datos sea "verdadero".

En el código, generalmente obtendremos una excepción lanzada en alguna parte, pero en SQL , generalmente obtendremos las respuestas "incorrectas".

En teoría, SQL Server podría usar restricciones como parte de un plan de consulta, pero a excepción de las restricciones de verificación para la partición, no puedo decir que haya sido testigo de eso.

Mark Brackett
fuente
Las restricciones de unicidad indican una cardinalidad alta que utiliza el optimizador al seleccionar un mecanismo de combinación.
Peter Wone
1

Las claves externas nunca habían sido explícitas (tabla REFERENCIAS DE CLAVES EXTRANJERAS (columna)) declaradas en proyectos (aplicaciones comerciales y sitios web de redes sociales) en los que trabajé.

Pero siempre hubo una especie de convención de nombrar columnas que eran claves externas.

Es como con la normalización de la base de datos : debe saber qué está haciendo y cuáles son las consecuencias de eso (principalmente el rendimiento).

Soy consciente de las ventajas de las claves externas (integridad de los datos, índice para la columna de clave externa, herramientas conscientes del esquema de la base de datos), pero también tengo miedo de usar claves externas como regla general.

Además, varios motores de base de datos podrían proporcionar claves externas de una manera diferente, lo que podría provocar errores sutiles durante la migración.

La eliminación de todos los pedidos y facturas del cliente eliminado con ON DELETE CASCADE es el ejemplo perfecto de un esquema de base de datos atractivo, pero con un diseño incorrecto.

Grzegorz Gierlik
fuente
0

Si. ON DELETE [RESTRICT | CASCADE] evita que los desarrolladores pierdan datos, manteniendo los datos limpios. Recientemente me uní a un equipo de desarrolladores de Rails que no se enfocaban en las limitaciones de la base de datos, como las claves externas.

Afortunadamente, encontré estos: http://www.redhillonrails.org/foreign_key_associations.html - Los complementos de RedHill on Ruby on Rails generan claves externas utilizando la convención sobre el estilo de configuración . Una migración con product_id creará una clave externa para el id en la tabla de productos .

Vea los otros excelentes complementos en RedHill , incluidas las migraciones envueltas en transacciones.

Peter Mortensen
fuente
0

Si planea generar su código de acceso a datos, es decir, Entity Framework o cualquier otro ORM, pierde por completo la capacidad de generar un modelo jerárquico sin claves externas

Mike Griffin
fuente