管理分区表和分区索引

在大型的企业应用或企业级的数据库应用中,要处理的数据量通常达到 TB 级,对于这样的大型表执行全表扫描或者 DML 操作时,效率是非常低的。

为了提高数据库在大数据量读写操作和查询时的效率,达梦数据库提供了对表和索引进行分区的技术,把表和索引等数据库对象中的数据分割成小的单位,分别存放在一个个单独的段中,用户对表的访问转化为对较小段的访问,以改善大型应用系统的性能。

DM 提供了水平分区方式。水平分区包括范围、哈希和列表三种方式,企业可以使用合适的分区方法,如日期(范围)、区域(列表),对大量数据进行分区。由于 DM 划分的分区是相互独立且可以存储于不同的存储介质上的,完全可满足企业高可用性、均衡 IO、降低维护成本、提高查询性能的要求。

15.1 分区的概念

分区是指将表、索引等数据库对象划分为较小的可管理片段的技术,每一个片段称为分区子表或分区索引。一个表被分区后,对表的查询操作可以局限于某个分区进行,而不是整个表,这样可以大大提高查询速度。

DM 支持对大表进行水平分区。例如,通讯公司将用户通话记录保存在一张表中,一年这个表产生 40GB 的数据。假设要对用户的通话信息按照季度进行统计,那么这样的统计需要在全表范围内进行。如果对表按季度进行水平分区,那么每个分区的大小平均为 10GB 左右,这样在进行统计时,只需在 10GB 的范围内进行即可。

DM 采用子表方式创建分区表,分区表作为分区主表,而每一个分区以一个子表实体存在,即每一个分区都是一个完整的表,一般命名为主表名_分区名。对于水平分区,子表跟主表具有相同的逻辑结构,即分区子表与分区主表有相同的列定义和约束定义。在 DM 分区表中,主表本身不存储数据,所有数据只存储在子表中,从而实现不同分区的完全独立性。水平分区子表删除后,会将子表上的数据一起删除。

由于每一个分区都以一个子表作为实体,那么不同分区可以存储于相同表空间,也可以位于不同的表空间中。将这些分区放在不同的表空间中具有以下的好处:

  1. 减少所有数据都损坏的可能性,一个表空间损坏不影响其他表空间,提高可用性;
  2. 恢复时间大大减少;
  3. 可以将同一个表中的数据分布在不同的磁盘上,从而均衡磁盘上的 I/O 操作;
  4. 提高了表的可管理性、可利用性和访问效率。

分区操作对现存的应用和运行在分区表上的标准 DML 语句来说是透明的。但是,可以通过在 DML 中使用分区子表名字来对应用进行编程,使其充分利用分区的优点。

15.2 分区的方法

达梦数据库 DM 支持对表进行水平分区。对于水平分区,提供以下分区方式:

  1. 范围(range)水平分区:对表中的某些列上值的范围进行分区,根据某个值的范围,决定将该数据存储在哪个分区上;
  2. 哈希(hash)水平分区:通过指定分区编号来均匀分布数据的一种分区类型,通过在 I/O 设备上进行散列分区,使得这些分区大小基本一致;
  3. 列表(list)水平分区:通过指定表中的某个列的离散值集,来确定应当存储在一起的数据。例如,可以对表上的 status 列的值在('A','H','O')放在一个分区,值在('B','I','P')放在另一个分区,以此类推;
  4. 多级分区表:按上述三种分区方法进行任意组合,将表进行多次分区,称为多级分区表。

15.3 创建水平分区表

在创建表的语法中,使用 partition 子句指定分区方式和分区列,以及分区的名字等信息,即可创建分区表。而分区子表可以指定 storage 子句,设置子表的存储属性,如所属表空间等;如果不指定,则继承分区主表的存储特性及表的其他属性。同时,支持多级分区表。

水平分区表的 ROWID 与其主表属性一致:LIST 表的水平分区表的 ROWID 是物理的;普通表的水平分区表的 ROWID 是逻辑的,且每个子表的 ROWID 都是从 1 开始增长,但是最终返回前,ROWID 的高字节会补充上子表序号。

15.3.1 创建范围分区表

