vista ventajas software programacion modelo ejemplos diagrama desventajas controlador capas arquitectura mysql database business-logic business-rules segment

mysql - ventajas - programacion en n capas



Almacenando la lógica de negocios en la base de datos (11)

¿Imagino que ya tiene documentadas las reglas y los requisitos de la lógica empresarial? ... Ese es el factor más importante para diseñar su esquema, elegir las mejores herramientas de desarrollo de clientes y diseñar los programas y procedimientos de sus clientes. Hice esto para mi aplicación de gestión de casas de empeño. La funcionalidad de la aplicación es totalmente basada en tablas. Tiene tablas de control en las que el administrador puede cambiar los parámetros válidos para modificar la forma en que funciona el sistema. Cuando se combina con técnicas de programación estructurada, esto minimiza la cantidad de modificaciones del código de programación. Las aplicaciones bancarias también son un buen ejemplo de reglas de negocio complejas.

Queremos escribir algunas reglas de lógica de negocios que funcionen sobre ciertos datos para generar informes. No estoy seguro de cuál es el mejor para almacenarlos en la base de datos MySQL.

Puede tener una cadena de reglas y luego una declaración para el resultado como se muestra arriba.


Creo que lo que se debe hacer primero es preguntarse si, para empezar, debería estar poniendo las reglas en una base de datos.

Las bases de datos son una solución de mano dura , y a menudo simplemente no son necesarias.

Habiendo tratado con los motores de reglas en varias formas, incluida la base de datos, puedo decirle que puede ser realmente frustrante e improductivo, muy rápido. Uno de los grandes errores que he visto pasar es intentar escribir su propio lenguaje de reglas ad-hoc y usarlo para controlar la lógica condicional a través de la base de datos. Como mínimo, use un lenguaje que ya esté probado (Python, javscript, etc.) e insértelo allí.

Mejor aún, si las reglas son lo suficientemente complejas, personalmente prefiero emplear hojas de cálculo de Excel. Usamos esto para la automatización (para manejar la lógica variable en función de la fecha efectiva, etc.) y también compilamos una lógica de calificación de seguros bastante compleja para los scripts de Perl interconectados a través de un servicio web, utilizando este producto: http://decisionresearch.com/products/rating.html .

Contraste almacenando la lógica en una base de datos versus, por ejemplo, una hoja de cálculo de Excel:

  1. La lógica en la base de datos es más difícil de probar y desarrollar en comparación con Excel, porque Excel proporciona retroalimentación instantánea.
  2. Una base de datos es menos (mucho menos) expresiva en comparación con Excel.
  3. Puede codificar con colores y agregar todo tipo de señales visuales a Excel para que las condiciones de error, etc., realmente se destaquen.

Ahora, por supuesto, como puede imaginar, un motor de reglas de Excel impulsado por un servicio web no se ajustará a todas las situaciones. Y no es la única solución posible aquí.

Sin embargo, lo que estoy tratando de hacer es asegurarnos de que estás haciendo las concesiones correctas en términos de usabilidad / expresividad / probabilidad / rendimiento. Donde trabajo, tener razón y ser productivo es más importante que ser rápido en la ejecución, por lo que optamos por el servicio Excel / web.

Y para ampliar el comentario de slavik262, lo que realmente desea lograr con los motores de reglas, en última instancia, es la abstracción y la generalización, para minimizar las partes móviles y aumentar la confiabilidad, la capacidad de prueba y la comprensibilidad. Un motor de reglas de base de datos, en mi experiencia, es subóptimo en comparación a menudo simplemente para hacer, por ejemplo, reglas basadas en Java. Siempre y cuando estén en un espacio aislado y organizado adecuadamente, y se oculten detrás de una interfaz generalizada y consistente, entonces funcionarán bien.

En mi empresa, depende de la escala de las reglas y de la frecuencia con la que cambian con respecto a lo que hacemos. Calificación de seguros- Excel, no hay duda al respecto. ¿Alguna lógica específica del estado? Los archivos de reglas de Java con interfaz son suficientes.


El único beneficio posible de usar procedimientos almacenados es la posibilidad de acceder a la base de datos desde aplicaciones que usan diferentes tecnologías, como Python y Java.


Entonces, si comprendo correctamente, ¿está buscando usar el extremo frontal para permitir que las personas creen dinámicamente la lógica que se aplicará a las consultas (construidas dinámicamente donde las cláusulas en tiempo de ejecución se basan en las reglas que se utilizan)?

