2009-11-19 18 views
5

Tengo una tabla de 100.000 de USUARIOS (nombre, edad, sexo, teléfono, empresa, calle, ciudad, estado, país, código postal, etc.).¿Cómo se representan las reglas usando una tabla MySQL?

También tengo una tabla de miles de PROMOCIONES que se ofrecen a los usuarios. Ahora, para cada promoción, necesito agregar una regla que defina a qué subconjunto de usuarios se aplica.

Por ejemplo, una regla podría ser: Todos los usuarios que tienen un código postal de 10000 a 19999.

Otra regla podría ser: Todos los usuarios que son de sexo femenino y no viven en los EE.UU.

Sin embargo, una La tercera regla podría ser: Usuarios mayores de 18 años que vivan en DC, MD o VA. Etc, etc.

Ahora dado un usuario específico, quiero (¡de manera eficiente!) Averiguar qué PROMOCIONES se aplican a ese usuario.

¿Cuál es una buena estrategia para modelar estas reglas, dado que quiero ser capaz de encontrar rápidamente las promociones correspondientes a un usuario específico?

+0

dado que no existe un consenso de que debe almacenar mis reglas como consultas SQL, ¿hay alguna herramienta para construir estas consultas de manera interactiva? Estoy ejecutando PHP/CakePHP/MySQL. ¡Gracias! – Sleepster

Respuesta

2

Aquí hay un enfoque.

Si puede desglosar cada regla en una comparación simple, es posible almacenarla de una manera que funcione para todo. Con lo que termina es una secuencia de elementos de reglas que comprende un campo, un valor y una comparación (por ejemplo, igual, no igual, etc.). También deben pertenecer a una regla real (que puede nombrar), que se enumeraría en otra tabla.

Ahora se complica. Cada elemento de la regla también es un nivel. Esto es para que pueda hacer comparaciones AND y OR ya que requieren una jerarquía. La forma en que he hecho esto antes es que incluso los niveles AND y los niveles impares O. Eso significa que dos elementos que deben ser verdaderos para una regla estarían ambos en el nivel 0, es decir, ambos deben validar. Para una regla que tiene una condición obligatoria y dos más donde cualquiera puede ser verdadera, es decir, 1 AND (2 O 3), coloca la regla obligatoria en el nivel 0 y las otras dos en el nivel 1.

La ventaja de esto El enfoque es que el código para ensamblar los filtros SQL hace que la anidación sea correcta porque tiene que hacer que el modo Y/O sea correcto. También hace posible construir un editor para las reglas.

Sin embargo, esta solución, al igual que todos los demás, todavía requiere la aplicación de todas las reglas a su vez a su usuario establece para encontrar qué reglas permiten al usuario le interesa.

+0

Esto es brillante. ¡Gracias! –

1

Esto no es algo normalmente hecho a nivel de base de datos; en su lugar, las "reglas" serían interpretadas por tu back-end (independientemente del idioma que estés usando allí). Cómo se almacenan en la base de datos depende de cómo se modelan. Este enfoque puede ser tan simple o tan complejo como debe ser: las reglas se pueden definir dinámicamente por los usuarios finales, etc.

Dicho esto, si está buscando algo rápido y sucio (con ENORME énfasis en la solución sucia), quizás pueda almacenar sus reglas como consultas reales (o where condiciones para consultas). Luego puede escribir un procedimiento almacenado para aplicar dichas reglas.

2

Me parece que sus reglas realmente pueden ser cualquier cosa y están mejor representadas por diferentes consultas.

Deben entrar en el modelo (MVC) o tal vez en procedimientos almacenados. Realmente no puedo pensar en eso.

Cada vez que llega una nueva promoción a la ciudad, el sistema pasa a todos los usuarios y almacena las coincidencias en una tabla que vincula usuarios y promociones. Eso también sería cierto para cada nuevo usuario que se registre. También podría considerar ponerlo en un cronjob.

EDIT:
tenga en cuenta que la tabla que vincula los usuarios directamente a las promociones es crucial si usted está realmente en busca de rendimiento .

Sólo mis dos centavos.

2

¿Qué pasa si almacena sus reglas en forma "SQL-like"? Por ejemplo, tiene una tabla de USUARIOS y una tabla PROMOCIONES como ya ha mencionado.

Puede agregar 2 tablas nuevas, PROMOTION_RULE y PROMOTION_PROMOTION_RULE. La PROMOTION_RULE contendría las reglas, y PROMOTION_PROMOTION_RULE vincularía una promoción dada a sus reglas asociadas. Este diseño le permite compartir la misma regla para múltiples promociones.

En PROMOTION_RULE, podría almacenar una columna llamada RULE_SQL, y se podía almacenar valores como:

(gender != 'F' and country != 'US')  
(age > 18 and state IN ('DC','MD','VA') 

etc.

Posteriormente, se podría mirar hacia arriba las reglas que se aplican para una promoción, y dinámicamente construir una instrucción SQL que estaría compuesta por los valores de rule_sql.

2

Depende de quién está ingresando las reglas y el nivel de confianza que tiene para ellas. Si eres tú quien está agregando las reglas, podrías almacenarlas como declaraciones SQL en la base de datos, pero eso parece chivo, o como procedimientos almacenados, pero no estoy seguro si puedes tener una columna que haga referencia a esas (podría ser una columna de cuerda, por supuesto).

No dice qué tipo de marco está utilizando, pero si está utilizando un ORM, sus reglas podrían ser objetos de consulta, que se pueden serializar a la base de datos como BLOB. Por ejemplo, si usaba SQLAlchemy para Python, cada regla podría ser una instancia de Query que podría pasar a la función User.filter.

En todos estos casos, está permitiendo el uso de código arbitrario, por lo que no son adecuados para permitir que otros agreguen reglas. La única solución válida sería crear un lenguaje específico de dominio limitado para expresar las reglas, y convertirlas a SQL o a su lenguaje ORM.

+0

Sí, soy yo quien agrega las reglas. Veo lo que dices sobre la conversión de "lenguaje de reglas" a consulta. ¿Alguna pista sobre herramientas para definir tales reglas y convertirlas a consultas SQL? – Sleepster

Cuestiones relacionadas