¿Qué pasó con las restricciones de la base de datos?

46

Cuando reviso los modelos de base de datos para RDBMS, generalmente me sorprende encontrar pocas o ninguna restricción (aparte de PK / FK). Por ejemplo, el porcentaje a menudo se almacena en una columna de tipo int(mientras tinyintque sería más apropiado) y no hay ninguna CHECKrestricción para restringir el valor al rango 0..100. De manera similar en SE.SE, las respuestas que sugieren restricciones de verificación a menudo reciben comentarios que sugieren que la base de datos es el lugar incorrecto para las restricciones.

Cuando pregunto sobre la decisión de no implementar restricciones, los miembros del equipo responden:

  • O que ni siquiera saben que tales características existen en su base de datos favorita. Es comprensible para los programadores que usan ORM únicamente, pero mucho menos para los DBA que afirman tener más de 5 años de experiencia con un RDBMS determinado.

  • O que imponen tales restricciones a nivel de aplicación, y duplicar esas reglas en la base de datos no es una buena idea, violando SSOT.

Más recientemente, veo más y más proyectos en los que ni siquiera se usan claves externas. Del mismo modo, he visto algunos comentarios aquí en SE.SE que muestran que a los usuarios no les importa mucho la integridad referencial, permitiendo que la aplicación lo maneje.

Cuando preguntan a los equipos sobre la opción de no usar FK, les dicen que:

  • Es PITA, por ejemplo, cuando uno tiene que eliminar un elemento al que se hace referencia en otras tablas.

  • NoSQL es genial, y no hay claves foráneas allí. Por lo tanto, no los necesitamos en RDBMS.

  • No es un gran problema en términos de rendimiento (el contexto suele ser pequeñas aplicaciones web de intranet que trabajan en pequeños conjuntos de datos, por lo que incluso los índices no importarían demasiado; a nadie le importaría si el rendimiento de una consulta determinada pasa de 1,5 s . a 20 ms.)

Cuando miro la aplicación en sí, noto sistemáticamente dos patrones:

  • La aplicación desinfecta adecuadamente los datos y los verifica antes de enviarlos a la base de datos. Por ejemplo, no hay forma de almacenar un valor 102como porcentaje a través de la aplicación.

  • La aplicación supone que todos los datos que provienen de la base de datos son perfectamente válidos. Es decir, si 102viene como un porcentaje, algo, algún lugar se bloqueará, o simplemente se mostrará como es para el usuario, dando lugar a situaciones extrañas.

  • Si bien más del 99% de las consultas las realiza una sola aplicación, con el tiempo, los scripts comienzan a aparecer: los scripts se ejecutan a mano cuando es necesario o los trabajos cron. Algunas operaciones de datos también se realizan manualmente en la base de datos. Tanto los scripts como las consultas manuales de SQL tienen un alto riesgo de introducir valores no válidos.

Y aquí viene mi pregunta:

¿Cuáles son las razones para modelar bases de datos relacionales sin restricciones de verificación y eventualmente incluso sin claves foráneas?


Por lo que vale, esta pregunta y las respuestas que recibí (especialmente la interesante discusión con Thomas Kilian) me llevaron a escribir un artículo con mis conclusiones sobre el tema de las restricciones de la base de datos .

Arseni Mourzenko
fuente
8
Siento por ti, pero parece que ya sabes por qué las restricciones son una buena idea, por lo que no hay mucho que agregar en forma de respuesta. Sin embargo, señalaré que la falta de restricciones no es un fenómeno nuevo, lo he visto durante décadas en bases de datos diseñadas por desarrolladores sin una gran comprensión de las bases de datos relacionales. Creo que rara vez es una decisión de diseño deliberada.
JacquesB
1
@JacquesB: puede publicar una respuesta, ya que "lo he visto durante décadas" da una visión muy diferente de la que tuve sobre un fenómeno que apareció hace tres o cuatro años (dado que he trabajado en TI por menos de un década, mi visión del fenómeno es probablemente incorrecta). Por lo tanto, las conclusiones también serían muy diferentes.
Arseni Mourzenko
1
Trabajamos con muchos clientes. Y si bien la implementación de una nueva versión de nuestro software es pan comido, actualizar todas las bases de datos de esquemas en todas partes es una molestia. Es por eso que tenemos la mayoría de las limitaciones en el software. Ah, sí, una minúscula para un porcentaje a menudo no es una buena idea porque los porcentajes pueden ser fracciones.
Pieter B
1
Votar para reabrir esta pregunta ya que se ha cerrado incorrectamente como "principalmente basado en opiniones" cuando las respuestas hasta ahora muestran que ese no es el caso.
David Arno
3
Estoy contigo 110%.
Periata Breatta