范围分区是按照某个列或几个列的值的范围来创建分区,当用户向表中写入数据时,数据库服务器将按照这些列上的值进行判断,将数据写入相应的分区中。

在创建范围分区时,首先要指定分区列,即按照哪些列进行分区,然后为每个分区指定数据范围。范围分区支持 MAXVALUE 范围值的使用,MAXVALUE 相当于一个比任何值都大的值。范围分区非常适用于数据按时间范围组织的表,不同的时间段的数据属于不同的分区。

例如,以下语句创建一个范围分区表 callinfo,用来记录用户的 2010 年的电话通讯信息,包括主叫号码、被叫号码、通话时间和时长,并且根据季度进行分区。

    CREATE  TABLE  callinfo( 
    caller 	CHAR(15), 
    callee 	CHAR(15),
    time		DATETIME,
    duration	INT
    )
    PARTITION BY RANGE(time)(
    PARTITION p1 VALUES LESS THAN ('2010-04-01'),
    PARTITION p2 VALUES LESS THAN ('2010-07-01'),
    PARTITION p3 VALUES LESS THAN ('2010-10-01'),
    PARTITION p4 VALUES EQU OR LESS THAN ('2010-12-31')  //'2010-12-31'也可替换为MAXVALUE
    );

值得注意的是,MAXVALUE 之间无法比较大小。如下所示:

    create table callinfo (
    caller 	CHAR(15), 
    callee 	CHAR(15),
    time		DATETIME,
    duration	INT
    ) 
    partition by range(caller, callee)
            (
            partition p1 values less than ('a', 'b'),
            partition p2 values less than (maxvalue, 'd'),
            partition p3 values less than (maxvalue,maxvalue)
                );     //报“范围分区值非递增”错误,建分区表失败

在创建分区表时,首先通过“PARTITION BY RANGE”子句指定分区的类型为范围分区,然后在这个子句之后指定一个或多个列作为分区列,如 callinfo 的 time 字段。

表中的每个分区都可以通过“PARTITION”子句指定一个名称。并且每一个分区都有一个范围,通过“VALUES LESS THAN”子句可以指定上界,而它的下界是前一个分区的上界。如分区 p2 的 time 字段取值范围是['2010-04-01','2010-07-01')。如果通过“VALUES EQU OR LESS THAN”指定上界,即该分区包含上界值,如分区 p4 的 time 字段取值范围是['2010-10-01','2010-12-31']。另外,可以对每一个分区指定 storage 子句,不同分区可存储在不同表空间中。

如果分区表包含多个分区列,采用多列比较方式定位匹配分区。首先,比较第一个分区列值,如果第一列值在范围之内,就以第一列为依据进行分区;如果第一列值处于边界值,那么需要比较第二列的值,根据第二列为依据进行分区;如果第二列的值也处于边界值,需要继续比较后续分区列值,以此类推,直到确定目标分区为止。匹配过程参看表 15.1。

表15.1 多分区列匹配
插入记录 分区范围值
(10, 10, 10) (20, 20, 20) (30, 30, 30)
(5, 100, 200) 满足
(10, 10, 11) 满足
(31, 1, 1) 不满足 不满足 不满足

当在分区表中执行 DML 操作时,实际上是在各个分区子表上透明地修改数据。当执行 SELECT 命令时,可以指定查询某个分区上的数据。

例 以下语句查询 callinfo 表中分区 p1 的数据

  SELECT * FROM callinfo PARTITION (p1);

15.3.2 创建 LIST 分区表

范围分区是按照某个列上的数据范围进行分区的,如果某个列上的数据无法通过划分范围的方法进行分区,并且该列上的数据是相对固定的一些值,可以考虑使用 LIST 分区。一般来说,对于数字型或者日期型的数据,适合采用范围分区的方法;而对于字符型数据,取值比较固定的,则适合于采用 LIST 分区的方法。

