¿Qué hay de malo con las claves foráneas?

259

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)?

Editar: "Todavía no tengo una razón para crear una clave foránea, por lo que esta podría ser mi primera razón para configurarla".

Zolomon
fuente
9
No creo que Joel no use FK, es solo que no hace que la base de datos los haga cumplir. ¡Lógicamente, siguen siendo FK!
Daren Thomas
66
Dice que no usa claves foráneas, pero estoy de acuerdo con Daren en que lo que quiere decir es que no usa CONSTRAINTS de claves foráneas. Una columna en una tabla cuyos valores deben tomarse de la clave primaria / única de otra tabla SON claves foráneas, ya sea que agregue la restricción o no.
Tony Andrews el
22
... En general, es una tontería no agregar la restricción: ASEGURA la integridad en todo momento, incluso si hay un error en el código de la aplicación o si está trabajando detrás de escena haciendo una "corrección" de datos.
Tony Andrews el
2
+1 Por el comentario de Tony. Hay demasiada confusión entre la función y el concepto lógico de claves foráneas.
JohnFx
44
@ Danman, no sé de dónde sacaste la impresión, creo que eso. De hecho, digo más arriba "En general es una tontería no agregar la restricción: ASEGURA la integridad en todo momento"
Tony Andrews

Respuestas:

352

Razones para usar claves extranjeras:

  • no obtendrás filas huérfanas
  • puede obtener un buen comportamiento "al eliminar la 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 una ejecución más eficiente, ya que puede obtener mejores estimaciones sobre la cardinalidad de unión.
  • Los FK dan una pista bastante grande sobre qué estadísticas son más importantes para recopilar en la base de datos, lo que a su vez conduce a un mejor rendimiento
  • permiten todo tipo de soporte autogenerado: los ORM pueden generarse por sí 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 cosas más rápido ya que de lo contrario las relaciones implícitas se documentan explícitamente

Razones para no usar claves extranjeras:

  • está haciendo que el DB funcione más en cada operación CRUD porque tiene que verificar la consistencia de FK. Esto puede ser un gran costo si 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 desea. (De acuerdo, en tales casos, lo que está tratando de hacer es crear una fila huérfana, y eso no suele ser algo bueno). Esto es especialmente doloroso cuando está realizando grandes actualizaciones por lotes, y carga una tabla antes que otra, con la segunda tabla creando un estado consistente (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 sabes de antemano que tus datos estarán sucios, lo aceptas y quieres que la base de datos lo acepte
  • solo estás siendo vago :-)

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.

SquareCog
fuente
12
Buena lista! Los DBM no verificarán la consistencia de la parte "R" de CRUD, por lo que sacaría esa parte. Además, probablemente sea un lavado porque en su aplicación hace lo mismo que hace el DBMS: ¡verificará y se asegurará de que la ID principal sea válida antes de CRD y que en realidad sea más lenta que hacer que los DBM lo hagan!
Matt Rogish
66
¿Qué sucede si alguien elimina al padre mientras está insertando hijos? En este momento cuando envío "agregar comentario", si ya ha eliminado su respuesta, este comentario ahora es huérfano. Los FK lo habrían evitado. Además, podría cambiar el parentID para que sea lo que quiera. Alguien necesita verificar. :)
Matt Rogish
77
Precisamente, debería ser el trabajo de la base de datos, ya que es el único que puede garantizar la transaccionalidad frente a múltiples clientes concurrentes.
SquareCog
3
+1 Excelente respuesta: podría pensarse en la segunda razón para no usar las restricciones FK "hace que sea más difícil romper la consistencia", ¡lo que en realidad suena como algo bueno !
Bill Karwin
9
Los beneficios de usar claves foráneas LEJOS superan cualquier beneficio de no usarlos en mi opinión.
Nick Bedford
80

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. :-)

