Restricciones en bases de datos relacionales: ¿por qué no eliminarlas por completo?

20

¿Hay alguna razón para construir restricciones entre tablas (dentro del servidor SQL) hoy en día? ¿Si es así cuando? La mayoría de las aplicaciones en mi área se basan en principios de objetos y las tablas se unen bajo demanda. La demanda se basa en la necesidad de la aplicación. No cargaré un montón de tablas restringidas para una búsqueda simple, que a su vez (después de la acción) requiere una búsqueda simple.

Las herramientas ORM como EntityContext, Linq2Data, NHibernate también manejan las restricciones por sí mismas, al menos usted sabe qué tablas se necesitan entre sí. ¿Hacer restricciones dentro del servidor consiste en hacer (forzar) los mismos cambios dos veces?

Por lo general, esto no es una cuestión pendiente de decisión, pero esta base de datos está diseñada de manera bastante diferente. El diseño se ve bien, en su mayoría refleja los objetos utilizados por las aplicaciones. Lo que me preocupa son todas las restricciones configuradas dentro de SQLserver con "no en cascada". Lo que significa que debe jugar "buscar y encontrar" al codificar nuevas consultas de bases de datos. Algunos casos requieren hasta 10 niveles de un orden exacto para hacer una sola eliminación.

Esto me sorprende y no estoy seguro de cómo manejarlo.

En mi mundo simple, esa configuración hace que las restricciones pierdan la mayor parte del propósito. OK si se accedió a la base de datos desde hosts sin conocimiento del diseño.

¿Cómo actuarías en este escenario?
¿Por qué no simplemente eliminar todas las restricciones de db y mantenerlas en el nivel de aplicación?

Independiente
fuente
66
¿Planeaba acceder siempre a los datos a través de una única herramienta ORM? ¿O planeaba divertirse replicando todas las restricciones correctamente en cada herramienta ORM en uso?
Donal Fellows
1
Según mi último comentario a Peter, tengo que estar de acuerdo. El punto de confiar todas las restricciones a la base del código (y eliminarlas de db) era muy limitado y probablemente sea totalmente aplicable a aplicaciones de corta duración. Probablemente también para algunos desarrolladores / proyectos RAD.
Independiente
44
Minipick: creo que se vuelve un poco confuso cuando llamas a las conexiones de clave externa entre las tablas "relaciones". Las "relaciones" en una base de datos relacional son las tablas mismas, no las conexiones. Especialmente cuando luego continuamos y hablamos sobre "diseño relacional", ¿eso significa tablas o significa claves foráneas?
Thomas Padron-McCarthy
Gracias. Llamo a las "conexiones entre las tablas" por restricciones. Por lo tanto, probablemente tiene razón en que veo "base de datos relacional" para los principios del diseño de tablas (estructura de tablas). Una descripción aún más precisa sería "patrón de diseño", cuando se relaciona con la base de datos "relación versus objeto".
Independiente
1
Su base de datos va a sobrevivir a su código de aplicación. Además, su ORM está perjudicando el rendimiento de su aplicación y hay una buena posibilidad de que termine deseando evitarlo al menos en ciertos casos de uso. Si no lo sabes ahora, lo sabrás eventualmente. samsaffron.com/archive/2011/03/30/… . Además, eliminar todas las restricciones deja su base de datos completamente incapaz de proteger su propia integridad cuando es abusada por aplicaciones que no sean la suya, lo que podría ser cualquier cosa, desde otra aplicación real hasta un ejecutivo en el pasillo con Excel.
Craig

Respuestas:

46