例 创建一个产品销售记录表 sales,记录产品的销量情况。由于产品只在几个固定的城市销售,所以可以按照销售城市对该表进行分区。

    CREATE  TABLE  sales( 
    sales_id	INT,
    saleman	CHAR(20),
    saledate	DATETIME,
    city		CHAR(10)
    )
    PARTITION BY LIST(city)(
    PARTITION p1 VALUES ('北京', '天津'),
    PARTITION p2 VALUES ('上海', '南京', '杭州'),
    PARTITION p3 VALUES ('武汉', '长沙'),
    PARTITION p4 VALUES ('广州', '深圳')
    );

在创建 LIST 分区时,通过“PARTITION BY LIST”子句指定对表进行 LIST 分区,然后在每个分区中分区列的取值通过 VALUES 子句指定。当用户向表插入数据时,只要分区列的数据与 VALUES 子句指定的数据之一相等,该行数据便会写入相应的分区子表中。

注意的是,LIST 分区的分区键必须唯一。

15.3.3 创建哈希分区表

在很多情况下,用户无法预测某个列上的数据变化范围,因而无法实现创建固定数量的范围分区或 LIST 分区。

在这种情况下,DM 哈希分区提供了一种在指定数量的分区中均等地划分数据的方法,基于分区键的散列值将行映射到分区中。当用户向表中写入数据时,数据库服务器将根据一个哈希函数对数据进行计算,把数据均匀地分布在各个分区中。在哈希分区中,用户无法预测数据将被写入哪个分区中。

现在重新考虑产品销售表的例子。如果销售城市不是相对固定的,而是遍布全国各地,这时很难对表进行 LIST 分区。如果为该表进行哈希分区,可以很好地解决这个问题。

    CREATE  TABLE  sales01( 
    sales_id	INT,
    saleman	CHAR(20),
    saledate	DATETIME,
    city		CHAR(10)
    )
    PARTITION BY HASH(city)(
    PARTITION p1,
    PARTITION p2,
    PARTITION p3,
    PARTITION p4
    );

如果不需指定分区表名,可以通过指定哈希分区个数来建立哈希分区表。

    CREATE  TABLE  sales02( 
    sales_id	INT,
    saleman	CHAR(20),
    saledate	DATETIME,
    city		CHAR(10)
    )
    PARTITION BY HASH(city) 
    PARTITIONS 4 STORE IN (ts1, ts2, ts3, ts4);

PARTITIONS 后的数字表示哈希分区的分区数,STORE IN 子句中指定了哈希分区依次使用的表空间。使用这种方式建立的哈希分区表分区名是匿名的,DM 统一使用 DMHASHPART+ 分区号(从 0 开始)作为分区名。例如,需要查询 sales 第一个分区的数据,可执行以下语句:

  SELECT * FROM sales02 PARTITION (dmhashpart0);

15.3.4 创建多级分区表

在很多情况下,经过一次分区并不能精确地对数据进分类,这时需要多级分区表。

例 创建一个产品销售记录表 sales,记录产品的销量情况。由于产品需要按地点和销售时间进行统计,则可以对该表进行 LIST-RANGE 分区。

    DROP TABLE SALES;
    CREATE  TABLE  SALES( 
    SALES_ID	 INT,
    SALEMAN	CHAR(20),
    SALEDATE	DATETIME,
    CITY		  CHAR(10)
    )
    PARTITION BY LIST(CITY)
     SUBPARTITION BY RANGE(SALEDATE) SUBPARTITION TEMPLATE(
        SUBPARTITION P11 VALUES LESS THAN ('2012-04-01'),
        SUBPARTITION P12 VALUES LESS THAN ('2012-07-01'),
        SUBPARTITION P13 VALUES LESS THAN ('2012-10-01'),
        SUBPARTITION P14 VALUES EQU OR LESS THAN (MAXVALUE))
    (
        PARTITION P1 VALUES ('北京', '天津')
        (
          SUBPARTITION P11_1 VALUES LESS THAN ('2012-10-01'),
          SUBPARTITION P11_2 VALUES EQU OR LESS THAN (MAXVALUE)
        ),
        PARTITION P2 VALUES ('上海', '南京', '杭州'),
        PARTITION P3 VALUES (DEFAULT)
    );

在创建多级分区表时,指定了子分区模板,同时子分区 P1 自定义了子分区描述 P11_1 和 P11_2。P1 有两个子分区 P11_1 和 P11_2。而子分区 P2 和 P3 有四个子分区 P11、P12、P13 和 P14。

