¿Las claves externas son realmente necesarias en el diseño de una base de datos?

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

¿Hay algún otro uso para claves extranjeras? ¿Me estoy perdiendo de algo?

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

Las claves externas también pueden ayudar al progtwigdor 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í, la eliminación del usuario podría eliminar automáticamente todas las órdenes que apuntan a ese usuario.

No me puedo imaginar el diseño de una base de datos sin claves externas. Sin ellos, eventualmente se cometerá un error y se 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 presentará una incoherencia.

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

Un día, te arrepentirás. No gastar ese pequeño 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 código en tu aplicación que fuera tan descuidado? Eso directamente accedió a los objetos miembros y modificó las estructuras de datos directamente.

¿Por qué crees que esto se ha hecho difícil e incluso inaceptable en los idiomas modernos?

Sí.

  1. Te mantienen honesto
  2. Mantienen a los nuevos desarrolladores honestos
  3. Puedes hacer ON DELETE CASCADE
  4. Te ayudan a generar buenos diagtwigs que explican los enlaces entre tablas

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

Restricciones de claves preexternas (también conocida como integridad referencial declarativa o DRI) se empleó mucho tiempo implementando estas relaciones mediante desencadenadores. 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 lo hace. 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 añadir que, IMO, el uso de claves foráneas en apoyo de ON DELETE o ON UPDATE CASCADE no es necesariamente algo bueno. En la práctica, he descubierto que cascade on delete se debe considerar cuidadosamente en función de la relación de los datos; por ejemplo, si tiene un elemento primario padre hijo cuando esto puede estar bien o si 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 cuanto a que la clave principal de una tabla no debería cambiar. Las claves deben ser inherentemente constantes.

Supongamos que un progtwigdor lo está haciendo de la manera correcta

Hacer tal suposición me parece una idea extremadamente mala; en general, el software es increíblemente defectuoso.

Y ese es el punto, realmente. 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 una buena cosa.

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

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

Creo que a lo que se refiere 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 se deben confundir con la existencia de claves externas en El primer lugar.

¿Hay algún beneficio de no tener claves extranjeras? A menos que esté utilizando una base de datos cutre, los FK no son tan difíciles de configurar. Entonces, ¿por qué tienes una 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 en realidad está verificando esa relación por usted.

Supongo que estás hablando de restricciones de clave externa impuestas por la base de datos . Probablemente ya esté utilizando claves externas, simplemente no le ha contado a la base de datos al respecto.

Supongamos que un progtwigdor lo está haciendo de la manera correcta, ¿realmente necesitamos el concepto de claves externas?

Teóricamente, no. Sin embargo, nunca ha habido una pieza de software sin errores.

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

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

En aplicaciones web, normalmente solo tiene un progtwig que habla en 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 que hablan en 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 asegurarse de que todas las aplicaciones sigan las mismas suposiciones sin errores, siempre y para siempre.

Si las restricciones están codificadas en la base de datos, entonces lo peor que puede pasar con los errores es que el usuario recibe un feo mensaje de error sobre alguna restricción SQL no satisfecha. Esto es mucho más fácil que dejar datos no deseados en su base de datos empresarial, donde a su vez romperá todas sus aplicaciones o simplemente generará todo tipo de resultados erróneos o engañosos.

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

Los FK son muy importantes y siempre deberían existir en tu esquema, a menos que seas eBay .

Creo que algo único en algún momento debe ser responsable de garantizar relaciones válidas.

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

Sin embargo, si tiene otros clientes que escriben 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, que cualquier progtwigdor debería poder contar es un pecado capital.

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

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

Todo puede estar bien ahora, pero piense qué pasará cuando su progtwigdor 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.

Hasta donde yo sé, las claves externas se utilizan para ayudar al progtwigdor 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 progtwigdor no lo hace y, a veces, para protegerse de los errores de los progtwigdores.

Supongamos que un progtwigdor lo está haciendo de la manera correcta, ¿realmente necesitamos el concepto de claves externas?

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

¿Hay algún otro uso para claves extranjeras? ¿Me estoy perdiendo de algo?

Aunque esta no es la razón por la que se crearon, los FK brindan sugerencias fuertes y confiables para las herramientas de diagtwigción y para los constructores de consultas. Esto se transmite a los usuarios finales, quienes necesitan desesperadamente consejos confiables.

No son estrictamente necesarios, en la forma en que los cinturones de seguridad no son estrictamente necesarios. Pero realmente pueden salvarte de hacer algo estúpido que arruina tu base de datos.