Dos razones generales para no eliminar las improntas de DB :

  • Se puede acceder a él mediante más aplicaciones, ahora o en el futuro , que pueden usar ORM o no. Incluso si los desarrolladores de esas aplicaciones duplican fielmente todas las restricciones allí (lo que puede ser significativamente más difícil usando soluciones no ORM de nivel inferior), siempre es un trabajo extra. Y si no, incluso una pequeña omisión es suficiente para romper la integridad del esquema ... que es algo que no quiere arriesgar. En la mayoría de las empresas, los datos almacenados en su base de datos son el elemento vital de su negocio, por lo que su integridad debe garantizarse por cualquier medio. Y el mejor medio probado para lograr esto es implementar tantas restricciones como sea posible en la base de datos.
  • El optimizador de consultas depende mucho de las restricciones conocidas en el nivel de base de datos. Si elimina restricciones, el rendimiento de la consulta puede comenzar a deteriorarse . Es posible que no lo note de inmediato, pero un día lo golpeará y, para entonces, puede ser demasiado tarde para solucionarlo fácilmente. La naturaleza de las cosas es que el rendimiento de la base de datos tiende a romperse en el momento de carga máxima, cuando existe la menor posibilidad de realizar mejoras de diseño cuidadosas y bien pensadas, respaldadas por mediciones de rendimiento exactas y análisis detallados para identificar las causas fundamentales.

Su caso concreto parece que el esquema DB puede haber sido generado originalmente por una herramienta ORM (o diseñado por alguien que no tiene mucha experiencia en el mundo relacional), por lo que es subóptimo desde el punto de vista relacional. Probablemente sea mejor analizarlo y mejorarlo hacia un diseño relacional más "natural", mientras lo mantiene consistente con las vistas ORM. Puede ser útil involucrar a un experto en DB en este análisis.

Péter Török
fuente
55
@Jonas, luego habla con el chico sobre los problemas percibidos con su diseño de base de datos. Relacional y orientado a objetos son dos mundos diferentes: ninguno es una "mejora" sobre el otro per se, y ambos tienen su propio lugar. Diseñar una aplicación C # en principios relacionales es un error tan grande como diseñar una base de datos de la manera original.
Péter Török
3
@Jonas, reflexionando sobre sus actualizaciones: si necesita escribir consultas demasiado complejas para lograr cosas aparentemente simples contra el esquema de la base de datos, es una señal de que el diseño de la base de datos es inadecuado para su propósito, o de que no tiene la habilidad suficiente (por favor no se ofenda, no es obvio por su publicación lo experimentado que es con SQL. Como descargo de responsabilidad, yo mismo estoy lejos de ser un experto.)
Péter Török
1
Probablemente tengo algunas expresiones para aprender, para hacerme perceptible :). Volví a leer la pregunta y las respuestas y tengo que revertir. Definitivamente, hay un punto fuerte que tiene DB como maestro para todas las restricciones. Todos los sistemas deben diseñarse a partir de eso. Una visión muy limitada para decir que la base del código haría el trabajo. Si cada sistema puede tener su propia decisión sobre las restricciones, esto terminará en un capítulo alto con relaciones sugeridas erróneas y tablas enteras huérfanas. Si no ahora, entonces ocurre más tarde con otros codificadores.
Independiente
8
"Se puede acceder a más aplicaciones, ahora o en el futuro". Sin mencionar a algún administrador de base de datos, que ejecuta consultas SQL sin procesar para solucionar un problema con la base de datos, mientras los usuarios esperan ...
Thomas Padron-McCarthy
55
+1: si db está almacenando datos comerciales (no solo la configuración de la aplicación, etc.), la probabilidad de que la base de datos salga en vivo o se extienda fuera de la aplicación actual se aproxima al 100%
Binary Worrier
27

Las aplicaciones pueden ir y venir, pero los datos viven para siempre. En mi empresa, la base de datos tiene más de 30-40 años, vivirá mientras exista la empresa. Las aplicaciones cambian, los desarrolladores van y vienen. Es mejor tener integridad y un buen modelo de datos lógicos. De esa manera, alguien puede ver los datos y obtener una comprensión significativa sin tener que pasar por una base de código compleja. Esto también ayuda a informar de manera significativa. También las aplicaciones pueden y tendrán errores y la restricción de DB es una protección contra eso. Mi posición predeterminada es tener tanta restricción (FK y verificación) como sea posible.
La única razón para no tener una restricción sería si su patrón de diseño no lo permite, por ejemplo, Tabla por jerarquía o problemas de rendimiento.

