¿Por qué se aplican restricciones en la base de datos en lugar del código?


21

¿Por qué se aplican restricciones en la base de datos? ¿No será más flexible ponerlo en el código?

Estoy leyendo un libro para principiantes sobre la implementación de bases de datos, así que estoy preguntando esto como principiante. Digamos que he diseñado una base de datos, incluido este modelo de entidad:

 entity type    |   sub-types
----------------+--------------------------------------------
   Person       |   Employee, Student,       ...
   Student      |   Graduate, Undergraduate, ...
   Employee     |   Teacher,  Administrator, ...

Restricciones actuales:

  1. Una persona registrada en el sistema solo puede ser un Estudiante o un Empleado.
  2. La entidad de la persona requiere la unicidad del número social, que suponemos que cada persona tiene solo un único (también conocido como una clave primaria lo suficientemente buena ). (ver # 1)

Más tarde, decidimos eliminar el número 1: si un día la universidad decide que el Teacher(el Employeesubtipo) también puede ser Student, tomando cursos en su tiempo libre, es mucho más difícil cambiar el diseño de la base de datos que podría tener miles, millones, miles de millones, millones de entradas en lugar de simplemente cambiar la lógica en el código: solo la parte que no permitió que una persona se registrara como estudiante y como empleado.

(Es muy improbable, pero no puedo pensar en otra cosa en este momento. Aparentemente es posible).

¿Por qué nos interesan las reglas comerciales en el diseño de bases de datos en lugar de en el código?

# 1: Una nota 7 años después, un ejemplo de la vida real:
he visto un gobierno donde, por un error, se duplicaron los SSN emitidos: varias personas, el mismo SSN. Aquellos que diseñaron el DB original definitivamente cometieron el error de no aplicar esta restricción de unicidad en la base de datos. (¿y luego un error en la aplicación original? ¿múltiples aplicaciones que usan la base de datos compartida y no acuerdan dónde colocar, verificar y aplicar la restricción? ...).
Este error continuará viviendo en el sistema y todo el sistema desarrollado después de lo cual dependerá de la base de datos de ese sistema original, durante muchos años por venir. Leyendo las respuestas aquí, aprendí a aplicar todas las restricciones, tantas como sea posible, sabiamente (no a ciegas) en la base de datos para representar el mundo físico real lo mejor que pueda.


2
En su mayoría, nos preocupamos de que se apliquen las reglas comerciales y cuál es la mejor manera de hacerlo.
ypercubeᵀᴹ

3
En realidad, está presentando un muy mal ejemplo de para qué se utilizan las restricciones, ya que la flexibilidad de sus entidades y la capacidad de expansión de la base de datos se definen principalmente por la normalización. Dicho esto, las restricciones son la protección final contra cualquier dato corrupto que ingrese a la base de datos, incluso si la aplicación tiene errores, incluso si se desarrolla una nueva aplicación, incluso si se agrega una API externa, incluso si alguien edita la base de datos directamente. Las restricciones protegen la base de datos, además de eso, la lógica de negocios también tendrá que hacer sus propias cosas antes de intentar acceder a la base de datos.
Niels Keurentjes

3
En realidad, como estudiante de posgrado, soy considerado un estudiante, un empleado y un maestro. Entonces su ejemplo no es realmente improbable.
Winston Ewert

44
Nunca debe basar un diseño de base de datos en los objetos de su aplicación. Noramente diseñaría esto como persona, luego tendría una tabla relacionada para desinfectar los roles de las personas. Entonces el problema no surge, ya que tiene una tabla real para los roles, por lo que las personas pueden tener múltiples roles. Si desea tener una sola persona de rol, entonces restringe la tabla para que el peopleID sea único. Cuando desee cambiar eso, elimine la restricción.
HLGEM

Objeto <-> El mapeo relacional es un arte.
Thorbjørn Ravn Andersen

Respuestas:


34

Algunas restricciones se aplican mejor en la base de datos, y otras se aplican mejor en la aplicación.

Las restricciones que se aplican mejor en la base de datos generalmente están ahí porque son fundamentales para la estructura del modelo de datos, como una restricción de clave externa para garantizar que un producto tenga una validez category_id.

Las restricciones impuestas en una aplicación pueden no ser fundamentales para el modelo de datos, como todos los productos FooBar deben ser azules, pero luego alguien podría decidir que los FooBars también pueden ser amarillos. Esta es la lógica de la aplicación que realmente no necesita estar en la base de datos, aunque podría crear una colourstabla separada y la base de datos puede requerir que el producto haga referencia a una entrada válida de esa tabla. Pero la decisión de que el único registro en colourscuenta el valor blueque todavía venir de alguna parte fuera de la base de datos.

Considere lo que sucedería si no tuviera restricciones en la base de datos y requiriera que todas se aplicaran en la aplicación. ¿Qué pasaría si tuviera más de una aplicación que necesitara trabajar con los datos? ¿Cómo se verían sus datos si las diferentes aplicaciones deciden aplicar restricciones de manera diferente?

Su ejemplo muestra una situación en la que podría haber sido más beneficioso tener la restricción en la aplicación en lugar de en la base de datos, pero ¿tal vez hubo un problema fundamental con el modelo de datos inicial demasiado restrictivo e inflexible?


De acuerdo con esta respuesta, la regla <una persona solo puede existir en la tabla de subtipo de Estudiante o solo en la tabla de subtipo de Empleados> debe aplicarse en código, y la Base de Datos tiene <El subtipo de Estudiante / Empleado debe ser válido persona> restricción. Estoy en lo cierto? (Fue el ejemplo del libro). Gracias.
hkoosha

2
@loolooyyyy: Sí, creo que es correcto. Si la base de datos aplica la primera regla (que una persona solo puede ser un estudiante o un empleado), entonces la situación que describió (en la que un empleado desea registrarse para una clase) es imposible porque: la persona no puede ser ambas cosas, y no es incluso es posible crear un segundo registro de "persona" porque no pueden compartir Números de Seguro Social que presumiblemente son emitidos por un tercero (como el gobierno). Por supuesto, este modelo de datos demasiado restrictivo podría funcionar para algunos casos ...
FrustratedWithFormsDesigner

2
@loolooyyyy: Otra forma de usar el modelo de datos original y aún permitir que los maestros sean estudiantes podría ser tener otra tabla llamada, teachers_as_studentsque es otro subtipo de Studentsy tiene una nueva clave externa que hace referencia Teachers, y una clave primaria generada por el sistema , en lugar de un Social Numero de seguridad. De esta manera, un "estudiante" en realidad es un alias para un maestro, por lo que el maestro aún puede inscribirse para tomar una clase. Es difícil decir con certeza qué tan bien funcionaría esto sin ver todo el modelo de datos.
FrustratedWithFormsDesigner

2
Voté en contra de esto. No hay tiempo cuando una restricción se aplica mejor en la aplicación solamente. El tono de esta respuesta está ponderado incorrectamente.
Evan Carroll

3
@FrustratedWithFormsDesigner ciertamente, en realidad es el elemento secundario de una restricción de clave externa. Suponga que tiene tres clientes de diferentes versiones / compilaciones del punto de acceso db, ¿qué va a hacer cuando deje de enviar ese producto en rojo? ¿Dónde vas a almacenar la lista de posibles combinaciones de colores? Sugerencia: tengo un lugar centralizado para ti. Y si crea la tabla color_productsy colores probable que pueda crear los menús desplegables adicionales con más facilidad: la mayoría de los IDE / cargadores de esquemas, admiten las siguientes teclas.
Evan Carroll

35

Porque:

  1. Quiero que todos los datos en la base de datos estén sujetos a las mismas restricciones, no solo los nuevos datos estén sujetos a las restricciones en la versión del código que se está ejecutando hoy.
  2. Quiero restricciones declarativas, no restricciones programáticas.
  3. Los datos en la base de datos a menudo sobreviven al código que está escrito para interactuar con él hoy. Y esos datos, no el código, son el activo de la organización.
  4. Mi código se vuelve mucho más simple cuando sé que todos los datos están sujetos a restricciones rigurosas. Ya no tengo que considerar casos especiales que sé que la base de datos garantiza que son imposibles.

Solo algunas razones que son importantes para mí.


44
Semi-relacionado con (1) y (3): los errores en el código de la aplicación se pueden corregir, los errores en sus datos a menudo son irreparables.
mu es demasiado corto el

17

Los datos probablemente durarán más que el código de la aplicación. Si la regla es crítica para que los datos sean útiles con el tiempo (como restricciones de clave externa que ayudan a mantener la integridad de los datos), debe estar en la base de datos. De lo contrario, corre el riesgo de perder la restricción en una nueva aplicación que llega a la base de datos. No solo las aplicaciones múltiples llegan a las bases de datos (incluidas algunas que pueden no darse cuenta de que hay una regla de datos importante) sino que algunas de ellas, como las importaciones de datos o las aplicaciones de informes, pueden no ser capaces de usar la capa de datos configurada en la aplicación de entrada de datos principal. Francamente, en mi experiencia, las posibilidades de que haya un error en la restricción son mucho mayores en el código de la aplicación.

En mi opinión personal (basado en más de 30 años de tratar con datos y experiencia con cientos de bases de datos diferentes utilizadas para muchos propósitos diferentes), cualquiera que no ponga las restricciones en la base de datos a la que pertenecen tendrá eventualmente datos deficientes. A veces datos incorrectos hasta el punto de ser inutilizables. Esto es especialmente cierto cuando tiene datos financieros / reglamentarios que deben cumplir ciertos criterios para la auditoría.


17

La mayoría de las restricciones de integridad referenciales que se implementan fuera de la base de datos se pueden vencer, por lo que si desea que sus datos tengan integridad garantizada en todo momento, debe aplicar restricciones en la base de datos. Punto final, eso es.

Por lo general, las restricciones a nivel de aplicación se eliminan a través del mecanismo de coherencia de lectura de la base de datos, por el cual las sesiones no pueden ver los datos de otras sesiones hasta que se confirman.

Por ejemplo, dos sesiones pueden intentar insertar el mismo valor en una columna que pretende ser única. Ambos pueden verificar al mismo tiempo que el valor aún no existe, ambos pueden insertar su valor y ambos pueden confirmar. Una restricción única implementada en la base de datos no permitiría que esto suceda.

Por cierto, esto no es desconocido para los diseñadores de lenguaje de aplicación. Lea la sección 3.10 singularidad en las Guías de Ruby on Rails: Validaciones de registros activos y devoluciones de llamadas

Este asistente valida que el valor del atributo es único justo antes de que se guarde el objeto. No crea una restricción de unicidad en la base de datos, por lo que puede suceder que dos conexiones de base de datos diferentes creen dos registros con el mismo valor para una columna que pretende ser única. Para evitar eso, debe crear un índice único en su base de datos.


16

Beneficios de las restricciones impuestas por la base de datos:

Simplicidad : declarar una restricción es significativamente más simple que declarar una restricción y escribir el código que hará cumplir esa declaración.

Precisión : el código que no escribió nunca tendrá un error que haya creado. Los proveedores de bases de datos pasan tiempo asegurándose de que su código de restricción sea preciso, para que no tenga que hacerlo.

Velocidad : su aplicación nunca puede tener más distribuciones que la base de datos en la que se basa. Los proveedores de bases de datos pasan tiempo asegurándose de que su código de restricción sea eficiente, para que no tenga que hacerlo. La base de datos en sí también tiene un acceso más rápido a los datos que una aplicación podría tener sin importar cuán eficiente sea.

Reutilización : puede comenzar con una aplicación en una plataforma, pero puede que no permanezca así. ¿Qué sucede si necesita acceder a los datos desde un sistema operativo diferente, hardware diferente o desde una interfaz de voz? Al tener restricciones en la base de datos, este código nunca tiene que ser reescrito para la nueva plataforma y nunca tiene que ser depurado para mayor precisión o perfilado para la velocidad.

Integridad : las aplicaciones imponen restricciones cuando se ingresan datos en la base de datos y requerirían un esfuerzo adicional para verificar que los datos más antiguos sean precisos o para manipular los datos que ya están en la base de datos.

Longevidad : es probable que su plataforma de base de datos sobreviva a cualquier aplicación en particular.


11

¿Por qué se aplican restricciones en el servidor? Porque no puedes obligar a los malos a usar a tu cliente.

Para aclarar, si solo está procesando las reglas de negocios en su aplicación cliente, alguien que use otra herramienta puede conectarse al servidor de la base de datos y hacer lo que quiera sin estar limitado por ninguna de sus reglas de negocios y verificaciones de integridad. Evitar que alguien use una herramienta arbitraria en cualquier lugar de la red es muy difícil.

Si realiza la comprobación de integridad en el servidor de la base de datos, cada intento de acceder a los datos, independientemente de la herramienta, estará limitado por sus reglas.


10

Algunas excelentes respuestas aquí, y a riesgo de repetir otros pensamientos:

  • El SSN no es necesariamente único. Diablos, el SSN ni siquiera siempre se conoce, y en algunos casos no existe (todavía). Los SSN pueden reutilizarse y no todos los empleados o estudiantes pueden tener un SSN. Esto es periférico a la pregunta, pero demuestra que, sin importar dónde imponga sus restricciones, debe comprender el modelo de datos y el dominio bastante a fondo para tomar decisiones sobre las reglas comerciales.
  • Personalmente, prefiero que las restricciones estén lo más cerca posible de los datos. La razón muy simple es que no todos usarán el código de la aplicación para cambiar los datos en la base de datos. Si aplica las reglas de su negocio a nivel de aplicación y ejecuto una UPDATEdeclaración directamente en la base de datos, ¿cómo evita su aplicación un cambio no válido? Otro problema con las reglas de negocio en la aplicación es que recompilar / volver a implementar puede ser difícil, especialmente para aplicaciones distribuidas donde es posible que no todos reciban la actualización al mismo tiempo. Y finalmente, cambiar las reglas de negocio en la aplicación no hace absolutamente nada con los datos que ya existen que violan las nuevas reglas: si agrega la nueva restricción a los datos, debe corregir los datos.
  • Es posible que pueda justificar múltiples verificaciones redundantes en varios niveles. Todo esto depende de la flexibilidad de las metodologías de implementación, qué tan probable es un cambio y qué tan difícil es sincronizar un cambio de reglas de negocio en la base de datos y otras capas. Un argumento convincente para repetir las comprobaciones en la capa de la aplicación es que potencialmente puede evitar un viaje de ida y vuelta a la base de datos solo para fallar una restricción allí (dependiendo de la naturaleza de la restricción y si se basa en datos existentes). Pero si tuviera que elegir uno u otro, lo pondría en la base de datos por los motivos anteriores.

En el caso que mencione explícitamente, donde de repente está permitiendo algo que no estaba permitido anteriormente, esto no es realmente un problema: elimina cualquier restricción que se aplique, independientemente de dónde exista. En el caso opuesto, donde de repente a los maestros ya no se les permite ser estudiantes, es posible que tenga un montón de datos para limpiar, nuevamente, independientemente de dónde existía la restricción anteriormente.


9
  1. La base de datos puede verificar las restricciones de manera efectiva. Mejor que el código.

  2. Las restricciones de integridad ayudan a la base de datos a encontrar un plan de ejecución efectivo

  3. La aplicación ve una vista coherente de lectura, por lo tanto, difícilmente puede garantizar la unicidad. Mientras que la base de datos también puede ver datos no comprometidos.


8

Respuesta corta ... para preservar la integridad de los datos (es decir, precisión y validez).

Una excepción ...
Si la base de datos solo está almacenando datos de una sola aplicación para un solo usuario, como en la mayoría de las bases de datos Sqlite, es posible que no necesite restricciones. De hecho, generalmente no lo hacen, para mantener el tiempo de acceso tan rápido que no se puede medir.

Para todo lo demás ... Las
bases de datos siempre sirven a dos maestros que llamaré editores y usuarios .

Los editores en su mayoría colocan datos en la base de datos y recuperan datos uno o un pequeño número de registros a la vez. Sus principales preocupaciones son el acceso rápido y preciso a todos los datos relacionados y el almacenamiento rápido y confiable de sus cambios.

La mayoría de los usuarios recuperan datos y están más preocupados por el acceso rápido a información indudablemente precisa. A menudo necesitan varios recuentos, agregaciones y listados que solían generarse en esas pilas icónicas de impresiones de papel de barra verde, pero que generalmente terminan en las páginas web hoy en día.

Los proyectos de desarrollo de bases de datos casi siempre se inician a instancias de los Usuarios , pero el diseño se ve impulsado por las necesidades de entrada de datos y registro a la vez de los Editores . Como tal, los desarrolladores sin experiencia a menudo responden a la necesidad inmediata de velocidad (principalmente, de desarrollo ) al no poner restricciones en la base de datos.

Si una y sólo una aplicación es cada vez va a ser utilizado para realizar cambios en los datos de la totalidad de la vida de la base de datos, y que la aplicación está desarrollada por uno o un pequeño número de individuos bien coordinados, entonces podría ser razonable que depender de La aplicación para asegurar la integridad de los datos.

Sin embargo, por mucho que pretendamos que podemos predecir el futuro, no podemos.

El esfuerzo para producir cualquier base de datos es demasiado valioso para tirarlo. Como una casa, la base de datos se ampliará, modificará y renovará muchas veces. Incluso cuando se reemplaza por completo, todos los datos se migrarán a la nueva base de datos mientras se conservan todas las reglas y relaciones comerciales anteriores.

Las restricciones implementan esas reglas y relaciones en una forma concisa y declarativa en el propio motor de la base de datos donde se puede acceder fácilmente. Sin ellos, los desarrolladores posteriores tendrían que pasar por los programas de aplicación para aplicar ingeniería inversa a esas reglas. ¡Buena suerte!

Esto, por cierto, es exactamente lo que los programadores COBOL de mainframe tienen que hacer, ya que esas bases de datos masivas a menudo se crearon antes de que tuviéramos motores y restricciones relacionales. Incluso si se migra a un sistema moderno como el DB2 de IBM, las restricciones a veces no se implementan completamente, ya que la lógica de las viejas reglas, incorporadas quizás en una serie de programas "por lotes" de COBOL, puede ser tan complicada que no sea práctico convertir. En cambio, las herramientas automatizadas se pueden usar para convertir el viejo COBOL en una versión más nueva con interfaces para el nuevo motor relacional y con un pequeño ajuste, se preserva la integridad de los datos ... hasta que se escriba una nueva aplicación que corrompa sutilmente todo y la empresa sea transportada en la corte por, por ejemplo, la ejecución hipotecaria de miles de propietarios que no deberían tener.


7

Además de los otros comentarios ...

Si / cuando tiene una base de datos en la que una tabla puede actualizarse mediante una o más aplicaciones o rutas de código, colocar las restricciones apropiadas en la base de datos significa que sus aplicaciones no duplicarán el "mismo" código de restricción. Esto lo beneficia al simplificar el mantenimiento (reduciendo el número de lugares para cambiar si hay un cambio en el modelo de datos) y asegura que las restricciones se apliquen de manera consistente independientemente de la aplicación que actualice los datos.


5

Personalmente, creo que es más fácil crear y alterar restricciones que crear desencadenantes, por ejemplo, lo que sería una forma de hacer cumplir su regla empresarial utilizando el código fuente.

También es menos probable que los desencadenantes sean portátiles, ya que generalmente están escritos en lenguajes específicos del proveedor, como PL / SQL.

Pero si las restricciones no satisfacen sus necesidades, siempre puede usar desencadenantes para hacer cumplir las reglas de su negocio.


55
Además, los desencadenantes no garantizan la integridad, debido a problemas de coherencia de lectura.
David Aldridge

3

Siempre deben aplicarse primero en la base de datos porque,

  1. La base de datos garantiza la integridad entre diferentes clientes. Puede tener diferentes clientes en diferentes plataformas para acceder a la base de datos. Las restricciones en la base de datos no corren el riesgo de problemas de integridad cuando crea un nuevo cliente. Esto le ahorra tener que Q / A sus limitaciones en caso de una reescritura o un punto de acceso adicional.
  2. La base de datos tiene un DSL para construir restricciones: SQL DDL!
  3. La base de datos proporciona acceso a esas restricciones en los catálogos del sistema para que un ORM o "cargador de esquemas" adecuado pueda leer esas restricciones y llevarlas a su aplicación. Por ejemplo, si su base de datos especifica que tiene un varchar(5)tipo, existe una buena posibilidad de que pueda encontrar un esquema que cargue ORM para su idioma específico que asigne el tipo de idioma al tipo de esquema, y ​​reúna su propia restricción de tamaño. DBIx for Perl is one such schema loader; Aquí hay otro para Entity Framework . Las capacidades de estos cargadores varían, pero cualquier cosa que puedan proporcionar es un buen comienzo para garantizar la integridad de la aplicación sin el viaje a la base de datos.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.