Я хочу зробити так, щоб користувач міг шукати товари в ціновому діапазоні. Користувач повинен мати можливість використовувати будь-яку валюту (USD, EUR, GBP, JPY, ...), незалежно від того, яку валюту встановлює продукт. Отже, ціна товару - 200 доларів США, і якщо користувач шукає товари, які коштують 100 євро - 200 євро, він все одно може знайти його. Як зробити це швидко та ефективно?
Ось що я робив дотепер. Я зберігаю price
, currency code
і calculated_price
це ціна в євро (євро), яка є валютою за замовчуванням.
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';
Якщо користувач здійснює пошук в іншій валюті, скажімо, у доларах США, ми розраховуємо ціну в євро та шукаємо calculated_price
стовпець.
SELECT * FROM "products" WHERE calculated_price > 100.0 AND calculated_price < 200.0;
Таким чином ми можемо порівнювати ціни дуже швидко, тому що нам не потрібно обчислювати фактичну ціну для кожного ряду, оскільки вона розраховується один раз.
Погано, що щонайменше щодня нам доводиться повторно обчислювати default_price
всі рядки, оскільки курси валют були змінені.
Чи є кращий спосіб впоратися з цим?
Хіба немає іншого розумного рішення? Може, якась математична формула? У мене є ідея, що calculated_price
це співвідношення проти деякої змінної, X
і коли валюта змінюється, ми оновлюємо лише цю змінну X
, а не ту calculated_price
, тож нам навіть не потрібно нічого оновлювати (рядки) ... Можливо, якийсь математик може це вирішити подобається це?
calculated_price
? Я міг би просто зберігатиinitial_currency_value
(постійний курс валюти, який приймаємо, скажімо, сьогодні), і завжди обчислювати проти цього! А коли відображається ціна в євро, то, звичайно, підрахуйте фактичний курс валюти. Чи правий я? Або є проблема, яку я не бачу?