Java Flyway和PostgreSQL可空外键定义仍然生成非空约束
我将Spring Boot和Flyway用于以下初始化脚本:Java Flyway和PostgreSQL可空外键定义仍然生成非空约束,java,spring,postgresql,spring-boot,flyway,Java,Spring,Postgresql,Spring Boot,Flyway,我将Spring Boot和Flyway用于以下初始化脚本: CREATE TABLE ADDRESS( ID bigserial NOT NULL PRIMARY KEY ); CREATE TABLE ROLE( ID bigserial NOT NULL PRIMARY KEY ); CREATE TABLE PERSON( ID bigserial NOT NULL PRIMARY KEY, FIRST_NAME
CREATE TABLE ADDRESS(
ID bigserial NOT NULL PRIMARY KEY
);
CREATE TABLE ROLE(
ID bigserial NOT NULL PRIMARY KEY
);
CREATE TABLE PERSON(
ID bigserial NOT NULL PRIMARY KEY,
FIRST_NAME VARCHAR(255),
LAST_NAME VARCHAR(255),
ADDRESS bigserial NOT NULL REFERENCES ADDRESS (ID),
ROLE bigserial REFERENCES ROLE (ID) -- notice here is no 'not null'
);
表之间的所有关系是:
- 每个
都有人
0-1
。因此,每个角色
都属于角色
0-n
。因此,此关系可为空个人
- 每个
都有人
1
。因此,每个地址
都属于地址
1-n
。因此,此关系不是空的个人
PERSON
和ROLE
表之间生成约束not null
使用DataGrip,我选择SQL脚本->生成DDL以查询控制台并获取表的DDL(请参见下文,为了简洁起见,省略了新行和角色定义)
令我惊讶的是,notnull
存在,尽管我还没有定义这样的约束。除了换桌子外,如何摆脱它
create table if not exists address
(
id bigserial not null
constraint address_pkey primary key
);
create table if not exists role
(
id bigserial not nullconstraint role_pkey primary key
);
create table if not exists person
(
id bigserial not null
constraint person_pkey primary key,
first_name varchar(255),
last_name varchar(255),
address bigserial not null
constraint person_address_fkey references address,
role bigserial not null -- why is 'not null' here?
constraint person_role_fkey references role
);
我使用的PostgreSQL版本(通过
SELECT version()
)是:
:
数据类型smallserial
、serial
和bigserial
不正确
类型,但这仅仅是创建唯一
标识符列(类似于支持的自动增量
属性
由其他一些数据库提供)。在当前实现中,指定:
CREATE TABLE tablename (
colname SERIAL
);
CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
等同于指定:
CREATE TABLE tablename (
colname SERIAL
);
CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
注意不为空
不要对外键使用bigserial
。那没有多大意义。只需使用bigint
CREATE TABLE IF NOT EXISTS person
(...
role bigint REFERENCES role);
:
数据类型smallserial
、serial
和bigserial
不正确
类型,但这仅仅是创建唯一
标识符列(类似于支持的自动增量
属性
由其他一些数据库提供)。在当前实现中,指定:
CREATE TABLE tablename (
colname SERIAL
);
CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
等同于指定:
CREATE TABLE tablename (
colname SERIAL
);
CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
注意不为空
不要对外键使用bigserial
。那没有多大意义。只需使用bigint
CREATE TABLE IF NOT EXISTS person
(...
role bigint REFERENCES role);
请注意,对于Postgres 10或更高版本,
identity
列建议优先于serial
列:请注意,对于Postgres 10或更高版本,identity
列建议优先于serial
列:这在使用(推荐)时更为明显identity
而不是serial
我是否正确理解bigserial
对于主键定义是好的,只要它指定了自动递增,并且bigint
适合引用这些键?@nikolasharalalambidis:bigint
是这里的基本实际数据类型。使用bigserial
也是一种bigint
,它只是添加了一些巫毒,以使用序列自动为列创建唯一值,就像一些宏,如果需要,可以展开。对于主键,这很方便。但是自动为外键创建值没有多大意义。他们只是或多或少地随机引用一条记录(至少可能不是您想要的记录),或者偶尔生成一个引用表中不存在的值,从而导致错误。这不太方便。使用(推荐)时,这一点更加明显identity
而不是serial
我是否正确理解bigserial
对于主键定义是好的,只要它指定了自动递增,并且bigint
适合引用这些键?@nikolasharalalambidis:bigint
是这里的基本实际数据类型。使用bigserial
也是一种bigint
,它只是添加了一些巫毒,以使用序列自动为列创建唯一值,就像一些宏,如果需要,可以展开。对于主键,这很方便。但是自动为外键创建值没有多大意义。他们只是或多或少地随机引用一条记录(至少可能不是您想要的记录),或者偶尔生成一个引用表中不存在的值,从而导致错误。那不太方便。