达梦数据库中分区表的创建与使用

创建和使用分区表

范围分区

以某个范围进行分区,通常采用日期进行范围分区。
有以下几个特性:
1、每个分区都有一个VALUES LESS THEN字句,指定了该分区不包括的上限值。
2、除了第一个分区,其他的每一个分区都有一个下限值,这个值就是此分区的前一个分区的上限值。
3、有一个MAXVALUE分区,来存放于其它分区的值。
示例:
以时间为范围的分区表

范围分区创建表
CREATE TABLE "SYSDBA"."TABLE_DATE_RANGE"
(
"ID" VARCHAR2(10) NOT NULL,
"TRANSACTION_DATE" DATE NOT NULL)
PARTITION BY RANGE("TRANSACTION_DATE")
(
PARTITION  "P2020"  VALUES LESS THAN(DATE'2021-01-01'),
PARTITION  "P2021"  VALUES LESS THAN(DATE'2022-01-01'),
PARTITION  "P2022"  VALUES LESS THAN(DATE'2023-01-01'),
PARTITION  "P2023"  VALUES LESS THAN(DATE'2024-01-01'),
PARTITION  "P2024"  VALUES LESS THAN(DATE'2025-01-01')
);

在每个分区后面可以加STORAGE(ON “表空间名”, CLUSTERBTR)来指定表空间,一般用于分布式系统中。
创建时MAXVALUE分区非必须。

插入一条数据:

insert into TABLE_DATE_RANGE values('01',to_date('20240816','yyyymmdd'));commit;

查询指定分区的值:

select * from TABLE_DATE_RANGE PARTITION(P2024);

可以看到刚刚的数据在P2024的分区中。

当插入不属于某一分区的数据时,则会报错没有找到合适的分区:

insert into TABLE_DATE_RANGE values('01',to_date('20260816','yyyymmdd'));commit;
范围分区添加分区:
ALTER TABLE TABLE_DATE_RANGE ADD PARTITION P2025 VALUES LESS THAN(TO_DATE('2026-01-01','YYYY-MM-DD'));

注:添加分区时添加最小的分区会报错范围分区值非递增比如,添加最小分区要通过拆分分区:

ALTER TABLE TABLE_DATE_RANGE ADD PARTITION P2019 VALUES LESS THAN(TO_DATE('2020-01-01','YYYY-MM-DD'));
范围分区删除分区:
ALTER TABLE TABLE_DATE_RANGE DROP PARTITION P2025 ;
范围分区截断分区(即删除分区的值):
ALTER TABLE TABLE_DATE_RANGE TRUNCATE PARTITION P2025;
范围分区拆分分区:
ALTER TABLE TABLE_DATE_RANGE SPLIT PARTITION P2020 AT(TO_DATE('2020-01-01','YYYY-MM-DD')) INTO (PARTITION P2019,PARTITION P2020);

注:拆分时要主要注意,以填写的数值为分界线(‘2020-01-01’,‘YYYY-MM-DD’),写在前面的是小于分界线的,写在后面的是大于分界线的

范围分区合并分区:

合并分区必须两个分区要连续,而且不能合并最小分区,否则会报错:合并分区不能将下界分区作为结果分区重用

ALTER TABLE TABLE_DATE_RANGE MERGE PARTITIONS p2024, p2023 into partition p2023_24;

有MAXVALUE分区。
在创建时,最后一个分区的值写为MAXVALUE
PARTITION “PMAX” VALUES LESS THAN (MAXVALUE)
添加新分区只能通过拆分的方式:

ALTER TABLE TABLE_DATE_RANGE SPLIT PARTITION PMAX AT(TO_DATE('2026-01-01','YYYY-MM-DD')) INTO (PARTITION P2025,PARTITION PMAX);
列表分区

某列的值只有几种,比如班级,性别
通常会有一个默认分区(DEFAULT分区)存放,不是所有分区值的值,默认分区不是必须。

列表分区创建表
CREATE TABLE "SYSDBA"."TABLE_LIST"
(
"NAME" VARCHAR2(10) NOT NULL,
"SEX" int NOT NULL)
PARTITION BY list("SEX")
(
PARTITION  MAN  VALUES (1),
PARTITION  WOMAN  VALUES (0)
)

