database database-design foreign-keys referential-integrity data-integrity

database - ¿Qué pasa con las claves externas?



database-design foreign-keys (30)

Recuerdo haber escuchado a Joel Spolsky mencionar en el podcast 014 que casi nunca había usado una clave foránea (si recuerdo bien). Sin embargo, para mí, parecen ser muy importantes para evitar la duplicación y los problemas subsiguientes de integridad de los datos en toda su base de datos.

¿Las personas tienen algunas razones sólidas de por qué (para evitar una discusión en línea con los principios de desbordamiento de pila)?

Edición: "Todavía no tengo una razón para crear una clave externa, por lo que esta podría ser mi primera razón para configurar una".


Las claves externas complican las pruebas automatizadas

Supongamos que está utilizando claves externas. Estás escribiendo una prueba automatizada que dice "cuando actualizo una cuenta financiera, debería guardar un registro de la transacción". En esta prueba, solo te interesan dos tablas: accounts y transactions .

Sin embargo, las accounts tienen una clave externa para los contracts , y los contracts tienen un fk para los clients , y los clients tienen un fk para las cities , y las cities tienen un fk para los states .

Ahora la base de datos no le permitirá ejecutar su prueba sin configurar los datos en cuatro tablas que no están relacionadas con su prueba .

Hay al menos dos perspectivas posibles sobre esto:

  • "Eso es algo bueno: su prueba debe ser realista, y esas restricciones de datos existirán en la producción".
  • "Eso es algo malo: debería poder hacer pruebas unitarias del sistema sin involucrar otras piezas. Puede agregar pruebas de integración para el sistema en su conjunto".

También puede ser posible desactivar temporalmente las comprobaciones de claves externas mientras se ejecutan las pruebas. MySQL, al menos, soporta esto .

Actualización : siempre uso claves externas ahora. Mi respuesta a la objeción "ellos complicaron las pruebas" es "escriba sus pruebas unitarias para que no necesiten la base de datos. Cualquier prueba que use la base de datos debería usarla correctamente, y eso incluye claves externas. Si la configuración es dolorosa, Encuentra una forma menos dolorosa de hacer la configuración ".


"Antes de agregar un registro, verifique que exista un registro correspondiente en otra tabla" es lógica de negocios.

Aquí hay algunas razones por las que no quieres esto en la base de datos:

  1. Si las reglas de negocio cambian, tiene que cambiar la base de datos. La base de datos deberá volver a crear el índice en muchos casos y esto es lento en tablas grandes. (Las reglas cambiantes incluyen: permitir a los invitados publicar mensajes o permitir que los usuarios eliminen su cuenta a pesar de haber publicado comentarios, etc.).

  2. Cambiar la base de datos no es tan fácil como implementar una solución de software al enviar los cambios al repositorio de producción. Queremos evitar cambiar la estructura de la base de datos tanto como sea posible. Cuanta más lógica de negocios haya en la base de datos, más posibilidades tendrá de cambiar la base de datos (y desencadenar la reindexación).

  3. TDD. En las pruebas unitarias, puede sustituir la base de datos por simulacros y probar la funcionalidad. Si tiene alguna lógica de negocios en su base de datos, no está haciendo pruebas completas y tendrá que hacer una prueba con la base de datos o replicar la lógica de negocios en el código para propósitos de prueba, duplicar la lógica y aumentar la probabilidad de que la lógica no funcione en la base de datos. mismo camino.

  4. Reutilizando tu lógica con diferentes fuentes de datos. Si no hay lógica en la base de datos, mi aplicación puede crear objetos a partir de registros de la base de datos, crearlos desde un servicio web, un archivo json o cualquier otra fuente. Solo necesito intercambiar la implementación del asignador de datos y puedo usar toda la lógica de mi negocio con cualquier fuente. Si hay lógica en la base de datos, esto no es posible y tiene que implementar la lógica en la capa del asignador de datos o en la lógica de negocios. De cualquier manera, necesitas esas verificaciones en tu código. Si no hay lógica en la base de datos, puedo implementar la aplicación en diferentes ubicaciones utilizando diferentes bases de datos o implementaciones de archivos planos.


