Postgres违反了非空约束,即使没有定义非空约束。
Postgres违反了非空约束,即使没有定义非空约束。
嘿,我有一个带有模式的Postgres数据库
CREATE TABLE Mentor ( mentor_ID serial unique, person_ID serial not null unique, career_history varchar(255) not null, preferred_communication varchar(50) not null, mentoring_preference varchar(50) not null, linked_in varchar(100) not null, capacity int not null, feedback_rating int, feeback_comment varchar(255), PRIMARY KEY (mentor_ID), CONSTRAINT fk_person FOREIGN KEY (person_ID) REFERENCES Person(person_ID) ); CREATE TABLE Mentee( mentee_ID integer not null unique, mentor_ID serial references Mentor(mentor_ID), person_ID serial not null unique, study_year int, motivation varchar(50), interests varchar(255), random_match boolean default false, PRIMARY KEY (mentee_ID), CONSTRAINT fk_person FOREIGN KEY (person_ID) REFERENCES Person(person_ID) );
我期望能够在我的数据库中为mentor_ID输入空值,但是当我输入以下查询时
insert into mentee(mentee_ID, mentor_ID, person_ID) VALUES (12313, null, 1)
我得到了违反约束条件的错误
ERROR: null value in column "mentor_id" of relation "mentee" violates not-null constraint
我想知道如何使mentor_ID能够接受空值?尽管我在表中将其设置为非空,但它仍然显示违反非空约束条件。
谢谢你的帮助。
PostgreSQL在使用serial
作为主键时,即使没有设置为not null
,也会违反not null
约束。这是因为serial
被设计用于主键,而不是外键。外键始终被分配,不需要自动递增。
解决方法是改用普通的integer
类型来定义外键。外键只需要与被引用的主键具有相同的类型,不关心主键上的其他约束,只要类型匹配即可。
需要注意的是:
- identity是SQL标准中用于自动递增主键的方法。
- 不需要将主键声明为唯一的,主键已经是唯一的。
- 除非有特定原因限制文本字段的大小,否则应该使用text
类型。varchar
和text
类型只使用每行所需的空间。例如,在varchar(10)
和varchar(255)
中,"foo"占用的空间相同。因此,在LinkedIn和Motivation字段中,没有明确限制其大小的理由。
通过将mentor_ID
更改为使用identity
自动递增的integer
类型,可以成功引用该字段,并且在此情况下可以将其设置为null
。
总结,当在PostgreSQL中使用serial
作为主键时,即使没有设置为not null
,也会违反not null
约束。解决方法是改用普通的integer
类型来定义外键,并保证类型匹配即可。