插入一条数据:

insert into TABLE_LIST values('张三',1);commit;

列表分区查看指定分区:

select * from TABLE_LIST PARTITION(MAN);
列表分区添加分区:
ALTER TABLE TABLE_LIST ADD PARTITION ET VALUES (3); 
列表分区删除分区:
ALTER TABLE TABLE_LIST DROP PARTITION ET ;
列表分区截断分区(即删除分区的值):
ALTER TABLE TABLE_LIST TRUNCATE PARTITION ET; 
列表分区拆分分区:
在列表分区当中,如果拆分分区必须确保分区当中有不同的值,比如在创建过程当中,使用PARTITION  MAN  VALUES (1,2)
ALTER TABLE TABLE_LIST SPLIT PARTITION OTHER INTO ( PARTITION ET VALUES (3),PARTITION OTHER ); 
ALTER TABLE TABLE_LIST SPLIT PARTITION MAN  INTO ( PARTITION MAN1 VALUES (1),PARTITION MAN2); 
列表分区合并分区:
ALTER TABLE TABLE_LIST MERGE PARTITIONS MAN, WOMAN into partition HUMAN;

有DEFAULT分区。
PARTITION OTHER VALUES (DEFAULT)
有DEFAULT分区不能添加分区,添加分区只能通过拆分来获得;

ALTER TABLE TABLE_LIST SPLIT PARTITION OTHER INTO ( PARTITION ET VALUES (3),PARTITION OTHER VALUES(DEFAULT));  
哈希分区

哈希分区是通过将数据的值转化为哈希函数来分配到各个分区当中。

哈希分区创建表
CREATE TABLE HASH_TABLE   
(   
  COL NUMBER(8),   
  INF VARCHAR2(100)   
)   
PARTITION BY HASH (COL)   
(   
  PARTITION PART01 TABLESPACE HASH_TS01,   
  PARTITION PART02 TABLESPACE HASH_TS02,   
  PARTITION PART03 TABLESPACE HASH_TS03   
) ;
或者可以使用简化版自动命名分区名:
CREATE TABLE HASH_TABLE02  
(  
    COL NUMBER(8),   
  INF VARCHAR2(100)  
)  
PARTITION BY  HASH (COL) PARTITIONS 3 ;
哈希分区添加分区:
ALTER TABLE HASH_TABLE ADD PARTITION PART04; 

删除分区,拆分分区,合并分区::HASH水平分区表[HASH_TABLE]不支持删除分区操作

ALTER TABLE HASH_TABLE DROP PARTITION PART04 ;
哈希分区截断分区(即删除分区的值):
ALTER TABLE HASH_TABLE TRUNCATE PARTITION PART04; 

所以在建立哈希分区的时候,分区数量一定要谨慎对待,只能增加,不能减少。

二级分区表

二级分区表,也称为“子分区表”,是在一级分区的基础上进一步细分的分区策略。它是一种多级分区策略,其中表首先被分为多个一级分区,然后每个一级分区又被细分为多个二级分区。

二级分区创建分区:

下面的分区是先通过UNIT_ID进行列表分区,再通过TRANSACTION_DATE进行时间分区。

