2008-08-20 24 views
94

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 lo está haciendo de la manera correcta, ¿realmente necesitamos el concepto de claves externas?¿Las claves externas son realmente necesarias en el diseño de una base de datos?

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

+66

"Supongamos que un programador está haciendo esto de la manera correcta" - No puedo imaginarme tal escenario. – recursive

+11

"Clave externa" es una idea, no una tecnología. Es una regla relacional. Su pregunta es realmente si debe intentar aplicar 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 ocurre en la base de datos, mientras que su código posiblemente no sea consciente. – Triynko

+0

@Triynko, el concepto de claves foráneas no es una regla relacional. –

Respuesta

95

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

+45

Si necesitas un índice crear uno, esto no debería ser un tema primario motivo de FK. (De hecho, en determinadas circunstancias (más inserciones que las seleccionadas, por ejemplo) mantener un FK podría ser más lento.) – Robert

+3

Esa es una respuesta horrible. FK genaeralmente puede agregar una sobrecarga adicional que no mejora el rendimiento. –

+0

En SQL-Server, no están indexados por defecto ni en el árbitro ni en el referente. http://www.sqlskills.com/blogs/kimberly/when-did-sql-server-stop-putting-indexes-on-foreign-key-columns/ – user420667

55

Las claves foráneas 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í, la eliminación del usuario podría eliminar automáticamente todas las órdenes que apuntan a ese usuario.

+7

Aunque esto probablemente debería manejarse en la capa de lógica de negocios. Decidir si mantener o no registros secundarios relacionados no es lo mismo que garantizar que ningún valor viole las relaciones de claves externas. – Codewerks

+4

El otro problema es la auditoría, si la auditoría no se realiza en el nivel de base de datos, las actualizaciones en cascada o las eliminaciones anularán su pista de auditoría. – si618

+0

@Codewerks: la lógica empresarial puede estar en la base de datos. – Fantius

41

No 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 requeridos, 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 Fog Creek Software estructura su código para garantizar que nunca presentará una incoherencia.

+39

Joel: "Hasta ahora nunca hemos tenido un problema". Hasta ahora, nunca he conducido a una farola. Pero todavía creo que es una buena idea usar los cinturones de seguridad ;-) –

+2

Puede ser que nunca hayas visto el problema, pero puede que esté allí ... La mayoría de las bases de datos usan una convención como id_xxx que es exactamente la misma que ixXXX – FerranB

+1

@Joel: ¿Convenciones de nomenclatura en lugar de aplicación de reglas? También podría acabar con el tipo mientras estás en ello. – jcollum

8

Sin una clave externa ¿cómo se puede decir 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 deben confundirse con la existencia de llaves extranjeras en primer lugar.

1

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

  • ayudar a mantener la integridad de los datos
  • Muestra cómo los datos se relacionan entre sí (lo que puede ayudar en la aplicación de la lógica de negocio y reglas)
  • Si utilizado correctamente, puede ayudar a aumentar la eficiencia con la que se extraen los datos de las tablas.
6

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

Por ejemplo, Ruby on Rails no utiliza 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, deben implementar su propia validación. Luego tiene dos copias del código de validación que probablemente sean diferentes, que cualquier programador debería poder contar es un pecado capital.

En ese punto, las claves foráneas son realmente necesarias, ya que le permiten volver a transferir la responsabilidad a un único punto.

+2

Es como una cebolla. Los FK son la última capa de defensa. A menos que sea una base de datos local incrustada, las aplicaciones que intentan hacer una integridad referencial siempre son una mala idea. –

12

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

Haciendo tal suposición me parece ser una muy mala idea; 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 utilizarían las relaciones (es decir, las restricciones FK) en lugar de los nombres de columna coincidentes. Esto haría FKs aún más útil.

+2

Buen punto, sería bueno unir dos tablas con "ON [Relationship]" u otra palabra clave y dejar que db descubra qué columnas están involucradas. Parece bastante razonable realmente. – jcollum

12

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 datos, ¡a pesar de las mejores intenciones!

Restricciones de clave preexterna (también conocida como integridad referencial declarativa o DRI) se gastó 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 foráneas por separado (lo cual puede ser beneficioso)

Editar: Me gustaría agregar que, IMO, el uso de claves foráneas en apoyo de ON DELETE o ON UPDATE CASCADE no es necesariamente una cosa buena. En la práctica, he descubierto que Cascade on delete debe considerarse cuidadosamente en función de la relación de los datos, p. Ej. ¿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 cuanto a que la clave principal de una tabla no debería cambiar. Las claves deben ser inherentemente constantes.

+2

+1 Para que las claves sean constantes siempre que sea posible. – dshaw

20

