SYSTEM.ADMIN(ADMIN)=> create table test ( name varchar(20), age int);
CREATE TABLE
SYSTEM.ADMIN(ADMIN)=> alter table test add column dob varchar(20) NOT NULL;
错误:ALTER TABLE:列" DOB"的非空约束;不允许没有默认值
即使在空表上,我们是否必须在非空后指定默认值?
SYSTEM.ADMIN(ADMIN)=> alter table test add column dob varchar(20) NOT NULL DEFAULT '0';
ALTER TABLE
这是预期的行为吗?
答案 0 :(得分:4)
您可以从头创建表而不指定默认值。
create table test ( name varchar(20)
, age int
,dob varchar(20) NOT NULL );
但是,在添加列时,postgresql(netezza)中需要指定一个默认值来填充将出现的任何空值。这是预料之中的。删除默认值的顺序如下:
create table test ( name varchar(20), age int);
ALTER TABLE test add column dob varchar(20) NOT NULL default 'a';
ALTER TABLE test ALTER COLUMN dob DROP DEFAULT;
How can I add a column to a Postgresql database that doesn't allow nulls?
答案 1 :(得分:1)
此行为是预期的。在更改表时,Netezza使用版本化表方法。如果向表中添加列,则实际上会有两个不同的表版本,它们作为单个表呈现给用户。
在GROOM VERSIONS将版本再次折叠到单个基础表中之前,不会修改原始表版本(没有新的NOT NULL DEFAULT列的版本)。这里的优点是更改很快,因为它不需要扫描/更新现有行。相反,它知道为原始基础表版本中不存在的列提供DEFAULT值。
当更改表以添加具有NOT NULL属性的列时,系统需要 DEFAULT规范,以便它知道如何表示添加的列。无论表是否实际包含任何行,都需要这样做。
TESTDB.ADMIN(ADMIN)=> CREATE TABLE TEST ( NAME VARCHAR(20), AGE INT);
CREATE TABLE
TESTDB.ADMIN(ADMIN)=> insert into test values ('mine',5);
INSERT 0 1
TESTDB.ADMIN(ADMIN)=> ALTER TABLE TEST ADD COLUMN DOB VARCHAR(20) NOT NULL DEFAULT '0';
ALTER TABLE
TESTDB.ADMIN(ADMIN)=> insert into test values ('yours',50);
INSERT 0 1
TESTDB.ADMIN(ADMIN)=> select* from test;
NAME | AGE | DOB
-------+-----+-----
yours | 50 | 0
mine | 5 | 0
(2 rows)
好消息是,您可以更改新添加的列以删除该默认值。
TESTDB.ADMIN(ADMIN)=> ALTER TABLE TEST ALTER COLUMN DOB DROP DEFAULT;
ALTER TABLE
TESTDB.ADMIN(ADMIN)=> \d test
Table "TEST"
Attribute | Type | Modifier | Default Value
-----------+-----------------------+----------+---------------
NAME | CHARACTER VARYING(20) | |
AGE | INTEGER | |
DOB | CHARACTER VARYING(20) | NOT NULL |
Distributed on random: (round-robin)
Versions: 2
TESTDB.ADMIN(ADMIN)=> select * from test;
NAME | AGE | DOB
-------+-----+-----
yours | 50 | 0
mine | 5 | 0
(2 rows)
作为分离注释,尽可能及时地修饰任何版本化的表非常重要,这样可以防止由于版本化表的性质而导致性能降低。
TESTDB.ADMIN(ADMIN)=> GROOM TABLE TEST VERSIONS;
NOTICE: Groom will not purge records deleted by transactions that started after 2015-07-27 01:32:16.
NOTICE: If this process is interrupted please either repeat GROOM VERSIONS or issue 'GENERATE STATISTICS ON "TEST"'
NOTICE: Groom processed 1 pages; purged 0 records; scan size unchanged; table size unchanged.
GROOM VERSIONS
TESTDB.ADMIN(ADMIN)=> \d test
Table "TEST"
Attribute | Type | Modifier | Default Value
-----------+-----------------------+----------+---------------
NAME | CHARACTER VARYING(20) | |
AGE | INTEGER | |
DOB | CHARACTER VARYING(20) | NOT NULL |
Distributed on random: (round-robin)
此时,该表不再是版本化表,NOT NULL列的所有值都完全具体化。