DM 支持最多八层多级分区。

下面给出一个三级分区的例子,更多级别的分区表的建表语句语法类推。

    CREATE TABLE STUDENT(NAME VARCHAR(20), AGE INT, SEX VARCHAR(10) CHECK (SEX IN ('MALE','FEMALE')), GRADE INT CHECK (GRADE IN (7,8,9)))
    PARTITION BY LIST(GRADE)
      SUBPARTITION BY LIST(SEX) SUBPARTITION TEMPLATE
      (
         SUBPARTITION Q1 VALUES('MALE'),
         SUBPARTITION Q2 VALUES('FEMALE')
      ),
      SUBPARTITION BY RANGE(AGE) SUBPARTITION TEMPLATE
      (
         SUBPARTITION R1 VALUES LESS THAN (12),
         SUBPARTITION R2 VALUES LESS THAN (15),
         SUBPARTITION R3 VALUES LESS THAN (MAXVALUE)
       )
    (
      PARTITION P1 VALUES (7),
      PARTITION P2 VALUES (8),
      PARTITION P3 VALUES (9)
    );

15.4 在水平分区表建立索引

DM 支持在水平分区表上建立普通索引、唯一索引、聚集索引、函数索引、位图索引和空间索引。

此外,只支持在水平分区表上创建局部聚集索引、不支持全局聚集索引、不支持局部唯一函数索引。HUGE 水平分区表不支持全局索引。

在水平分区表上创建索引的方式分为两种:隐式和显式。下面分别进行介绍:

隐式地创建索引

创建水平分区表时,若使用了 PRIMARY KEY 或 UNIQUE 关键字,无需用户显式指定,系统会隐式创建全局索引或局部索引。

创建水平分区表时,若表的 PRIMARY KEY 或 UNIQUE 列未包含所有分区列,系统会自动创建全局索引,否则自动创建局部索引。创建全局索引时,在水平分区表的主表创建全局索引,每个分区子表的数据都被索引在同一个 B 树中,并在每个子表创建全局本地索引,与主表共用一个 B 树。

例 1 下面的语句在创建水平分区表 test 时会自动创建一个全局索引

CREATE TABLE test(c1 INT, c2 INT PRIMARY KEY) PARTITION BY HASH(c1) PARTITIONS 2;

例 2 下面的语句在创建水平分区表 test2 时会自动创建一个局部索引(PRIMARY KEY 对应) 和一个全局索引(UNIQUE 对应)。

CREATE TABLE test2(c1 INT, c2 INT primary key,c3 int unique) PARTITION BY HASH(c2) PARTITIONS 2;

显式地创建索引

当使用创建索引语句在水平分区表上创建索引时,若指定 GLOBAL 关键字,创建全局索引,否则创建为局部索引。

例 通过 CREATE INDEX 语句显式地创建全局和局部索引

//首先,创建表t1
create table t1(c1 int, c2 int, c3 int)  partition by range(c1)
(
	partition p1 values less than(100),
	partition p2 values less than(200),
	PARTITION p3 VALUES EQU OR LESS THAN (MAXVALUE)
);
//其次,指定GLOBAL创建全局索引idx1
create index idx1 on t1(c2) GLOBAL;
//再次,缺省GLOBAL创建局部索引idx2
create index idx2 on t1(c3);

在水平分区表上创建全局唯一索引时,对索引键是否全部包含分区键没有使用限制,若要创建局部唯一索引,则要求索引键必须包含所有的分区键。这是因为对于局部索引,每一个分区子表都会建立一个索引分区,负责索引分区子表的数据。由于每个索引分区只负责索引本分区上的数据,其他分区上的数据无法维护,只有当分区键都包含在索引键中时,才能对分区主表保证索引键唯一。

例 在 t1 表上的 c1 列上建立局部唯一索引,必须包含全部的分区键 C1

CREATE UNIQUE INDEX ind_c1 ON t1(c1);

CREATE UNIQUE INDEX ind_c13 ON t1(c1,c3);

15.5 维护水平分区表

