ITPub博客

首页 > 数据库 > 国内数据库 > 国产数据库分区表居然可以直接“撤回”成普通表了

国产数据库分区表居然可以直接“撤回”成普通表了

原创 国内数据库 作者:sjw1933 时间:2026-01-09 15:42:22 0 删除 编辑

在数据库运维这条路上,有些技术当年看起来是“高级配置”,过几年却往往变成“历史包袱”。

分区表就是最典型的一类。

系统刚上线时,按年、按月、按业务维度切分,看起来专业又稳妥;
但几年之后,很多库开始变得越来越难调:SQL 越跑越慢,优化器越来越玄,分区规则复杂到没人敢轻易碰,新同事更是绕着走。

慢慢地,一个问题就绕不开了:

如果当年的分区设计并不合适,现在还能不能改?

现实却往往很残酷——在大多数数据库里,这几乎意味着重建表、搬数据、停业务,代价不小,也风险不低。

直到我在 YashanDB V23.5 看到这条语法:

ALTER TABLE … EXCHANGE PARTITION … WITH TABLE …

粗体第一反应是:

这玩意要真靠谱,那不是“小功能”,是运维体系级能力。

于是,我做了一次完整实操测试,模拟如下真实场景:

场景:把“已经分错”的历史分区,原地退回成一张普通表

不是导数据、不是 CTAS、不是 COPY。

是 真正意义上的:分区表 → 普通表

实验全过程

一、创建历史分区表

CREATE TABLE SHIJW.CW_MZSFMX_INTERIM
(
  JLID   NUMBER(10),
  BMID   NUMBER(4),
  ZKID   NUMBER(4),
  BRBH   VARCHAR2(28),
  BRXM   VARCHAR2(20),
  DWDM   VARCHAR2(5),
  ZHID   NUMBER(8),
  XMID   NUMBER(8),
  FLM    VARCHAR2(8),
  TJM    VARCHAR2(4),
  MC     VARCHAR2(100),
  KZJB   VARCHAR2(1),
  YZLB   VARCHAR2(2),
  DJ     NUMBER(8,2),
  SL     NUMBER(4),
  ZFJE   NUMBER(9,2),
  JZJE   NUMBER(9,2),
  JMJE   NUMBER(9,2),
  ZLJE   NUMBER(9,2),
  ZFBL   NUMBER(3,2),
  YSID   NUMBER(5),
  JYID   NUMBER(10),
  SFYQ   VARCHAR2(2),
  ZTBZ   VARCHAR2(1),
  ZLHDID NUMBER(9),
  JMID   NUMBER(8),
  SFLX   VARCHAR2(1),
  SFRYID NUMBER(8),
  SFSJ   DATE,
  SPBZ   VARCHAR2(1),
  BZDM   VARCHAR2(2),
  BAFLM  VARCHAR2(3)
)
PARTITION BY RANGE (SFSJ)
(
  PARTITION CW_MZSFMX_p1  VALUES LESS THAN (DATE '2011-01-01'),
  PARTITION CW_MZSFMX_p2  VALUES LESS THAN (DATE '2012-01-01'),
  PARTITION CW_MZSFMX_p3  VALUES LESS THAN (DATE '2013-01-01'),
  PARTITION CW_MZSFMX_p4  VALUES LESS THAN (DATE '2014-01-01'),
  PARTITION CW_MZSFMX_p5  VALUES LESS THAN (DATE '2015-01-01'),
  PARTITION CW_MZSFMX_p6  VALUES LESS THAN (DATE '2016-01-01'),
  PARTITION CW_MZSFMX_p7  VALUES LESS THAN (DATE '2017-01-01'),
  PARTITION CW_MZSFMX_p8  VALUES LESS THAN (DATE '2018-01-01'),
  PARTITION CW_MZSFMX_p9  VALUES LESS THAN (DATE '2019-01-01'),
  PARTITION CW_MZSFMX_p10 VALUES LESS THAN (DATE '2020-01-01'),
  PARTITION CW_MZSFMX_p11 VALUES LESS THAN (DATE '2021-01-01'),
  PARTITION CW_MZSFMX_p12 VALUES LESS THAN (DATE '2022-01-01'),
  PARTITION CW_MZSFMX_p13 VALUES LESS THAN (DATE '2023-01-01'),
  PARTITION CW_MZSFMX_p14 VALUES LESS THAN (DATE '2024-01-01'),
  PARTITION CW_MZSFMX_p15 VALUES LESS THAN (DATE '2025-01-01')
);