"Pueden hacer que la eliminación de registros sea más complicada; no puede eliminar el registro" maestro "en el que hay registros en otras tablas en las que las claves externas violarían esa restricción".

Es importante recordar que el estándar SQL define las acciones que se realizan cuando se elimina o actualiza una clave externa. Los que conozco son:

  • ON DELETE RESTRICT : evita que se eliminen las filas de la otra tabla que tienen claves en esta columna. Esto es lo que Ken Ray describió anteriormente.
  • ON DELETE CASCADE : si se elimina una fila de la otra tabla, elimine las filas de esta tabla que hacen referencia a ella.
  • ON DELETE SET DEFAULT : si se elimina una fila de la otra tabla, establezca las claves foráneas que hagan referencia al valor predeterminado de la columna.
  • ON DELETE SET NULL : si se elimina una fila de la otra tabla, establezca cualquier clave foránea que haga referencia a esta tabla como nula.
  • ON DELETE NO ACTION : esta clave externa solo marca que es una clave externa; a saber, para su uso en los mapeadores OR.

Estas mismas acciones también se aplican a ON UPDATE .

El valor predeterminado parece depender de qué servidor sql está utilizando.


¿Qué tal el mantenimiento y la constancia a lo largo de los ciclos de vida de las aplicaciones? La mayoría de los datos tiene una vida útil más larga que las aplicaciones que los utilizan. Las relaciones y la integridad de los datos son demasiado importantes como para dejarlas con la esperanza de que el próximo equipo de desarrollo haga lo correcto en el código de la aplicación. Si no has trabajado en una base de datos con datos sucios que no respetan las relaciones naturales, lo harás. La importancia de la integridad de los datos será muy clara.


@imphasing: este es exactamente el tipo de mentalidad que causa las pesadillas de mantenimiento.

¿Por qué, oh, por qué ignoraría la integridad referencial declarativa, donde se puede garantizar que los datos sean al menos consistentes, en favor de la llamada "aplicación de software", que es una medida preventiva débil en el mejor de los casos?


Desde mi experiencia, siempre es mejor evitar el uso de FK en aplicaciones de base de datos críticos. No estaría en desacuerdo con los chicos de aquí que dicen que los FK son una buena práctica, pero no es práctico donde la base de datos es enorme y tiene enormes operaciones de CRUD / seg. Puedo compartir sin nombrar ... uno de los bancos de inversión más grandes no tiene un solo FK en las bases de datos. Estas restricciones son manejadas por los programadores mientras crean aplicaciones que involucran DB. La razón básica es que cada vez que se realiza un nuevo CRUD tiene que afectar a varias tablas y verificar cada inserción / actualización, aunque esto no será un gran problema para las consultas que afectan a filas individuales, pero crea una gran latencia cuando se trata de Procesamiento por lotes que cualquier gran banco tiene que hacer como tareas diarias.

Es mejor evitar los FK, pero su riesgo debe ser manejado por los programadores.


El argumento que he escuchado es que el front-end debe tener estas reglas comerciales. Las claves externas "agregan una sobrecarga innecesaria" cuando no debería permitir ninguna inserción que rompa sus restricciones en primer lugar. Estoy de acuerdo con esto? No, pero eso es lo que siempre he escuchado.

EDITAR: Supongo que se refería a restricciones de clave externa , no a claves externas como concepto.


Este es un problema de educación. Si en algún lugar de tu carrera educativa o profesional pasaste tiempo alimentando y cuidando bases de datos (o trabajaste estrechamente con personas talentosas que lo hicieron), entonces los principios fundamentales de las entidades y las relaciones están bien arraigados en tu proceso de pensamiento. Entre esos rudimentos está cómo / cuándo / por qué especificar claves en su base de datos (primaria, extranjera y quizás alternativa). Es una segunda naturaleza.

