我目前正在设计一个必须处理大量时态数据的数据库。因此,有很多列应该保持时间间隔类似的值。重要的是,这些值中的每一个都必须符合一组固定的数值范围。因此,创建数据库级约束来强制执行这些检查会很有意义(并且还提供一些有用的故障)。
首先我考虑使用BIGINT
数据类型&将间隔存储为UNIX时间戳。这将允许我编写一些简单的CHECK约束,并且只需完成它。但是,调查PostgreSQL特定的INTERVAL
数据类型似乎发现了一些非常有用的功能。此外,使用它可能在我的设计语义方面更有意义。
切换到INTERVAL
之后我遇到的最大问题是,我似乎无法找到一种很好的统一方法来定义前面提到的CHECK约束。
以下是我正在尝试做的一个粗略的例子:
CREATE TABLE PURCHASE( PURCHASE_ID SERIAL, PURCHASE_STATE_TYPE_ID SMALLINT NOT NULL, CUSTOMER_ID INTEGER NOT NULL, ... COOLINGOFF_PERIOD INTERVAL(3) NOT NULL, CONSTRAINT PK_PURCHASE PRIMARY KEY(PURCHASE_ID), CONSTRAINT FK_PURCHASE_PURCHASE_STATE_TYPE_ID FOREIGN KEY(PURCHASE_STATE_TYPE_ID) REFERENCES PURCHASE_STATE_TYPE(PURCHASE_STATE_TYPE_ID) ON UPDATE CASCADE, ... CONSTRAINT CHK_PURCHASE_COOLINGOFF_PERIOD_IN_RANGE CHECK((EXTRACT(EPOCH FROM INTERVAL COOLINGOFF_PERIOD)) BETWEEN 0 AND 315400000) ... );
在这种情况下,我们有CHK_PURCHASE_COOLINGOFF_PERIOD_IN_RANGE
CHECK约束,它强制每个COOLINGOFF_PERIOD
的{{1}}落在0到10年之间。
不幸的是,上面的DDL语句因语法错误而失败:PURCHASE
我在这里遗漏了什么吗?有没有一个漂亮而干净的(即声明性)方式来实现这一点,还是应该回到使用ERROR: syntax error at or near "COOLINGOFF_PERIOD".
呢?
答案 0 :(得分:1)
从技术上讲,检查约束中的语法错误与此部分有关:
EPOCH FROM INTERVAL COOLINGOFF_PERIOD
这是不被接受的,因为在此上下文中INTERVAL
意味着后跟文字,如INTERVAL '10 days'
无论如何,根据评论中的建议,甚至不需要EPOCH
的翻译,更容易编写:
CREATE TABLE ... (
...
COOLINGOFF_PERIOD INTERVAL(3) NOT NULL
CHECK (COOLINGOFF_PERIOD between '0'::interval and '10 years'::interval)
...
);
有关所有详细信息和语法变体,请参阅文档中的Interval Input。