softveda
fuente
Diré que estás haciendo un consejo muy sabio aquí. Mi opinión puede coincidir mejor con el desarrollo de RAD o cualquier desarrollo donde las aplicaciones tengan una vida útil corta, solo por el mantenimiento minimizado durante el desarrollo.
Independiente
15

Lo que me preocupa son todas las restricciones configuradas dentro de SQLserver con "no en cascada".

Eso no me molesta, eso significa que alguien ha demostrado tener sentido común. Las eliminaciones en cascada a menudo son muy malas para la base de datos. En primer lugar, a veces desea que falle una eliminación si tiene datos en tablas relacionadas. Por ejemplo, si tiene un cliente que tiene un pedido en el pasado, no desea que se elimine o pierde los datos sobre para quién fue el pedido y una eliminación en cascada eliminará el registro que arruinaría sus informes financieros .

Parece pensar que la facilidad de desarrollo es lo más importante. En el mundo de la base de datos esto simplemente no es cierto. La integridad de los datos es lo primero más crítico, seguido de cerca por el rendimiento y la seguridad de los datos. Si lleva más tiempo escribir las consultas, que así sea.

Por lo general, muchas aplicaciones actúan sobre la base de datos = uno o más sitios web o aplicaciones de escritorio, una aplicación de informes, servicios web, la ventana de consulta, procesos ETL, etc. Si no aplica restricciones en el nivel de la base de datos, primero pierde la integridad de los datos como una de esas aplicaciones puede no seguir todas las reglas. En segundo lugar, debe codificar esas restricciones varias veces y volver a escribirlas si decide utilizar una aplicación diferente más adelante. En tercer lugar, no puede controlar de antemano si será necesario realizar algún tipo de tarea de mantenimiento de datos que no se realizará a través de la aplicación (por ejemplo, arreglando los datos de una importación de datos de un cliente incorrecto o cambiando todos los 10,000,000 registros de un cliente a otro cliente cuando la compañía es comprada por un competidor). Por lo general, los desarrolladores de aplicaciones no '

HLGEM
fuente
Gracias por responder. Todos los procesos y tipos de aplicaciones de los que habla deben comunicarse con un DAL (que a su vez contendría las restricciones). ¡PERO! Tu punto es perfecto y tu comentario es bueno. Nota al margen: sí. Tiendo a probar formas de facilitar el desarrollo. Para mí, menos complejidad puede significar menos formas de hacer el mal. Esto no es "querer desarrollar más fácil / más rápido", incluso si pudiera serlo, si se maneja mal. ¡Por eso publico esta pregunta! También vería a alguien con sentido común si esta no cascada se eligió con sentido, no al 100% como en este escenario. Tengo que averiguar las razones.
Independiente
@Jonas, puede haber razones de rendimiento también. Depende del número de registros secundarios. Está bien si está eliminando grupos pequeños pero si se pueden activar millones de registros, es mejor hacer lotes y no bloquear todas las tablas mientras ocurre todo el proceso. En general, muchos dbas no permitirán eliminaciones en cascada solo por esa razón, ya que puede bloquear un sistema de producción si una eliminación afecta a demasiados registros.
HLGEM
2
No, todos los procesos no deben hablar con un DAL. Los procesos de ETL generalmente no suceden ni las cosas que deben suceder a nivel de la base de datos que afectan a muchos registros cuando ocurre un gran cambio (como el cliente que se compra). Tampoco puede prohibir que alguien use la ventana de consulta para hacer un cambio único. Nunca he visto una base de datos que no imponga restricciones a nivel de base de datos que no haya tenido problemas de integridad con el tiempo.
HLGEM
10