Sin embargo, si no ha tenido una experiencia tan completa o positiva en su pasado con los esfuerzos relacionados con RDBMS, es probable que no haya estado expuesto a dicha información. O tal vez su pasado incluya la inmersión en un entorno que era ruidosamente anti-base de datos (por ejemplo, "esos DBA son idiotas; nosotros pocos, elegimos pocos java / c # que los honderos de código salvarán el día"), en cuyo caso podría oponerse con vehemencia. para los arcanos balbuceos de algún dweeb que te dicen que los FK (y las limitaciones que pueden implicar) son realmente importantes si solo escuchas.

A la mayoría se les enseñó, cuando eran niños, que lavarse los dientes era importante. ¿Puedes arreglártelas sin eso? Claro, pero en algún lugar de la línea tendrá menos dientes disponibles de los que podría tener si se hubiera cepillado después de cada comida. Si las mamás y los papás fueran lo suficientemente responsables como para cubrir el diseño de la base de datos y la higiene bucal, no tendríamos esta conversación. :-)


Estoy de acuerdo con las respuestas anteriores en que son útiles para mantener la consistencia de los datos. Sin embargo, hubo un post interesante por Jeff Atwood hace algunas semanas que discutió los pros y los contras de los datos normalizados y consistentes.

En pocas palabras, una base de datos desnormalizada puede ser más rápida cuando se manejan grandes cantidades de datos; y puede que no le importe la consistencia precisa dependiendo de la aplicación, pero lo obliga a ser mucho más cuidadoso al tratar con los datos, ya que el DB no lo será.


Hay una buena razón para no usarlos: si no entiende su función o cómo usarlos.

En las situaciones equivocadas, las restricciones de clave externa pueden llevar a la replicación de accidentes en cascada. Si alguien elimina el registro incorrecto, deshacerlo puede convertirse en una tarea gigantesca.

Además, a la inversa, cuando necesita eliminar algo, si las restricciones están mal diseñadas, las restricciones pueden causar todo tipo de bloqueos que lo impiden.


La base de datos Clarify es un ejemplo de una base de datos comercial que no tiene claves primarias o externas.

http://www.geekinterview.com/question_details/18869

Lo curioso es que la documentación técnica hace todo lo posible para explicar cómo se relacionan las tablas, qué columnas usar para unirlas, etc.

En otras palabras, podrían haberse unido a las tablas con declaraciones explícitas (DRI) pero optaron por no hacerlo .

En consecuencia, la base de datos de Clarify está llena de inconsistencias y tiene un rendimiento inferior.

Pero supongo que hizo que el trabajo de los desarrolladores fuera más fácil, no tener que escribir código para tratar con la integridad referencial, como verificar las filas relacionadas antes de eliminarlas, agregarlas.

Y eso, creo, es el principal beneficio de no tener restricciones de clave externa en una base de datos relacional. Facilita el desarrollo, al menos desde el punto de vista de Devil-may-car.


La pregunta más grande es: ¿conducirías con la venda puesta? Así es como se desarrolla un sistema sin restricciones referenciales. Tenga en cuenta que los requisitos de negocio cambian, los cambios en el diseño de la aplicación, los supuestos lógicos respectivos en los cambios de código, la lógica misma se puede refactorizar, etc. En general, las restricciones en las bases de datos se establecen bajo supuestos lógicos contemporáneos, aparentemente correctos para un conjunto particular de aserciones y supuestos lógicos.

A través del ciclo de vida de una aplicación, las restricciones de referencia y las verificaciones de datos controlan la recolección de datos a través de la aplicación, especialmente cuando los nuevos requisitos impulsan cambios lógicos en la aplicación.

