2012-03-27 10 views
6

Este es un seguimiento de mis preguntas aquí:
How to implement a many-to-many hierarchical structure in MySQL
y aquí:
How to record sequential collections of records in MySQL.¿Cómo agregar un orden de clasificación a una tabla de cierre MySQL que representa una relación muchos a muchos?

En resumen, quiero implementar en MySQL una tabla de recetas y otra de instrucciones. Una receta es una serie secuencial de instrucciones u otras recetas. Entonces, por ejemplo, podría imaginarse una receta Peach_preserve, y una Peach_tart que usa el Peach_preserve, más una serie de otros pasos (instrucciones). Peach_preserve podría usarse para muchas otras recetas.

Leo this blog post by Bill Karwin about closure tables, y creo que esta solución responde mejor a mis desafíos (mi jerarquía es many-to-many y los pasos son secuenciales). Así, por ejemplo, me gustaría tener:

recipe 
id name 
1 Peach preserve 
2 Cubed peeled peaches 
3 Fresh peaches 
4 Powdered sugar 
5 Cook together 
6 Peel and cut in chunks 
7 Mix 

step (or instruction) 
id desc 
1 Cook together 
2 Buy peaches 
3 Buy sugar 
4 Peel and cut in chunks 
5 Mix 

recipe_instruction 
(Ancestor) (Descendant) 
recipe_id step_id depth descendant_is_instruction 
3   3   0  0 
3   2   1  1 
4   4   0  0 
4   3   1  1 
6   6   0  0 
6   4   1  1 
2   2   0  0 
2   3   1  0 
2   2   2  1 
2   6   1  0 
2   4   2  1 
(and so on...) 

no soy un fan de la bandera descendant_is_instruction, pero no sé qué otra manera de hacer eso. Supongo que podría reemplazarlo con un descendant_is_leaf para identificar los elementos terminales ...

El orden es un género representado por una tabla que incorpora todas las relaciones a una profundidad de 1:

Depth=1 table 
recipe_id step_id  order 
3   2   1 
4   3   1 
6   4   1 
2   3   1 
2   6   2 

estoy simplificando aquí porque en la práctica separaría ingredientes e instrucciones, pero entiendes la idea.

Entonces, ¿es una buena manera de combinar una estructura de datos jerárquica y una noción de orden por pasos? ¿Algo que debería hacer para mejorar/simplificar?

Respuesta

0

Así que he investigado un poco sobre mi problema, aprovechando en su mayoría la información proporcionada aquí y en otras partes por Bill Karwin (finalmente decidí comprar su libro). En base a esto, creo que la mejor opción es agregar una columna de migas de pan a mi tabla de cierre, de manera similar a lo que recomienda Bill aquí MySQL Closure Table hierarchical database - How to pull information out in the correct order.

Las migas de pan me permitirían ORDER BY, lo que resolvería mi problema de pedido.

Encontraría los nodos del terminal consultando la tabla de cierre, buscando todos los nodos que no tengan ancestros que no sean ellos mismos.

0

Puedo estar muy lejos de aquí, pero la receta y las instrucciones podrían ser la misma tabla, lo que simplificará sus relaciones.

Instrucción: id, nombre, is_recipe

pasos: parent_id, child_id, orden

Ahora una receta puede tener instrucciones y recetas como los niños. Una instrucción podría ser incluso seguir una receta, pero con la mantequilla reducida ...

Es posible que necesite añadir un poco de control de bucle aunque ...

8

Una receta es una serie secuencial de instrucciones u otras recetas .

Dependiendo de cómo se lea esa oración, esto puede ser ambiguo.

¿Qué tal:

Una receta es una serie secuencial de instrucciones.

Una instrucción es simple (una hoja) o compleja (usa otra receta).

cual da:

Table recipe: 
- column id 
- column name 
- column total_cost, total_preparation_time, etc 

Table instruction: 
- column id 
- column recipe_id 
- column step_order 
- column description 
- column child_recipe_id (can be NULL) 

lo tanto, si la tarta de melocotón utiliza la pasta y el melocotón conservan:

select * from recipe order by id; 
id  name 
1  Dough 
2  Peach preserve 
3  Peach tart 

select * from instruction order by recipe_id, step_order; 
id recipe_id step_order description  child_recipe_id 

100  1  1  Get flour  NULL 
101  1  2  Add water  NULL 
102  1  3  Mix together NULL 

201  2  1  Peel peaches NULL 
202  2  2  Cube peaches NULL 
203  2  3  Add sugar  NULL 
204  2  4  Cook together NULL 

301  3  1  Pre heat oven NULL 
302  3  2  Prepare dough 1 
303  3  3  Prepare peach 2 
304  3  4  Bake   NULL 

no hay "es la hoja de" banderas.

Una instrucción es una hoja si no apunta a una receta secundaria, es decir, child_recipe_id es NULL.

+0

En ese sentido, los campos 'description' /' name' son redundantes entre sí. ¿Qué tal tener una mesa con el árbol de recetas y el otro solo los nombres? – Yuval

+0

@Yuval, no veo el nombre de la receta ni la descripción de la instrucción que utiliza la receta como redundante. El primero describe "qué" es el ingrediente resultante (por ejemplo, "chocolate derretido"), el "cómo" más tarde se usa el resultado (por ejemplo, "dibujar arte en un plato con chocolate derretido"). Yumm. –

Cuestiones relacionadas