首页 > 数据库 > 国内数据库 > 南大通用GBase8s SQL常用SQL语句(四)
BEFORE 和 AFTER 选项允许您在现有分片之前或之后放入新的分片。当分布方案为循环或区间间隔时,您不能使用 BEFORE 和 AFTER 选项。
当您连接新的列表或表达式的分片而没有显式地使用 BEFORE 或 AFTER 关键字选项时,数据库服务器会将所添加的分片置于分片存储列表的末尾,除非存在一个余项分片。如果存在一个余项分片,则新分片会刚好置于该余项分片前。您不能在余项分片之后连接一个新分片。
当分布方案是循环或区间间隔时,您无法定义余项分片。
如果您省略了 AS PARTITION 分片 规范,该分片的名称就是存储它的 dbspace 的名称。如果同一表的另一个分片已经具有其 dbspace 的名称,那么数据库服务器会声明异常,并且 ALTER FRAGMENT ATTACH 操作失败。
当您具有相同表结构的表转换为单独一个表中的分片时,您是允许数据库服务器管理分片存储,而不是允许应用程序管理分片存储。分布方案可以是循环的或急于表达式的。
要从两个或两个以上相同结构的未分片表创建单独一个分片表,ATTACH 子句必须包含 连接列表 中的活表。连接列表是 ATTACH 子句中表的列表。
要在新创建的单独一个分片表中包含 rowid ,请首先连接所有表,然后使用 ALTER TABLE 语句添加 rowid 。
要将一个未分片表连接到一个已分片的表,必须已在独立的 dbspace 中创建该未分片表,并且必须具有与该分片表相同的表结构。在以下示例中,循环分布方案将表 cur_acct 分片,而且表 old_acct 是驻留在独立 dbspace 中的未分片表。以下示例说明了如何将 old_acct (作为 consumed table )连接到 cur_acct (作为 surviving table):
ALTER FRAGMENT ON TABLE cur_acct ATTACH old_acct;
当您将一个或多个连接到一个分片表时,consumed_table 必须是未分片的 。
如果没有错误,ONLINE 关键字指示数据库服务器内部提交 ALTER FRAGMENT ATTACH 工作,并在活表上放置意图互斥锁而不是互斥锁。互斥锁只能应用在未分片的死表上。
ONLINE ATTACH 操作的要求
只有通过间隔分片结构分片的 surviving table 才能使用 ALTER FRAGMENT ONLINE ON TABLE 语句 ATTACH 选项。该死表必须是未分片的。
所有在活表上的索引必须具有与表相同的分片结构。(也就是说,任何索引都要连接。)出于这一原因,如果表中有主键约束或其它参考约束,那么,建议您首先为该约束创建连接索引,然后使用 ALTER TABLE 语句添加该约束。(缺省情况下,系统创建的主键约束和其它约束是拆离的。)
对于活表上的每个约束,死表上必须有相同的相符合的索引。死表上匹配的索引在 ATTACH 操作里会作为活表上的再生的索引分片。死表上的其它索引将在 ATTACH 操作中被删除。死表上的每个将会重复利用的索引必须分离于单独的 dbspace 中,并且存储该再生索引的 dbspace 必须是存储该死表的 dbspace 。
如果活表上的索引是唯一的,那么在死表上与其对应的索引也必须唯一。
死表必须具有满足以下条件的检查约束:
l 它必须严格符合要连接的分片的表达式。
l 它只能跨越一个区间。
最后一个要求,死表中的行在活表的区间间隔分片结构中只能跨越单个区间,这对于保护数据移动十分重要。在包含 ONLINE 关键字的 ALTER FRAGMENT ATTACH 操作中不允许数据移动。
ONLINE ATTACH 操作中只能指定一个死表。
所有其它 ATTACH 选项的限制也适用于 ONLINE ATTACH 操作。有关这些限制,请参阅 ATTACH 子句的一般限制 和 ATTACH 子句的其他限制 。
ALTER FRAGMENT ONLINE ATTACH 示例
以下 SQL 语句定义了分片表 employee ,它使用区间间隔存储分布方案,在 emp_id 列上使用唯一索引 employee_id_idx (也是分片密钥)并在 dept_id 列上使用另一个索引 employee_dept_idx 。
CREATE TABLE employee
(emp_id INTEGER, name CHAR(32),
dept_id CHAR(2), mgr_id INTEGER, ssn CHAR(12))
FRAGMENT BY RANGE (emp_id)
INTERVAL (100) STORE IN (dbs1, dbs2, dbs3, dbs4)
PARTITION p0 VALUES < 200 IN dbs1,
PARTITION p1 VALUES < 400 IN dbs2;
CREATE UNIQUE INDEX employee_id_idx ON employee(emp_id);
CREATE INDEX employee_dept_idx ON employee(dept_id);
最后两条语句使用高于该事务分片的上限的分片键值插入行,这导致数据库服务器产生了两个新的区间分片,由此产生的分片列表包含四个分片:
Fragments in surviving table before ALTER FRAGMENT ONLINE:
p0 VALUES < 200 - range fragment
p1 VALUES < 400 - range fragment (transition fragment)
sys_p2 VALUES >= 400 AND VALUES < 500 - interval fragment
sys_p4 VALUES >= 600 AND VALUES < 700 - interval fragment
下一条 SQL 语句定义了未分片表 employee2 ,它与 employee 表具有相同的列结构,并在两个与 employee 表中索引对应的列( emp_id 和 dept_id )上放置单独列索引。该语句在 emp_ssn 列上定义了唯一索引 employee2_ssn_idx 在列 name 上定义了 employee_dept_idx 索引。这四个索引都存储在 dbspace dbs4 中。CREATE TABLE 也语句指定检查约束( (emp_id >=500 AND emp_id <600) ),该约束符合要连接死表的分片表达式并跨越了 employee 表结构区间间隔分片的单个分区。
CREATE TABLE employee2
(emp_id INTEGER, name CHAR(32),
dept_id CHAR(2), mgr_id INTEGER, ssn CHAR(12),
CHECK (emp_id >=500 AND emp_id <600)) in dbs4;
CREATE UNIQUE INDEX employee2_id_idx ON employee2(emp_id) in dbs4;
CREATE INDEX employee2_dept_idx ON employee2(dept_id) in dbs4;
CREATE UNIQUE INDEX employee2_ssn_idx ON employee2(ssn) in dbs4;
CREATE INDEX employee2_name_idx ON employee2(name) in dbs4;
以下语句因为要连接的分片是区间分片(存储了分片键值低于 employee 表的事务值 400 的分片)而返回了错误。只有区间分片才能联机连接。
ALTER FRAGMENT ONLINE ON TABLE employee
ATTACH employee2 AS PARTITION p3 VALUES < 300;
以下语句成功运行并创建了新的间隔分片 p3 :
ALTER FRAGMENT ONLINE ON TABLE employee
ATTACH employee2 AS PARTITION p3 VALUES < 600;
Fragments in surviving table after ALTER FRAGMENT ONLINE:
p0 VALUES < 200 - range fragment
p1 VALUES < 400 - range fragment
sys_p2 VALUES >= 400 AND VALUES < 500 - interval fragment
sys_p3 VALUES >= 500 AND VALUES < 600 - interval fragment
sys_p4 VALUES >= 600 AND VALUES < 700 - interval fragment
注意到成功的 ALTER FRAGMENT ONLINE . . . ATTACH 操作多个必要规范符合 DDL 语句中的规范,它定义了活表和死表,包括列、索引、索引存储位置和活表的分片策略:
l 死表上的检查约束只能跨越单个区间。活表的区间值为 100 ,检查约束为 >= 500 and < 600 。
l 要连接的条件表达式( < 600 )会在内部被转换为符合检查约束的区间分片表达式格式( >= 500 and < 600 )。
l 活表上的索引可以连接(也就是说,它们由具有表相同分片结构分片),因为 CREATE INDEX 语句中没有显示地指定分片策略。
l 死表上的索引会被分离到单独的 dbspace ( dbs4 ),也是存储该死表的 dbspace 。
l 对于活表上的每个索引,死表上都有与其对应的索引。
l 死表上的与 employee 活表不对应的其它索引( employee2_ssn_idx 和 employee2_name_idx )将在 ONLINE ATTACH 操作中删除。
在进行 ATTACH 操作之后,所有死表不再存在。对死表的任何 CHECK 约束或 NOT NULL 约束也不再存在。您必须通过活表引用原来死表中的记录。
活表上的拆离索引保留其同一分片存储策略。即,拆离索引不自动调整以适应活表的新分片存储。关于对于索引有何影响的更多信息,请参阅 GBase 8s 性能指南 中有关更改表分片的讨论。
在一个日志记录数据库中,ATTACH 操作根据活表的新的分片存储策略,扩展了活表中任何连接的索引。死表中的所有行都服从这些自动调整的索引。关于数据库服务器是完全重建活表的索引还是重新使用原来死表上的索引的信息,请参阅 GBase 8s 性能指南 。
在 GBase 8s 的非日志记录数据库中, ATTACH 操作并不会根据活表新的分片存储策略扩展活表的索引。要根据活表的新的分片存储策略扩展所连接的索引的分片存储策略,您必须删除该索引,并在活表上重新创建它。
一些连接分片的 ALTER FRAGMENT ... ATTACH 操作可能导致数据库服务器更新索引的结构。当在这种情况下重建索引时,数据库服务器也将重新计算相关联列的分布方案,并且当其为连接分片的表设置查询计划时这些统计信息可用于查询优化器:
l 对于在 ALTER FRAGMENT ... ATTACH 自动重建 B-tree 索引的索引的列(或列的集合),重新计算的列分布统计信息相当于在 HIGH 模式下 UPDATE STATISTICS 语句创建的分布。
l 如果重建索引不是 B-tree 索引,对应自动重新计算的分布统计信息由 UPDATE STATISTIC 语句在 LOW 模式下创建。
有关在现有表上创建索引或约束时自动产生统计分布的其他信息,请参阅 CREATE INDEX 语句中自动计算分布统计信息一节的描述。
当 ATTACH 发生时,死表的 BYTE 和 TEXT 分片会成为活表的一部分,并继续与 ATTACH 操作之前所关联的相同行和数据分片相关联。
ATTACH 子句中指定的每个表中的每个 BYTE 和 TEXT 列必须具有相同的存储类型: blobspace 或 tblspace 。如果 BYTE 或 TEXT 列存储在 blobspace 中,则所有表中的同一列必须在同一 blobspace 中。如果 BYTE 或 TEXT 列存储在 tblspace 中,则所有的表中的同一列必须存储在一个 tblspace 中。
当您连接表时,活表中的触发器将在 ATTACH 后保留下来,但死表中的触发器会被自动删除。 ATTACH 子句不激活任何触发器,但随后对新行的数据处理操作会激活触发器。
活表中的视图在 ATTACH 操作后保留下来,但死表中的视图会被自动删除。
您可以将未分片表连接到一个具有任何类型的受支持分布方案的表。通常,生成的表具有同 surviving table 先前的分片存储策略相同的分片存储策略。
但是,当您连接两个或两个以上的未分片表时,分布方案可以基于表达式也可以基于循环。
通过在 ATTACH 子句中结合表的分布方案,只能生成以下分布方案:
|
活表先前的分布方案 |
死表先前的分布方案 |
生成的分布方案 |
|
无 |
无 |
循环或表达式 |
|
循环 |
无 |
循环 |
|
表达式 |
无 |
表达式 |
以下示例将未分片表 pen_types 和 pen_makers 合并为单独一个分片表 pen_types 。表 pen_types 驻留在 dbspace dbsp1 中,表 pen_makers 驻留在 dbspace dbsp2 中。每个表中的表结构是相同的。
ALTER FRAGMENT ON TABLE pen_types ATTACH pen_types, pen_makers;
执行 ATTACH 子句之后,数据库服务器使用循环分布方案将表 pen_types 分片为两个 dbspaces :包含 pen_types 的 dbspace 和包含 pen_makers 的 dbspace 。表 pen_makers 已死,并且不再存在;原来在表 pen_makers 中的所有行现在都在表 pen_types 中。
考虑以下将表 cur_acct 和 new_acct 合并以及使用基于表达式的分布方案的示例。表 cur_acct 最初创建为一个分片表,并且在 dbspace dbsp1 和 dbsp2 中有分片。该示例的第一个语句显示表 cur_acct 是以基于表达式的分布方案创建的。该示例的第二个语句在 dbsp3 中创建表 new_acct ,而没有分片存储策略。第三个语句合并了表 cur_acct 和 new_acct 。每个表中的表结构(列)都是相同的。
CREATE TABLE cur_acct (a int) FRAGMENT BY EXPRESSION
a < 5 in dbsp1, a >= 5 and a < 10 in dbsp2;
CREATE TABLE new_acct (a int) IN dbsp3;
ALTER FRAGMENT ON TABLE cur_acct ATTACH new_acct AS a>=10;
当您更改分片后检查 sysfragments 系统目录表时,您可以看到表 cur_acct 按表达式分片为三个 dbspace 。关于 sysfragments 系统目录表的其它信息,请参阅 GBase 8s SQL 参考指南 。
除了简单的范围规则,您也可以使用 ATTACH 子句,通过哈希或仲裁规则按表达式分片。关于您可以在基于表达式的分布方案中用到的所有表达式类型的讨论,请参阅 通过 EXPRESSION 分片 。
警告 : 当您指定一个日期值作为参数的缺省值时,请确保对年份指定 4 位数字,而非 2 位数字。当指定 2 位数字的年份时,环境变量 DBCENTURY 可能不使用希望的缺省值。有关更多信息,请参阅 GBase 8s SQL 参考指南 。
官网:
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70002567/viewspace-2782437/ ,如需转载,请注明出处,否则将追究法律责任。