Chcę umożliwić użytkownikom wyszukiwanie produktów w przedziale cenowym. Użytkownik powinien mieć możliwość korzystania z dowolnej waluty (USD, EUR, GBP, JPY, ...), bez względu na walutę ustawioną przez produkt. Cena produktu wynosi 200 USD, a jeśli użytkownik wyszuka produkty kosztujące 100 EUR - 200 EUR, nadal może go znaleźć. Jak zrobić to szybko i skutecznie?
Oto, co zrobiłem do tej pory. Przechowuję price
, currency code
a calculated_price
to jest cena w euro (EUR), która jest domyślną walutą.
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';
Jeśli użytkownik szuka innej waluty, powiedzmy USD, obliczamy cenę w EUR i przeszukujemy calculated_price
kolumnę.
SELECT * FROM "products" WHERE calculated_price > 100.0 AND calculated_price < 200.0;
W ten sposób możemy bardzo szybko porównywać ceny, ponieważ nie musimy obliczać rzeczywistej ceny dla każdego wiersza, ponieważ jest ona obliczana raz.
Złą rzeczą jest to, że przynajmniej codziennie musimy ponownie obliczyć default_price
wszystkie wiersze, ponieważ zmieniono kursy walut.
Czy istnieje lepszy sposób, aby sobie z tym poradzić?
Czy nie ma innego sprytnego rozwiązania? Może jakiś wzór matematyczny? Mam pojęcie, że calculated_price
jest to stosunek do jakiejś zmiennej, X
a kiedy zmienia się waluta, aktualizujemy tylko tę zmienną X
, a nie tę calculated_price
, więc nawet nie musimy niczego aktualizować (wiersze) ... Może jakiś matematyk może to rozwiązać lubię to?
calculated_price
w ogóle powinienem aktualizować ? Mógłbym po prostu zapisaćinitial_currency_value
(stały, przyjęty, powiedzmy, dzisiaj, kurs walutowy) i zawsze liczyć się z tym! Oczywiście przy wyświetlaniu ceny w euro należy obliczyć rzeczywisty kurs walutowy. Czy mam rację? Czy istnieje problem, którego nie widzę?