二、准备测试数据

CREATE SEQUENCE SHIJW.SEQ_CW_MZSFMX
  START WITH 1
  INCREMENT BY 1
  NOCACHE
  NOCYCLE;
BEGIN
  FOR i IN 1..100000 LOOP
    INSERT INTO shijw.CW_MZSFMX_INTERIM
    (
      JLID, BMID, ZKID, BRBH, BRXM, DWDM, ZHID, XMID,
      FLM, TJM, MC, KZJB, YZLB,
      DJ, SL, ZFJE, JZJE, JMJE, ZLJE, ZFBL,
      YSID, JYID, SFYQ, ZTBZ,
      ZLHDID, JMID, SFLX, SFRYID,
      SFSJ, SPBZ, BZDM, BAFLM
    )
    VALUES
    (
      shijw.SEQ_CW_MZSFMX.NEXTVAL,
      TRUNC(DBMS_RANDOM.VALUE(1,10)),
      TRUNC(DBMS_RANDOM.VALUE(1,20)),
      'BR'||LPAD(i,6,'0'),
      '患者'||MOD(i,100),
      'DW'||MOD(i,50),
      TRUNC(DBMS_RANDOM.VALUE(10000,99999)),
      TRUNC(DBMS_RANDOM.VALUE(100,9999)),
      'FL'||MOD(i,10),
      'TJ'||MOD(i,20),
      '测试项目'||MOD(i,200),
      'A',
      '01',
      ROUND(DBMS_RANDOM.VALUE(10,500),2),
      TRUNC(DBMS_RANDOM.VALUE(1,20)),
      ROUND(DBMS_RANDOM.VALUE(50,2000),2),
      ROUND(DBMS_RANDOM.VALUE(50,2000),2),
      ROUND(DBMS_RANDOM.VALUE(0,100),2),
      ROUND(DBMS_RANDOM.VALUE(10,500),2),
      ROUND(DBMS_RANDOM.VALUE(0.1,1),2),
      TRUNC(DBMS_RANDOM.VALUE(1,50)),
      TRUNC(DBMS_RANDOM.VALUE(100000,999999)),
      'N',
      '1',
      0,
      TRUNC(DBMS_RANDOM.VALUE(1,500)),
      '1',
      TRUNC(DBMS_RANDOM.VALUE(10,100)),
      DATE '2011-01-01' + TRUNC(DBMS_RANDOM.VALUE(0, 5000)),
      '0',
      '01',
      '001'
    );
    IF MOD(i,1000)=0 THEN
      COMMIT;
    END IF;
  END LOOP;
  COMMIT;
END;
/

三、验证分区数据

SELECT JLID, BMID, BRBH
FROM SHIJW.CW_MZSFMX_INTERIM PARTITION (CW_MZSFMX_p3);

四、创建目标普通表

