PostgreSQL双表结构工作不正常
我运行以下代码:PostgreSQL双表结构工作不正常,postgresql,check-constraints,Postgresql,Check Constraints,我运行以下代码: -- Table describing messages CREATE TABLE messages ( id serial PRIMARY KEY NOT NULL, text TEXT -- Message can have or not have text ); -- Table describing media attached to messages CREATE TABLE messages_attachments ( message_id integer
-- Table describing messages
CREATE TABLE messages
(
id serial PRIMARY KEY NOT NULL,
text TEXT -- Message can have or not have text
);
-- Table describing media attached to messages
CREATE TABLE messages_attachments
(
message_id integer NOT NULL REFERENCES messages,
-- Messages can have any number of attachments, including 0
attachment_id TEXT NOT NULL
);
-- Messages must have either text or at least one attachment
CREATE FUNCTION message_has_text_or_attachments(integer) RETURNS bool STABLE
AS
$$
SELECT
EXISTS(SELECT 1 FROM messages_attachments WHERE message_id = $1)
OR
(SELECT text IS NOT NULL FROM messages WHERE id = $1);
$$ LANGUAGE SQL;
ALTER TABLE messages ADD CONSTRAINT nonempty_message CHECK ( message_has_text_or_attachments(id) );
-- Insert a message with no text and no attachments. Should fail, but it does not
INSERT INTO messages(text) VALUES (NULL);
SELECT *, message_has_text_or_attachments(id) FROM messages;
我希望它在INSERT
行失败,因为插入的行违反了检查约束(我们正在插入一条文本为NULL
且该消息没有附件的消息),但它成功运行,下一个查询返回(1
,NULL
,false
)(这是一个略加修改的函数定义(由于数据库版本的原因,用撇号代替美元符号)
更有趣的是,如果在添加约束之前更改命令的顺序并插入行,则PostgreSQL无法更改表,因为某些行违反了“检查约束”非空消息”
为什么PostgreSQL允许插入违反约束的行?我在函数定义中的某个地方弄错了吗?在如何应用约束以及它们可以依赖哪些表方面是否存在一些限制?这是PostgreSQL错误吗?来自:
PostgreSQL不支持引用被检查的新行或更新行以外的表数据的检查约束。尽管违反此规则的检查约束可能在简单测试中有效,但它不能保证数据库不会达到约束条件为false的状态(由于涉及的其他行的后续更改)