Tengo una lista de productos. Cada uno de ellos es ofrecido por N proveedores.
Cada proveedor nos cotiza un precio para una fecha específica. Ese precio es efectivo hasta que ese proveedor decida establecer un nuevo precio. En ese caso, el proveedor le dará el nuevo precio con una nueva fecha.
El encabezado de la tabla MySQL actualmente se ve así:
provider_id, product_id, price, date_price_effective
Cada dos días, compilamos una lista de productos / precios que son efectivos para el día actual. Para cada producto, la lista contiene una lista ordenada de los proveedores que tienen ese producto en particular. De esa manera, podemos ordenar ciertos productos de quien sea que ofrezca el mejor precio.
Para obtener los precios efectivos, tengo una instrucción SQL que devuelve todas las filas que tienen date_price_effective >= NOW()
. Ese conjunto de resultados se procesa con un script ruby que realiza la clasificación y el filtrado necesarios para obtener un archivo que se ve así:
product_id_1,provider_1,provider_3,provider8,provider_10...
product_id_2,provider_3,provider_2,provider1,provider_10...
Esto funciona bien para nuestros propósitos, pero todavía tengo ganas de que una tabla SQL probablemente no sea la mejor manera de almacenar este tipo de información. Tengo la sensación de que este tipo de problema se ha resuelto previamente de otras maneras más creativas.
¿Hay una mejor manera de almacenar esta información que no sea en SQL? o, si usa SQL, ¿hay un mejor enfoque que el que estoy usando?
Respuestas:
Para los ítems que varían según el tiempo (como poder responder cosas como "cuál era el precio de X en la fecha D" o "qué vaca estaba en el corral de engorde Q en la fecha E"), recomiendo leer el libro "Desarrollo orientado al tiempo Aplicaciones de bases de datos en SQL ". Mientras este libro está agotado, el autor ha puesto a disposición el PDF del libro y el CD asociado en su sitio web.
http://www.cs.arizona.edu/~rts/publications.html (busque el primer elemento en "libros").
Para una breve introducción en línea, consulte:
fuente
Ciertamente almacenaría la fecha de vigencia en la base de datos. Después de todo, es probable que las personas quieran poder realizar consultas para ver cómo ha cambiado el precio con el tiempo o para verificar las rarezas en los pedidos contra la tabla de precios histórica del producto. Dependiendo del tipo de consultas que esté ejecutando y la frecuencia de los cambios de precios, puede tener sentido tener tablas separadas para el precio actual y los precios históricos.
En la mayoría de los sistemas que almacenan precios, querrá una columna de fecha de vencimiento además de la fecha de vigencia para que sea más fácil determinar qué precio está actualmente vigente, ya que le ahorra la molestia de tener que mirar la fila anterior o siguiente para calcular fuera de qué precio estaba vigente en un momento dado. No tengo claro qué
NOW() >= date_price_effective
está haciendo su condición, presumiblemente, eso devuelve el precio actual junto con todos los precios históricos anteriores, lo que me parece extraño. Yo pensaría que el "precio efectivo" sería el precio actual que se definiría por algo comoNOW() BETWEEN date_price_effective AND date_price_expired
Tampoco estoy seguro de cómo debe verse su archivo. No está claro para mí lo que
provider_1
represents-- la PROVIDER_ID = 1 precio -? O cómo se está ordenando el proveedor de Data-- ¿por quéprovider_1
aparece primero paraproduct_id_1
y el tercero paraproduct_id_2
.fuente
Si entiendo su enunciado del problema correctamente, necesita una forma de manejar los datos generacionales (es decir, la tabla contiene varias filas para cada par de id_productor / id_producto, cada una de las cuales es sensible a la fecha). En ese caso, está buscando el precio más reciente para un producto con un valor date_price_effective que sea menor o igual que hoy. Este tipo de situación se maneja fácilmente utilizando una subselección SQL.
Un precio es efectivo siempre que tenga el mayor valor date_price_effective que sea menor o igual que la fecha en que se ejecuta la consulta. Un valor date_price_effective que es mayor que hoy es una fecha efectiva futura. El código enumerado anteriormente devuelve los datos de la fila para cada par proveedor_id / producto_id que tiene el valor date_price_effective que es el más cercano, pero no posterior a la fecha en que se ejecuta la consulta. La solución pone automáticamente los precios en intervalos de fechas efectivos. La clave principal para esta tabla sería el triple {provider_id, product_id, date_price_effective};
fuente