存储和查询每行不同的定价结构?

Storing and querying pricing structures which differ for each row?

我一直在努力想出一种存储这些数据的好方法...

每一行都是医生的做法。每种做法的价格因年龄段而异。例如,一种做法可能具有这种定价结构,其中左边是年龄,右边是价格:

0: 0
13: 20
21: 35
35: 35
60: 20

但是结构因实践而异。所以另一种做法可能是这样的:

0: 5
25: 50
40: 35
60: 20

我需要能够获取任何给定年龄的价格。

目前我将所有价格存储在每行的 JSONB 列中。我在 nodeJS 中获取 JSON 对象和 运行 一种算法来获取某个年龄段的价格。这当然不理想,但我想不出任何方法来在 postgres 中存储和查询它。

到目前为止,我考虑过另外 table 的费用,并像这样存储每个 age/price 对:

name | age | price

但这似乎有点笨拙并且会创建数千行。我的另一个想法是在练习行中为每个可能的年龄设置成本列,如下所示:

name | 0 | 5 | 6 | 13 | 16 | 18 | 21 | 25 | 40 | 60

但这也显得非常笨拙和笨拙。

有什么想法吗?或者,也许我最好将其保留在 JSON?

如果我没有理解错的话,价格取决于练习和年龄的结合。制作一个包含 3 列的 table 怎么样:

Practice_ID | Age | Price

其中 Practice_ID 和 Age 是主键。这样你就可以查询到价格和年龄。

我会将价格存储在单独的 table 中,该 table 定义价格有效的 "interval":

create table practice
(
  id integer not null primary key,
  name text
);

create table prices
(
  practice_id integer not null references practice,
  from_age integer not null,
  to_age integer,
  price integer not null,
  constraint valid_interval check (from_age < to_age)
);

您还可以添加排除约束以防止间隔重叠:

CONSTRAINT no_overlap 
   EXCLUDE USING gist (practice_id WITH =, int4range(from_age, to_age)  WITH &&)

当然,除了使用 from_ageto_age 两列之外,您还可以将其放入单个 int4range 列中,这具有可索引的优点。由于您通常会根据只留下极少数行的做法进行查询,因此范围列上的索引不是必需的(或无济于事)

查询价格,您只需:

select price
from prices
where practice_id = 42
and 25 between from_age and to_age

由于条件 practice_id = 42 已经将其缩小到仅 5 或 6 行,因此速度非常快。纵有千行。