2008-09-23 9 views
7

En mi base de datos, tengo un modelo que tiene un campo que debe seleccionarse de una lista de opciones. Como ejemplo, considere un modelo que necesita almacenar una medida, como 5 pies o 13 cm o 12.24 m3. La forma obvia de lograr esto es tener un campo decimal y luego otro campo para almacenar la unidad de medida.¿La mejor manera de almacenar constantes a las que se hace referencia en la base de datos?

¿Cuál es la mejor manera de almacenar la unidad de medida? He usado un par de enfoques en el pasado:

1) Almacenando las diversas opciones en otra tabla DB (y modelo asociado), y uniendo las dos con una clave foránea estándar (y generalmente ansioso por cargar el modelo asociado) . Esto parece exagerado, ya que está obligando al DB a realizar un join en cada consulta.

2) Almacenando las opciones como un Hash constante, cargado en uno de los inicializadores, donde la clave en el Hash se almacena en el campo de unidad de medida. De esta forma, efectivamente se unirá a Ruby (que puede o no ser un aumento en el rendimiento), pero se pierde la posibilidad de realizar consultas desde el lado de "unidad de medida". Esto no sería un problema siempre que no sea probable que deba hacer consultas como "buscar todas las medidas con unidades de cm".

Ninguno de estos me parece especialmente elegante ... ¿alguien puede sugerir algo mejor?

Respuesta

3

Me gustaría ir con la opción uno. ¿Qué tan grande será la tabla UnitOfMeasurement? Y, si usa una clave primaria entera, ¿por qué se preocupa tanto por la velocidad?

La opción 1 es el camino a seguir por motivos de diseño. Simplemente déselo con una clave primaria entera (incluso una pequeña) y un campo para la descripción de la unidad.

1

¿Ya tiene ActiveRecord soporte para llaves naturales? Si tiene, puede simplemente hacer que la columna name (o lo que sea) de la tabla UnitOfMeasure sea PK, de esa manera el valor de la columna FK tiene toda la información que necesita, y aún tiene una base de datos completamente normalizada con un conjunto canónico de UnitOfMeasurement valores.

0

¿Necesita realizar búsquedas en estos valores? Si no, también podría almacenarlos como una cadena y analizar la cadena más adelante en la aplicación que lee los valores. Si bien corre el riesgo de almacenar datos inaplicables, gana velocidad y reduce la complejidad de la base de datos. A veces, la normalización de una base de datos no es útil. Al final/algo/dentro de su sistema necesita saber que "cm" es una medida de longitud y "m3" es una medida de habitación y comparar "3cm" a "1m3" no tiene ningún sentido de todos modos. Entonces puedes poner todo ese conocimiento en código.

Digamos que solo vas a mostrar esa información de todos modos, ¿para qué sirve la normalización aquí?

6

¿Has visto constant_cache? Es una especie de combinación de lo mejor de 1 y 2: los datos de búsqueda se almacenan en la base de datos, pero están expuestos como constantes de clase en el modelo de búsqueda y solo se cargan al inicio de la aplicación, por lo que no sufre las penalizaciones de unión constantemente. El siguiente ejemplo proviene de la README:

migración:

create_table :account_statuses do |t| 
    t.string :name, :description 
end 

AccountStatus.create!(:name => 'Active', :description => 'Active user account') 
AccountStatus.create!(:name => 'Pending', :description => 'Pending user account') 
AccountStatus.create!(:name => 'Disabled', :description => 'Disabled user account') 

modelo:

class AccountStatus < ActiveRecord::Base 
    caches_constants 
end 

usarlo:

Account.new(:username => 'preagan', :status => AccountStatus::PENDING) 
Cuestiones relacionadas