带有区间分片的 MODIFY 子句的示例

本节阐述了对使用范围和区间分片作为其分布策略的表使用 ALTER FRAGMENT 语句的 MODIFY 子句的语法的功能和 MODIFY 子句可更改内容的限制。

有关按列表分片的表使用 MODIFY 子句的类似的示例,请参阅列表分片的 MODIFY 子句的示例

启用或禁用范围区间分片

此语句禁用范围区间分片的创建:

ALTER FRAGMENT ON TABLE tab MODIFY INTERVAL DISABLED;

以下语句恢复范围区间分片的创建,撤销了前一个例子的作用:

ALTER FRAGMENT ON TABLE tab MODIFY INTERVAL ENABLED;

以下语句禁用范围区间分片创建,并修改了 dbspace 列表(在 STORE IN 语句中表明了存储新分片的 dbspace )。如果随后的 ALTER FRAGMENT MODIFY 语句启用了 tab 表的范围区间分片创建功能。

ALTER FRAGMENT ON TABLE tab MODIFY INTERVAL DISABLED 
        STORE IN (dbs4, dbs5);

在范围区间分片中重命名分片

此语句重命名两个范围区间分片。没有指定新存储位置的 IN 子句,因此两个分片新的名称替代了现有的名称:

ALTER FRAGMENT ON TABLE tab MODIFY 
        PARTITION p1 TO PARTITION newp1, 
        PARTITION sys_p6 TO PARTITION newsys_p6;

范围区间分片需要 PARTITION 关键字。如果您使用 MODIFY 子句重命名现有的分片,那么在 MODIFY 子句中声明的新的名称不能以字符串 sys 开头(该字符串用于系统定义的分片), 以上示例成功地重命名了系统定义的分片 sys_p6

重新定位范围或区间分片

假设下表有范围区间分片并接收了来自插入操作的两行:
CREATE TABLE tab2 (i INT, c CHAR(2))
          FRAGMENT BY RANGE (i) 
          INTERVAL (100) STORE IN (dbs1, dbs2, dbs3)
          PARTITION p0 VALUES < 100 IN dbs0,
          PARTITION p1 VALUES < 200 IN dbs1;
          
          INSERT INTO tab2 VALUES (201, "AA");  
          -- creates a system-generated interval fragment sys_p2 
          -- with fragment expression >= 200 AND < 300 
          -- assume that this fragment is created in dbs1
          
          INSERT INTO tab2 VALUES (601, "BB");  
          -- creates a system-generated interval fragment sys_p6 
          -- with fragment expression >= 600 AND < 700 
          ---assume that this fragment is created in dbs2
        
以下语句标示了数据库服务器将范围分片 p1dbs1 移动到 dbs2
ALTER FRAGMENT ON TABLE tab2 MODIFY 
          PARTITION p1 TO PARTITION p1 IN dbs2;
下一示例将范围分片 p1dbs1 移动到 dbs2 并将区间分片 sys_p6dbs2 移动到 dbs3
ALTER FRAGMENT ON TABLE tab2 MODIFY 
        PARTITION p1 TO PARTITION p1 IN dbs2, 
        PARTITION sys_p6 TO PARTITION sys_p6 IN dbs3;

替换存储新区间分片的 dbspace 列表

以下 CREATE TABLE 语句定义了一个范围区间分片策略,其中:
  • i 是分片键,
  • 100 是范围区间的大小,
  • 新分片将存储在 dbspace dbs1dbs2dbs3
  • 初始分片 p0(在 dbspace dbs0 中),p1 (在 dbspace dbs1 中)的过渡值分别为 100200
CREATE TABLE tab (i INT, c CHAR(2))
              FRAGMENT BY RANGE (i) 
              INTERVAL (100) STORE IN (dbs1, dbs2, dbs3)
              PARTITION p0 VALUES < 100 IN dbs0,
              PARTITION p1 VALUES < 200 IN dbs1;
下列 ALTER FRAGMENT 语句在 STORE IN 中用新的列表 (dbs4dbs5)替换了列表(dbs1dbs2dbs3)。
ALTER FRAGMENT ON TABLE tab 
        MODIFY INTERVAL STORE IN (dbs4, dbs5);