Es mucho mejor depurar un error de restricción FK que tener que reconstruir una eliminación que rompió su aplicación.

Son importantes, porque su aplicación no es la única forma en que los datos pueden ser manipulados en la base de datos. Su aplicación puede manejar la integridad referencial tan honestamente como lo desee, pero todo lo que necesita es un bozo con los privilegios correctos para emitir un comando de inserción, eliminación o actualización a nivel de base de datos, y se evita toda aplicación de integridad referencial de la aplicación. Poner restricciones FK al nivel de la base de datos significa que, salvo que este bozo elija desactivar la restricción FK antes de emitir su comando, la restricción FK hará que falle una instrucción de inserción / actualización / eliminación incorrecta con una violación de integridad referencial.

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 llaves extranjeras. Las claves externas evitan datos incorrectos (es decir, filas huérfanas) que pueden no afectar la lógica o la funcionalidad comercial y, por lo tanto, pasan desapercibidos y se acumulan. También evita que los desarrolladores que no están familiarizados con el esquema implementen trozos completos de trabajo sin darse cuenta de que están perdiendo una relación. Tal vez todo sea excelente dentro del scope de su aplicación actual, pero si se le pasó algo y algún día se agrega algo inesperado (piense en informes elaborados), es posible que se encuentre en un lugar donde tenga que limpiar manualmente los datos incorrectos que se han acumulado desde el inicio del esquema sin una verificación de base de datos.

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

La pregunta:

¿Hay algún otro uso para claves extranjeras? ¿Me estoy perdiendo de algo?

Está un poco cargado. Inserte comentarios, sangría o nomenclatura variable en lugar de “claves externas” … Si ya entiende la cosa en cuestión a la perfección, es “inútil” para usted.

Reducción de entropía. Reduzca la posibilidad de que ocurran escenarios caóticos en la base de datos. Tenemos un momento difícil 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 orden tiene un cliente, esa suposición debería ser impuesta por algo . En las bases de datos, “algo” son claves foráneas.

Creo que esto vale la compensación en la velocidad de desarrollo. Claro, puedes codificar más rápido con ellos y es probable que algunas personas no los usen. Personalmente, he sacrificado 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, así que es un problema menor. Estoy usando herramientas normales y hay recursos para ayudarme a solucionar esto, ¡incluso personas para ayudar!

La alternativa es permitir que un error se infiltre en el sistema (y con 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, investigas y “OH”. La base de datos está jodida. Ahora, ¿cuánto tiempo llevará eso arreglarlo?

Puede ver claves externas como una restricción que,

  • Ayuda a mantener la integridad de los datos
  • Mostrar cómo se relacionan los datos entre sí (lo que puede ayudar a hacer cumplir las reglas y la lógica de negocios)
  • Si se usa correctamente, puede ayudar a boost la eficiencia con la que se extraen los datos de las tablas.

Actualmente no usamos claves foráneas. Y, en general, no nos arrepentimos.

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

  1. Diagtwigción Es mucho más fácil producir un diagtwig de una base de datos si se usan correctamente las relaciones de claves externas.

  2. Soporte de herramienta. Es mucho más fácil construir modelos de datos con Visual Studio 2008 que se pueden usar para LINQ to SQL si existen relaciones de claves externas adecuadas.

Así que supongo que mi punto es que hemos encontrado que si estamos haciendo un montón de trabajo manual SQL (construir consulta, ejecutar consulta, blahblahblah) las claves externas no son necesariamente esenciales. Una vez que empiezas a usar herramientas, se vuelven mucho más útiles.

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

En el código, en general, solo tendremos una excepción en algún lado, pero en SQL , generalmente solo 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 comprobación para la creación de particiones, no puedo decir que haya sido testigo de eso.

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

Pero siempre hubo una especie de convención de nombrar columnas que eran claves foráneas.

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

Soy consciente de las ventajas de las claves externas (integridad de datos, índice para la columna de clave externa, herramientas que conocen el 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 servir 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 buen aspecto, pero con un diseño incorrecto, el esquema de la base de datos.

Sí. ON DELETE [RESTRICT | CASCADE] mantiene a los desarrolladores sin datos varados, manteniendo los datos limpios. Recientemente me uní a un equipo de desarrolladores de Rails que no se centraron en las restricciones de la base de datos, como las claves externas.

Afortunadamente, encontré estos: http://www.redhillonrails.org/foreign_key_associations.html – RedHill en los complementos de Ruby on Rails genera claves externas usando 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 .

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