2011-12-05 9 views
5

Tengo una base de datos llena de recetas, una receta por fila. Necesito almacenar un montón de "banderas" arbitrarias para cada receta para marcar varias propiedades como Sin Glutón, Sin carne, Sin carne roja, Sin carne de cerdo, Sin animales, Rápida, Fácil, Baja en grasa, Baja en azúcar, Baja en calorías, Bajo en sodio y bajo en carbohidratos Los usuarios deben poder buscar recetas que contengan uno o más de esos indicadores marcando las casillas de verificación en la interfaz de usuario.¿Cuál es la mejor manera en Postgres para almacenar un grupo de valores booleanos arbitrarios para una fila?

Estoy buscando la mejor manera de almacenar estas propiedades en la tabla de Recetas. Mis ideas hasta ahora:

  1. Tenga una columna separada para cada propiedad y cree un índice en cada una de esas columnas. Puede que tenga más de 20 de estas propiedades, así que me pregunto si hay inconvenientes con la creación de un montón de columnas BOOL en una sola tabla.
  2. Utilice una máscara de bits para todas las propiedades y almacene todo en una columna numérica que contenga la cantidad adecuada de bits. Cree un índice separado en cada bit para que las búsquedas sean rápidas.
  3. Crea un ENUM con un valor para cada etiqueta, luego crea una columna que tenga un ARRAY de ese tipo ENUM. Creo que una cláusula CUALQUIERA en una columna de matriz puede usar un ÍNDICE, pero nunca lo hizo.
  4. Cree una tabla separada que tenga un mapeo uno a muchos de las recetas de las etiquetas. Cada etiqueta sería una fila en esta tabla. La tabla contendría un enlace a la receta y un valor ENUM para el cual la etiqueta está "encendida" para esa receta. Al consultar, tendré que hacer un SELECT anidado para filtrar recetas que no contengan al menos una de estas etiquetas. Creo que esta es la forma más "normal" de hacer esto, pero hace que algunas consultas sean más complicadas: si quiero consultar 100 recetas y también mostrar todas sus etiquetas, tendría que usar una UNIÓN INTERNA y consolidar el filas, o use un SELECT anidado y agregue sobre la marcha.

El rendimiento de escritura no es demasiado importante aquí ya que las recetas se agregan mediante un proceso de back-end, y la velocidad de búsqueda es crítica (puede haber unos cientos de miles de recetas). Dudo que agregue nuevas etiquetas con tanta frecuencia, pero quiero que al menos sea posible sin grandes dolores de cabeza.

Gracias!

Respuesta

4

Le aconsejo que use una configuración normalizada. Configurar esto desde el principio como una estructura des-normalizada no es lo que yo aconsejaría.

Sin conocer todos los detalles de lo que está pasando, creo que la mejor configuración sería tener su tabla de recetas y la nueva tabla de propiedades y una nueva tabla recipe_property. Eso permite que una receta tenga 0 o muchas propiedades y normaliza sus datos, lo que hace que sea rápido y fácil de mantener y consulte sus datos.

estructura de alto nivel sería:

CREATE TABLE recipe(recipe_id); 
CREATE TABLE property(property_id); 
CREATE TABLE recipe_property(recipe_property_id,recipe_id,property_id); 
+0

Sí que es definitivamente una ruta. También estoy pensando en usar un 'ENUM' en lugar de' property_id', y no tener una tabla 'property'. Sin embargo, internamente en la base de datos es lo mismo que tienes. –

+0

Solo asegúrese de que su solución final no lo arrincone. – Kuberchaun

+1

Terminé yendo por la ruta normalizada después de recibir el mismo consejo de muchos expertos. Sin embargo, miré brevemente en el módulo 'hstore' para Postgres, que es bastante dulce; sin embargo, elegí no usarlo para esta situación particular. –

Cuestiones relacionadas