Quero tornar possível ao usuário pesquisar produtos dentro de uma faixa de preço. O usuário deve poder usar qualquer moeda (USD, EUR, GBP, JPY, ...), independentemente da moeda definida pelo produto. Portanto, o preço do produto é 200USD e, se o usuário pesquisar os produtos que custam 100EUR - 200EUR, ele ainda poderá encontrá-lo. Como torná-lo rápido e eficaz?
Aqui está o que eu fiz até agora. Eu guardo o price
, currency code
e calculated_price
esse é o preço em euros (EUR), que é a moeda padrão.
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';
Se o usuário estiver pesquisando com outra moeda, digamos USD, calculamos o preço em EUR e pesquisamos na calculated_price
coluna.
SELECT * FROM "products" WHERE calculated_price > 100.0 AND calculated_price < 200.0;
Dessa forma, podemos comparar preços muito rapidamente, porque não precisamos calcular o preço real de cada linha, porque é calculado uma vez.
O ruim é que pelo menos todos os dias temos que recalcular o valor default_price
de todas as linhas, porque as taxas de câmbio foram alteradas.
Existe uma maneira melhor de lidar com isso?
Não existe outra solução inteligente? Talvez alguma fórmula matemática? Eu tenho uma ideia de que calculated_price
é uma razão em relação a alguma variável X
e, quando a moeda muda, atualizamos apenas essa variável X
, não a calculated_price
, então nem precisamos atualizar nada (linhas) ... Talvez algum matemático possa resolvê-la como isso?
fonte
calculated_price
? Eu poderia simplesmente armazenar ainitial_currency_value
(taxa de câmbio constante hoje, digamos, hoje) e sempre calcular com base nisso! E ao exibir o preço em euros, calcule com base na taxa de câmbio real, é claro. Estou certo? Ou há um problema que não vejo?Eu vim com minha própria ideia. Diga-me se realmente vai funcionar, por favor!
O problema.
Quando o produto está sendo adicionado na
products
tabela, o preço é convertido para a moeda padrão (EUR) e armazenado nacalculated_price
coluna.Queremos que o usuário possa pesquisar (filtrar) preços de qualquer moeda. Isso é feito convertendo o preço de entrada para a moeda padrão (EUR) e comparando-o com a
calculated_price
coluna.Precisamos atualizar as taxas de câmbio, para que os usuários possam pesquisar por novas taxas de câmbio. Mas o problema é - como atualizar com
calculated_price
eficiência.A solução (espero).
Não! :)
A ideia é que utilizemos apenas as taxas de câmbio de ontem ( todas na mesma data ) . Tipo ... para sempre! Não há atualizações diárias. A única coisa que precisamos antes de comparar / filtrar / pesquisar os preços é levar as taxas de câmbio de hoje como eram de ontem.
calculated_price
Portanto,
calculated_price
usaremos apenas a taxa de câmbio da data fixa (escolhemos, digamos, ontem). O que precisaremos é converter o preço de hoje no preço de ontem. Em outras palavras, pegue a taxa de hoje e converta-a na taxa de ontem:E esta é a tabela das moedas:
Veja como adicionar um produto que custa 200 USD e como
calculated_price
é calculado o ganho: da taxa de USD ao mais recente em EUR e à taxa fixa (antiga)Isso também pode ser pré-calculado no lado do cliente e é isso que eu vou fazer - calcular o preço de entrada do usuário para o
calculated_price
valor compatível antes de fazermos uma consulta, para que seja usado muito bemSELECT * FROM products WHERE calculated_price > 100.0 AND calculated_price < 200.0;
Conclusão.
Essa ideia me veio há apenas algumas horas e atualmente estou pedindo que você verifique se estou certo sobre esta solução. O que você acha? Isso vai funcionar? Ou eu me enganei?
Espero que você entenda tudo isso. Eu não sou um falante nativo de inglês, também é tarde e estou cansado. :)
ATUALIZAR
Bem, parece que resolve um problema, mas apresenta outro. Que pena. :)
fonte
rate_newest / rate_fixed
é diferente por moeda, e esta solução considera apenas a do dinheiro escolhido pelo usuário na pesquisa. Qualquer preço em uma moeda diferente não seria comparado com as taxas atualizadas. A resposta que enviei de alguma forma teve um problema semelhante, mas acho que a corrigi na versão atualizada.