上个示例中,MODIFY 子句指定了新的分片将会轮流创建于 dbs4dbs5 中。任何创建在最初 STORE IN 列的 dbspace (dbs1dbs2dbs3) 中的系统定义的分片(和分片 p1) 仍保留在这些 dbspace 中。现有的和随插入行之后的分片键在这些分片范围区间内的分片仍将继续存储在这些分片中,但是将会创建新的区间分片,轮流地存储于 dbs4dbs5 dbspace 中。

考虑以下分片表:
CREATE TABLE mytab (col1 int)
          FRAGMENT BY RANGE (c1) INTERVAL (100) 
          STORE IN (dbs1, dbs2, dbs3, dbs4, dbs5)
          PARTITION p1 VALUES < 300 in dbs0;
此 ALTER FRAGMENT 语句替换了存储新区间分片的 dbspace 列表:
ALTER FRAGMENT ON TABLE mytab MODIFY 
          STORE IN (dbs1, dbs6, dbs3, dbs4, dbs8);
新的列表用 dbs6 代替了 dbs2dbs8 替换了 dbs5。如果您希望来自当前 STORE IN 列表的任何 dbspace 可用于新的分片,那么 MODIFY 子句必须在新的列表(在已修改的分片存储方案中替换了旧的列表)中包含它们。在上述示例中,新区间分片将在 STORE IN 关键字之后列出的五个 dbspace 中创建 ,但是任何创建于 dbs2dbs5 中的现有的分片将继续存储数据值符合分片键值范围的分片的行。

您可以在 STORE IN 子句中修改 dbspace 的列表。旧的列表会被您指定的新的列表所替换。不会移动旧的 dbspace 中的分片。考虑下表:

您可以通过更改该分片的 IN dbspace 规范而将现有分片移动到另一个 dbspace :

CREATE TABLE tab (i INT, c CHAR(2))     
        FRAGMENT BY RANGE (i)      
        INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) 
        PARTITION p0 VALUES < 100 IN dbs0,      
        PARTITION p1 VALUES < 200 IN dbs1;   
        
        INSERT INTO tab VALUES (201, "AA");  
        -- creates interval fragment sys_p2 
        -- with fragment expression >= 200 AND < 300 
        -- (assume that this fragment is created in dbs1)
        INSERT INTO tab VALUES (601, "BB");  
        -- creates interval fragment sys_p6 
        -- with fragment expression >= 600 AND < 700 
        -- (assume that this fragment is created in dbs2)
下一个语句指示数据库服务器将分片 p1dbs1 移动到 dbs2
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p1 TO PARTITION p1 IN dbs2; 
以下示例将范围分片 p1dbs1 移动到 dbs2 ,并将区间分片 sys_p6dbs2 移动到 dbs3
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p1 TO PARTITION p1 IN dbs2, 
          PARTITION sys_p6 TO PARTITION sys_p6 IN dbs3;
然而,当系统生成分片后,您不能修改该区间分片的表达式。考虑此表:
CREATE TABLE tab (i INT, c CHAR(2)) 
          FRAGMENT BY RANGE (i)      
          INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) 
          PARTITION p0 VALUES < 100 IN dbs0,
          PARTITION p1 VALUES < 200 IN dbs1;   
          
          INSERT INTO tab VALUES (201, "AA");  
          -- creates interval fragment sys_p2 
          -- with fragment expression >= 200 AND < 300 
          INSERT INTO tab VALUES (601, "BB");  
          -- creates interval fragment sys_p6 
          -- with fragment expression >= 600 AND < 700
现在您不能修改 sys_p2sys_p6 的分片表达式。如果您尝试修改,则会返回错误。
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION sys_p6 TO PARTITION sys_p6 
          VALUES < 900 IN dbs2;  
上述语句失败并发生了错误。

修改定义范围分片的表达式

在某些情况下,您可以使用 MODIFY 子句更改定义范围分片的表达式。以下示例说明了您可以对该表达式做出更改的种种的限制。然而,在系统生成此区间分片后,您就不能修改此范围分片的表达式。考虑下表:
CREATE TABLE tab (i INT, c CHAR(2))     
          FRAGMENT BY RANGE (i)      
          INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) 
          PARTITION p0 VALUES < 100 IN dbs0,     
          PARTITION p1 VALUES < 200 IN dbs1;  
          
          INSERT INTO tab VALUES (201, "AA");  
          -- creates interval fragment sys_p2 
          -- with fragment expression >= 200 AND < 300  
          INSERT INTO tab VALUES (601, "BB");  
          -- creates interval fragment sys_p6 
          -- with fragment expression >= 600 AND < 700