Ed Lucas
fuente
61
Voy a usar las destiladas "llaves foráneas son como cepillarse los dientes: adelante, no lo haga, pero tenga cuidado cuando sonríe"
Mark Sowul
55
Personalmente, considero que los principios de RDBMS 'son mucho más simples y mucho mejor definidos que los de la higiene bucal'
Ali Gangji
10 años en el futuro, estoy seguro de que este diseño de base de datos hablará con mi hijo / a para que él / ella no se equivoque y termine siendo la razón del próximo colapso de Wall Street debido a un problema con la base de datos.
VarunAgw
52

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;)

AlexCuse
fuente
26
Realmente no entiendo a las personas que no tienen FK en su base de datos. La última vez que trabajé con alguien que no lo tenía, dijo "no, lo aplicamos en la solicitud". Excepto que hice una encuesta de todas las bases de datos de clientes y descubrí que la mayoría de ellos tenían huérfanos ...
ErikE
1
Ese generalmente parece ser el caso. Creo que podría salirse con la suya SOLO en la base de datos (siempre y cuando a sus usuarios no les importen las excepciones de tiempo de ejecución), pero tener ambos es realmente el único camino a seguir.
AlexCuse
Todo está en las transcripciones / la respuesta de Atwood "Atwood: ... basándose en las claves externas que estableces en los índices, se dan cuenta ... Spolsky: [risas] Suponiendo que hagas eso. Atwood: Bueno, suponiendo que configuraste tu base de datos correctamente ... "
MemeDeveloper
44
Las bases de datos no se denominan relacionales debido a las relaciones entre tablas (¡CADA tipo de base de datos tiene algún tipo de relación entre entidades!), Sino porque las tablas en sí son relaciones , en términos matemáticos. Ver Wikipedia .
Massimiliano Kraus
41

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

Galuego
fuente
54
El modelo, si. La implementación, no esencial, solo probablemente útil.
dkretz 01 de
44
Lo sentimos, pero la razón principal por la cual los desarrolladores de aplicaciones no usan los sistemas de administración de bases de datos de objetos (también conocidos como bases de datos NoSQL) es más ampliamente debido a la inversión en RDBMS. La mayoría de las veces la base de datos (no el sistema de administración de la base de datos) es un modelo de objetos de nivel medio que a menudo involucra cachés distribuidos. Aquí es donde la eliminación en cascada, la propiedad y la sincronización de los cambios tienen que suceder de todos modos. El RDBMS se utiliza principalmente para la persistencia de este modelo de objetos, y generalmente después de un ejercicio ORM minucioso y prácticamente inútil. ¡La mayoría de las veces los modelos de relación no son necesarios!
Sentinel
2
no, las claves externas no son obligatorias para indicar "relacional"
Silver Moon
Esto realmente no explica mucho.
Nae
29

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?

Hormiga
fuente
2
Buena idea Yo diría que los datos son tan importantes para cada aplicación que realmente se usa. Lo único que difiere son las consecuencias de los datos corruptos. Son altos para su tipo de aplicación ...
Jay Godse
20

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: accountsy transactions.

Sin embargo, accountstiene una clave externa para contracts, y contractstiene una fk para clients, y clientstiene una fk para cities, y citiestiene una fk para 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 bueno: su prueba debe ser realista, y esas restricciones de datos existirán en la producción".
  • "Eso es algo malo: debería poder unir las piezas de prueba del sistema sin involucrar a otras piezas. Puede agregar pruebas de integración para el sistema en su conjunto".

También es posible desactivar temporalmente las comprobaciones de clave externa mientras se ejecutan las pruebas. MySQL, al menos, es compatible con esto .

