Quiero que el usuario pueda buscar productos dentro de un rango de precios. El usuario debe poder usar cualquier moneda (USD, EUR, GBP, JPY, ...), sin importar la moneda que establezca el producto. Por lo tanto, el precio del producto es de 200 USD y, si el usuario busca los productos que cuestan 100EUR - 200EUR, aún puede encontrarlo. ¿Cómo hacerlo rápido y efectivo?
Esto es lo que he hecho hasta ahora. Almaceno el price
, currency code
y calculated_price
ese es el precio en euros (EUR) que es la moneda predeterminada.
CREATE TABLE "products" (
"id" serial,
"price" numeric NOT NULL,
"currency" char(3),
"calculated_price" numeric NOT NULL,
CONSTRAINT "products_id_pkey" PRIMARY KEY ("id")
);
CREATE TABLE "currencies" (
"id" char(3) NOT NULL,
"modified" timestamp NOT NULL,
"is_default" boolean NOT NULL DEFAULT 'f',
"value" numeric NOT NULL, -- ratio additional to the default currency
CONSTRAINT "currencies_id_pkey" PRIMARY KEY ("id")
);
INSERT INTO "currencies" (id, modified, is_default, value)
VALUES
('EUR', '2012-05-17 11:38:45', 't', 1.0),
('USD', '2012-05-17 11:38:45', 'f', '1.2724'),
('GBP', '2012-05-17 11:38:45', 'f', '0.8005');
INSERT INTO "products" (price, currency, calculated_price)
SELECT 200.0 AS price, 'USD' AS currency, (200.0 / value) AS calculated_price
FROM "currencies" WHERE id = 'USD';
Si el usuario está buscando con otra moneda, digamos USD, calculamos el precio en EUR y buscamos en la calculated_price
columna.
SELECT * FROM "products" WHERE calculated_price > 100.0 AND calculated_price < 200.0;
De esta manera, podemos comparar precios muy rápido, porque no necesitamos calcular el precio real de cada fila, ya que se calcula una vez.
Lo malo es que al menos todos los días tenemos que volver a calcular default_price
para todas las filas, porque las tasas de cambio han cambiado.
¿Hay una mejor manera de lidiar con esto?
¿No hay alguna otra solución inteligente? Tal vez alguna fórmula matemática? Tengo una idea de que calculated_price
es una relación con alguna variable X
y, cuando la moneda cambia, actualizamos solo esa variable X
, no la calculated_price
, por lo que incluso no necesitamos actualizar nada (filas) ... Tal vez algún matemático pueda resolverlo ¿Me gusta esto?
fuente
calculated_price
? ¡Podría almacenar elinitial_currency_value
(tipo de cambio constante que se toma, digamos hoy) y siempre calcularlo contra eso! Y cuando muestre el precio en euros, calcule contra la tasa de cambio real, por supuesto. Estoy en lo cierto? ¿O hay un problema que no veo?Se me ocurrió mi propia idea. ¡Dime si realmente va a funcionar, por favor!
El problema.
Cuando se agrega un producto en la
products
tabla, el precio se convierte a la moneda predeterminada (EUR) y se almacena en lacalculated_price
columna.Queremos que el usuario pueda buscar (filtrar) precios de cualquier moneda. Se realiza convirtiendo el precio de entrada a la moneda predeterminada (EUR) y comparándolo con la
calculated_price
columna.Necesitamos actualizar los tipos de cambio, para que los usuarios puedan buscar por tipo de cambio nuevo. Pero el problema es: cómo actualizar de manera
calculated_price
eficiente.La solución (con suerte).
No lo hagas :)
La idea es que tomemos las tasas de cambio de ayer ( todas de la misma fecha ) en el
calculated_price
uso solo de esas. ¡Una eternidad! No hay actualizaciones diarias. Lo único que necesitamos antes de comparar / filtrar / buscar los precios es tomar las tasas de cambio de hoy como si fueran las de ayer.Entonces, en
calculated_price
usaremos solo la tasa de cambio de la fecha fija (hemos elegido, digamos, ayer). Lo que necesitaremos es convertir el precio de hoy en el precio de ayer. En otras palabras, tome la tasa de hoy y conviértala en la tasa de ayer:Y esta es la tabla de las monedas:
Esta es la forma de agregar un producto que cuesta 200 USD y cómo
calculated_price
se calcula el get: del USD al tipo de cambio más reciente en EUR y a la tasa fija (antigua)Esto también se puede calcular previamente en el lado del cliente y eso es lo que voy a hacer: calcule el precio de entrada del usuario con el
calculated_price
valor compatible antes de realizar una consulta, por lo que se usará como antes.SELECT * FROM products WHERE calculated_price > 100.0 AND calculated_price < 200.0;
Conclusión.
Esta idea se me ocurrió hace unas horas y actualmente te pido que verifiques si tengo razón sobre esta solución. ¿Qué piensas? ¿Esto va a funcionar? O me he equivocado?
Espero que entiendas todo esto. No soy un hablante nativo de inglés, también es tarde y estoy cansado. :)
ACTUALIZAR
Bueno, parece que resuelve un problema, pero presenta otro. Demasiado. :)
fuente
rate_newest / rate_fixed
es diferente por moneda, y esta solución considera solo la del dinero elegido por el usuario en la búsqueda. Cualquier precio en una moneda diferente no se compararía con las tasas actualizadas. La respuesta que he enviado de alguna manera tenía un problema similar, pero creo que lo solucioné en la versión actualizada.