Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
唯一日期字段postgresql默认值_Postgresql_Date_Unique - Fatal编程技术网

唯一日期字段postgresql默认值

唯一日期字段postgresql默认值,postgresql,date,unique,Postgresql,Date,Unique,我有一个date列,我希望该列在填充后是唯一的,但如果未填充,则希望忽略date字段 在MySQL中,实现这一点的方法是将date列设置为“notnull”,并给它一个默认值“0000-00-00”-这允许“检查”唯一索引中的所有其他字段,即使date列尚未填充 这在PosgreSQL中不起作用,因为“0000-00-00”不是有效的日期,所以不能将其存储在日期字段中(这对我来说很有意义) 乍一看,将字段保留为空似乎是一个选项,但这会产生一个问题: => create table uniq

我有一个
date
列,我希望该列在填充后是唯一的,但如果未填充,则希望忽略
date
字段

在MySQL中,实现这一点的方法是将
date
列设置为“notnull”,并给它一个默认值“0000-00-00”-这允许“检查”唯一索引中的所有其他字段,即使
date
列尚未填充

这在PosgreSQL中不起作用,因为“0000-00-00”不是有效的日期,所以不能将其存储在日期字段中(这对我来说很有意义)

乍一看,将字段
保留为空似乎是一个选项,但这会产生一个问题:

=> create table uniq_test(NUMBER bigint not null, date DATE, UNIQUE(number, date));
CREATE TABLE
=> insert into uniq_test(number) values(1);
INSERT 0 1
=> insert into uniq_test(number) values(1);
INSERT 0 1
=> insert into uniq_test(number) values(1);
INSERT 0 1
=> insert into uniq_test(number) values(1);
INSERT 0 1
=> select * from uniq_test;
 number | date 
--------+------
      1 | 
      1 | 
      1 | 
      1 | 
(4 rows)
NULL显然“不等于自身”,因此它不计入约束

如果我只在
number
字段上添加了一个额外的唯一约束,它只检查
number
而不检查
date
,因此我不能有两个日期不同的数字

我可以选择一个“有效日期”(但不在工作范围内)的默认日期来回避这个问题,并且可以(事实上)在当前项目中避开这个问题,但实际上,在未来几年中,我可能会遇到一些情况,事实上不会因为“很久以前”而很明显该日期是非真实日期或者“在未来”

“0000-00-00”技工给我带来的好处就是,这个日期不是真实的,因此表示一个未填充的条目(其中“未填充”是一个有效的唯一性属性)。当我在互联网上四处寻找解决方案时,我发现大多数是“只使用NULL”和“存储零是愚蠢的”

TL;博士
是否存在需要在包含日期字段的唯一约束中包含“未填充”作为可能值的PostgreSQL最佳做法?

这不是最佳做法,但您可以这样做:

t=# create table so35(i int, d date);
CREATE TABLE
t=# create unique index i35 on so35(i, coalesce(d,'-infinity'));
CREATE INDEX
t=# insert into so35 (i) select 1;
INSERT 0 1
t=# insert into so35 (i) select 2;
INSERT 0 1
t=# insert into so35 (i) select 2;
ERROR:  duplicate key value violates unique constraint "i35"
DETAIL:  Key (i, (COALESCE(d, '-infinity'::date)))=(2, -infinity) already exists.
STATEMENT:  insert into so35 (i) select 2;

这不是最佳做法,但您可以这样做:

t=# create table so35(i int, d date);
CREATE TABLE
t=# create unique index i35 on so35(i, coalesce(d,'-infinity'));
CREATE INDEX
t=# insert into so35 (i) select 1;
INSERT 0 1
t=# insert into so35 (i) select 2;
INSERT 0 1
t=# insert into so35 (i) select 2;
ERROR:  duplicate key value violates unique constraint "i35"
DETAIL:  Key (i, (COALESCE(d, '-infinity'::date)))=(2, -infinity) already exists.
STATEMENT:  insert into so35 (i) select 2;

不清楚你想要什么。这是我的猜测:

create table uniq_test (number bigint not null, date date);

create unique index i1 on uniq_test (number, date)
where date is not null;

create unique index i2 on uniq_test (number)
where date is null;
对于非空日期和空日期,将有一个唯一的约束,有效地将
(number,date)
元组转换为不同的值


选中“不清楚您想要什么”。这是我的猜测:

create table uniq_test (number bigint not null, date date);

create unique index i1 on uniq_test (number, date)
where date is not null;

create unique index i2 on uniq_test (number)
where date is null;
对于非空日期和空日期,将有一个唯一的约束,有效地将
(number,date)
元组转换为不同的值


检查

我更喜欢
-infinity
而不是
0001-01-01
我发现它更合理-它更好地记录了预期行为(在我看来)。我不知道是否有任何性能优势(或劣势),我想让它看起来更接近OP提到的“0000-00-00”机制,但你是对的-
-infinity
更有意义我更喜欢
-infinity
而不是
0001-01-01
我发现它更合理-它更好地记录了预期的行为(在我看来)。我不知道是否有任何性能优势(或劣势),我想让它看起来接近OP提到的“0000-00-00”机制,但你是对的-
-infinity
更有意义。你可以使用
-infinity
作为默认值。你可以使用
-infinity
作为默认值。谢谢,这样排序-我几乎完全不知道部分索引。我想我可以把这归因于填补了一个知识空白。谢谢,这样排序-我是几乎完全不知道部分索引。我想我可以把这归因于填补了一个知识缺口。