Si ese es el caso, debe ser bastante específico acerca de las condiciones que pueden seleccionar en sus reglas (cambiar el valor (columna) para que solo puedan tener reglas condicionales contra las columnas que existen en el conjunto de datos desde el que informa).

Si estoy entendiendo su pregunta correctamente, comenzaría por mapear en qué tablas / columnas desea que puedan seleccionar las condiciones. Estos serán tus controles para que la página web diseñe las reglas.

Sin embargo, si solo está preguntando cómo almacenar las reglas una vez que se eligen en la base de datos, sugeriría almacenarlo en una sola tabla que contenga:

ID | RuleSetName | Table | Column | Comparison | Value | Percentage | Notes | CreatedDate | Created By 1 | ''VisitorAnalytics'' | Visitors | SUM(Views) | > | null | 10 | n/a | 1/1/2012 | JohnDoe

Luego, una vez que se crean estos registros, los usará inyectando las tablas en la cláusula from, las columnas en la cláusula where para su sql dinámico.

Sé que esto puede parecer confuso, pero lo que está preguntando es una solución bastante compleja. Pero, en última instancia, solo desea almacenar las reglas en un solo lugar donde pueda realizar un ciclo para construir dinámicamente y luego ejecutar un SQL para generar su informe. Esperemos que esto te apunte en la dirección correcta.


Para crear informes, puede convertir la lógica empresarial en cualquier lenguaje de programación. Y usa los datos de la base de datos para generar informes.

En contra de la lógica empresarial almacenada en la base de datos.

Pongo un alto valor en el poder de la expresión, y no encuentro que el espacio SQL sea tan expresivo. Use las mejores herramientas que tenga a mano para las tareas más apropiadas. Jugar con la lógica y los conceptos de orden superior se hace mejor al más alto nivel. En consecuencia, el almacenamiento y la manipulación masiva de datos se realiza mejor a nivel de servidor, probablemente en procedimientos almacenados.

Pero depende. Si tiene varias aplicaciones que interactúan con un mecanismo de almacenamiento y desea asegurarse de que mantiene su integridad y flujo de trabajo, debe descargar toda la lógica en el servidor de la base de datos. O prepárese para gestionar el desarrollo concurrente en múltiples aplicaciones.

Fuente: Argumentos a favor y en contra de la lógica empresarial en procedimientos almacenados.

Ver también:

  1. Lógica de negocios en la base de datos
  2. Logica Empresarial En Procedimientos Almacenados
  3. Almacenamiento de expresiones lógicas condicionales / reglas en una base de datos

Si no necesita realizar búsquedas basadas en los componentes de las reglas, puede almacenar la regla en dos campos de la base de datos. La condición bajo la cual la instrucción se ejecuta en una y la instrucción que se ejecuta en otra.

id, name, description, condition, statement

Sus reglas se pueden almacenar utilizando JSON o algún formato similar.

Tendré que definir alguna terminología que estaré usando. Hay términos atómicos , valores del sistema comparados con los valores ingresados ​​por el usuario que evalúan a verdadero / falso, y términos complejos combinados usando operadores lógicos.

En un término atómico , var denota un valor que proporcionará el sistema (como el número de visitantes o el número de visitantes únicos). Las comparaciones determinan cómo se debe evaluar la var contra el valor . El valor es un número o cadena que el usuario produce. Cuando una var y un valor son ambos números, las comparaciones pueden ser "<", "<=", "=", "> =" o ">". Cuando una var y un valor son ambas cadenas, las comparaciones pueden ser "iguales", "comienza con", "termina con" o "contiene". Los términos atómicos se pueden almacenar de la siguiente manera:

{ var: varName, comp: comparison, value: numberOrString }

Puede almacenar los términos complejos que consisten en conjunciones, disyunciones y negaciones (y / o / no) utilizando los siguientes formatos.

// Conjunction { op: "and", terms: [ term, ..., term ] } // Disjunction { op: "or", terms: [ term, ..., term ] } // Negation { op: "not", term: term }

Luego, puede construir declaraciones que evalúen a verdadero / falso usando estos métodos. Un ejemplo es el siguiente:

{ op: "and", terms: [ {op "or", terms: [ { field: "numVisitors", comp: ">", value: 1000 }, { field: "numUniqueVisitors", comp: ">=" 100 } ]}, { op: "not", term: { { field: "numVisitors", comp: "<", value: 500 } }} ]}

