在大型的企业应用或企业级的数据库应用中,要处理的数据量通常达到 TB 级,对于这样的大型表执行全表扫描或者 DML 操作时,效率是非常低的。
为了提高数据库在大数据量读写操作和查询时的效率,达梦数据库提供了对表和索引进行分区的技术,把表和索引等数据库对象中的数据分割成小的单位,分别存放在一个个单独的段中,用户对表的访问转化为对较小段的访问,以改善大型应用系统的性能。
DM 提供了水平分区方式。水平分区包括范围、哈希和列表三种方式,企业可以使用合适的分区方法,如日期(范围)、区域(列表),对大量数据进行分区。由于 DM 划分的分区是相互独立且可以存储于不同的存储介质上的,完全可满足企业高可用性、均衡 IO、降低维护成本、提高查询性能的要求。
15.1 分区的概念
分区是指将表、索引等数据库对象划分为较小的可管理片段的技术,每一个片段称为分区子表或分区索引。一个表被分区后,对表的查询操作可以局限于某个分区进行,而不是整个表,这样可以大大提高查询速度。
DM 支持对大表进行水平分区。例如,通讯公司将用户通话记录保存在一张表中,一年这个表产生 40GB 的数据。假设要对用户的通话信息按照季度进行统计,那么这样的统计需要在全表范围内进行。如果对表按季度进行水平分区,那么每个分区的大小平均为 10GB 左右,这样在进行统计时,只需在 10GB 的范围内进行即可。
DM 采用子表方式创建分区表,分区表作为分区主表,而每一个分区以一个子表实体存在,即每一个分区都是一个完整的表,一般命名为主表名_分区名。对于水平分区,子表跟主表具有相同的逻辑结构,即分区子表与分区主表有相同的列定义和约束定义。在 DM 分区表中,主表本身不存储数据,所有数据只存储在子表中,从而实现不同分区的完全独立性。水平分区子表删除后,会将子表上的数据一起删除。
由于每一个分区都以一个子表作为实体,那么不同分区可以存储于相同表空间,也可以位于不同的表空间中。将这些分区放在不同的表空间中具有以下的好处:
- 减少所有数据都损坏的可能性,一个表空间损坏不影响其他表空间,提高可用性;
- 恢复时间大大减少;
- 可以将同一个表中的数据分布在不同的磁盘上,从而均衡磁盘上的 I/O 操作;
- 提高了表的可管理性、可利用性和访问效率。
分区操作对现存的应用和运行在分区表上的标准 DML 语句来说是透明的。但是,可以通过在 DML 中使用分区子表名字来对应用进行编程,使其充分利用分区的优点。
15.2 分区的方法
达梦数据库 DM 支持对表进行水平分区。对于水平分区,提供以下分区方式:
- 范围(range)水平分区:对表中的某些列上值的范围进行分区,根据某个值的范围,决定将该数据存储在哪个分区上;
- 哈希(hash)水平分区:通过指定分区编号来均匀分布数据的一种分区类型,通过在 I/O 设备上进行散列分区,使得这些分区大小基本一致;
- 列表(list)水平分区:通过指定表中的某个列的离散值集,来确定应当存储在一起的数据。例如,可以对表上的 status 列的值在('A','H','O')放在一个分区,值在('B','I','P')放在另一个分区,以此类推;
- 多级分区表:按上述三种分区方法进行任意组合,将表进行多次分区,称为多级分区表。
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。
插入记录 | 分区范围值 | ||
(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 提供了对分区表的修改,功能包括:
- 增加分区:建立水平分区表后,可根据实际需要新增一个分区;
- 删除分区:建立水平分区表后,可根据实际需要删除一个分区;
- 合并分区:将相邻的两个范围分区合并为一个分区。合并分区通过指定两个分区名进行,将相邻的两个分区的数据进行合并,构建新的大分区。只能在范围和 LIST 分区上进行合并分区;
- 拆分分区:将某一个范围分区拆分为相邻的两个分区。拆分分区时指定的常量表达式值必须是原范围分区的有效范围值。只能在范围分区和 LIST 上进行拆分分区;
- 交换分区:将分区数据跟普通表数据进行交换,交换的两张表需要具有相同的结构。仅范围分区和 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 合并的注意事项:
- 仅支持一级子表类型为 RANGE、LIST;
- 合并多级分区表中的一级子表时,该一级子表下的二级及以上层次子表按照级别分别判断:在创建分区表时当前层次是否指定了模板,若指定了模板,则按照模板创建当前层次子表;若未指定模板,则由系统自动合并为一个子表,子表名称为系统内部设置。RANGE 类型范围值为 MAXVALUE;LIST 类型范围值为 DEFAULT;
- 不允许自定义二级及以上层次子表;
- 不允许直接合并二级及以上层次子表。
合并分区会导致数据的重组和分区索引的重建,因此,合并分区可能会比较耗时,所需时间取决于分区数据量的大小。
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 注意事项:
- 仅支持一级子表类型为 RANGE、LIST;
- 支持 SPLIT 为 2 个或多个子表;
- 不允许自定义二级及以上层次子表;
- SPLIT 产生的新分区二级及以上层次子表结构与被分隔子表保持一致,名称由系统内部定义。
拆分分区会导致数据的重组和分区索引的重建,因此,拆分分区可能会比较耗时,所需时间取决于分区数据量的大小。
15.6 水平分区表的限制
DM 水平分区表有如下限制条件:
-
分区列类型必须是数值型、字符型或日期型,不支持 BLOB、CLOB、IMAGE、TEXT、LONGVARCHAR、BIT、BINARY、VARBINARY、LONGVARBINARY、时间间隔类型和用户自定义类型为分区列;
-
范围分区和哈希分区的分区键可以多个,每一层最多不超过 16 列;LIST 分区的分区键必须唯一;
-
只有当分区键都包含在索引键中时,才能创建非全局唯一索引;
-
水平分区表不支持临时表;
-
不能在水平分区表上建立自引用约束;
-
普通环境中,水平分区表的各级分区数的总和上限是 65535;MPP 环境下,水平分区表的各级分区总数上限取决于 INI 参数 MAX_EP_SITES,上限为 2^( 16 - log2MAX_EP_SITES)。比如:当 MAX_EP_SITES 为默认值 64 时,分区总数上限为 1024;
-
不允许对分区子表执行任何 DDL 操作;
-
哈希分区支持重命名、增加/删除约束、设置触发器是否启用的修改操作;
-
范围分区支持分区合并、拆分、增加、删除、交换、重命名、增加/删除约束、设置触发器是否生效操作;
-
LIST 分区支持分区合并、拆分、增加、删除、交换、重命名、增加/删除约束、设置触发器是否生效操作;
-
LIST 分区范围值不能为 NULL;
-
LIST 分区子表范围值个数与数据页大小和相关系统表列长度相关,存在以下限制:
- 4K 页,单个子表最多支持 120 个范围值;
- 8K 页,单个子表最多支持 254 个范围值;
- 16K\32K 页,单个子表最多支持 270 个范围值;
-
对范围分区增加分区值必须是递增的,即只能在最后一个分区后添加分区。LIST 分区增加分区值不能存在于其他已存在分区;
-
当分区数仅剩一个时,不允许删除分区;
-
仅能对相邻的范围分区进行合并,合并后的分区名可为高分区名或新分区名;
-
拆分分区的分区值必须在原分区范围中,并且分区名不能跟已有分区名相同;
-
与分区进行分区交换的普通表,必须与分区表拥有相同的列及索引,但交换分区并不会对数据进行校验,即交换后的数据并不能保证数据完整性,如 CHECK 约束;分区表与普通表创建的索引顺序要求一致;
-
不能对水平分区表建立全局聚集索引或局部唯一函数索引;
-
不能对分区子表单独建立索引;
-
在未指定 ENABLE ROW MOVEMENT 的分区表上执行更新分区键,不允许更新后数据发生跨分区的移动,即不能有行迁移;
-
不能在分区语句的 STORAGE 子句中指定 BRANCH 选项;
-
不允许引用水平分区子表作为外键约束;
-
多级分区表最多支持八层;
-
多级分区表支持下列修改表操作:新增分区、新增列、删除列、删除表级约束、修改表名、设置与删除列的默认值、设置列 NULL 属性、设置列可见性、设置行迁移属性、启用超长记录、with delta、新增子分区、删除子分区、修改二级分区模板信息;
-
水平分区表支持的列修改操作除了多级分区表支持的操作外,还支持:设置触发器生效/失效、修改列名、修改列属性、增加表级主键约束、删除分区、SPLIT/MERGE 分区和交换分区;
-
在分布式集群中,包含大字段列或自定义字段列的水平分区表不支持 ENABLE ROW MOVEMENT 参数(可以指定,但是无效),即不允许更新后数据发生跨分区的移动;
-
间隔分区表的限制说明:
- 仅支持一级范围分区创建间隔分区;
- 只能有一个分区列,且分区列类型为日期或数值;
- 对间隔分区进行 SPLIT,只能在间隔范围内进行操作;
- 被 SPLIT/MERGE 的分区,其左侧分区不再进行自动创建;
- 不相邻的间隔的分区,不能 MERGE;
- 表定义不能包含 MAXVALUE 分区;
- 不允许新增分区;
- 不能删除起始间隔分区;
- 间隔分区表定义语句显示到起始间隔分区为止;
- 自动生成的间隔分区,均不包含边界值;
- 间隔表达式只能为常量或日期间隔函数。日期间隔函数为:NUMTOYMINTERVAL、NUMTODSINTERVAL;数值常量可以为整型、DEC 类型;
- MPP 下不支持间隔分区表。