您正在努力与现有的 Oracle 和 SQL Server 实现 兼容 。
这是一个比较三个涉及的RDBS的物理行存储格式的演示。
由于Oracle根本不实现
NULL行存储中的值,因此
NULL无论如何也无法分辨出空字符串与字符串之间的区别。因此,对于 这种
特殊的用例,使用空字符串(
'')代替
NULLPostgres中的值是否明智? __
将唯一约束中包含的列定义为
NOT NULL DEFAULT '',已解决的问题:
CREATE TABLE example ( example_id serial PRIMARY KEY , field1 text NOT NULL DEFAULT '' , field2 text NOT NULL DEFAULT '' , field3 text NOT NULL DEFAULT '' , field4 text NOT NULL DEFAULT '' , field5 text NOT NULL DEFAULT '' , ConSTRAINT example_index UNIQUE (field1, field2, field3, field4, field5));
笔记
- 您在问题中展示的是 唯一 索引 :
CREATE UNIQUE INDEX ...
而不是您一直在谈论的 唯一 约束 。有细微,重要的差异!
* [PostgreSQL如何执行UNIQUE约束/它使用什么类型的索引?](https://stackoverflow.com/questions/9066972/how-does-postgresql-enforce-the-unique-constraint-what-type-of-index-does-it-u/9067108#9067108)
我将其更改为实际约束,就像您将其作为帖子主题一样。
关键字
ASC
只是noise,因为这是默认的排序顺序。我把它丢了。serial
为简单起见,使用PK列是完全可选的,但通常比存储为的数字更好text
。
使用它
只需从中忽略空/空字段
INSERT:
INSERT INTO example(field1) VALUES ('F1_DATA');INSERT INTO example(field1, field2, field5) VALUES ('F1_DATA', 'F2_DATA', 'F5_DATA');重复任何这些插入操作都会违反唯一约束。
或者, 如果您坚持要省略目标列(这在持久化
INSERT语句中有点反模式):
或者 对于需要列出所有列的批量插入:
INSERT INTO example VALUES ('1', 'F1_DATA', DEFAULT, DEFAULT, DEFAULT, DEFAULT), ('2', 'F1_DATA','F2_DATA', DEFAULT, DEFAULT,'F5_DATA');或者 简单地:
INSERT INTO example VALUES ('1', 'F1_DATA', '', '', '', ''), ('2', 'F1_DATA','F2_DATA', '', '','F5_DATA');或者,您可以编写一个
BEFORE INSERT OR UPDATE转换
NULL为的触发器
''。
替代解决方案
如果您需要使用实际的NULL值,则建议使用唯一 索引 , COALESCE
就像您在选项(2)中提到的那样,并在最后一个示例中提供@wildplasser。
像@Rudolfo这样的 数组
上的索引很简单,但是要昂贵得多。数组处理在Postgres中并不是很便宜,并且存在类似于行(24字节)的数组开销
数组仅限于相同数据类型的列。您可以将所有列都强制转换为,
text如果不是,则通常会进一步增加存储需求。或者您可以将众所周知的行类型用于异构数据类型…
一个极端的情况:具有所有NULL值的数组(或行)类型被视为相等(!),因此只能有1行且所有涉及的列均为NULL。可能会或可能不会符合要求。