创建水平分区表后,DM 提供了对分区表的修改,功能包括:

  1. 增加分区:建立水平分区表后,可根据实际需要新增一个分区;
  2. 删除分区:建立水平分区表后,可根据实际需要删除一个分区;
  3. 合并分区:将相邻的两个范围分区合并为一个分区。合并分区通过指定两个分区名进行,将相邻的两个分区的数据进行合并,构建新的大分区。只能在范围和 LIST 分区上进行合并分区;
  4. 拆分分区:将某一个范围分区拆分为相邻的两个分区。拆分分区时指定的常量表达式值必须是原范围分区的有效范围值。只能在范围分区和 LIST 上进行拆分分区;
  5. 交换分区:将分区数据跟普通表数据进行交换,交换的两张表需要具有相同的结构。仅范围分区和 LIST 分区支持交换分区。不支持含有加密列的分区表交换分区。

在 DM 中,由于局部索引反映基础表的结构,因此当对表的分区和子分区进行修改操作时,会自动地对局部索引进行相应的修改。

15.5.1 增加分区

DM 支持用 ALTER TABLE ADD PARTITION 语句将新分区增加到最后一个现存分区的后面。

例 范围分区表 callinfo 现需要记录用户的 2011 年的第一季度的通讯信息,那么,需要为 2011 年第一季度增加一个分区,并将其存储在表空间 ts5 中

  ALTER TABLE callinfo
  ADD PARTITION p5 VALUES LESS THAN ('2011-4-1') STORAGE (ON ts5);

对于范围分区,增加分区必须在最后一个分区范围值的后面添加,要想在表的开始范围或中间增加分区,应使用 SPLIT PARTITION 语句。

对于 LIST 分区,增加分区包含的离散值不能已存在于某个分区中。

例 为 LIST 分区表 sales 添加一个分区管理拉萨和呼和浩特的销售情况

  ALTER TABLE sales
  ADD PARTITION p5 VALUES ('拉萨', '呼和浩特') STORAGE (ON ts5);

只能对范围分区和 LIST 分区增加分区,不能对哈希分区增加分区。并且增加分区不会影响分区索引,因为分区索引只是局部索引,新增分区仅是新增分区子表,并更新分区主表的分区信息,其他分区并不发生改变。

15.5.2 删除分区

DM 支持用 ALTER TABLE DROP PARTITION 语句将分区删除。

例 范围分区表 callinfo 现需要删除记录用户的 2011 年的第一季度的通讯信息,那么,只需删除 callinfo 的分区 p1 即可。

  ALTER TABLE callinfo DROP PARTITION p1;

只能对范围分区和 LIST 分区进行删除分区,哈希分区不支持删除分区。跟增加分区一样,删除分区不会影响分区索引,因为分区索引只是局部索引,删除分区仅是删除分区子表,并更新分区主表的分区信息,其他分区并不发生改变。

15.5.3 交换分区

DM 支持用 ALTER TABLE EXCHANGE PARTITION 语句将分区数据跟普通表数据进行交换,交换的两张表需要具有相同的结构。仅范围分区和 LIST 分区支持交换分区。进行交换的两张表,如果包含加密列,对应的加密列要求加密信息完全一致。

假设上文提到的 callinfo 表是用于维护最近 12 个月的用户通话信息,超过 12 个月的订单需要迁移到该季度的通话信息历史表中,并且每一个季度都有一个相应的历史表。如果没有使用水平分区,需要较多的删除和插入操作,并产生大量的 redo 和 undo 日志。

如果使用分区表,如上文提到的 callinfo,只需使用交换分区即可完成以上功能。

例如,2011 年第二季度已到了,需删除 2010 年第二季度的通话记录,因此,可通过以下脚本来实现:

CREATE  TABLE  callinfo_2011Q2( 
caller 	CHAR(15), 
callee 	CHAR(15),
time		DATETIME,
duration	INT
);
//交换分区
ALTER TABLE callinfo EXCHANGE PARTITION p2 WITH TABLE callinfo_2011Q2;
//删除原分区
ALTER TABLE callinfo DROP PARTITION p2;
//新增分区,记录2011年第二季度通话记录
ALTER TABLE callinfo
ADD PARTITION p6 VALUES LESS THAN ('2011-7-1') STORAGE (ON ts2);

