Recuerdo haber escuchado a Joel Spolsky mencionar en el podcast 014 que apenas había usado una clave foránea (si no recuerdo mal). Sin embargo, para mí parecen bastante vitales para evitar la duplicación y los subsiguientes problemas de integridad de datos en toda su base de datos.
¿Las personas tienen algunas razones sólidas sobre por qué (para evitar una discusión en línea con los principios de desbordamiento de pila)?
Respuestas:
Razones para usar claves extranjeras:
Razones para no usar claves extranjeras:
Creo (¡no estoy seguro!) Que la mayoría de las bases de datos establecidas proporcionan una forma de especificar una clave foránea que no se aplica y que es simplemente un poco de metadatos. Dado que la falta de cumplimiento elimina todas las razones para no usar FK, probablemente deba seguir esa ruta si se aplica alguna de las razones en la segunda sección.
fuente
Este es un problema de educación. Si en algún momento de su carrera educativa o profesional pasó tiempo alimentando y cuidando bases de datos (o trabajó estrechamente con personas talentosas que lo hicieron), entonces los principios fundamentales de las entidades y las relaciones están bien arraigados en su proceso de pensamiento. Entre esos rudimentos se encuentra 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 el RDBMS, es probable que no haya estado expuesto a dicha información. O tal vez su pasado incluye la inmersión en un entorno que era vociferantemente anti-base de datos (por ejemplo, "esos DBA son idiotas, somos pocos, elegimos pocos slingers de código java / c # que salvarán el día"), en cuyo caso podría ser vehementemente opuesto a los balbuceos arcanos de algunos imbéciles que te dicen que los FK (y las limitaciones que pueden implicar) realmente son importantes si solo escuchas.
A casi todos se les enseñó cuando eran niños que lavarse los dientes era importante. ¿Puedes pasar sin eso? Claro, pero en algún momento 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 padres fueran lo suficientemente responsables como para cubrir el diseño de la base de datos y la higiene bucal, no estaríamos teniendo esta conversación. :-)
fuente
Estoy seguro de que hay muchas aplicaciones en las que puedes salirte con la tuya, pero no es la mejor idea. No siempre puede contar con que su aplicación administre adecuadamente su base de datos, y francamente, administrar la base de datos no debería ser una gran preocupación para su aplicación.
Si está utilizando una base de datos relacional , entonces parece que debería tener algunas relaciones definidas en ella. Desafortunadamente, esta actitud (no necesita claves externas) parece ser adoptada por muchos desarrolladores de aplicaciones que prefieren no molestarse con cosas tontas como la integridad de los datos (pero lo necesitan porque sus empresas no tienen desarrolladores de bases de datos dedicados). Por lo general, en las bases de datos reunidas por estos tipos tiene la suerte de tener claves principales;)
fuente
Las claves externas son esenciales para cualquier modelo de base de datos relacional.
fuente
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, realmente no importa cuánto esfuerzo pones en tu código / diseño front-end. Solo estás perdiendo el tiempo.
También existe el hecho de que varios sistemas generalmente necesitan interactuar directamente con la base de datos, desde otros sistemas que solo leen datos (Crystal Reports) hasta sistemas que insertan datos (no necesariamente usando una API que he diseñado; puede ser escrita por un gerente tonto que acaba de descubrir VBScript y tiene la contraseña SA para el cuadro SQL). Si la base de datos no es tan idiota como sea posible, bueno, 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 haga la base de datos más difícil que pueda. Si sus datos no son importantes, ¿por qué está creando una base de datos para empezar?
fuente
Actualización : siempre uso claves foráneas ahora. Mi respuesta a la objeción "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 foráneas. Si la configuración es dolorosa, encuentre una forma menos dolorosa de hacer la configuración ".
Las claves foráneas complican las pruebas automatizadas
Supongamos que está utilizando claves foráneas. Está escribiendo una prueba automatizada que dice "cuando actualizo una cuenta financiera, debería guardar un registro de la transacción". En esta prueba, solo le interesan dos tablas:
accounts
ytransactions
.Sin embargo,
accounts
tiene una clave externa paracontracts
, ycontracts
tiene una fk paraclients
, yclients
tiene una fk paracities
, ycities
tiene una fk parastates
.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:
También es posible desactivar temporalmente las comprobaciones de clave externa mientras se ejecutan las pruebas. MySQL, al menos, es compatible con esto .
fuente
"Pueden hacer que la eliminación de registros sea más engorrosa: no puede eliminar el registro" maestro "donde hay registros en otras tablas donde las claves externas violarían esa restricción".
Es importante recordar que el estándar SQL define las acciones que se toman 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 cualquier fila de esta tabla que haga referencia a ella.ON DELETE SET DEFAULT
- Si se elimina una fila en la otra tabla, establezca las claves externas que hacen referencia a la columna predeterminada.ON DELETE SET NULL
- Si se elimina una fila de la otra tabla, establezca las claves externas que hacen referencia a ella en esta tabla como nulas.ON DELETE NO ACTION
- Esta clave foránea solo marca que es una clave foránea; es decir, para usar en mapeadores OR.Estas mismas acciones también se aplican a
ON UPDATE
.El valor predeterminado parece depender de qué sql servidor que está utilizando
fuente
@imphasing: este es exactamente el tipo de mentalidad que causa pesadillas de mantenimiento.
¿Por qué? ¿Por qué ignorarías la integridad referencial declarativa, donde se puede garantizar que los datos sean al menos consistentes, a favor de la llamada "aplicación de software", que es una medida preventiva débil en el mejor de los casos?
fuente
Hay una buena razón para no usarlos: si no comprende su función o cómo usarlos.
En situaciones incorrectas, las restricciones de claves externas pueden conducir a la replicación en cascada de accidentes. Si alguien elimina el registro incorrecto, deshacerlo puede convertirse en una tarea gigantesca.
Además, a la inversa, cuando necesita eliminar algo, si está mal diseñado, las restricciones pueden causar todo tipo de bloqueos que lo impiden.
fuente
No hay buenas razones para no usarlas ... a menos que las filas huérfanas no sean un gran problema para ti, supongo.
fuente
La pregunta más importante es: ¿conducirías con los ojos vendados? Así es si desarrolla un sistema sin restricciones referenciales. Tenga en cuenta que los requisitos comerciales cambian, los cambios en el diseño de la aplicación, los supuestos lógicos respectivos en los cambios del código, la lógica en sí misma se puede refactorizar, etc. En general, las restricciones en las bases de datos se establecen bajo suposiciones lógicas contemporáneas, aparentemente correctas para un conjunto particular de aserciones y suposiciones lógicas.
A través del ciclo de vida de una aplicación, las comprobaciones de referencia y de datos restringen la recopilación de datos policiales a través de la aplicación, especialmente cuando los nuevos requisitos generan 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 el 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 alto volumen. Entonces, aquí está la diferencia, proceso de transacción en tiempo real versus proceso por lotes; procesamiento por lotes: donde el costo total, incurrido por verificaciones de restricciones, de un lote procesado secuencialmente representa un impacto en el rendimiento.
En un sistema bien diseñado, las verificaciones de consistencia de datos se realizarían "antes" de procesar un lote (sin embargo, también hay un costo asociado aquí); por lo tanto, no se requieren verificaciones de restricciones de clave externa durante el tiempo de carga. De hecho, todas las restricciones, incluida la clave externa, deben deshabilitarse temporalmente hasta que se procese el lote.
RENDIMIENTO DE CONSULTA : si las tablas se unen en claves foráneas, tenga en cuenta el hecho de que las columnas de claves foráneas NO ESTÁN INDEXADAS (aunque la clave primaria respectiva está indexada por definición). Al indexar una clave externa, para el caso, al indexar cualquier clave, y unir tablas en indexadas ayuda a obtener mejores rendimientos, no al unir claves no indexadas con restricciones de clave externa.
Cambiando de tema , si una base de datos solo admite la visualización del sitio web / contenido de representación / etc. y registra clics, entonces una base de datos con restricciones completas en todas las tablas se elimina por completo para tales fines. Piénsalo. La mayoría de los sitios web ni siquiera usan una base de datos para tal. Para requisitos similares, donde los datos solo se registran y no se mencionan por ejemplo, use 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 ningún modelo de datos físicos.
fuente
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 reduciendo la reutilización.
fuente
Desde mi experiencia, siempre es mejor evitar el uso de FK en aplicaciones críticas de bases de datos. No estaría en desacuerdo con los muchachos aquí que dicen que FK es una buena práctica, pero no es práctico donde la base de datos es enorme y tiene enormes operaciones CRUD / seg. Puedo compartir sin nombrar ... uno de los mayores bancos de inversión no tiene un solo FK en las bases de datos. Los programadores manejan estas restricciones mientras crean aplicaciones que involucran DB. La razón básica es que, cuando se realiza un nuevo CRUD, tiene que efectuar 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 latencia enorme cuando se trata procesamiento por lotes que cualquier gran banco tiene que hacer como tareas diarias.
Es mejor evitar los FK, pero los programadores deben manejar su riesgo.
fuente
"Antes de agregar un registro, verifique que exista un registro correspondiente en otra tabla" es lógica empresarial.
Aquí hay algunas razones por las que no quiere esto en la base de datos:
Si las reglas de negocio cambian, debe cambiar la base de datos. La base de datos necesitará recrear el índice en muchos casos y esto es lento en tablas grandes. (Las reglas cambiantes incluyen: permitir a los invitados publicar mensajes o permitir a los usuarios eliminar su cuenta a pesar de haber publicado comentarios, etc.).
Cambiar la base de datos no es tan fácil como implementar una solución de software empujando 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 aumentará las posibilidades de necesitar cambiar las bases de datos (y desencadenar la reindexación).
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 necesitaría probar con la base de datos o replicar la lógica de negocios en el código para fines de prueba, duplicando la lógica y aumentando la probabilidad de que la lógica no funcione en el mismo camino.
Reutilizando su 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 cambiar la implementación del mapeador de datos y puedo usar toda mi lógica de negocios con cualquier fuente. Si hay lógica en la base de datos, esto no es posible y debe implementar la lógica en la capa del mapeador de datos o en la lógica de negocios. De cualquier manera, necesita esos controles en su 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.
fuente
Estoy de acuerdo con las respuestas anteriores en que son útiles para mantener la consistencia de los datos. Sin embargo, hubo una publicación interesante de 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 es posible que no le importe la coherencia precisa según la aplicación, pero le obliga a ser mucho más cuidadoso al tratar con datos, ya que la base de datos no lo será.
fuente
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 decidieron no hacerlo .
En consecuencia, la base de datos Clarify está llena de inconsistencias y tiene un rendimiento inferior.
Pero supongo que facilitó el trabajo de los desarrolladores, ya que no tuvo que escribir código para lidiar con la integridad referencial, como verificar filas relacionadas antes de eliminar, agregar.
Y eso, creo, es el principal beneficio de no tener restricciones de clave externa en una base de datos relacional. Hace que sea más fácil de desarrollar, al menos desde el punto de vista del diablo.
fuente
Solo conozco las bases de datos de Oracle, no otras, 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 eso se hace, 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 implementó en otro nivel. Ambos son, en el contexto de Oracle, grandes 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. A mí 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 extranjeras son esenciales, al igual que las claves primarias. Es como decir: ¿y si eliminamos las claves principales? Bueno, el caos total va a suceder. Eso es lo que. No puede trasladar la responsabilidad de la clave principal o externa al nivel de programación, debe ser a nivel de datos.
Inconvenientes? Si, absolutamente ! Porque en la inserción, se realizarán 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.
fuente
Pueden hacer que la eliminación de registros sea más engorrosa: no puede eliminar el registro "maestro" donde hay registros en otras tablas donde las claves externas violarían esa restricción. Puede usar disparadores para tener eliminaciones en cascada.
Si elige 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 de esa clave un FK en la tabla de "pedidos", si el cliente quiere cambiar su nombre, entonces es un dolor real. . pero eso es simplemente un diseño de base de datos de mala calidad.
Creo que las ventajas en el uso de las teclas de fireign son mayores que las supuestas desventajas.
fuente
La verificación de restricciones de clave externa requiere algo de tiempo de CPU, por lo que algunas personas omiten claves externas para obtener un rendimiento adicional.
fuente
También escuché este argumento, de personas que olvidaron poner un índice en sus claves externas y luego se quejaron de que ciertas operaciones eran lentas (porque la verificación de restricciones podría aprovechar cualquier índice). En resumen: no hay una buena razón para no usar claves foráneas. Todas las bases de datos modernas admiten eliminaciones en cascada, así que ...
fuente
El argumento que escuché es que el front-end debería tener estas reglas comerciales. Las claves foráneas "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.
fuente
Para mí, si desea seguir los estándares de ACID , es fundamental contar con claves externas para garantizar la integridad referencial.
fuente
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 ELIMINAR Y ACTUALIZAR le permitirán evitar algunas de las "caídas" que la gente menciona 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 mantener sus datos antiguos, independientemente de cuán malos sean ... pero luego paso mucho tiempo escribiendo código que solo entra para obtener los datos válidos de todos modos, por lo que no tiene sentido.
fuente
¿Qué tal la mantenibilidad y la constancia en los ciclos de vida de la aplicación? La mayoría de los datos tienen una vida útil más larga que las aplicaciones que los utilizan. Las relaciones y la integridad de los datos son demasiado importantes para dejarlas con la esperanza de que el próximo equipo de desarrollo lo haga bien en el código de la aplicación. Si no ha trabajado en una base de datos con datos sucios que no respetan las relaciones naturales, lo hará. La importancia de la integridad de los datos quedará muy clara.
fuente
También creo que las claves externas son una necesidad en la mayoría de las bases de datos. El único inconveniente (además del éxito en el rendimiento que viene con 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 debería permitirse.
Por ejemplo, he visto a personas escribir código que se inserta en la tabla referenciada y luego intenta insertar en la tabla de referencia sin verificar que la primera inserción fue exitosa. Si la clave externa se elimina más adelante, eso da como resultado una base de datos inconsistente.
Tampoco tiene la opción de asumir un comportamiento específico en la actualización o eliminación. Aún necesita escribir su código para hacer lo que quiera, independientemente de si hay una clave externa presente. Si asume que las eliminaciones están en cascada cuando no lo están, sus eliminaciones fallarán. Si supone que las actualizaciones de las columnas referenciadas 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 características están activadas, su código las emulará de todos modos y perderá un poco de rendimiento.
Entonces, el resumen ... Las claves externas son esenciales si necesita una base de datos consistente. Nunca se debe suponer que las claves externas están presentes o son funcionales en el código que usted escribe.
fuente
Me hago eco de la respuesta de Dmitriy: muy bien dicho.
Para aquellos que están preocupados por la sobrecarga de rendimiento que a menudo aportan los FK, hay una manera (en Oracle) de que pueden obtener la ventaja del optimizador de consultas de la restricción de FK sin la sobrecarga de costos de la validación de la restricción durante la inserción, eliminación o actualización. 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 generar consultas, sin que la base de datos realmente aplique la restricción. Debe tener mucho cuidado aquí para asumir la responsabilidad cuando llene una tabla con una restricción FK como esta para asegurarse de que no tiene datos en sus columnas FK que violen la restricción, como si lo hiciera. podría obtener resultados poco confiables de consultas que involucran la tabla en la que está esta restricción FK.
Usualmente uso esta estrategia en algunas tablas en mi esquema de data mart, pero no en mi esquema de etapas integrado. Me aseguro de que las tablas de las que estoy copiando datos ya tengan la misma restricción impuesta, o la rutina ETL aplica la restricción.
fuente
Muchas de las personas que responden aquí se obsesionan demasiado 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 para eliminar en cascada. Mi regla general es que las aplicaciones nunca deben actualizar la base de datos directamente y deben realizarse a través de un procedimiento almacenado. Esto mantiene la base del código dentro de la base de datos y significa que la base de datos mantiene su integridad.
Cuando 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 hay un problema más amplio en el sentido de que los desarrolladores de aplicaciones pueden tener requisitos muy diferentes con los que los desarrolladores de bases de datos pueden no estar tan familiarizados.
fuente
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 de la vida real para no usar claves foráneas:
Está desarrollando un producto que debería admitir diferentes sistemas de bases de datos.
Si está trabajando con Entity Framework, que puede conectarse a muchos sistemas de bases de datos diferentes, es posible que también desee admitir bases de datos sin servidor "de código abierto y sin cargo". No todas estas bases de datos pueden admitir sus reglas de clave externa (actualizar, eliminar filas ...).
Esto puede conducir a diferentes problemas:
1.) Puede encontrarse con errores cuando se crea o actualiza la estructura de la base de datos. Tal vez solo habrá errores silenciosos, porque el sistema de base de datos simplemente ignora sus claves externas.
2.) Si confía en claves externas, probablemente hará menos o incluso ninguna verificación de integridad de datos en su lógica comercial. 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 reescribir su lógica de negocios.
Puede preguntar: ¿Quién necesita diferentes sistemas de bases de datos? Bueno, no todos pueden permitirse o quieren un servidor SQL completo en su máquina. Este es un software que debe mantenerse. Otros ya han invertido tiempo y dinero en algún otro sistema de base de datos. 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 empresarial, con comprobaciones de integridad, siempre permanece igual.
fuente
Siempre pensé que era flojo no usarlos. Me enseñaron que siempre debe hacerse. Pero entonces, no escuché la discusión de Joel. Puede haber tenido una buena razón, no lo sé.
fuente
Una vez que 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 desea que la clave esté disponible.
Obviamente, la solución es diseñar las cosas mejor desde el principio, 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 búsqueda
customer_type
que enumera los 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 ocultó esta situación. al desarrollar el software, el hecho de que sea una clave foránea en alguna otra tabla puede evitar que elimine la fila aunque conozca los datos históricos que hacen referencia a ella es irrelevante.Después de ser quemado con esto algunas veces, probablemente se aleje de la aplicación de relaciones db.
(No digo que esto sea bueno, solo le doy una razón por la que puede decidir evitar FKs y db contraints en general)
fuente