Respuestas:

28

Es importante distinguir entre diferentes casos de uso para bases de datos.

Múltiples aplicaciones independientes y servicios acceden a la base de datos comercial tradicional y quizás directamente por usuarios autorizados. Es fundamental tener un esquema y restricciones bien pensadas a nivel de la base de datos, por lo que un error o supervisión en una sola aplicación no corrompe la base de datos. La base de datos es crítica para el negocio, lo que significa que los datos inconsistentes o corruptos pueden tener resultados desastrosos para el negocio. Los datos vivirán para siempre mientras las aplicaciones van y vienen. Estos son los lugares que pueden tener un DBA dedicado para garantizar la coherencia y el estado de la base de datos.

Pero también hay sistemas en los que la base de datos está estrechamente integrada con una sola aplicación. Aplicaciones independientes o aplicaciones web con una única base de datos integrada. Siempre que una única aplicación acceda a la base de datos, puede considerar las restricciones como redundantes, siempre que la aplicación funcione correctamente. Estos sistemas a menudo son desarrollados por programadores con un enfoque en el código de la aplicación y quizás sin una comprensión profunda del modelo relacional. Si la aplicación usa un ORM, las restricciones podrían declararse a nivel ORM de una forma más familiar para los programadores de aplicaciones. En el extremo inferior, tenemos aplicaciones PHP que usan MySQL, y durante mucho tiempo MySQL no admitió restricciones básicas, por lo que tuvo que confiar en la capa de aplicación para garantizar la coherencia.

Cuando los desarrolladores de estos diferentes orígenes se encuentran, obtienes un choque cultural.

En esta mezcla obtenemos la nueva ola de bases de datos distribuidas de "almacenamiento en la nube". Es muy difícil mantener una base de datos distribuida coherente sin perder el beneficio de rendimiento, por lo que estas bases de datos a menudo evitan las comprobaciones de coherencia a nivel de base de datos y, básicamente, permiten a los programadores manejarla a nivel de aplicación. Las diferentes aplicaciones tienen diferentes requisitos de consistencia, y aunque el motor de búsqueda de Google prioriza la disponibilidad sobre la consistencia en sus servidores, estoy dispuesto a apostar que su sistema de nómina se ejecuta en una base de datos relacional con muchas restricciones.

JacquesB
fuente
55
+! 1 por mencionar al elefante en la habitación: la falsa suposición de que una aplicación usa solo una base de datos y que una base de datos es usada por una sola aplicación
Tulains Córdova
44
@ TulainsCórdova, pensé que el elefante en la habitación aquí era el sistema de nómina de Google. :)
Machado
55
@Machado Esto es genial: "Estoy dispuesto a apostar que su sistema de nómina se ejecuta en una base de datos relacional con muchas restricciones".
Tulains Córdova
2
También es útil tener bases de datos restringidas adecuadamente ya que el código de su aplicación no es ACID.
Matthew Whited
3
Solo para enfatizar el comentario hecho por @MatthewWhited, no es posible que las aplicaciones impongan algunos tipos de restricciones entre filas / entre tablas sin realizar el bloqueo y ejecutar consultas adicionales. Un RDBMS puede hacerlo a un costo mucho menor.
David Aldridge
15

En la actualidad, cada vez más sistemas se ejecutan en entornos distribuidos, en la nube y adoptan la técnica para "escalar", en lugar de "escalar". Eso es aún más importante si se trata de aplicaciones en línea orientadas a Internet, como las aplicaciones de comercio electrónico.

Dicho esto, todas las aplicaciones que se supone que escalan están restringidas por el Teorema CAP , donde debe elegir 2 de 3: Consistencia, Disponibilidad y Tolerancia de Partición (tolerancia a fallas de red).

Al estudiar el teorema de la PAC, verá que no hay muchas opciones, sino elegir perder la Disponibilidad o la Consistencia, ya que NUNCA puede confiar realmente en la Red el 100% del tiempo.

En general, varias aplicaciones pueden permitirse ser inconsistentes durante un período de tiempo razonable, pero no pueden permitirse no estar disponibles para los usuarios. Por ejemplo, una línea de tiempo ligeramente desordenada en Facebook o Twitter es mejor que no tener acceso a una línea de tiempo.

Por lo tanto, varias aplicaciones están optando por dejar ir las restricciones de la base de datos relacionales, ya que las bases de datos relacionales son realmente buenas en Consistencia, pero a costa de la disponibilidad.