El ejemplo anterior equivale a verdadero cuando el número de visitantes es mayor que 1000 o el número de visitantes únicos es mayor o igual a 100, y el número de visitantes no es menor a 500.

Luego puede ejecutar lo que se refiere como una "declaración" cuando la regla se evalúa como verdadera.


Supongo que el propósito de las reglas es nombrar los campos calculados de una tabla (o tablas) de base de datos existente. De lo contrario, para propósitos de informes simples, podría volcar los datos en Excel y permitir que los usuarios usen las funciones y tablas dinámicas de Excel para sus propósitos.

La pregunta clave es cómo transformarás las reglas en acción. Si el propósito es solo almacenar reglas de negocios, para que pueda crear un informe de reglas de negocios, entonces una simple estructura de datos en SQL es suficiente.

Sin embargo, si desea convertir las reglas en código, debe considerar dónde se ejecutará el código. Cuando los datos se almacenan en SQL, tiene varias opciones:

  • Cree un código SQL que extraiga los resultados de la "regla de negocios".
  • Cree una función definida por el usuario que analizará y ejecutará la regla de negocios.
  • Extraiga los datos a otro entorno, como C ++ o C #, y ejecute el código allí.

Tengo un sesgo hacia el primero de estos. La razón principal es que limita las herramientas a una: SQL.

No estoy seguro de lo que están haciendo sus reglas; la clave es lo que hace el componente "declaración". Permítame asumir que esta es una constante o una expresión en los datos que se pueden calcular. En ese caso, sus reglas comienzan a parecerse mucho a una declaración de caso. Una advertencia es que la declaración puede requerir ver más de una fila en su tabla de datos (para manejar los cambios a lo largo del tiempo).

Mi recomendación es almacenar estas reglas en la base de datos. Este almacenamiento le permitiría construir una consulta a partir de una secuencia de reglas de negocio utilizando la codificación SQL. Mysql permite SQL dinámico (hoy en día). Sin saber un poco más sobre la tabla subyacente y las reglas, es difícil dar más información.

Puedo decir que diseñé un sistema mucho más complicado para el análisis de escenarios. Los escenarios en sí se almacenaron en hojas de cálculo, en una serie de tablas, constantes, etc., muy parecidas a las reglas de su negocio. El sistema funcionó utilizando SQL (y algo de Excel) para transformar la representación en hoja de cálculo de un escenario en una consulta (gigante). Luego podría ejecutar la consulta para generar los informes asociados. Este sistema ha demostrado ser flexible, eficaz y potente.


Todo lo que puedo darte es la forma en que deberías resolver este problema, y ​​no la respuesta en sí.

La forma general de diseñar una base de datos para almacenar datos complejos como este es diseñar la forma en que los guardaría en la memoria como objetos y luego intentar y diseñar la base de datos en consecuencia. Estarás evaluando las reglas en un lenguaje de programación después de todo. El procedimiento será el siguiente: Primero el diagrama de clase.

Entonces es hora de convertirlo en un ERD:

Una vez que tenga una estructura de base de datos para almacenar / recargar su objeto en / desde, puede simplemente crear sus clases de modo que cada objeto sea responsable de cargar / almacenar.

[ACTUALIZAR]

Por ejemplo, si desea almacenar la declaración a + b * -c en la base de datos, podría traducirse como las siguientes inserciones:

-- c INSERT INTO statement (statement_id) VALUES (1); INSERT INTO operand (statement_id, type) VALUES (1, ''double''); -- - (minus) INSERT INTO statement (statement_id) VALUES (2); INSERT INTO operator (statement_id, type) VALUES (2, ''minus''); -- -c INSERT INTO binary (operator_statement_id, operand_statement_id) VALUES (2, 1); -- b INSERT INTO statement (statement_id) VALUES (3); INSERT INTO operand (statement_id, type) VALUES (3, ''double''); -- * (multiply) INSERT INTO statement (statement_id) VALUES (4); INSERT INTO operator (statement_id, type) VALUES (4, ''multiply''); -- b * -c INSERT INTO unary (operator_statement_id, operand_statement_id1, operand_statement_id2) VALUES (4, 3, 2); -- a INSERT INTO statement (statement_id) VALUES (5); INSERT INTO operand (statement_id, type) VALUES (5, ''double''); -- + (plus) INSERT INTO statement (statement_id) VALUES (6); INSERT INTO operator (statement_id, type) VALUES (6, ''sum''); -- a + b * -c INSERT INTO unary (operator_statement_id, operand_statement_id1, operand_statement_id2) VALUES (6, 5, 4);