现在您不能修改区间分片 sys_p2sys_p6 的表达式。如果您尝试修改,则会返回错误。
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION sys_p6 TO PARTITION sys_p6 
          VALUES < 900 IN dbs2;  
以上语句因产生错误而失败。
您可以修改第一个中间范围分片,但是替换的表达式不能跨越相邻分片的边界。此操作会导致数据移动。示例如下:
CREATE TABLE tab (i INT, c CHAR(2))
          FRAGMENT BY RANGE (i) 
          INTERVAL (100) STORE IN (dbs1, dbs2, dbs3)
          PARTITION p0 VALUES < 100 IN dbs0,
          PARTITION p1 VALUES < 200 IN dbs1,
          PARTITION p2 VALUES < 300 IN dbs0; 
          
          INSERT INTO tab VALUES (301, "AA");  
          -- creates interval fragment sys_p3 
          -- with fragment expression >= 300 AND < 400 
          INSERT INTO tab VALUES (601, "BB");  
          -- creates interval fragment sys_p6 
          -- with fragment expression >= 600 AND < 700
以下所有的 ALTER 示例都基于上述 CREATE 语句中定义的表的分片。下列 ALTER FRAGMENT 语句修改了范围分片 p0 的表达式:
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p0 TO PARTITION p0 
          VALUES < -50 IN dbs0; 
以下语句修改了分片 p0 的表达式并将此分片从 dbs0 移动到 dbs5
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p0 TO PARTITION p0 
          VALUES < -50 IN dbs5;
下列语句成功地完成了对分片 p0 的三次更改:
  • 修改了 p0 的分片表达式,
  • 修改了newp0 的分片名称,
  • 并将已命名的分片从 dbs0 移动到 dbs5
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p0 TO PARTITION newp0 
          VALUES < -50 IN dbs5;  
然而,下一示例因产生错误而失败,因为分片 p0 的新表达式超越了下一个相邻分片 p1 的范围的边界:
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p0 TO PARTITION p0 
          VALUES < 250 IN dbs0; 
以下 ALTER FRAGMENT 示例成功地修改了范围分片 p1 的表达式:
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p1 TO PARTITION p1 
          VALUES < 150 IN dbs1;
以下修改因产生错误而失败,因为分片 p1 的新表达式超越了前一个相邻分片 p0 的范围的边界:
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p0 TO PARTITION p0 
          VALUES < 50 IN dbs0;
出于某种原因,ALTER FRAGMENT MODIFY 操作失败,行无法移动到新的分片中,并返回了错误。 示例如下:
CREATE TABLE tab (i INT, c CHAR(2)) 
          FRAGMENT BY RANGE (i)      
          INTERVAL (100) STORE IN (dbs1, dbs2, dbs3)  
          PARTITION p0 VALUES IS NULL IN dbs0,    
          PARTITION p1 VALUES < 200 IN dbs1,     
          PARTITION p2 VALUES < 300 IN dbs0;    
          
          ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p0 TO PARTITION p0 
          VALUES < 100 IN dbs0;     
由于进行了修改,生成的表具有以下分片:
PARTITION p0 VALUES < 100 IN dbs0,  
          PARTITION p1 VALUES < 200 IN dbs1,
          PARTITION p2 VALUES < 300 IN dbs0  
如果之前的 NULL 分片存储了行(意味着表中的列 i 的有 NULL值行),那么这些行不适合此新分片结构中的任何分片。当移动行时,上述的 ALTER FRAGMENT 操作将因此失败。
注意该 NULL 分片也是表中的第一个分片。即使在 CREATE TABLE 或 ALTER TABLE 操作中用户指定此 NULL 分片作为最后一个分片,它会重新分配为该表中的首个分片,并有分片列表中的最小的 evalpos 值。当修改第一个和中间范围分片时,数据库服务器会施加新表达式不能超过相邻分片边界的限制。因此当修改 NULL 分片时,您指定的任何表达式都不能超过下一个范围或区间分片的边界。示例如下:
CREATE TABLE tab (i INT, c CHAR(2))     
          FRAGMENT BY RANGE (i)      
          INTERVAL (100) STORE IN (dbs1, dbs2, dbs3)
          PARTITION p0 VALUES IS NULL IN dbs0,  
          PARTITION p1 VALUES < 200 IN dbs1,  
          PARTITION p2 VALUES < 300 IN dbs0;