Nota personal: también estoy pasado de moda, y he estado trabajando con algunos sistemas financieros realmente antiguos donde la consistencia de los datos es un requisito de primera clase la mayor parte del tiempo, y soy un gran admirador de las restricciones de la base de datos. Las restricciones de la base de datos son la última línea de defensa contra años y años de mal desarrollo y equipos de desarrolladores que van y vienen.

"Est modus in rebus". Sigamos usando la consistencia de DB "bajo nivel" donde la consistencia es un requisito de primera clase. Pero a veces, dejarlo ir no es un gran pecado después de todo.

- EDITAR: -

Dado que hay una pequeña edición en la pregunta, hay otra razón legítima para eliminar las restricciones en la base de datos, IMO. Si diseña un producto desde cero, donde diseña su sistema para que sea compatible con la tecnología de bases de datos múltiples, puede conformarse con el mínimo común denominador entre las bases de datos compatibles y, finalmente, eliminar el uso de cualquier restricción, dejando toda la lógica de control para tu solicitud.

Aunque es legítimo, también es un área gris para mí, porque hoy no puedo encontrar ningún motor de base de datos que no admita restricciones simples como la propuesta en la pregunta original.

Machado
fuente
"Simplemente no puedo encontrar ningún motor de base de datos hoy que no admita restricciones simples como la propuesta en la pregunta original". ¿MySQL admite restricciones CHECK todavía?
Vincent Savard el
@VincentSavard, quizás no sea el CHECK MS SQL exacto, pero sí algún tipo de restricción: dev.mysql.com/doc/refman/5.7/en/constraint-invalid-data.html
Machado
@Machado: sin embargo, no se trata de restricciones específicas, sino de identificar cuándo las consultas incluyen datos que no se pueden representar en los tipos apropiados. Lo cual es una clara mejora en la situación hace años cuando MySQL simplemente ignoraba silenciosamente tales valores.
Periata Breatta
1
@PeriataBreatta, en una nota al margen, nunca entendí completamente por qué MySQL era la base de datos OSS "de facto" elegida por los desarrolladores de sitios web, cuando PostgreSQL estaba completamente disponible y era más avanzado. Tal vez fue más fácil de instalar, no lo sé.
Machado
@machado - No puedo estar seguro , pero sé que en los primeros días (a mediados de los 90) tendía a preferir mysql a postgres (que no fue renombrado a postgresql hasta más tarde) debido a una idea errónea de que postgres no era compatible con SQL (sus primeras versiones no lo eran, tenía su propio lenguaje de consulta llamado "postquel") y no me había mantenido al día con su desarrollo, así que no me había dado cuenta de que agregaron soporte para SQL aproximadamente al mismo tiempo mysql estuvo disponible). Si esta idea errónea era común, es posible que mysql se haya adelantado solo por eso. Y una vez que se adelantó, los efectos de la red se hicieron cargo.
Periata Breatta
10

¿Cuáles son las razones para modelar bases de datos relacionales sin restricciones de verificación y eventualmente incluso sin claves foráneas?

Primero aclaremos que estoy hablando aquí solo de RDBM, no de bases de datos sin SQL.

He visto algunas bases de datos sin FK o PK, y mucho menos verificando restricciones, pero para ser sincero, son una minoría. Quizás porque trabajo en una gran empresa.

En mi experiencia a través de los años, puedo decir que algunas razones pueden ser:

  • En el caso de principiantes o programadores de pasatiempos , todas las habilidades de modelado
  • Uso extenso o casi exclusivo de ORM sin contacto real con el mundo de la base de datos
  • Ausencia de un DBA u otro experto en modelado de datos en un equipo o proyecto pequeño
  • Falta de participación del DBA o experto en modelado de datos en las primeras etapas del desarrollo
  • Las decisiones de diseño deliberado por parte de la comunidad de desarrolladores que considera que incluso una restricción de comprobación que hace cumplir que una determinada columna sólo puede tener 1,2 or 3como valor, o que la columna de "edad" debe ser >= 0es "tener la lógica de negocio en la base de datos" . Algunos consideran que incluso las cláusulas predeterminadas son lógicas comerciales que no pertenecen a una base de datos, como puede ver en varias preguntas y respuestas recientes en este mismo sitio. Estos desarrolladores que así lo consideran, obviamente usarían la menor cantidad de restricciones posible y harán todo en código, incluso integridad referencial y / o unicidad. Creo que esta es una posición extrema.
  • Uso de RDBM como almacenamientos de valores clave , ya sea para emular el comportamiento sin SQL porque los requisitos son lo suficientemente simples como para ser satisfechos mediante el uso de tablas RDBMS como aislamientos de repositorios de valores clave.
  • Suponiendo que "la aplicación" siempre escriba en la base de datos y que nadie necesite realizar una carga masiva de datos, o editar o insertar filas a través de un cliente SQL (en muchos casos para corregir los datos erróneos que la aplicación insertó). En el mejor de los casos, siempre habrá otra aplicación (además de "la aplicación") que emite instrucciones DML a la base de datos: un cliente SQL.
  • Sin darse cuenta de que los datos pertenecen al propietario del negocio , no a la aplicación.

