5
系统列
每一个表都拥有一些由系统隐式定义的
系统列
。因此,这些列的名字不能像用户定义的列一样使用(注意这种限制与名称是否为关键词没有关系,即便用引号限定一个名称也无法绕过这种限制)。事实上用户不需要关心这些列,只需要知道它们存在即可。
tableoid
包含这一行的表的
OID
。该列是特别为从继承层次(见
继承
)中选择的查询而准备,因为如果
没有它将很难知道一行来自于哪个表。
tableoid
可以与
sys_class
的
oid
列进行连接来获得表
的名称。
xmin
插入该行版本的事务身份(事务
ID
)。一个行版本是一个行的一个特别版本,对一个逻辑行的每一次
更新都将创建一个新的行版本。
cmin
插入事务中的命令标识符(从
0
开始)。
xmax
删除事务的身份(事务
ID
),对于未删除的行版本为
0
。对于一个可见的行版本,该列值也可能为非
零。这通常表示删除事务还没有提交,或者一个删除尝试被回滚。
cmax
删除事务中的命令标识符,或者为
0
。
ctid
行版本在其表中的物理位置。注意尽管
ctid
可以被用来非常快速地定位行版本,但是一个行的
ctid
会在被更新或者被
VACUUM FULL
移动时改变。因此,
ctid
不能作为一个长期行标识符。
rowid
行版本在其表中的物理位置。注意尽管
rowid
可以被用来非常快速地定位行版本,但是一个行的
rowid
会在被更新或者被
VACUUM FULL
移动时改变。因此,
rowid
不能作为一个长期行标识符。
请注意:
KingbaseES ROWID
伪列的返回值与
ORACLE ROWID
的返回值不一致。是
KingbaseES
行版
本的物理位置信息。
1
,支持在投影列中,使用
ROWID
伪列关键字,查询数据的当前最新行版本信息(即物理位置信息)。
2
,支持在过滤条件(
WHERE
)中使用
ROWID OP CONST
(历史行版本)或者
CONST OP ROWID
的
形式,用于条件过滤查询当前行最新的行版本信息。可以与其它过滤条件组成使用。
OP
只支持关系运
算符,即
>,<,>=,<=,<>
等。
3
,支持在
ORDER BY
和
GROUP BY
中使用
ROWID
。
4
,可以在存储过程中,使用
1
,
2
,
3
或者是
1
,
2
,
3
的组合形式。
5
,不支持
ROWID
与其它(
2
中
OP
)以外的运算符进行运算。
6
,
ROWID
不支持索引
,
不能在
ROWID
系统列上创建索引。
事务标识符也是
32
位量。在一个历时长久的数据库中事务
ID
同样会绕回。但如果采取适当的维护过程,这
不会是一个致命的问题,详见
KingbaseES
数据库维护指南。但是,长期(超过
10
亿个事务)依赖事务
ID
的
唯一性是不明智的。
命令标识符也是
32
位量。这对一个事务中包含的
SQL
命令设置了一个硬极限:
2
32
(
40
亿)。在实践中,该
限制并不是问题—注意该限制只是针对
SQL
命令的数目而不是被处理的行数。同样,只有真正修改了数据
库内容的命令才会消耗一个命令标识符。
6
修改表
当我们已经创建了一个表并意识到犯了一个错误或者应用需求发生改变时,我们可以移除表并重新创建它。
但如果表中已经被填充数据或者被其他数据库对象引用(例如有一个外键约束),这种做法就显得很不方便。
因此,
KingbaseES
提供了一族命令来对已有的表进行修改。注意这和修改表中所包含的数据是不同的,这里
要做的是对表的定义或者说结构进行修改。
利用这些命令,我们可以:
•
增加列
•
移除列
•
增加约束
•
移除约束
•
修改默认值
•
修改列数据类型
•
重命名列
•
重命名表
6.1
增加列
要增加一个列,可以使用这样的命令:
ALTER TABLE products ADD COLUMN description text;
新列将被默认值所填充(如果没有指定
DEFAULT
子句,则会填充空值)。
Tip:
在
KingbaseES V8R6
,添加具有常量默认值的列不再意味着在执行
ALTER TABLE
语句时需要更新表
的每一行。相反,默认值将在下一次访问该行时返回,并在重写表时应用,这使得
ALTER TABLE
非常快,
即使在大型表上也是如此。
但是,如果默认值是
volatile (e.g.
clock_timestamp()
)
,每一行都需要在执行
ALTER TABLE
时计算出
的值来更新。以避免潜在的冗长的更新操作
,
特别是如果你打算填列主要是默认的值
,
它可能是更可取的添加
没有默认的列
,
使用
UPDATE
插入正确的值
,
然后添加任何所需的默认如下所述。
也可以同时为列定义约束,语法:
ALTER TABLE products ADD COLUMN description text CHECK (description
<>
''
);
事实上
CREATE TABLE
中关于一列的描述都可以应用在这里。记住不管怎样,默认值必须满足给定的约
束,否则
ADD
将会失败。也可以先将新列正确地填充好,然后再增加约束(见后文)。
6.2
移除列
为了移除一个列,使用如下的命令:
ALTER TABLE products DROP COLUMN description;
列中的数据将会消失。涉及到该列的表约束也会被移除。然而,如果该列被另一个表的外键所引用,
KingbaseES
不会安静地移除该约束。我们可以通过增加
CASCADE
来授权移除任何依赖于被删除列的所有东西:
ALTER TABLE products DROP COLUMN description CASCADE;
6.3
增加约束
为了增加一个约束,可以使用表约束的语法,例如:
ALTER TABLE products ADD CHECK (name
<>
''
);
ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no);
ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES product_groups;
要增加一个不能写成表约束的非空约束,可使用语法:
ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;
该约束会立即被检查,所以表中的数据必须在约束被增加之前就已经符合约束。
6.4
移除约束
为了移除一个约束首先需要知道它的名称。如果在创建时已经给它指定了名称,那么事情就变得很容易。否
则约束的名称是由系统生成的,我们必须先找出这个名称。
ksql
的命令
\d
表名将会对此有所帮助,其他接
口也会提供方法来查看表的细节。因此命令是:
ALTER TABLE products DROP CONSTRAINT some_name;
(如果处理的是自动生成的约束名称,如
$2
,别忘了用双引号使它变成一个合法的标识符。)
和移除一个列相似,如果需要移除一个被某些别的东西依赖的约束,也需要加上
CASCADE
。一个例子是一
个外键约束依赖于被引用列上的一个唯一或者主键约束。
这对除了非空约束之外的所有约束类型都一样有效。为了移除一个非空约束可以用:
ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
(回忆一下,非空约束是没有名称的,所以不能用第一种方式。)
6.5
更改列的默认值
要为一个列设置一个新默认值,使用命令:
ALTER TABLE products ALTER COLUMN price SET DEFAULT
7.77
;
注意这不会影响任何表中已经存在的行,它只是为未来的
INSERT
命令改变了默认值。
要移除任何默认值,使用:
ALTER TABLE products ALTER COLUMN price DROP DEFAULT;
这等同于将默认值设置为空值。相应的,试图删除一个未被定义的默认值并不会引发错误,因为默认值已经
被隐式地设置为空值。
6.6
修改列的数据类型
为了将一个列转换为一种不同的数据类型,使用如下命令:
ALTER TABLE products ALTER COLUMN price TYPE numeric(
10
,
2
);
只有当列中的每一个项都能通过一个隐式造型转换为新的类型时该操作才能成功。如果需要一种更复杂的转
换,应该加上一个
USING
子句来指定应该如何把旧值转换为新值。
KingbaseES
将尝试把列的默认值转换为新类型,其他涉及到该列的任何约束也是一样。但是这些转换可能失
败或者产生奇特的结果。因此最好在修改类型之前先删除该列上所有的约束,然后在修改完类型后重新加上
相应修改过的约束。
6.7
重命名列
要重命名一个列:
ALTER TABLE products RENAME COLUMN product_no TO product_number;
6.8
重命名表
要重命名一个表:
ALTER TABLE products RENAME TO items;