Una vez leí en alguna parte que decía básicamente: Los datos son la clave de su aplicación . Si solo tendrá acceso a los datos a través de su interfaz de usuario (y quiero decir siempre , como ahora y para siempre, por toda la eternidad ... o la vida útil de su aplicación, de todos modos) entonces no necesita restricciones de la base de datos. Pero siempre existe la posibilidad de que algo más que la propia aplicación necesite tocar datos, por ejemplo, un servicio web, API pública, tarea de rastrillo / trabajo SQL / cron / script automatizado, y luego se ahorrará muchos problemas potenciales en el futuro. camino manteniendo las restricciones DB.

Creo firmemente que esta es el área de desarrollo de software en la que no debe aplicar DRY (y estoy totalmente esperando un montón de votos negativos para esa declaración). Sus datos son el corazón y el alma de su aplicación; si alguna vez se corrompe sin posibilidad de reparación, eso: se acabó el juego. Vale la pena en mi opinión hacer cumplir las restricciones en todas partes donde se necesitan. Si eso significa en forma de disparadores y restricciones en el nivel de base de datos, validaciones del lado del servidor en el middleware y Javascript del lado del cliente en la interfaz de usuario (para aplicaciones web), entonces es IMO un mal necesario para garantizar que los datos siempre estén impecables .

Wayne Molina
fuente
6

¿Sabes lo que significa ORM? Mapeo objeto-relacional. Citando Wikipedia "técnica para convertir datos entre sistemas de tipos incompatibles ". Sí, los modelos relacionales y de objetos no encajan entre sí. Los ORM hacen una conversión bastante buena, respetando las reglas de ambos sistemas de tipos. Los RDBMS están organizados de tal manera que logra la integridad de los datos mediante el uso de restricciones. En general, es muy bueno tener integridad, por lo que los ORM tienden a usarlos al crear un modelo de datos para almacenar datos de objetos. Su ORM probablemente tiene una buena razón para usar restricciones "no en cascada". Y si esto lo obliga a realizar consultas complicadas en lugar de simplemente crear / actualizar / soltar ciertos objetos, entonces algo está mal con su configuración ORM.

Si considera que el concepto relacional es molesto, ¿por qué no utiliza la base de datos de objetos? Hace algún tiempo eran lentos (razón por la cual la mayoría de las personas todavía usan RDBMS), pero por lo que escuché, las cosas cambiaron un poco. Te deshacerías de todos los nitpicks relacionales. Simplemente objetos adentro, objetos afuera.

Jacek Prucia
fuente
El tema trata acerca de sacar la funcionalidad de restricción de DB y confiar en la configuración / desarrollo dentro de la base del código (por ejemplo .net hablando: Entity / Linq2Sql).
Independiente
Sí, lo sé, pero mi punto es que primero debe comprender por qué las restricciones están allí en primer lugar y luego por qué podría ser una mala idea eliminarlas.
Jacek Prucia
¡Movido! No se cayó Entiendo que lamentas el conocimiento de la pregunta, de la que no se trataba.
Independiente
Realmente no puedes mover nada entre sistemas incompatibles. Va a eliminar las restricciones de la base de datos, introducir restricciones de la aplicación y simplemente esperar que funcionen de la misma manera (lo que podría resultar tanto verdadero como falso). De todos modos, mi sincera disculpa si entendí mal tu pregunta.
Jacek Prucia
¡Gracias! "Mover" significa "movimiento" literario. Lo que significa que crea restricciones de aplicación (buena expresión) en cada sistema. Al menos cada sistema que no puede compartir el mismo DAL. Un ejemplo muy bueno fueron las consultas directas de un administrador de db que "arreglan algo". Sin restricciones de db y la falta de conocimiento del diseño pueden resultar en datos huérfanos o datos completamente burlados.
Independiente
6

Bueno, eso es lo que hizo eBay y probablemente tengan una de las bases de datos más grandes del mundo:

http://www.dba-oracle.com/oracle_news/news_ebay_massive_oracle.htm http://www.addsimplicity.com/downloads/eBaySDForum2006-11-29.pdf

A pesar de lo que se ha dicho anteriormente sobre el aumento del rendimiento por la integridad referencial, en realidad puede degradarse; Es por eso que las bases de datos masivas han estado dejando caer sus restricciones y haciendo el trabajo en la capa de aplicación. Y por lo que puedo decir, es la única razón realmente buena.