Nathan Long
fuente
Por lo general, me encuentro por el camino medio aquí: uso FK, luego escribo métodos auxiliares de prueba de unidad que configuran la base de datos para admitir varios escenarios de prueba, por ejemplo, un método auxiliar para poblar "ciudades" y "estados" para cualquier prueba que necesitan esas tablas pobladas.
Joelpt
Quizás debiste haber usado tablas de enlaces entre las entidades no relacionadas. O vaya más allá: DBS separado: considere la situación en una Arquitectura Orientada a Servicios, o Microservicio, donde cada elemento (clientes, cuentas, transacciones) son sistemas diferentes, con bases de datos diferentes. No hay FK entre ellos como todos. En este caso, los FK deben usarse para evitar datos huérfanos en subtablas para cada tipo de datos.
JeeBee
3
También hay DBMS que permiten a las limitaciones a aplazarse de forma que sólo se comprueban cuando se comprometa toda la transacción, por lo que el orden de inserción, actualización, borrado no importa
a_horse_with_no_name
2
Si está probando una actualización desde una capa empresarial, su entorno de desarrollo debería tener el FK presente. Cuando actualice su registro, debe tener los valores de columna que necesita para que la actualización se realice correctamente. De lo contrario, en mi humilde opinión, su prueba no es válida.
KeyOfJ
3
Tu base de datos ni siquiera debería participar en las pruebas de tu unidad, debes burlarte de ellas. En las pruebas de integración, estarían involucrados, pero cualquier problema debido a claves externas es algo en lo que sus usuarios también se encontrarán a menos que lo solucione.
Andreas Bergström
16

"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é servidor que está utilizando

Powerlord
fuente
14

@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?

Ed Guiness
fuente
Porque los desarrolladores involucrados nunca han abordado un problema que exige un modelo relacional no trivial, normalizado. Muchos problemas no, especialmente el tipo que abunda en la programación de tipo web / "redes sociales" que está de moda en la actualidad. Si lo que pasa por el back-end de un marco ORM satisface el problema en alfa, es poco probable que alguien piense mucho más sobre el modelado de datos. Muchos de estos problemas son manejados fácilmente por las tiendas K / V, las bases de datos de documentos o la serialización de objetos directos.
zxq9
12

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.

Kent Fredric
fuente
8
Eliminar una fila en producción sin respaldo no es un argumento válido. Si no los comprende, debería considerar aprender sobre ello en lugar de omitirlo.
Guillaume
2
@Guillaume Creo que su respuesta fue un poco sarcástica, no se debe tomar literalmente: si no los comprende, no los use. Pero, por supuesto , ambos deben comprenderlos y usarlos.
Benjamin
^ Esto. Son herramientas útiles, pero en manos de un novato, son herramientas peligrosas.
Kent Fredric
11

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

Matt Rogish
fuente
11
¿Por qué las filas huérfanas son un gran problema?
Seun Osewa
2
¿Qué pasa con multihilo? Pueden causar una pesadilla de subprocesos múltiples en ciertas situaciones. En una aplicación compleja con múltiples subprocesos que escriben en la base de datos que pueden encontrarse con objetos que necesitan referenciarse entre sí, es mejor controlar la integridad referencial en la lógica de negocios, particularmente si las tablas se van a volver estáticas después.
Keith Pinson
Estoy de acuerdo. Además, prefiero tener filas de ophan que pueda recuperar más adelante en el tiempo que descartarlas sin piedad.
PedroD
4

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.

jasbir L
fuente
Bueno, no sé por qué insertar 3 nuevas líneas dobles en lugar de espacios en blanco y cambiar dos palabras cuenta como '67% es Jonathan Leffler ', pero no creo que haya hecho algo así. El texto principal fue aportado por @jay (usuario 183837).
Jonathan Leffler el
Supuse que paragrahps no funcionaría aquí, como es el caso en la mayoría de los otros sitios. Entonces, lo puse todo como uno, usando negrita para el cambio de flujo.
jasbir L
3

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.

Dan
fuente
3

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.

Rachit
fuente
8
No creo que las prácticas de desarrollo en los grandes bancos establezcan el estándar de oro.
Adriaan Koster
3

"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:

  1. 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.).

  2. 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).

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

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

Tom B
fuente
2

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

Santiago Palladino
fuente
Jeff hace algunos buenos puntos. Sin embargo, Dan Chak en "Enterprise Rails" muestra una forma de diseñar tablas de caché que son esencialmente una copia desnormalizada de los datos. Las consultas se ejecutan rápidamente, y si la tabla no tiene que actualizarse, funciona bien. Creo que si sus datos impulsan el comportamiento (por ejemplo, el estado de la aplicación) de su aplicación, necesita que los datos se normalicen tanto como sea posible porque, de lo contrario, los datos inconsistentes conducen a un comportamiento inconsistente de la aplicación.
Jay Godse
Un almacén de datos desnormalizado puede ser útil al leer grandes volúmenes de datos en rutas de acceso consistentes y anticipadas . En todos los demás escenarios, esta es una falacia peligrosa.
Peter Wone
2

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.

