通过本文的学习,您将能够
- 删除一个数据库
- 改变或删除一个表
- 了解alter table时表的三种改变方式
- 将简单大对象转换至智能大对象
1. 改变一个表
SinoDB的ALTER TABLE 语句允许:
- 在表末尾增加新字段
- 在表内的一个字段前增加新列字段
- 为列添加 NOT NULL 约束或缺省值
- 删除字段
- 增加和删除整数约束
- 修改已有字段的定义
- 改变后续分配的extent大小值
- 改变表的锁定模式
在执行ALTER TABLE 命令时,SinoDB数据库会使用会使用以下三个算法之一进行处理,包括:
- Fast Alter
- In-Place Alter
- Slow Alter
2. Fast Alter 快速改变
当ALTER TABLE 语句执行不会影响表数据改变的操作时,SinoDB服务器执行Fast Alter 。这时候只需要更新系统目录表,而无需修改任何数据页。该表只在对系统目录表上执行更新操作的短暂时间内对用户不可用。当进行以下 ALTER TABLE 操作时执行的是Fast Alter:
- 修改锁定模式
alter table orders lock mode (row);
- 改变下一个extent大小
alter table customer next size 20;
- 增加或删除约束
alter table orders add constraint primary key (order_num);
3. In-place改变
对于实际修改了数据行并且影响数据页的大多数 ALTER TABLE 语句,执行的是In-place 改变。
一般来说,当 ALTER TABLE 命令执行以下操作时用的是In-place改变:
- 增加一个字段或者几个字段
alter table customer add birthday date;
- 删除字段
alter table customer drop birthday;
- 修改字段的数据类型
alter table customer modify birthday datetime year to minute;
- 修改做为分段表达式一部分的字段
In-place改变通过创建表定义的新版本来完成改变操作。每个数据页与一个版本相联系。在In-place ALTER TABLE 语句之后,新数据和新版本一起被插入页面。更新旧页上的数据行时,如果有足够的空间,数据页上的所有数据行都会被更新至新版本。如果空间不够,就从旧页上删除数据行,并把该数据行和新版本同时插入到新的数据页。
SinoDB数据库服务器允许表定义高达 255 个版本。但是在同一张表上后续的In-place ALTER TABLE 语句都会比前面花费更长时间去执行。所以 建议表上的In-place 改变不要多于 50 至 60 个。如果您想消除表的多个版本,可以强制对所有的数据行进行即时改变。例如,使用将数据字段的值设置给自身的虚拟 UPDATE 语句。 可以使用 oncheck 实用程序得到关于版本的信息:
oncheck -pT database:table
ALTER TABLE 语句跟所有 DDL 语句一样,即使当数据库模式是无日志记录时,也会创建日志条目。使用In-place改变算法,在实际发生更改时(即插入或更新行时),每个数据页都会有日志记录。
In-place改变 不会出现在使用 ROWID 的分段表上。
4. Slow Alter 慢速改变
当动态服务器无法使用快速改变或In-place改变算法时,将执行慢速改变。以下ALTER TABLE操作会执行慢速改变:
-
增加或删除由 ROWIDS 或 CRCOLS 关键词创建的字段时。
-
删除 TEXT 或 BYTE 数据类型的字段。
-
修改字段的数据类型,旧类型的值不能被转换为新的类型。
-
修改的字段包含在 FRAGMENT 子句里,而且值转换可能使得数据行被移到另一个分段。
-
如果超过 LTXHWM 阈值,ALTER TABLE 语句可能会被当作长事务,并且会被中止
慢速改变会生成带有新定义的表的副本,然后将数据行复制到新表上,所以要求表的 dbspace 要有足够空间用于存放数据副本。同时,它也要求有充足的逻辑日志空间去记录所有的改变,如果超过 LTXHWM 阈值,可能会被当作长事务被中止。在操作期间还会以排他模式锁定表,导致其他用户无法访问该表。所以,如果表非常大,则重写每个数据页所需的时间可能过多,从而使用户在较长时间内无法使用该表。
5. 数据空间回收
5.1 数据空间回收:CLUSTER Index
alter index item_idx to cluster;
执行以上命令创建聚集索引时,每个数据页都会被重新排序并进行重写,并且能够收回未使用的extent空间。
一旦extent分配至表,该extent就不会自动释放以被其他表使用。如果extent因为表大量删除数据而变为控,那么extent也会保留为 tblspace(段)的一部分。
SinoDB数据库允许通过强制进行表的物理重写来回收extent空间。其中一种最简单的方式是发出 ALTER INDEX index_name TO CLUSTER 命令完成这操作。
SinoDB数据库服务器进行聚集索引时,相当于是强制以索引键的顺序写入数据行。执行 ALTER INDEX index_name TO CLUSTER 命令时,每个数据页都被重新排序并进行重写(即使数据已经是按照索引顺序),并且数据库服务器能够收回未使用的extent空间。如果数据库是使用unbuffered logging 创建的,所有的事物活动都被写入共享内存里的逻辑日志缓冲区中,并在COMMIT 语句执行时刷新至磁盘。这样可以保证所有已完成的工作被保存至磁盘上,并保证所有已提交的事务都可以成功从系统失败中恢复过来。
减少extent数
ALTER INDEX 创建表的新副本和回收未使用的extent。即使压缩完所有行后,新表可能仍有很多extent。如果需要调整表以便有更少、更大的extent,则通过指定合适的 EXTENT SIZE 和 NEXT SIZE 来重建表。
最大extent数量
一张表允许的extent总数取决于页大小、索引数量、每个索引的字段数量和表内字段的数据类型(例如:VARCHAR TEXT 或 BYTE)。对于页大小为2KB的系统,最大extent数量大概是200。页大小为4KB的系统则可拥有约 450 个extent。
具有大量的extent可能会影响性能,尤其是在选择大量数据行的决策支持 (DSS) 环境中。而且,对于具有索引或 VARCHAR 数据类型的表,当使用的extent数为 60 时就可能出现问题。
具有太多扩展数据块的另一个缺点是可能会达到最大扩展数据块数。如果表意外增长并达到允许的最大扩展数据块数,则必须卸载它,找到足够的连续空间以重建具有较少扩展数据块的表,然后再重新加载数据。
5.2 数据空间回收:Truncate
回收空间的另一种方法是使用 TRUNCATE 语句。此语句将:
-
删除表中的所有行以及表关联的索引
-
保留表和索引结构
-
比delete效率高得多:
– 使用更少的日志空间
–自动更新系统系统目录表与分布信息 -
删除额外的extent:
– 这是默认操作
– 会保留第一个初始extent
TRUNCATE tab1;
TRUNCATE TABLE tab1 DROP STORAGE;
- 若要保留所有现有扩展数据块(例如,在清空表然后重新加载的情况下),请使用 REUSE STORAGE 子句
TRUNCATE TABLE tab1 REUSE STORAGE;
6. 重命名列,表和数据库
字段、表或数据库可以使用 RENAME COLUMN ,RENAME TABLE 或 RENAME DATABASE 命令分别重命名。
- 重命名字段
RENAME COLUMN invoice.paid_date TO date_paid;
- 重命名表
RENAME TABLE stock TO inventory;
- 重命名数据库
RENAME DATABASE stores7 TO stores9;
如果重命名一个在数据库中被视图引用的字段,则sysviews 系统目录表中的值将更新至新名称。如果在检查约束中引用了该字段,则检查约束的值将在 syschecks 系统目录表中更新。
为使用 ALTER TABLE 语句,必须满足以下条件之一:
- 拥有表所在的数据库的 DBA 特权。
- 拥有该表。
- 拥有该表的Alter特权,以及表所在的数据库的Resource特权。
- 若要增加一个引用约束,必须拥有DBA特权或者拥有引用字段或引用表的References特权。
- 若要删除一个约束,则必须拥有 DBA 特权或者成为该约束的所有者。如果您是该约束的所有者但不是该表的所有者,则必须拥有该表的Alter特权。删除约束则无需References特权。
当表重命名后,任何引用该表的视图都会被更改。如果表名字在触发器定义中出现,则名字将被替换。如果表名称在任何触发器的操作中,则不会被替换。RENAME TABLE 命令同样作用在同义词和表上。
存储过程中的字段名和表名称将不会被 RENAME COLUMN 或 RENAME TABLE 更改。如果存储过程引用不存在的列或表,则将返回错误。
7. 转换简单大对象为智能大对象
-
文本简单大对象 (TEXT)可以转为字符智能大对象 (CLOB)
-
字节简单大对象 (BYTE)可以转为字节智能大对象 (BLOB)
-
示例:将TEXT列转换位CLOB列
ALTER TABLE booklist MODIFY content CLOB,
PUT content IN (sbsp1) (log);
8. 删除表和数据库
- 语法:
DROP TABLE tablename;
DROP DATABASE databasename;
- 示例:
DROP TABLE customer;
DROP DATABASE stores_demo;
当执行 DROP TABLE 命令时:
- 系统目录表中所有对该表的引用都将删除。
- 表占用的空间将释放。
当执行 DROP DATABASE 命令时:
- 系统目录表将被删除。
- 所有表占用的空间将释放。
- 数据将无法被访问。
*不可以 ROLLBACK 一个删除的数据库或删除表语句。如果想恢复已删除的表或数据库,必须从备份中恢复。