假设该表在分片 p0 中没有行。在这种情况下,p0 能被更改为非 NULL 分片。
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p0 TO PARTITION p0 
          VALUES < 250 IN dbs0; 
然而,因为 p0VALUES < 250)的新的表达式超越了 p1VALUES < 200)的临界,以上示例返回了错误。
以下 ALTER FRAGMENT 语句可能是:
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p0 TO PARTITION p0 VALUES < 150 IN dbs0;
您可以修改最后一个范围分片的表达式(过渡分片)但是只能增加过渡值。在此操作中没有数据移动。
CREATE TABLE tab (i INT, c CHAR(2))   
          FRAGMENT BY RANGE (i)    
          INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) 
          PARTITION p0 VALUES < 100 IN dbs0,    
          PARTITION p1 VALUES < 200 IN dbs1,  
          PARTITION p2 VALUES < 300 IN dbs0;  
          -- last range fragment or transition fragment
以下修改返回错误。因为它尝试减少过渡值(从 300 变更为 250):
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p2 TO PARTITION p2 
          VALUES < 250 IN dbs0; 
以下语句修改了 p2(过渡分片)的分片表达式。因为还没有系统生成的区间分片,新的过渡值不需要与区间分片标记对齐。
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p2 TO PARTITION p2 
          VALUES < 350 IN dbs0; 
如果在新的和旧的过渡值之间没有区间分片,您可以将最后一个范围分片的表达式修改为 VALUES < new transition value。示例如下:
CREATE TABLE tab (i INT, c CHAR(2))
            FRAGMENT BY RANGE (i)       
            INTERVAL (100) STORE IN (dbs1, dbs2, dbs3) 
            PARTITION p0 VALUES < 100 IN dbs0,    
            PARTITION p1 VALUES < 200 IN dbs1,   
            PARTITION p2 VALUES < 300 IN dbs0;  
            -- last range fragment is the "transition fragment"
            
            INSERT INTO tab VALUES (601, "BB");  
            -- creates interval fragment sys_p6 
            -- with fragment expression >= 600 AND < 700 
            -- (assume that this fragment is created in dbs3)  
已修改的表现在具有这些分片:
分片
表达式和分片类型
p0
VALUES < 100   – range fragment
p1
VALUES < 200   – range fragment
p2
VALUES < 300   - last range fragment (or transition fragment)
sys_p6
VALUES >= 600 AND VALUES < 700 - interval fragment

在更改过渡值的过程中,分片以不会产生数据移动的方式修改。

下列语句修改了 p2 (过渡分片或最后一个范围分片)的分片表达式。
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p2 TO PARTITION p2 VALUES < 500 IN dbs0;
旧的过渡值是 300 ,新的过渡值是 500 。在这些范围分片中没有系统生成的区间分片,第一个区间分片的起始值为 600 。这也意味着在 300 和 500 之间没有数据行,因此此过渡分片(最后一个范围分片)的表达式可以修改为 VALUES < 500 而不用数据移动。因为在新的过渡值后没有区间分片,所以新过渡值必须与区间分片边界对齐。在这种情况下,新的过渡值 500 与区间分片的边界对齐(此区间分片不须存在)。

此修改的结果是,随后的区间分片的 evalpos 值改变,区间分片重命名为符合系统生成的分片的名称的格式。此 ALTER TABLE MODIFY 操作后,产生的表具有这些分片:

分片
表达式和分片类型
p0
VALUES < 100   – range fragment
p1
VALUES < 200   – range fragment
p2
VALUES < 500   – modified expression for transition fragment
sys_p4
VALUES >= 600 AND VALUES <700  – interval fragment

这是分片 p2 (最后一个范围分片)已修改的表达式。(也就是 transition fragment ,因为任何存储了大于分片键范围的值的分片将会是系统生成的区间分片。)系统生成的区间分片重命名为 sys_p4 ,因为过渡分片的表达式更改后,evalpos 值从 6 变为 4 。

以下修改由于产生错误而失败,因为有超过新过渡值的区间分片存在,并且新过渡值未与区间分片边界对齐:
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p2 TO PARTITION p2 VALUES YY 550 IN dbs0;
区间分片的范围可以是 300 到 400 、400 到 500 、500 到 600 、600 到 700 等等,但是新的过渡值 550 不在区间分片的边界,因此数据库服务器会声明错误。