Un argumento en contra de la lógica de negocios de "codificación suave" como esta: http://thedailywtf.com/Articles/Soft_Coding.aspx

"La razón por la que nos encontramos en Soft Coding es porque tememos el cambio. No es el miedo normal al cambio, sino que el miedo al código que escribimos tendrá que cambiarse como resultado de un cambio en las reglas de negocios. Es un miedo bastante tonto tenerlo". El punto principal del software (por lo tanto, el "software") es que puede cambiar y cambiar. La única manera de aislar su software de los cambios en las reglas de negocios es construir un programa completamente genérico que carezca de todas las reglas de negocios, pero implementa cualquier regla. Ah, y ya han creado esa herramienta. Se llama C ++. Y Java. Y C #. Y Básico. Y, me atrevo a decir, COBOL ".


Una forma fácil de hacerlo es usar un OODBMS. Allí, los métodos se encapsulan con ranuras en objetos, e incluso pueden ejecutarse en la base de datos (como activadores).

Ahora, si insiste en una base de datos SQL, lo que puede hacer es usar un lenguaje de programación dinámico y tener una tabla para almacenar el código, tal vez asociado a otras tablas o filas.

Hace unos años vi una licitación para el sistema fiscal del gobierno argelino, en el que planeaban almacenar las reglas comerciales (reglas fiscales), como código de Visual Basic en el RDBMS.

Puede elegir cualquier idioma para el que pueda integrar fácilmente el intérprete en su aplicación (Common Lisp http://ecls.sourceforge.net ; o http://common-lisp.net/project/armedbear/ si escribe su solicitud en Java), Lua, Javascript, Esquema, etc.

Tendría a favor de Common Lisp o Scheme, ya que con esos idiomas puede escribir fácilmente un DSL para las reglas comerciales.

El ejemplo dado podría escribirse como una expresión simbólica como:

(rule :name "RuleName" :description "Some description" :body (if (and (< (change-in total-visitor) (percent 10)) (> (change-in unique-visitors) (percent 2))) (do-something)))

En lisp, tal expresión simbólica se puede imprimir de forma legible con los operadores PRINT o PRINT-TO-STRING, para que pueda insertar esta expresión en una base de datos SQL:

insert into rules (id,expression) values (42,"(rule :name /"RuleName/" :description /"Some description/" :body (if (and (< (change-in total-visitor) (percent 10)) (> (change-in unique-visitors) (percent 2))) (do-something)))");

Y puede recuperarlo de SQL, leerlo de nuevo como una expresión simbólica con los operadores LEAD lisp o LEER DE LA CADENA, y luego, con el DSL correcto, puede evaluarlo con el operador EVAL lisp:

;; with the right DSL written: (eval (read-from-string (sql-select (expression) :where (= id 42))))


CREATE TABLE businessRule ( id INT NOT NULL , name VARCHAR(32) NOT NULL , description VARCHAR(255) NULL , statement VARCHAR(255) NOT NULL , PRIMARY KEY (id) ) ENGINE = InnoDB; CREATE TABLE leftOperand ( id INT NOT NULL , value VARCHAR(255) NOT NULL , PRIMARY KEY (id) ) ENGINE = InnoDB; CREATE TABLE ruleItem ( id INT NOT NULL , businessRuleId INT NOT NULL , operator ENUM(''if'',''and'',''or'',''not'') NOT NULL , loperand INT NOT NULL , comparator ENUM(''<'',''='',''>'') NOT NULL , roperand VARCHAR(255) NOT NULL , roperand_ispercentage TINYINT(1) NOT NULL , PRIMARY KEY (id) , INDEX businessRule_FK (businessRuleId ASC) , INDEX leftOperand_FK (loperand ASC) , CONSTRAINT businessRule_FK FOREIGN KEY (businessRuleId ) REFERENCES mydb.businessRule (id ) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT leftOperand_FK FOREIGN KEY (loperand ) REFERENCES mydb.leftOperand (id ) ON DELETE RESTRICT ON UPDATE RESTRICT) ENGINE = InnoDB;