Sí.

  1. le mantienen honestos
  2. Se mantienen los nuevos desarrolladores honestos
  3. Puede hacer ON DELETE CASCADE
  4. Ellos ayudan a generar buenos diagramas que la auto explicar los vínculos entre las tablas
+1

¿Qué quieres decir con honestidad? – dspacejs

+0

Honesto con la concepción, supongo. Le impide hacer trampa con los datos al hacer una programación rápida y coja. –

1

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

Dicho esto - que probable que empezar a usarlas mucho más en un futuro próximo por varias razones, tanto de ellos por razones similares estamos:

  1. Diagramación. Es mucho más fácil producir un diagrama 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 usando 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 encontrado que si estamos haciendo mucho trabajo manual de SQL (construcción de consulta, consulta de gestión, blahblahblah) claves externas no son necesariamente esenciales. Una vez que empiezas a usar herramientas, se vuelven mucho más útiles.

+1

Trabajo en sistemas que no los usan. Y lo lamento regularmente. He visto más casos que puedo contar de datos no sensuales que se hubieran evitado con las restricciones adecuadas. – recursive

+0

Y después de haber trabajado con claves externas en nuestro proyecto actual durante casi seis meses, estoy totalmente de acuerdo con este comentario. –

4

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.

1

Lo mejor de las restricciones de clave externa (y de las restricciones en general, en realidad) 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 la excepción lanzada a alguna parte, pero en el 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 comprobación para la creación de particiones, no puedo decir que alguna vez haya sido testigo de eso.

+0

Las restricciones de exclusividad indican una alta cardinalidad que el optimizador utiliza para seleccionar un mecanismo de combinación. –

36

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

Un día, lo lamentará. 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 descuidada? Eso directamente accedió a los objetos miembros y modificó las estructuras de datos directamente.

¿Por qué crees que esto se ha hecho difícil y incluso inaceptable dentro de las lenguas modernas?

+2

+1 para una buena analogía entre encapsulación y relaciones FK/PK. – jcollum

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 llaves foráneas. 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 alcance 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 le lleva codificar lo que tiene en mente cuando está armando cosas podría ahorrarle a usted oa alguien más un montón de dolor meses o años en el futuro.

La pregunta:

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

Es 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.

1

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 los que trabajé.

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

Es como con database normalization - tiene que saber qué está haciendo y cuáles son consecuencia de eso (principalmente el rendimiento).

Conozco las ventajas de las claves externas (integridad de datos, índice para la columna de clave externa, herramientas que tienen en cuenta el esquema de la base de datos), pero también tengo miedo de usar claves externas como regla general.

También 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.

Eliminar todos los pedidos y las 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.

8

¿Hay alguna ventaja de no tener claves externas? 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.

0

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 - Los complementos de RedHill en Ruby on Rails generan claves foráneas usando el estilo convention over configuration. Una migración con product_id creará una clave externa al id en la tabla de productos .

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

+0

El enlace está roto. –

5

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

Todo puede estar bien ahora, pero piense qué pasará cuando su programador se vaya y alguien más tenga que hacerse cargo.

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

8

Supongo que está hablando de restricciones de clave foránea 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 programador está haciendo realmente esto de la manera correcta ya, entonces es lo que 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 después de eso la aplicación se ejecuta sin problemas otra vez. 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 dañada 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? Corregir el código 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 programa que habla a 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 muestra un feo mensaje de error sobre alguna restricción SQL no satisfecha. Esto es mucho y es preferible dejar datos no deseados en su base de datos empresarial, donde a su vez romperá todas sus aplicaciones o conducirá a 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 no para utilizar restricciones de clave externa.

4

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.

5

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

FKs permiten que el DBA para proteger la integridad de los datos de la torpeza de los usuarios cuando el programador no para hacerlo, ya veces para proteger contra la torpeza de los programadores.

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

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

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

Aunque esta no es la razón por la que se crearon, los FK brindan una fuerte y confiable alusión a las herramientas de diagramación y a los constructores de consultas. Esto se transmite a los usuarios finales, quienes necesitan desesperadamente consejos confiables.

+0

Esta es una gran respuesta. – Dan

7

Las FK son muy importantes y siempre deben existir en su esquema, unless you are eBay.

+1

buen enlace allí – Quibblesome

+2

ese enlace es realmente muy fascinante ... realmente me gustaría saber más detalles y estoy algo asustado de usar ebay ahora. para otras personas: haga clic en la 4ª pregunta para ver lo que dice sobre su estructura de db. sin embargo, vale la pena ver toda la entrevista. también ... 'unibrow' –

2

Reducción de la 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 que la suposición debe ser forzada por algo. En las bases de datos, "algo" son claves foráneas.

Creo que vale la pena 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 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, 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 dado 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?

Cuestiones relacionadas