PostgreSQL: Unique constraint allow mutiple nulls

今天在和一个项目沟通过程中,开发人员说在 PostgreSQL 中的 unique 约束中可以存储多个null 值的记录,一开始觉得比较奇怪,难道 null 值不等于 null 值,带着疑问,赶紧测试下。

PostgreSQL 中测试 null

1.1 创建表并创建 unique 索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
francs=> create table test_unique (id int4,name varchar(32));  
CREATE TABLE

francs=> create unique index idx_test_unique_id on test_unique using btree (id);
CREATE INDEX

francs=> /d test_unique;
Table "francs.test_unique"
Column | Type | Modifiers
--------+-----------------------+-----------
id | integer |
name | character varying(32) |
Indexes:
"idx_test_unique_id" UNIQUE, btree (id)

1.2 重复插入数据 1

1
2
3
4
5
francs=> insert into test_unique (id ,name )values (1,'a');  
INSERT 0 1
francs=> insert into test_unique (id ,name )values (1,'a');
ERROR: duplicate key value violates unique constraint "idx_test_unique_id"
DETAIL: Key (id)=(1) already exists.

1.3 重复插入 null 值

1
2
3
4
5
6
7
8
9
10
11
francs=> insert into test_unique (id ,name )values (null,'b');  
INSERT 0 1
francs=> insert into test_unique (id ,name )values (null,'b');
INSERT 0 1
francs=> select * from test_unique;
id | name
----+------
1 | a
| b
| b
(3 rows)

备注:果然在唯一约束字段上可以存储多个 null 的记录,觉得很奇怪,猜测是因为 null 是一个不确定的值,没有确定的类型,所以 null != null,接下来看下在 Oracle 库的情况。

Oracle 库中测试 null

2.1 创建测试表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
20:45:03 [SYS@skytf](mailto:SYS@skytf)> select *From v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

20:00:38 [SKYTF@skytf](mailto:SKYTF@skytf)> create table test_unique (id integer,name varchar(32));
表已创建。

20:00:52 [SKYTF@skytf](mailto:SKYTF@skytf)> create unique index idx_test_unique_id on test_unique (id);
索引已创建。

2.2 插入数据测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
20:45:03 [SYS@skytf](mailto:SYS@skytf)> select *From v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

20:00:38 [SKYTF@skytf](mailto:SKYTF@skytf)> create table test_unique (id integer,name varchar(32));
表已创建。

20:00:52 [SKYTF@skytf](mailto:SKYTF@skytf)> create unique index idx_test_unique_id on test_unique (id);
索引已创建。

备注:可见 Oracle 中,唯一约束的字段上也允许存储多个 null,后来网上查了下资料,大致是说 NULL 是数据库中特殊的数据类型,这个值是不确定的,所以对于 NULL的判断是这样的:NULL 即不是NULL,也不是 NOT NULL,因为 NULL 具有无数的可能性,关于 NULL 的解释 itput 上有篇贴子解释得很好,有兴趣的朋友可以看看:http://www.itpub.net/thread-932786-1-1.html

原创文章,作者:1402239773,如若转载,请注明出处:https://blog.ytso.com/tech/database/237877.html

(0)
上一篇 2022年1月29日 22:30
下一篇 2022年1月29日 22:30

相关推荐

发表回复

登录后才能评论