Ed Guiness
fuente
El código para manejar una verificación de integridad referencial fallida es mucho más pequeño que el código para manejar datos inconsistentes.
Jay Godse
@ Jay de acuerdo! No pienses que estoy abogando por este enfoque.
Ed Guiness
2

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.

tvCa
fuente
1

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.

Ken Ray
fuente
55
Tiendo a borrar cosas raramente de todos modos. Solo marca tener un bit "Visible / activo".
Dana
1 para "Creo que las ventajas en el uso de las teclas fireign pesa más que cualquier desventajas supuestas"
Ian Boyd
2
Nunca, nunca cambias el valor de una clave primaria. Usted elimina toda la fila y volver a crear de manera diferente. Si cree que necesita cambiarlo , su esquema es defectuoso.
DanMan
Cambiar el nombre del cliente no sería un problema en absoluto SI su clave externa está configurada en el CustomerId (PK). en la tabla de pedidos. La única forma en que sería una molestia es si el FK se estableció en CustomerName, que nunca debería ser el caso. En mi humilde opinión
KeyOfJ
1

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.

remonedo
fuente
66
¿Cuánto tiempo de CPU se dedica a eliminar datos duplicados e inconsistentes?
Ed Guiness
Si, esto es verdad. En un sistema en el que trabajo, tenemos que insertar 10 - 40 gigas de datos a la vez en una base de datos y el rendimiento de FK con y sin es visible en el tiempo total que lleva.
Paul Mendoza
1

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

Arno
fuente
9
Creo que la razón real por la que algunos no utilizan las restricciones de FK (la mayoría, desde mi punto de vista) es la simple flojera con el pretexto de que pueden defender su flojera con su argumento de ahorro de rendimiento. Creo firmemente que la gran mayoría de los gastos de estupidez en los que incurre nuestra compañía se debe a la falta de cumplimiento de las restricciones de FK y al efecto dominó que esto tiene a través de una compañía. La falta de claves únicas es la otra cosa que me vuelve loco al lado de los procedimientos almacenados de más de 2000 líneas con 12 niveles de IF anidados y sangría aleatoria, pero me detendré ahora.
Chad
1

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.

lordscarlet
fuente
No ¡No le gustan las llaves reales!
ljs
Eso me asombra. Hay una gran diferencia entre no gustar las restricciones de claves externas y no gustar las claves externas. No estoy seguro de cómo tener una base de datos relacional sin ellos.
lordscarlet
Sí, me sorprendió cuando lo escuché. Sin embargo, podría haber sido involuntariamente irónico; tal vez publicará aquí y aclarará en algún momento :-)
ljs
1

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

CodeRot
fuente
1

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.

Mitchel Sellers
fuente
1

¿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
1

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.

Eric
fuente
1

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.

Mike McAllister
fuente
1

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.

Zak
fuente
55
"las aplicaciones nunca deben actualizar la base de datos directamente y deben realizarse mediante 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". <- Aquí se supone que la lógica en los procedimientos almacenados no puede violar la integridad de los datos, lo cual es simplemente incorrecto.
Tim Gautier
1

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.

Miguel
fuente
0

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

Kilhoffer
fuente
Fue más un comentario inesperado que una discusión, ¡aunque tal vez debería investigar con precisión lo que él piensa sobre el tema de forma independiente! Sin embargo, también sentía curiosidad por la opinión de la comunidad sobre este tema.
ljs
0

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_typeque 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)

hamishmcn
fuente
Si entiendo lo que está tratando de decir, creo que mi respuesta a eso sería eliminar lógicamente el registro en la tabla de búsqueda o archivar los datos históricos que ya no son relevantes y archivar el registro de búsqueda también.
Chad