Para el tema de este listado , una clave externa no "mejora el rendimiento" por sí misma, ni "degrada el rendimiento" significativamente desde un punto de vista del sistema de procesamiento de transacciones en tiempo real. Sin embargo, hay un costo agregado para la verificación de restricciones en el sistema de "lote" de volumen ALTO. Entonces, aquí está la diferencia, el proceso de transacción en tiempo real vs. procesamiento por lotes - donde el costo generado, incurrido por controles de restricción, de un lote procesado secuencialmente representa un impacto en el rendimiento.

En un sistema bien diseñado, las verificaciones de la consistencia de los datos se realizarían "antes" de procesar un lote (sin embargo, aquí también hay un costo asociado); por lo tanto, no se requieren controles de restricción de clave externa durante el tiempo de carga. De hecho, todas las restricciones, incluida la clave externa, deben desactivarse temporalmente hasta que se procese el lote.

RENDIMIENTO DE LA CONSULTA : si las tablas se unen en claves externas, tenga en cuenta el hecho de que las columnas de claves externas NO ESTÁN INDEXADAS (aunque la clave primaria respectiva está indexada por definición). En este caso, al indexar una clave foránea, al indexar cualquier clave y unir las tablas en las ayudas indexadas con mejores rendimientos, no al unirse a una clave no indexada con una restricción de clave externa.

Cambio de temas , si una base de datos solo admite la visualización / representación de contenido del sitio web / etc y la grabación de clics, entonces una base de datos con restricciones completas en todas las tablas está sobre matada para tales propósitos. Piénsalo. La mayoría de los sitios web ni siquiera utilizan una base de datos para tal. Para requisitos similares, donde los datos solo se están registrando y no se hace referencia a ellos, utilice una base de datos en memoria, que no tiene restricciones. Esto no significa que no haya un modelo de datos, sí un modelo lógico, pero no un modelo de datos físicos.


La verificación de las restricciones de las claves externas requiere algo de tiempo de CPU, por lo que algunas personas omiten las claves externas para obtener un rendimiento adicional.


Las claves externas son esenciales para cualquier modelo de base de datos relacional.


Muchas de las personas que responden aquí están demasiado obsesionadas con la importancia de la integridad referencial implementada a través de restricciones referenciales. Trabajar en grandes bases de datos con integridad referencial simplemente no funciona bien. Oracle parece particularmente malo en las eliminaciones en cascada. Mi regla de oro es que las aplicaciones nunca deben actualizar la base de datos directamente y deben ser a través de un procedimiento almacenado. Esto mantiene el código base dentro de la base de datos, y significa que la base de datos mantiene su integridad.

Donde muchas aplicaciones pueden acceder a la base de datos, surgen problemas debido a restricciones de integridad referencial, pero esto se debe a un control.

También existe un problema más amplio, ya que los desarrolladores de aplicaciones pueden tener requisitos muy diferentes con los que los desarrolladores de bases de datos no necesariamente están tan familiarizados.


No hay buenas razones para no usarlos ... a menos que las filas huérfanas no sean un gran problema para ti, supongo.


Para citar a Joe Celko:

"como una tanga de talla 26, solo porque puedas no significa que debas!"

Estoy seguro de que hay muchas aplicaciones en las que puedes salirte con la tuya, pero no es la mejor idea. No siempre se puede contar con su aplicación para administrar adecuadamente su base de datos, y la administración franca de la base de datos no debe ser una gran preocupación para su aplicación.

Si está utilizando una base de datos relacional , parece que debería tener algunas relaciones definidas en ella. Desafortunadamente, esta actitud (no necesita claves externas) parece ser aceptada por muchos desarrolladores de aplicaciones que prefieren no ser molestados con cosas tontas como la integridad de los datos (pero es necesario porque sus empresas no tienen desarrolladores de bases de datos dedicados). Generalmente en las bases de datos juntas por estos tipos, tienes suerte de tener claves primarias;)


Para mí, si desea ACID estándares ACID , es fundamental contar con claves externas para garantizar la integridad referencial.


Pueden hacer que la eliminación de registros sea más complicada: no puede eliminar el registro "maestro" donde hay registros en otras tablas donde las claves externas podrían violar esa restricción. Puedes usar los disparadores para tener eliminaciones en cascada.