Al eliminar esas restricciones, esencialmente pierde su red de seguridad que mantiene limpios los datos y genera sus propios problemas. Entonces, como con todo, es un acto de equilibrio. Supongo que, en general, mantener la integridad referencial es lo correcto.

Después de haber trabajado en un entorno de desarrollo con una fuerte integridad referencial, sé que desde el punto de vista del desarrollador puede ser un dolor total; a menudo, en un entorno de desarrollo, un poco de datos sucios no importa y determinar cómo eliminar una fila puede llevar una hora o más. Sin embargo, también puede ser muy útil, ya que las restricciones hacen que el esquema sea explícito.


fuente
Finalmente alguien que me entienda :-). Tienes toda la razón, el equilibrio es un gran punto aquí. Mover las restricciones al nivel de aplicación puede ser una alternativa segura, si se hace como un punto estratégico. Sería bueno con algunas URL a sitios que demuestren un rendimiento degradado debido a fuertes restricciones / integridad.
Independiente
10
Sí, y no olvide, no olvide , que Ebay, como Facebook y Amazon, es muchísimo más grande que el 99.99% de las bases de datos, y lo que es bueno para ellos es probablemente muy diferente de lo que es bueno para su base de datos.
Tony Andrews
2
Y eBay, Facebook, Amazon probablemente no utilicen bases de datos sin restricciones para su software financiero y contable o su software de inventario o sus datos de recursos humanos o en cualquier lugar donde no sea crítico perder datos.
HLGEM
2
Si tiene suficiente tiempo, experiencia y dinero, puede eventualmente programar cualquier RDBMS, servidor web o sistema operativo para satisfacer una necesidad específica.
JeffO
1
eBay no hizo eso hasta que el gran volumen de pérdida de datos con el que estaban lidiando esencialmente superó la capacidad de los servidores de bases de datos para hacer frente, y tuvieron millones para invertir en su nueva arquitectura. Si está haciendo miles de millones de transacciones al día, entonces, por supuesto, prepárese para eliminar las restricciones e ir a un sistema totalmente escalable, sin transacciones y masivamente escalable como eBay. De lo contrario, no subestimes tu servidor de base de datos y no dejes que la base de datos esté sujeta a corrupción de datos al eliminar todas tus restricciones.
Craig
4

Primero, mi respuesta: No, no debe confiar solo en la aplicación para cuidar sus datos.

Esto apunta a un debate más amplio: los ORM han fomentado una cultura de desdén por la interacción "directa" de DB, a menudo a expensas de la normalización / integridad referencial. Las tablas se asignan a la fuerza a jerarquías de objetos arbitrarias, a expensas del diseño implícito en el modelo relacional. El desacoplamiento favorecido por OOP se sacrifica aquí, ya que la aplicación hace que su diseño se sienta en la estructura de datos. Si bien ORM ha demostrado una gran utilidad, parece estar basado en el abuso o la desconfianza de SQL.

Nuevos paradigmas están (re) emergiendo, tome la programación funcional por ejemplo. Si el equipo de desarrollo decide adoptar una nueva metodología de programación, ¿qué implicaciones tendrá esto para los datos que se han estructurado de acuerdo con los requisitos del ORM?

Estoy de acuerdo con @Jacek Prucia: creo que ORM es una mala combinación para RDBMS, personalmente optaría por un DBAL en RDBMS, o elegir un OODB con ORM.

sunwukung
fuente
+1 para hablar alternativas al tema. El otro lado del debate es, por supuesto: "¿Qué tan malos serían algunos datos?" y la respuesta puede ser la cancelación o la inserción de mil millones de dinero en una cuenta bancaria de un millón de dólares. Además de algunos datos huérfanos que se eliminan con buenas rutinas de limpieza. El resumen de este tema parece coherente con el costo de la flexibilidad. Lo que a su vez depende completamente de la gravedad del contenido y uso de la base de datos.
Independiente
3

