如何在postgresql中保存年的间隔

Fed*_*nzi 3 postgresql datatypes

我必须保存几年的间隔,例如:

id intervalYears
1  2014/2015
2  2015/2016
3  2016/2017
Run Code Online (Sandbox Code Playgroud)

等等。那些年就像学术年,所以第一年必须小于第二年,但大于或等于实际年份。

那么,如何保存这种数据类型呢?我应该分开日期并添加一些cotraints吗?

Cra*_*ger 5

如果可能,只存储第一个值

看起来您根本不需要存储两个数字。

如果这些类似于纳税年度,即“2014/2015 财政年度”,您只需要一致地存储一部分。

如果您存储2014,您的应用程序就会知道这是从 2014 年开始的学年。所以它可以毫无歧义地显示“2014/2015学年”。

如果你真的需要一个范围

如果您确实需要范围并且您的示例数据没有表达这一点,例如您可能需要存储2012/2015,那么两int2列将是一个不错的选择。CHECK正如@Neil 已经表明的那样,您可以使用约束将范围限制为一个学年的合理值,并强制下限小于上限。

或者,您可以使用 new-ish 和 PostgreSQL 特定int4range类型:

SELECT int4range(2014, 2015);
Run Code Online (Sandbox Code Playgroud)

根据范围类型文档。这为您提供了更多的操作员,但代价是在处理基本查询和来自客户端应用程序时更加繁琐。

您甚至可以对其进行DOMAIN覆盖以限制其范围。

CREATE DOMAIN academicyearrange AS int4range 
  CONSTRAINT must_be_sane_year 
  CHECK ( lower(VALUE) BETWEEN 1900 AND 2100 
      AND upper(VALUE) BETWEEN 1900 AND 2100 );
Run Code Online (Sandbox Code Playgroud)

例如

regress=> SELECT '[1421,2247)'::academicyearrange;
ERROR:  value for domain academicyearrange violates check constraint "must_be_sane_year"

regress=> SELECT int4range(1421,2247)::academicyearrange;
ERROR:  value for domain academicyearrange violates check constraint "must_be_sane_year"
Run Code Online (Sandbox Code Playgroud)

(在范围类型之前,我会建议在复合类型上使用域,但int4range在各方面都比复合类型更好)。

很可能所有这些都是不必要的——如果你不需要可变长度范围,即它总是 someyear/thenextyear,你应该只存储 the first year