--交换分区

  ALTER TABLE callinfo EXCHANGE PARTITION p2 WITH TABLE callinfo_2011Q2;

--删除原分区

  ALTER TABLE callinfo DROP PARTITION p2;

--新增分区,记录 2011 年第二季度通话记录

  ALTER TABLE callinfo
  ADD PARTITION p6 VALUES LESS THAN ('2011-7-1') STORAGE (ON ts2);

通过交换分区实现分区 p2 和新建表 callinfo_2011Q2 的数据交换,表 callinfo_2011Q2 将得到 2010 年第二季度的通话记录,而分区 p2 数据将被清空。交换分区采用数据字典信息交换的技术,几乎不涉及 IO 操作,因此效率非常高。

15.5.4 合并分区

要想将两个范围分区的内容融合到一个分区,就要使用 ALTER TABLE MERGE PARTITION 语句。如果分区的数据很少,或相对其他分区某些分区的数据量较少,导致 I/O 不均衡,就可以考虑使用合并分区。

例 可将 callinfo 的 2010 第 3 季度和第 4 季度合并成一个分区

  ALTER TABLE callinfo MERGE PARTITIONS p3, p4 into partition p3_4;

仅范围分区表和 LIST 分区表支持合并分区。其中,合并的 RANGE 分区必须是范围相邻的两分区。

多级分区表进行 MERGE 合并的注意事项:

  1. 仅支持一级子表类型为 RANGE、LIST;
  2. 合并多级分区表中的一级子表时,该一级子表下的二级及以上层次子表按照级别分别判断:在创建分区表时当前层次是否指定了模板,若指定了模板,则按照模板创建当前层次子表;若未指定模板,则由系统自动合并为一个子表,子表名称为系统内部设置。RANGE 类型范围值为 MAXVALUE;LIST 类型范围值为 DEFAULT;
  3. 不允许自定义二级及以上层次子表;
  4. 不允许直接合并二级及以上层次子表。

合并分区会导致数据的重组和分区索引的重建,因此,合并分区可能会比较耗时,所需时间取决于分区数据量的大小。

15.5.5 拆分分区

ALTER TABLE 语句的 SPLIT PARTITION 子句被用于将一分区中的内容重新划分成两个新的分区。当一个分区变得太大以至于要用很长时间才能完成备份、恢复或维护操作时,就应考虑做分割分区的工作,还可以用 SPLIT PARTITION 子句来重新划分 I/O 负载。

例 将合并后的 p3_4 拆分为原两分区 p3 和 p4,分别记录 2010 年第三和第四季度的通话记录

  ALTER TABLE callinfo SPLIT PARTITION p3_4 AT ('2010-9-30') INTO (PARTITION p3, PARTITION p4);

仅范围分区表和 LIST 分区表支持拆分分区。拆分分区另一个重要用途是作为新增分区的补充。通过拆分分区,可以对范围分区表的开始或中间范围添加分区。

多级分区表进行拆分 SPLIT 注意事项:

  1. 仅支持一级子表类型为 RANGE、LIST;
  2. 支持 SPLIT 为 2 个或多个子表;
  3. 不允许自定义二级及以上层次子表;
  4. SPLIT 产生的新分区二级及以上层次子表结构与被分隔子表保持一致,名称由系统内部定义。

拆分分区会导致数据的重组和分区索引的重建,因此,拆分分区可能会比较耗时,所需时间取决于分区数据量的大小。

15.6 水平分区表的限制