Si eligió su clave principal de manera imprudente, cambiar ese valor se vuelve aún más complejo. Por ejemplo, si tengo el PK de mi tabla de "clientes" como el nombre de la persona, y hago que esa clave sea un FK en la tabla de "pedidos", si el cliente desea cambiar su nombre, entonces es un problema real. Pero eso es solo un diseño de base de datos de mala calidad.

Creo que las ventajas en el uso de las teclas de encendido superan cualquier supuesta desventaja.


Razón adicional para usar claves externas: - Permite una mayor reutilización de una base de datos

Razón adicional para NO usar claves externas: - Está intentando bloquear a un cliente en su herramienta al reducir la reutilización.


Razones para usar llaves foráneas:

  • no conseguirás filas huérfanas
  • puede obtener un buen comportamiento "en eliminar cascada", limpiando automáticamente las tablas
  • conocer las relaciones entre las tablas en la base de datos ayuda al Optimizador a planificar sus consultas para la ejecución más eficiente, ya que puede obtener mejores estimaciones sobre la cardinalidad de las uniones.
  • Los FK dan una pista bastante grande sobre qué estadísticas son las más importantes de recopilar en la base de datos, lo que a su vez conduce a un mejor rendimiento
  • Permiten todo tipo de soporte generado automáticamente: los ORM pueden generarse ellos mismos, las herramientas de visualización podrán crear diseños de esquemas agradables para usted, etc.
  • alguien nuevo en el proyecto entrará en el flujo de las cosas más rápido, ya que de lo contrario las relaciones implícitas están explícitamente documentadas

Razones para no usar llaves foráneas:

  • está haciendo que el DB funcione extra en cada operación CRUD porque tiene que verificar la consistencia de FK. Esto puede ser un gran costo si usted tiene mucha rotación
  • Al hacer cumplir las relaciones, los FK especifican un orden en el que tiene que agregar / eliminar cosas, lo que puede llevar a que el DB se niegue a hacer lo que quiera. (Por supuesto, en tales casos, lo que intentas hacer es crear una fila huérfana, y eso no suele ser algo bueno). Esto es especialmente doloroso cuando está realizando actualizaciones de lotes grandes, y carga una tabla antes que otra, con la segunda tabla creando un estado coherente (pero debería estar haciendo ese tipo de cosas si existe la posibilidad de que la segunda carga falle y su la base de datos ahora es inconsistente?).
  • a veces, usted sabe de antemano que sus datos estarán sucios, usted acepta eso y desea que la base de datos lo acepte
  • solo estas siendo perezoso :-)

Creo (¡no estoy seguro!) Que la mayoría de las bases de datos establecidas proporcionan una manera de especificar una clave externa que no se aplica, y es simplemente un poco de metadatos. Dado que el no cumplimiento elimina todas las razones para no usar FK, es probable que deba seguir esa ruta si se aplica alguna de las razones en la segunda sección.


Repito la respuesta de Dmitriy - muy bien dicho.

Para aquellos que están preocupados por la sobrecarga de rendimiento que suelen aportar los FK, hay una forma (en Oracle) de obtener la ventaja del optimizador de consultas de la restricción de FK sin el costo de la validación de restricciones durante la inserción, eliminación o actualización. Eso es crear la restricción FK con los atributos RELY DISABLE NOVALIDATE. Esto significa que el optimizador de consultas ASUME que la restricción se ha aplicado al crear consultas, sin que la base de datos realmente aplique la restricción. Debe tener mucho cuidado aquí para asumir la responsabilidad cuando rellene una tabla con una restricción FK como esta para asegurarse absolutamente de que no haya datos en sus columnas FK que violen la restricción, como si lo hiciera. podría obtener resultados poco confiables de las consultas que involucran la tabla en la que se encuentra esta restricción FK.

