改变和删除数据库和表

  通过本文的学习,您将能够

  • 删除一个数据库
  • 改变或删除一个表
  • 了解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;

%`DVC$0CR7X)Y(LF~Y(HY

  执行以上命令创建聚集索引时,每个数据页都会被重新排序并进行重写,并且能够收回未使用的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 一个删除的数据库或删除表语句。如果想恢复已删除的表或数据库,必须从备份中恢复。