Las restricciones son su única garantía de que tiene consistencia e integridad de datos a nivel de base de datos. Claro, puede imponer restricciones utilizando el código de su aplicación, pero ¿qué sucede si, en el futuro, necesita modificar los datos directamente? Es posible que comprenda cómo mantener la integridad de los datos, pero alguien más podría no hacerlo. Mantener las restricciones en el nivel de datos garantiza que se garantice la integridad, incluso cuando alguien está haciendo el ridículo en lugares que no entienden.

Además, supongamos que su aplicación necesita ser reescrita, pero con la misma base de datos en su lugar. Todas esas restricciones en el código solo están pidiendo errores que impiden alguna entrada al tiempo que permiten el paso de datos erróneos.

Al desarrollar, manténgalo simple. Las restricciones te permiten hacer eso. (Dicho esto, cuando una restricción arroja un error, no escupe el mismo error al usuario. Haga que el error sea comprensible).

(En cuanto al problema de la cascada: eso es algo bueno. Preferiría arrojar un error de que ciertos otros registros deben eliminarse primero, en lugar de confiar en la cascada para hacer todo bien. Las cascadas son buenas en teoría, pero no necesariamente así en la práctica)

Kerri Shotts
fuente
2

Un problema con las restricciones en una base de datos es que le dan al programa información limitada sobre lo que falló y cómo solucionarlo. Esto significa que, para un manejo fluido, a menudo es necesario repetir la verificación de restricciones en la aplicación y, por lo tanto, la verificación de restricciones de la base de datos es un esfuerzo inútil.

Esto corre el riesgo de comprometer la integridad de los datos, por lo que tenemos compensaciones aquí. Para los datos importantes, garantizar la integridad de los datos es casi siempre más importante que el rendimiento, y es mucho mejor fallar una transacción incluso si parece arbitraria que arruinar los datos.

Para eliminar restricciones de forma segura, es vital asegurar el acceso a la base de datos para que nada pueda cambiar la base de datos sin verificar las restricciones. Esto no es confiable al escribir nuevas aplicaciones o idear formas ad hoc de tratar los datos, ya que todo lo que se necesita es un error y la base de datos está dañada.

Por lo tanto, para prescindir de las restricciones de la base de datos, es necesario establecer qué se puede y qué no se puede hacer con la base de datos por adelantado, para que todas las aplicaciones se puedan escribir, revisar y probar exhaustivamente. Todos los requisitos de la base de datos deben establecerse por adelantado y cualquier cambio en los requisitos de la base de datos requerirá un trabajo extenso. Esto es algo así como una metodología de cascada congelada, que funciona solo en casos muy específicos. (Diseñar, implementar y cumplir con los requisitos es muy parecido a caminar sobre el agua. Primero hay que congelar algo, y si no se congela lo suficiente, los resultados pueden ser desastrosos).

Un caso en el que funciona son las aplicaciones empresariales masivas como PeopleSoft y SAP, donde la aplicación ya hace prácticamente todo, y hay formas cuidadosamente definidas para extenderla. Hay otras posibilidades muy raras.

Entonces, a menos que trabaje en un proyecto empresarial muy grande (y no me gustaría hacerlo) o pueda caminar sobre agua líquida, deje esas restricciones en la base de datos.

David Thornley
fuente
1
Gracias por responder. ¡Las restricciones estarán en la base de datos para este proyecto! Estoy completamente convencido :). También tendré los ojos más abiertos cuando decida esto en proyectos futuros y en discusiones con otras partes.
Independiente
1
También tenga en cuenta que sin las restricciones, lo está dejando en manos del código de la aplicación para detectar que se equivocó. Ese es el mismo código de aplicación que violó la restricción en su ejemplo, por cierto, la restricción que salvó su base de datos de inconsistencia o corrupción de datos. El uso de restricciones tampoco significa automáticamente un menor rendimiento, por cierto, y no usar restricciones deja su base de datos expuesta para que no pueda protegerse.
Craig