Usualmente uso esta estrategia en algunas tablas en mi esquema de data mart, pero no en mi esquema de almacenamiento integrado. Me aseguro de que las tablas de las que estoy copiando los datos ya tengan aplicada la misma restricción, o que la rutina ETL aplique la restricción.


Si está absolutamente seguro de que el sistema de base de datos subyacente no cambiará en el futuro, usaría claves externas para garantizar la integridad de los datos.

Pero aquí hay otra muy buena razón en la vida real para no usar claves externas:

Está desarrollando un producto, que debe soportar diferentes sistemas de bases de datos.

Si está trabajando con Entity Framework, que es capaz de conectarse a muchos sistemas de bases de datos diferentes, es posible que también desee admitir bases de datos sin servidor de "fuente abierta de forma gratuita". No todas estas bases de datos pueden admitir sus reglas de clave externa (actualización, eliminación de filas ...).

Esto puede llevar a diferentes problemas:

1.) Es posible que se produzcan errores al crear o actualizar la estructura de la base de datos. Tal vez solo haya errores silenciosos, porque el sistema de base de datos simplemente ignora sus claves externas.

2.) Si confía en claves externas, probablemente realizará menos o incluso ninguna verificación de integridad de datos en su lógica empresarial. Ahora, si el nuevo sistema de base de datos no admite estas reglas de clave externa o simplemente se comporta de una manera diferente, debe volver a escribir la lógica de su negocio.

Puede preguntar: ¿Quién necesita diferentes sistemas de base de datos? Bueno, no todos pueden permitirse o quieren un servidor SQL completo en su máquina. Este es un software, que necesita ser mantenido. Otros ya han invertido tiempo y dinero en algún otro sistema DB. La base de datos sin servidor es ideal para clientes pequeños en una sola máquina.

Nadie sabe cómo se comportan todos estos sistemas de bases de datos, pero su lógica de negocios, con controles de integridad, permanece siempre igual.


Siempre los uso, pero luego hago bases de datos para sistemas financieros. La base de datos es la parte crítica de la aplicación. Si los datos en una base de datos financiera no son totalmente exactos, entonces realmente no importa cuánto esfuerzo ponga en su diseño de código / front-end. Estás perdiendo el tiempo.

También existe el hecho de que, en general, los sistemas múltiples necesitan interactuar directamente con la base de datos, desde otros sistemas que simplemente leen datos (Crystal Reports) a sistemas que insertan datos (no necesariamente utilizando una API que he diseñado; el administrador ingenioso que acaba de descubrir VBScript y tiene la contraseña SA para el cuadro de SQL). Si la base de datos no está tan a prueba de idiotas como sea posible, adiós a la base de datos.

Si sus datos son importantes, entonces sí, use claves externas, cree un conjunto de procedimientos almacenados para interactuar con los datos y cree la base de datos más difícil que pueda. Si sus datos no son importantes, ¿por qué está haciendo una base de datos para empezar?


Siempre pensé que era perezoso no usarlos. Me enseñaron que siempre se debe hacer. Pero entonces, no escuché la discusión de Joel. Puede que haya tenido una buena razón, no lo sé.


Solo conozco las bases de datos de Oracle, ninguna otra, y puedo decir que las claves externas son esenciales para mantener la integridad de los datos. Antes de insertar datos, se debe crear una estructura de datos y hacerla correctamente. Cuando se hace eso, y así se crean todas las claves primarias y externas, ¡el trabajo está hecho!

Significado: filas huérfanas? No. Nunca he visto eso en mi vida. A menos que un mal programador haya olvidado la clave externa, o si la haya implementado en otro nivel. Ambos son, en el contexto de Oracle, enormes errores, que conducirán a la duplicación de datos, a los datos huérfanos y, por lo tanto, a la corrupción de datos. No puedo imaginar una base de datos sin FK forzada. Me parece un caos. Es un poco como el sistema de permisos de Unix: imagina que todos son root. Piensa en el caos.

