【发布时间】:2014-06-11 17:18:01
【问题描述】:
我正在使用 Postgres 9.3 并拥有以下四个表格,以便在未来价格和/或税率/税率变化方面具有最大的灵活性(更多详细信息请参见下文):
CREATE TABLE main.products
(
id serial NOT NULL,
"productName" character varying(255) NOT NULL,
"productStockAmount" real NOT NULL,
)
CREATE TABLE main."productPrices"
(
id serial NOT NULL,
product_id integer NOT NULL,
"productPriceValue" real NOT NULL,
"productPriceValidFrom" timestamp without time zone NOT NULL,
)
CREATE TABLE main."productTaxes"
(
id serial NOT NULL,
product_id integer NOT NULL,
"productTaxValidFrom" timestamp without time zone NOT NULL,
"taxRate_id" integer NOT NULL,
)
CREATE TABLE main."taxRateValues"
(
id integer NOT NULL,
"taxRate_id" integer NOT NULL,
"taxRateValueValidFrom" timestamp without time zone NOT NULL,
"taxRateValue" real,
)
我根据以下查询构建了一个视图以获取当前相关的值:
SELECT p.id, p."productName", p."productStockAmount", sub."productPriceValue", CHR(64+sub3."taxRate_id") AS taxRateId, sub3."taxRateValue" FROM main."products" p
CROSS JOIN LATERAL (SELECT * FROM main."productPrices" pp2 WHERE pp2."product_id"=p."id" AND pp2."productPriceValidFrom" <= NOW() ORDER BY pp2."productPriceValidFrom" DESC LIMIT 1) AS sub
CROSS JOIN LATERAL (SELECT * FROM main."productTaxes" pt WHERE pt."product_id"=p."id" AND pt."productTaxValidFrom" <= NOW() ORDER BY pt."productTaxValidFrom" DESC LIMIT 1) AS sub2
CROSS JOIN LATERAL (SELECT * FROM main."taxRateValues" trv WHERE trv."taxRate_id"=sub2."taxRate_id" AND trv."taxRateValueValidFrom" <= NOW() ORDER BY trv."taxRateValueValidFrom" DESC LIMIT 1) AS sub3
这很好用并且给了我正确的结果,但我假设如果数据库中有数千种产品、价格变化等会出现性能问题。
我可以做些什么来简化语句或整体数据库设计? 用词来描述所需的灵活性:
- 价格可以更改,我必须记录哪个价格在哪个时间有效(存档,因此不仅需要当前价格)
- 产品适用的税率可以更改(例如,由于法律的变化) - 也需要存档
- 一般税率可以更改(法律也可以更改,但与单个产品无关,而是与具有此标识符的所有产品相关)
可能发生的事情的一些例子:
- 产品 X 在 2014 年 5 月 9 日将价格从 100 更改为 200
- 产品 X 在 2014-07-01 将税率从 A 更改为 B
- 税率 A 的税率值在 2014 年 9 月 1 日从 16 更改为 19
【问题讨论】:
-
一个非常好的问题,包含表定义以及清晰的描述和基本原理。无需进一步编辑即可清除。这就是它的完成方式。 (仅缺少您的 Postgres 版本。)
-
感谢您的反馈。为了完整起见,我添加了 Postgres 版本;)
标签: sql performance postgresql join database-performance