如果在新的和旧的过渡值之间有区间分片,那么新过渡值必须与区间分片的边界对齐(该区间分片不须存在),除非新过渡值超过了最后一个区间分片。所有在新的和旧的过渡值之间的分片会被转换为范围分片,它们的表达式会被修改以符合范围分片表达式。最后一个区间分片的表达式转换为范围分片,更改为 VALUES < new transition value

下例示例可证明此行为:
CREATE TABLE tab (i INT, c CHAR(2))
          FRAGMENT BY RANGE (i) 
          INTERVAL (100) STORE IN (dbs1, dbs2, dbs3)
          PARTITION p0 VALUES < 100 IN dbs0,
          PARTITION p1 VALUES < 200 IN dbs1,
          PARTITION p2 VALUES < 300 IN dbs0;  
          -- last range fragment or transition fragment
          
          INSERT INTO tab VALUES (301, "AA");  
          -- creates interval fragment sys_p3 
          -- with fragment expression >= 300 AND < 400 
          -- (assume this fragment is created in dbs1)
          INSERT INTO tab VALUES (601, "BB");  
          -- creates interval fragment sys_p6 
          -- with fragment expression >= 600 AND < 700 
          -- (assume this fragment is created in dbs3)
在两个 INSERT 操作之后,该表将具有这些范围和区间分片:
分片
表达式和分片类型
p0
VALUES < 100   – range fragment
p1
VALUES < 200   – range fragment
p2
VALUES < 300   – range fragment
sys_p3
VALUES >= 300 AND VALUES <400  – interval fragment
sys_p4
VALUES >= 600 AND VALUES <700  – interval fragment

以下的 ALTER FRAGMENT 示例基于此表。

以下示例修改了分片 p2(过渡分片)的表达式:
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p2 TO PARTITION p2 VALUES < 500 IN dbs0;

因为在旧过渡值和新过渡值之间有一个区间分片(sys_p3),所以此分片转换为范围分片(其表达式变为 VALUES < 400)。

而且由于有超过新过渡值的区间分片(例如:分片 sys_p6),新过渡值必须与区间分片边界对齐,可能的区间分片必须是范围区间大小的整数倍(包括 400 到 500 、500 到 600 、700 到 800 等待)。新过渡值是 500 ,是一个区间分片的临界。它也可以在更改过渡分片期间有效避免移动数据和避免创建分片。这可能通过以下操作实现,将分片 sys_p3 转换为新的过渡分片,将它的表达式变更为 < 500 ,并重命名旧过渡分片的名称。

生成的表具有以下分片:

分片
表达式和分片类型
p0
VALUES < 100    – range fragment
p1
VALUES < 200   – range fragment
sys_p2rg
VALUES < 300   – range fragment (这是旧的过渡分片,现在重命名为 sys_p2rg 。系统生成的格式 sys_pevalposrg.)
p2
VALUES <500  - range fragment (这是之前的区间分片 sys_p3 。它的表达式被修改为范围表达式。现在定义了新过渡分片)
sys_p5
VALUES >= 600 AND VALUES <700 – interval fragment( 重命名为 sys_5 ,它的 evalpos 值在过渡分片该表后从 6 改为 5 )

以下对过渡分片 p2 的修改返回了错误:

ALTER FRAGMENT ON TABLE tab MODIFY 
        PARTITION p2 TO PARTITION p2 VALUES < 550 IN dbs0;

出现此错误的原因是有一个超过过渡值的区间分片 sys_p6,并且新过渡值不与区间分片边界对齐。

下一示例修改了分片 p2 (过渡分片)的表达式:
ALTER FRAGMENT ON TABLE tab MODIFY 
          PARTITION p2 TO PARTITION p2 VALUES < 750 IN dbs0;

因为没有区间分片超过新过渡值,它不须与区间分片边界对齐。

产生的表具有以下分片:

分片
表达式和分片类型
p0
VALUES < 100   – range fragment
p1
VALUES < 200   – range fragment
sys_p2rg
VALUES < 300   – range fragment (这是旧的过渡分片,现在按照系统生成的格式 sys_pevalposrg 重命名为 sys_p2rg。)
sys_p3rg
< 400    – range fragment (这是之前的区间分片 sys_p3 ,在它的表达式修改为一个范围表达式之前。)
p2
VALUES <750  - range fragment (之前的分片 sys_p6,在它的表达式修改为一个范围表达式之前。成了新的过渡分片。)