DM 水平分区表有如下限制条件:

  1. 分区列类型必须是数值型、字符型或日期型,不支持 BLOB、CLOB、IMAGE、TEXT、LONGVARCHAR、BIT、BINARY、VARBINARY、LONGVARBINARY、时间间隔类型和用户自定义类型为分区列;

  2. 范围分区和哈希分区的分区键可以多个,每一层最多不超过 16 列;LIST 分区的分区键必须唯一;

  3. 只有当分区键都包含在索引键中时,才能创建非全局唯一索引;

  4. 水平分区表不支持临时表;

  5. 不能在水平分区表上建立自引用约束;

  6. 普通环境中,水平分区表的各级分区数的总和上限是 65535;MPP 环境下,水平分区表的各级分区总数上限取决于 INI 参数 MAX_EP_SITES,上限为 2^( 16 - log2MAX_EP_SITES)。比如:当 MAX_EP_SITES 为默认值 64 时,分区总数上限为 1024;

  7. 不允许对分区子表执行任何 DDL 操作;

  8. 哈希分区支持重命名、增加/删除约束、设置触发器是否启用的修改操作;

  9. 范围分区支持分区合并、拆分、增加、删除、交换、重命名、增加/删除约束、设置触发器是否生效操作;

  10. LIST 分区支持分区合并、拆分、增加、删除、交换、重命名、增加/删除约束、设置触发器是否生效操作;

  11. LIST 分区范围值不能为 NULL;

  12. LIST 分区子表范围值个数与数据页大小和相关系统表列长度相关,存在以下限制:

    1. 4K 页,单个子表最多支持 120 个范围值;
    2. 8K 页,单个子表最多支持 254 个范围值;
    3. 16K\32K 页,单个子表最多支持 270 个范围值;
  13. 对范围分区增加分区值必须是递增的,即只能在最后一个分区后添加分区。LIST 分区增加分区值不能存在于其他已存在分区;

  14. 当分区数仅剩一个时,不允许删除分区;

  15. 仅能对相邻的范围分区进行合并,合并后的分区名可为高分区名或新分区名;

  16. 拆分分区的分区值必须在原分区范围中,并且分区名不能跟已有分区名相同;

  17. 与分区进行分区交换的普通表,必须与分区表拥有相同的列及索引,但交换分区并不会对数据进行校验,即交换后的数据并不能保证数据完整性,如 CHECK 约束;分区表与普通表创建的索引顺序要求一致;

  18. 不能对水平分区表建立全局聚集索引或局部唯一函数索引;

  19. 不能对分区子表单独建立索引;

  20. 在未指定 ENABLE ROW MOVEMENT 的分区表上执行更新分区键,不允许更新后数据发生跨分区的移动,即不能有行迁移;

  21. 不能在分区语句的 STORAGE 子句中指定 BRANCH 选项;

  22. 不允许引用水平分区子表作为外键约束;

  23. 多级分区表最多支持八层;

  24. 多级分区表支持下列修改表操作:新增分区、新增列、删除列、删除表级约束、修改表名、设置与删除列的默认值、设置列 NULL 属性、设置列可见性、设置行迁移属性、启用超长记录、with delta、新增子分区、删除子分区、修改二级分区模板信息;

  25. 水平分区表支持的列修改操作除了多级分区表支持的操作外,还支持:设置触发器生效/失效、修改列名、修改列属性、增加表级主键约束、删除分区、SPLIT/MERGE 分区和交换分区;

  26. 在分布式集群中,包含大字段列或自定义字段列的水平分区表不支持 ENABLE ROW MOVEMENT 参数(可以指定,但是无效),即不允许更新后数据发生跨分区的移动;

  27. 间隔分区表的限制说明:

    1. 仅支持一级范围分区创建间隔分区;
    2. 只能有一个分区列,且分区列类型为日期或数值;
    3. 对间隔分区进行 SPLIT,只能在间隔范围内进行操作;
    4. 被 SPLIT/MERGE 的分区,其左侧分区不再进行自动创建;
    5. 不相邻的间隔的分区,不能 MERGE;
    6. 表定义不能包含 MAXVALUE 分区;
    7. 不允许新增分区;
    8. 不能删除起始间隔分区;
    9. 间隔分区表定义语句显示到起始间隔分区为止;
    10. 自动生成的间隔分区,均不包含边界值;
    11. 间隔表达式只能为常量或日期间隔函数。日期间隔函数为:NUMTOYMINTERVAL、NUMTODSINTERVAL;数值常量可以为整型、DEC 类型;
    12. MPP 下不支持间隔分区表。
微信扫码
分享文档
扫一扫
联系客服