CREATE TABLE SHIJW.CW_MZSFMX
(
  JLID   NUMBER(10),
  BMID   NUMBER(4),
  ZKID   NUMBER(4),
  BRBH   VARCHAR2(28),
  BRXM   VARCHAR2(20),
  DWDM   VARCHAR2(5),
  ZHID   NUMBER(8),
  XMID   NUMBER(8),
  FLM    VARCHAR2(8),
  TJM    VARCHAR2(4),
  MC     VARCHAR2(100),
  KZJB   VARCHAR2(1),
  YZLB   VARCHAR2(2),
  DJ     NUMBER(8,2),
  SL     NUMBER(4),
  ZFJE   NUMBER(9,2),
  JZJE   NUMBER(9,2),
  JMJE   NUMBER(9,2),
  ZLJE   NUMBER(9,2),
  ZFBL   NUMBER(3,2),
  YSID   NUMBER(5),
  JYID   NUMBER(10),
  SFYQ   VARCHAR2(2),
  ZTBZ   VARCHAR2(1),
  ZLHDID NUMBER(9),
  JMID   NUMBER(8),
  SFLX   VARCHAR2(1),
  SFRYID NUMBER(8),
  SFSJ   DATE,
  SPBZ   VARCHAR2(1),
  BZDM   VARCHAR2(2),
  BAFLM  VARCHAR2(3)
);

五、统计分区数据分布

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(
    ownname    => 'SHIJW',
    tabname    => 'CW_MZSFMX_INTERIM',
    granularity => 'ALL'
  );
END;
/
FROM   USER_TAB_PARTITIONS
WHERE  TABLE_NAME = 'CW_MZSFMX_INTERIM'
ORDER BY PARTITION_POSITION;

示例结果:

CW_MZSFMX_P2  7347
CW_MZSFMX_P3  7245
...

六、执行:撤分区操作

ALTER TABLE SHIJW.CW_MZSFMX_INTERIM
  EXCHANGE PARTITION CW_MZSFMX_p2
  WITH TABLE CW_MZSFMX
  INCLUDING INDEXES
  UPDATE GLOBAL INDEXES;

输出:

Succeed.

七、检查结果

原分区表:

select count(*) from SHIJW.CW_MZSFMX_INTERIM;
92653

目标普通表:

select count(*) from shijw.CW_MZSFMX;
7347

核心感受:这是数据库工程化能力,不是 SQL 技巧

熟悉 Oracle 的 DBA 应该会很有共鸣:
在 Oracle 世界里,如果要对一张“大表”做结构调整,通常会想到一个包:

DBMS_REDEFINITION.START_REDEF_TABLE

它的核心思想是:
在不影响业务的情况下,在线重构一张表的物理结构。

分区调整、字段变更、表结构重排,本质上都可以通过 redefinition 绕一圈来完成。
这在 Oracle 体系里,是一条极其成熟也极其“工程化”的能力路径。

而这次在 YashanDB V23.5 上体验 EXCHANGE PARTITION,给我非常相似的感觉:
• 并不追求“语法像不像”
• 而是解决同一类问题:在线改结构
• 把风险从“人”转移到“系统”
• 把重构从“项目动作”变成“日常运维能力”

如果说 DBMS_REDEFINITION 代表的是 Oracle 多年积累出来的结构重构能力,
那 YashanDB 在分区撤回这条路径上,已经开始走向真正的“工程化数据库”。

对 DBA 来说,最有价值的从来不是多一条语法,而是多一条:

可以在生产环境里“安全改结构”的路。

作者:Digital Observer(施嘉伟)
Oracle ACE Pro
PostgreSQL ACE Partner
Oracle  OCM、KCM、PGCM、YCP、DB2 、MySQL OCP、PCTP、PCSD、OCI、PolarDB技术专家、达梦师资认证,从业11年+
ITPUB认证专家、崖山YVP、KWDB MVP、PolarDB开源社区技术顾问、HaloDB技术顾问、TiDB社区技术布道师、青学会MOP技术社区专家顾问、国内某高校企业实践指导教师
公众号/墨天轮/金仓社区/IF Club:Digital Observer;CSDN/PGfans:施嘉伟;ITPUB:sjw1933

hhh7.jpg


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23825935/viewspace-3107575/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
11年数据库行业经验,Oracle ACE、PG ACE、OCM、IBM Certified DBA、MySQL OCP、PolarDB技术专家、KCP、PCTP、PCSD、达梦师资认证、PolarDB开源社区技术顾问、ITPUB认证专家、某高校外聘教师

注册时间:2019-05-05

  • 博文量
    295
  • 访问量
    300690