Las claves foráneas son esenciales, al igual que las claves primarias. Es como decir: ¿y si eliminamos las claves primarias? Bueno, el caos total va a suceder. Eso es lo que No puede mover la responsabilidad de la clave principal o externa al nivel de programación, debe estar en el nivel de datos.

Inconvenientes? Si, absolutamente ! Porque en la inserción, van a suceder muchas más comprobaciones. Pero, si la integridad de los datos es más importante que el rendimiento, es obvio. El problema con el rendimiento en Oracle está más relacionado con los índices, que vienen con PK y FK.


También creo que las claves foráneas son una necesidad en la mayoría de las bases de datos. El único inconveniente (además del impacto de rendimiento que viene con tener una consistencia forzada) es que tener una clave externa permite a las personas escribir código que asume que hay una clave externa funcional. Eso nunca debe ser permitido.

Por ejemplo, he visto personas que escriben código que se inserta en la tabla a la que se hace referencia y luego intenta inserciones en la tabla de referencia sin verificar que la primera inserción fue exitosa. Si la clave foránea se elimina más adelante, eso da como resultado una base de datos incoherente.

Tampoco tiene la opción de asumir un comportamiento específico en la actualización o eliminación. Aún debe escribir su código para hacer lo que quiera sin importar si hay una clave externa presente. Si asume que las eliminaciones están en cascada cuando no lo están, las eliminaciones fallarán. Si asume que las actualizaciones a las columnas de referencia se propagan a las filas de referencia cuando no lo están, sus actualizaciones fallarán. A los efectos de escribir código, es posible que no tenga esas características.

Si esas funciones están activadas, entonces su código las emulará de todas formas y perderá un poco de rendimiento.

Entonces, el resumen ... Las claves foráneas son esenciales si necesita una base de datos consistente. Nunca se debe asumir que las claves externas están presentes o son funcionales en el código que usted escribe.


También he escuchado este argumento: de personas que olvidaron poner un índice en sus claves externas y luego se quejaron de que ciertas operaciones fueron lentas (porque la comprobación de restricciones podría aprovechar cualquier índice). Entonces, para resumir: no hay una buena razón para no usar claves externas. Todas las bases de datos modernas soportan eliminaciones en cascada, así que ...


Tengo que secundar la mayoría de los comentarios aquí, las claves externas son elementos necesarios para garantizar que tenga datos con integridad. Las diferentes opciones para ON DELETE y ON UPDATE te permitirán sortear algunas de las "caídas" que las personas mencionan aquí con respecto a su uso.

Encuentro que en el 99% de todos mis proyectos tendré FK para hacer cumplir la integridad de los datos, sin embargo, existen esas raras ocasiones en las que tengo clientes que DEBEN conservar sus datos antiguos, independientemente de lo malos que sean ... pero luego dedico mucho tiempo a escribir el código que se usa para obtener solo los datos válidos de todos modos, por lo que se vuelve inútil.


Una vez cuando un FK puede causarle un problema es cuando tiene datos históricos que hacen referencia a la clave (en una tabla de búsqueda) aunque ya no desee que la clave esté disponible.
Obviamente, la solución es diseñar cosas mejor por adelantado, pero estoy pensando en situaciones del mundo real aquí donde no siempre tienes el control de la solución completa.
Por ejemplo: quizás tenga una tabla de consulta tipo de customer_type que enumera diferentes tipos de clientes; digamos que necesita eliminar un determinado tipo de cliente, pero (debido a restricciones comerciales) no puede actualizar el software del cliente, y nadie lo hizo. Cuando se desarrolla el software, el hecho de que sea una clave externa en otra tabla puede impedirle eliminar la fila aunque sepa que los datos históricos que hacen referencia a ella no son relevantes.
Después de ser quemado con esto unas cuantas veces, es probable que se aleje de la aplicación de las relaciones de la DB.
(No estoy diciendo que esto sea bueno, solo te explico una razón por la que puedes decidir evitar las restricciones de FK y DB en general)