CREATE TABLE "SYSDBA"."TRANSACTIONS"
(
"UNIT_ID" VARCHAR2(10) NOT NULL,
"TRANSACTION_DATE" DATE NOT NULL,
"AMOUNT" NUMBER(10,2) NOT NULL)
PARTITION BY LIST("UNIT_ID")
SUBPARTITION BY RANGE("TRANSACTION_DATE")
(
PARTITION  "P_01"  VALUES('01')   STORAGE(ON "TS_2_1", CLUSTERBTR) (
SUBPARTITION  "P2020"  VALUES LESS THAN(DATE'2021-01-01') STORAGE(ON "TS_2_1", CLUSTERBTR) ,
SUBPARTITION  "P2021"  VALUES LESS THAN(DATE'2022-01-01') STORAGE(ON "TS_1_2", CLUSTERBTR) ,
SUBPARTITION  "P2022"  VALUES LESS THAN(DATE'2023-01-01') STORAGE(ON "TS_2_2", CLUSTERBTR) ,
SUBPARTITION  "P2023"  VALUES LESS THAN(DATE'2024-01-01') STORAGE(ON "TS_1_3", CLUSTERBTR) ,
SUBPARTITION  "P2024"  VALUES LESS THAN(DATE'2025-01-01') STORAGE(ON "TS_2_3", CLUSTERBTR) 
)
,
PARTITION  "P_02"  VALUES('02')   STORAGE(ON "TS_1_2", CLUSTERBTR) (
SUBPARTITION  "P2020"  VALUES LESS THAN(DATE'2021-01-01') STORAGE(ON "TS_2_1", CLUSTERBTR) ,
SUBPARTITION  "P2021"  VALUES LESS THAN(DATE'2022-01-01') STORAGE(ON "TS_1_2", CLUSTERBTR) ,
SUBPARTITION  "P2022"  VALUES LESS THAN(DATE'2023-01-01') STORAGE(ON "TS_2_2", CLUSTERBTR) ,
SUBPARTITION  "P2023"  VALUES LESS THAN(DATE'2024-01-01') STORAGE(ON "TS_1_3", CLUSTERBTR) ,
SUBPARTITION  "P2024"  VALUES LESS THAN(DATE'2025-01-01') STORAGE(ON "TS_2_3", CLUSTERBTR) 
)
,
PARTITION  "P_03"  VALUES('03')   STORAGE(ON "TS_2_2", CLUSTERBTR) (
SUBPARTITION  "P2020"  VALUES LESS THAN(DATE'2021-01-01') STORAGE(ON "TS_2_1", CLUSTERBTR) ,
SUBPARTITION  "P2021"  VALUES LESS THAN(DATE'2022-01-01') STORAGE(ON "TS_1_2", CLUSTERBTR) ,
SUBPARTITION  "P2022"  VALUES LESS THAN(DATE'2023-01-01') STORAGE(ON "TS_2_2", CLUSTERBTR) ,
SUBPARTITION  "P2023"  VALUES LESS THAN(DATE'2024-01-01') STORAGE(ON "TS_1_3", CLUSTERBTR) ,
SUBPARTITION  "P2024"  VALUES LESS THAN(DATE'2025-01-01') STORAGE(ON "TS_2_3", CLUSTERBTR) 
)
,
PARTITION  "P_04"  VALUES('04')   STORAGE(ON "TS_1_3", CLUSTERBTR) (
SUBPARTITION  "P2020"  VALUES LESS THAN(DATE'2021-01-01') STORAGE(ON "TS_2_1", CLUSTERBTR) ,
SUBPARTITION  "P2021"  VALUES LESS THAN(DATE'2022-01-01') STORAGE(ON "TS_1_2", CLUSTERBTR) ,
SUBPARTITION  "P2022"  VALUES LESS THAN(DATE'2023-01-01') STORAGE(ON "TS_2_2", CLUSTERBTR) ,
SUBPARTITION  "P2023"  VALUES LESS THAN(DATE'2024-01-01') STORAGE(ON "TS_1_3", CLUSTERBTR) ,
SUBPARTITION  "P2024"  VALUES LESS THAN(DATE'2025-01-01') STORAGE(ON "TS_2_3", CLUSTERBTR) 
)
,
PARTITION  "P_05"  VALUES('05')   STORAGE(ON "TS_2_3", CLUSTERBTR) (
SUBPARTITION  "P2020"  VALUES LESS THAN(DATE'2021-01-01') STORAGE(ON "TS_2_1", CLUSTERBTR) ,
SUBPARTITION  "P2021"  VALUES LESS THAN(DATE'2022-01-01') STORAGE(ON "TS_1_2", CLUSTERBTR) ,
SUBPARTITION  "P2022"  VALUES LESS THAN(DATE'2023-01-01') STORAGE(ON "TS_2_2", CLUSTERBTR) ,
SUBPARTITION  "P2023"  VALUES LESS THAN(DATE'2024-01-01') STORAGE(ON "TS_1_3", CLUSTERBTR) ,
SUBPARTITION  "P2024"  VALUES LESS THAN(DATE'2025-01-01') STORAGE(ON "TS_2_3", CLUSTERBTR) 
)
,
PARTITION  "P_06"  VALUES('06')   STORAGE(ON "TS_1_1", CLUSTERBTR) (
SUBPARTITION  "P2020"  VALUES LESS THAN(DATE'2021-01-01') STORAGE(ON "TS_2_1", CLUSTERBTR) ,
SUBPARTITION  "P2021"  VALUES LESS THAN(DATE'2022-01-01') STORAGE(ON "TS_1_2", CLUSTERBTR) ,
SUBPARTITION  "P2022"  VALUES LESS THAN(DATE'2023-01-01') STORAGE(ON "TS_2_2", CLUSTERBTR) ,
SUBPARTITION  "P2023"  VALUES LESS THAN(DATE'2024-01-01') STORAGE(ON "TS_1_3", CLUSTERBTR) ,
SUBPARTITION  "P2024"  VALUES LESS THAN(DATE'2025-01-01') STORAGE(ON "TS_2_3", CLUSTERBTR) 
)
,
PARTITION  "P_07"  VALUES('07')   STORAGE(ON "TS_2_1", CLUSTERBTR) (
SUBPARTITION  "P2020"  VALUES LESS THAN(DATE'2021-01-01') STORAGE(ON "TS_2_1", CLUSTERBTR) ,
SUBPARTITION  "P2021"  VALUES LESS THAN(DATE'2022-01-01') STORAGE(ON "TS_1_2", CLUSTERBTR) ,
SUBPARTITION  "P2022"  VALUES LESS THAN(DATE'2023-01-01') STORAGE(ON "TS_2_2", CLUSTERBTR) ,
SUBPARTITION  "P2023"  VALUES LESS THAN(DATE'2024-01-01') STORAGE(ON "TS_1_3", CLUSTERBTR) ,
SUBPARTITION  "P2024"  VALUES LESS THAN(DATE'2025-01-01') STORAGE(ON "TS_2_3", CLUSTERBTR) 
)
) STORAGE(HASHPARTMAP(1), ON "TS_1_1", CLUSTERBTR) ;
分区表相关的视图
--一级分区表视图
SELECT *FROM DBA_TAB_PARTITIONS WHERE TABLE_NAME ='T_PARTITION_HASH';
--二级分区表视图
SELECT *FROM DBA_TAB_SUBPARTITIONS;
--一级分区索引视图
SELECT *FROM DBA_IND_PARTITIONS;
--二级分区索引视图
SELECT *FROM DBA_IND_SUBPARTITIONS;
<think>好的,我现在要解决用户的问题:达梦数据库分区表如何实现ID自增。首先,我需要回顾达梦数据库的相关知识,特别是分区表和自增字段的实现方式。 用户提到的是分区表,而达梦支持多种分区方式,比如范围分区、列表分区等。自增字段通常是通过IDENTITY属性来实现的,这在达梦中类似于其他数据库的自动递增功能。但是,在分区表使用自增ID可能会有一些需要注意的地方,比如分区键和自增字段的关系。 首先,我需要确认在达梦数据库中,是否允许在分区表使用IDENTITY列。根据已有的知识,达梦的IDENTITY列是表级别的自增机制,每个表维护自己的自增序列。因此,在分区表中,每个分区可能共享同一个自增序列,这样插入数据时,无论插入到哪个分区,ID都会连续递增。这一点需要验证,是否有文档说明或者实际测试结果支持。 接下来,考虑具体的实现步骤。用户可能需要创建一个分区表,并指定某个字段为自增主键。例如,创建一个按范围分区的表,其中ID字段是自增的。这时候,创建表的SQL语句应该如何编写?需要确保IDENTITY关键字正确应用,并且分区子句正确设置。 可能的示例代码结构如下: CREATE TABLE 表名 ( ID INT IDENTITY(1,1) PRIMARY KEY, ...其他字段... ) PARTITION BY RANGE (分区键) ( PARTITION p1 VALUES LESS THAN (值), PARTITION p2 VALUES LESS THAN (值), ... ); 这里需要注意,IDENTITY列通常不能作为分区键,因为分区键的值需要明确分配到不同的分区,而自增ID的值是自动生成的,可能导致不可控的分区分配。因此,分区键应该是另一个字段,比如时间字段或其他业务相关的字段。 此外,还需考虑自增ID在分布式系统或高并发插入时的性能问题,虽然这可能超出了当前问题的范围,但作为最佳实践,可能需要提醒用户注意自增字段可能成为性能瓶颈,尤其是在分区较多的情况下。 还需要检查达梦的文档,确认是否有关于分区表自增ID的特殊限制或注意事项。例如,是否每个分区有自己的自增序列,或者全局共享一个。如果是后者,那么插入不同分区时,ID会连续递增,这可能符合用户需求,也可能不符合,需要用户根据业务场景决定。 总结步骤应该是: 1. 创建表时定义ID字段为IDENTITY类型。 2. 指定合适的分区键(非自增字段)。 3. 确保分区策略正确,不影响自增ID的生成。 4. 插入数据测试,验证ID是否按预期自增,并且数据正确分布到各分区。 可能遇到的问题包括:分区键选择不当导致数据分布不均,或者自增ID分区键的关系不符合业务逻辑。需要提醒用户根据实际需求设计分区策略,并测试验证。</think>在达梦数据库中实现分区表的ID自增,需结合**自增列(IDENTITY)**和**分区表**的特性。以下是分步实现方法: --- ### 一、核心原理 1. **自增列(IDENTITY)**:通过 `IDENTITY(起始值, 步长)` 语法实现字段自动递增。 2. **分区表**:将数据按规则(如范围、列表等)分布到不同物理分区,但逻辑上仍为一张表。 --- ### 二、实现步骤 #### 1. 创建分区表时定义自增列 ```sql -- 示例:按范围分区的自增ID表 CREATE TABLE user_data ( id INT IDENTITY(1,1), -- 自增ID,从1开始,步长1 name VARCHAR(50), create_time DATE, PRIMARY KEY (id, create_time) -- 主键需包含分区键(create_time) ) PARTITION BY RANGE(create_time) ( PARTITION p2023_01 VALUES LESS THAN ('2023-02-01'), PARTITION p2023_02 VALUES LESS THAN ('2023-03-01') ); ``` #### 2. 关键注意事项 - **分区键选择**: - 必须包含分区键字段(如 `create_time`),但自增列(`id`)**不能直接作为分区键**。 - 主键需包含分区键字段(达梦要求)。 - **ID连续性**: - 自增ID是表级全局唯一,跨分区连续递增。例如: - 插入分区 `p2023_01` 生成 `id=1` - 插入分区 `p2023_02` 生成 `id=2` --- ### 三、验证自增效果 ```sql -- 插入数据(无需指定id) INSERT INTO user_data (name, create_time) VALUES ('张三', '2023-01-15'); INSERT INTO user_data (name, create_time) VALUES ('李四', '2023-02-20'); -- 查询结果 SELECT * FROM user_data; ``` 输出: ``` id | name | create_time 1 | 张三 | 2023-01-15 2 | 李四 | 2023-02-20 ``` --- ### 四、扩展场景 #### 1. 分区间自增独立 若需不同分区独立自增ID,需手动管理(如通过计算规则生成ID): ```sql -- 示例:按月份拼接自增ID(如2023010001) CREATE TABLE user_data_custom ( id VARCHAR(20) PRIMARY KEY, name VARCHAR(50), create_time DATE ) PARTITION BY RANGE(create_time) (...); -- 通过触发器或程序生成自定义ID ``` #### 2. 重置自增序列 ```sql -- 修改表的自增列起始值 ALTER TABLE user_data MODIFY id IDENTITY(1000,1); ``` --- ### 五、总结 - **标准方案**:直接使用 `IDENTITY` 属性,适合全局连续ID场景。 - **定制方案**:通过业务逻辑生成ID,满足分区间独立自增需求。 - **性能优化**:分区键应选择高频查询字段(如时间),避免自增ID成为性能瓶颈。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值