存储和使用值范围(PostgreSQL)

时间:2018-04-17 21:17:58

标签: postgresql database-design relational-database

我有一个PostgreSQL数据库,其中物理活动存储一定的能量十进制值,例如

ACTIVITY   ENERGY
-----------------
Activity1  0.7
Activity2  1.3
Activity3  4.5

我有一个分类系统,将每个能量值分类为

Light:    0 - 2.9
Moderate: 3.0 - 5.9
Vigorous: >= 6.0

分类和能源价值可能会发生变化。我需要一种方法来快速获取每个活动的类型。但是如何以易于检索的方式存储这些?

一种解决方案是定义类型“分类”的MIN / MAX查找 - 并提取所有可用的分类;然后做一个CASE / WHEN经历每一个。

LOOKUP_ID   LOOKUP_NAME     LOOKUP_VALUE      LOOKUP_TYPE
---------------------------------------------------------
1           LIGHT_MIN       0                 CLASSIFICATION
2           LIGHT_MAX       2.9               CLASSIFICATION
3           MODERATE_MIN    3                 CLASSIFICATION
4           MODERATE_MAX    5.9               CLASSIFICATION
5           VIGOROUS_MIN    6                 CLASSIFICATION
6           VIGOROUS_MAX    null              CLASSIFICATION

但这对我来说并不容易 - 如果开发人员需要获得当前的分类,他们将不得不逐步完成不同的情况并进行比较。

是否有更好的策略来捕捉这些范围,或者这是正确的?

2 个答案:

答案 0 :(得分:1)

使用range type

create table classification 
(
  description text,
  energy numrange
);

insert into classification 
  (description, energy)
values
  ('Light',  numrange(0,3.0,'[)')),
  ('Moderate', numrange(3.0, 6.0, '[)')),
  ('Vigorous', numrange(6.0, null, '[)'));

然后,您可以使用<@运算符加入这两个表:

select *
from activity a
  join classification c on a.energy <@ c.energy

关于范围类型的好处是,您可以使用exclusion constraint

来防止插入重叠范围
alter table classification 
  add constraint check_range_overlap
  exclude using gist (energy with &&);

鉴于以上样本数据,将拒绝以下插入:

insert into classification 
  (description, energy)
values 
  ('Strenuous', numrange(8.0, 11.0, '[)'));

答案 1 :(得分:0)

我不认为这是一个很好的解决方案,但它似乎比上面的模型更好。

创建一个包含范围和分类的表:

create table classification (
  energy_min numeric,
  energy_max numeric,
  classification text
);

然后按如下方式在该表上进行连接:

  a.activity, a.energy, c.classification
from
  activities a
  left join classification c on
    a.energy >= c.energy_min and
   (a.energy <= c.energy_max or c.energy_max is null);

如果可能的分类相对较小,这应该足够好。我不认为它在后端有效,因为它可能在分类表上进行交叉连接。也就是说,如果它有三个(甚至十个)记录,那就没什么大不了的了。

它应该可以很好地扩展,并使您能够快速修改值并快速获得结果。

如果您真的想要获得幻想,您还可以在&#34;分类&#34;中包含有效期和有效期。表,您可以更改分类,但也保留旧记录的历史分类。