Postgresql 空组合类型和包含所有空列的组合类型之间的差异
空值和所有列都为空的行类型之间有什么区别吗?Postgres查询似乎能够区分差异(显示空列而不是空列),我想知道是否有什么我应该知道的。e、 gPostgresql 空组合类型和包含所有空列的组合类型之间的差异,postgresql,null,distinct,postgresql-9.6,row-value-expression,Postgresql,Null,Distinct,Postgresql 9.6,Row Value Expression,空值和所有列都为空的行类型之间有什么区别吗?Postgres查询似乎能够区分差异(显示空列而不是空列),我想知道是否有什么我应该知道的。e、 g CREATE TYPE node AS ( rank integer , id integer ); CREATE TABLE hierarchy ( node node ); INSERT INTO hierarchy (node) VALUES (null); INSERT INTO hierarchy (node) VALUES
CREATE TYPE node AS (
rank integer
, id integer
);
CREATE TABLE hierarchy (
node node
);
INSERT INTO hierarchy (node) VALUES (null);
INSERT INTO hierarchy (node) VALUES ((null, null));
SELECT *, node IS NULL AS check_null FROM hierarchy;
空值和所有列都为空的行类型之间有什么区别吗?
NULL:node
仍然不同于(NULL,NULL)::node
:
SELECT null::node IS DISTINCT FROM (null, null)::node AS dist;
我同意这令人困惑。还有:
对于非空输入,不同于
与
运算符相同。
但是,如果两个输入都为null,则返回false,如果只有一个输入,则返回false
输入为null,则返回true
事实证明,在上面的演示中有点不正确。尽管有进一步的暗示:
如果表达式
是行值表达式,则当行
表达式本身为空或当所有行的字段为空时
因此我们有两种不同的情况,行值为null:
不同于时,这两种情况仍然被认为是不同的。可能值得一份文档错误报告
有什么我应该知道的吗?
对。只要DISTINCT
起作用,这两种变体都被认为是不同的:
SELECT DISTINCT * FROM hierarchy;
注意第二行不可见,因为psql以这种方式显示空值
阻止(,)案例发生?
针对您的评论:
CREATE TABLE hierarchy (
node node CHECK (node IS DISTINCT FROM (null, null)::node)
);
注意两件事:
显式强制转换(null,null)::node
是必需的
仍然允许使用简单的空值,只有包含所有空值的行才违反约束
检查数据库设计,因为所有列都为NULL的行在关系模型中没有意义。您总是需要一个唯一的主键来标识表中的每一行。行可以有一些空字段,但行的主键永远不应该为空。@aicastell将问题中的rowtype读取为复合类型。您的问题有许多语法错误(以及语义错误,f.ex.node既是复合类型又是表名)。你确定是你干的?(NULL,NULL)的奇怪行为是NULL
来自SQL标准。但实际上,当处理外部连接时,它非常方便。您所显示的内容是不可能的。表和复合类型不能具有相同的名称。请修正你的问题使其有意义。并始终声明您正在使用的Postgres版本。因此,为了防止出现(,)
情况,我必须添加检查(node1不同于(null,null))
约束?@dbeacham:是的,但您需要显式类型转换。我在上面加了更多。
SELECT DISTINCT * FROM hierarchy;
node1
------
(,)
(2 rows)
CREATE TABLE hierarchy (
node node CHECK (node IS DISTINCT FROM (null, null)::node)
);