Dicho esto, me gustaría afirmar que RDBMS son piezas de software muy avanzadas que se han construido sobre los hombros de gigantes y han demostrado ser muy eficientes para muchos requisitos comerciales, liberando a los programadores de tareas mundanas de imponer la integridad referencial en una serie de archivos binarios o archivos de texto. Como siempre digo "ya no vivimos en un mundo de una aplicación, una base de datos" . Como mínimo, un cliente SQL emitirá DML además de "la aplicación". Por lo tanto, la base de datos debe defenderse de errores humanos o de programación en un grado razonable

En los tipos de requisitos bien conocidos en los que RDBMS no escalará bien, adopte la tecnología sin SQL . Pero es preocupante la proliferación de bases de datos relacionales sin restricciones, donde miles de líneas de código (generadas o escritas) dedicadas a aplicar lo que el RDBMS debería aplicar para usted de manera más eficiente.

Tulains Córdova
fuente
3

Existen limitaciones externas que impulsan las decisiones tecnológicas. Solo hay algunas situaciones en las que tiene la necesidad o el lujo de utilizar las restricciones de campo de la base de datos de manera regular.

  1. Las empresas tienen desarrolladores para aplicaciones y bases de datos junto con DBA, pero la mayoría de los desarrolladores no trabajan en este tipo de entorno. Hacen todo lo que pueden en el código. Además, algunos del lado de la base de datos no se involucran en las reglas comerciales. Principalmente están ahí para mantener las cosas funcionando. Nunca presionarán por restricciones en la base de datos. Tener que lidiar con aplicaciones heredadas, integraciones, migraciones, fusiones, adquisiciones, una restricción db puede ser la mejor solución.
  2. La sobrecarga de la base de datos puede crear un cuello de botella que no se resuelve fácilmente lanzando más máquinas al problema. Hay algunas situaciones en las que el lenguaje db no maneja algunos problemas de programación sin un impacto importante en el rendimiento, por lo que no puede planear usar una restricción para todo. Stackoverflow tiene un servidor de base de datos porque arrojar 2 a un problema es un desafío.
  3. Pruebas automatizadas: están llegando allí, pero muchos desarrolladores de db llegan tarde a la fiesta junto con los marcos IDE / testing.
  4. Implementación: más cosas de db lo hacen más complicado. ¿Qué sucede cuando no se permite una actualización de la base de datos de un cliente porque hay datos que violan la restricción? El juego termina a menos que tengas una manera de abordar esto. En su aplicación, puede decidir dejar que el usuario maneje esto según sea necesario o indicar a algún administrador que lo haga en un lote.
  5. Solo la aplicación / api / service escribirá datos en la base de datos, entonces, ¿por qué molestarse? Esto se mantiene la mayor parte del tiempo y es por eso que no es común.
  6. Manejar errores de db es bastante difícil sin cientos de violaciones de restricciones con las que lidiar si todo se sale de control. La mayoría está feliz de hacer una conexión y obtener el nombre correcto de la tabla.

Muchos equipos de desarrollo no quieren dar demasiado control a un desarrollador de db. Tienes suerte si obtienes más de uno, por lo que las vacaciones son muy divertidas. No muchos requieren un control absoluto sobre el dominio de la base de datos y se responsabilizan de cada consulta, regla comercial, rendimiento, disponibilidad, seguridad y qué datos van a qué RAID. Estos son los procedimientos almacenados que puede ejecutar. Que te diviertas. Ni siquiera pienses en tocar una mesa.

JeffO
fuente
2

Este es un problema que he tenido problemas con toda mi carrera (casi 40 años) y también al escribir mi DBMS. Una descripción de mi punto final está aquí: http://unibase.zenucom.com . Así que aquí están mis pensamientos.

  1. En términos generales, la mayoría de las restricciones se manejan mejor en la aplicación para que diferentes partes de la aplicación puedan aplicar restricciones diferentes. por ejemplo, un código de estado podría no aplicarse en todas las jurisdicciones.
  2. Como un lado ten cuidado con%. Los recargos son> 100% o te vas a la quiebra :)
  3. Las restricciones se describen mejor negativamente. es decir, lo que no pueden ser, no lo que deberían ser. Siempre es una lista más simple.
  4. Las claves foráneas siempre son buenas y deben usarse. Fullstop. FK es una de las pocas construcciones semánticas en un RDBMS y es muy útil. La mayor dificultad es decidir si dejar que un valor cuelgue si se elimina el FK o usar filas dependientes como una razón para no eliminar el registro FK.
  5. Las restricciones en el mundo real suelen ser más complejas que una restricción de valor de campo único.
  6. Algunas restricciones, incluso a nivel de aplicación, funcionan en contra de las buenas operaciones. Por ejemplo, la verificación agresiva de la fecha oculta errores en fechas aparentemente buenas. Necesita un error del operador para obtener una medida de los errores en fechas de aspecto razonable.
Rick Marshall
fuente
1

Las restricciones de la base de datos podrían haber sido una idea inteligente, pero ¿qué pasa con un uso práctico para ellas? Tome su restricción porcentual. Si aplica eso, su base de datos rechazará felizmente porcentajes inválidos. ¿Y entonces? Necesitará lógica de negocios para manejar la excepción. Lo que en realidad significa que la lógica de negocios al escribir un porcentaje incorrecto ya falló en otra parte. En resumen: la única restricción práctica que queda son las que ve (como PK / FK).

qwerty_so
fuente
15
Estoy cortésmente en desacuerdo con esto. Si realmente necesita la consistencia de los datos, las restricciones de la base de datos son imprescindibles, especialmente si su lógica empresarial está fallando. De la forma en que está describiendo el escenario, se produciría una falla silenciosa, donde el daño causado por una falla porcentual incorrecta se propagaría más en el sistema. Si tiene una restricción de la base de datos al respecto, fallaría rápidamente y, por lo tanto, les daría a los desarrolladores de lógica de negocios la oportunidad de ver el error temprano y parchear el sistema de lógica de negocios, en lugar de permitir que los datos corruptos entren en él.
Machado
55
Entiendo que si se viola la restricción de porcentaje, no tiene que manejar esta excepción, porque dicha violación indica que hay un error en su código en primer lugar (o alguien usó un entero simple en lugar de una instancia de Percentageclase, o hay un error en la validación en sí), a diferencia de un caso excepcional (como una conexión de red inactiva). Para mí, la violación debería llevar a HTTP 500 para una aplicación web o un bloqueo para una aplicación de escritorio, y luego debería registrarse y repararse.
Arseni Mourzenko
77
@ThomasKilian: no; exactamente lo contrario No entrarán los datos incorrectos, específicamente porque existen restricciones de la base de datos. Si su lógica empresarial es correcta en el código, nunca violará esas restricciones en primer lugar. Si se produjo un error en el código, esas restricciones lo alertarán sobre este error, mientras mantiene la base de datos a salvo del desecho.
Arseni Mourzenko
99
@ThomasKilian: No creo que nadie esté argumentando en contra de "hacer las cosas bien en primer lugar"; probablemente sea más que alguien con un poco de experiencia sabe que es una mala idea diseñar un sistema con la suposición de que usted lo hará haga todo bien la primera vez y nunca se producirán errores o errores durante la vida útil del sistema. Las restricciones de la base de datos aseguran que un error o error no dañe la base de datos.
JacquesB
3
@JacquesB Estoy luchando contra los molinos de viento. Si coloca la lógica de negocios en la base de datos, también puede fallar como en primer lugar y no salvarlo de la misma manera. Pero (!) Ahora tiene una lógica de negocios donde no pertenece. Creer que el DB puede salvar su podrida lógica de negocios es simplemente incorrecto. La lógica en la base de datos tiene que seguir las mismas reglas que toda la lógica de negocios.
qwerty_so
1

Más a menudo en estos días, las personas usan software (por ejemplo, Entity Framework) para generar tablas y columnas automáticamente. La idea es que no necesitan habilidades de SQL, liberando capacidad cerebral.

Las expectativas de que el software "resolverá las cosas" a menudo son poco realistas, y no crea las restricciones que un humano haría.

Para obtener mejores resultados, cree tablas con SQL y agregue restricciones manualmente, pero a veces las personas no pueden hacer esto.


fuente
Algunos marcos admiten agregar PK y FK (semi) automáticamente, por supuesto.
David Aldridge