虽然从 Oracle 12.2 开始技术上已经可以直接通过以下方式转换非分区表为分区表ALTER TABLE … MODIFY但一些较为复杂分区场景还是建议采用在线重定义操作来更改为分区表。什么是表重定义Table Redefinition在线表重定义Online Table Redefinition允许在表正在被使用的情况下对其进行结构变更且零停机时间。它是如何工作的Oracle 通过创建临时表和同步机制来实现在线重定义你创建一个具有目标结构的临时表interim tableOracle 将数据从原表复制到临时表在此期间产生的任何变更都会被同步最后Oracle 以原子方式将原表与临时表进行交换测试案例1. 创建 Sequence用于生成 ORDER_IDCREATESEQUENCE SZR.CUSTOMER_ORDERS_SEQSTARTWITH1INCREMENTBY1NOCACHE NOCYCLE;2. 创建测试用的非分区表 CUSTOMER_ORDERS11g 兼容CREATETABLESZR.CUSTOMER_ORDERS(ORDER_ID NUMBERPRIMARYKEY,ORDER_DATEDATENOTNULL,CUSTOMER_ID NUMBERNOTNULL,CUSTOMER_NAME VARCHAR2(120),PRODUCT_CODE VARCHAR2(50),QUANTITY NUMBER(8),UNIT_PRICE NUMBER(12,2),TOTAL_AMOUNT NUMBER(14,2)GENERATED ALWAYSAS(QUANTITY*UNIT_PRICE)VIRTUAL,ORDER_STATUS VARCHAR2(20)DEFAULTPENDING,CREATED_BY VARCHAR2(60))TABLESPACEUSERS;-- 创建 Trigger 实现自增主键CREATEORREPLACETRIGGERSZR.CUSTOMER_ORDERS_TRG BEFOREINSERTONSZR.CUSTOMER_ORDERSFOR EACH ROWBEGINIF:NEW.ORDER_IDISNULLTHENSELECTSZR.CUSTOMER_ORDERS_SEQ.NEXTVALINTO:NEW.ORDER_IDFROMDUAL;ENDIF;END;/3. 插入一些测试数据覆盖不同年份INSERTINTOSZR.CUSTOMER_ORDERS(ORDER_DATE,CUSTOMER_ID,CUSTOMER_NAME,PRODUCT_CODE,QUANTITY,UNIT_PRICE,ORDER_STATUS,CREATED_BY)SELECTADD_MONTHS(TO_DATE(2020-03-10,YYYY-MM-DD),LEVEL*1)ASORDER_DATE,5000MOD(LEVEL,300)ASCUSTOMER_ID,Customer_||TO_CHAR(5000MOD(LEVEL,300))ASCUSTOMER_NAME,PROD_||LPAD(MOD(LEVEL,99)1,3,0)ASPRODUCT_CODE,MOD(LEVEL,50)1ASQUANTITY,ROUND(DBMS_RANDOM.VALUE(10,500),2)ASUNIT_PRICE,CASEMOD(LEVEL,5)WHEN0THENCOMPLETEDWHEN1THENSHIPPEDWHEN2THENPENDINGELSECANCELLEDENDASORDER_STATUS,User_||MOD(LEVEL,10)ASCREATED_BYFROMDUALCONNECTBYLEVEL1200;COMMIT;-- 查看原表记录数和数据分布SELECTCOUNT(*)AStotal_rowsFROMSZR.CUSTOMER_ORDERS;SELECTMIN(ORDER_DATE),MAX(ORDER_DATE)FROMSZR.CUSTOMER_ORDERS;SELECTTRUNC(ORDER_DATE,MM),COUNT(*)FROMSZR.CUSTOMER_ORDERSGROUPBYTRUNC(ORDER_DATE,MM)ORDERBY1;4. 检查表是否支持重定义使用 CONS_USE_PKsetserveroutputon;BEGINDBMS_REDEFINITION.CAN_REDEF_TABLE(unameSZR,tnameCUSTOMER_ORDERS,options_flagDBMS_REDEFINITION.CONS_USE_PK);DBMS_OUTPUT.PUT_LINE(表支持重定义CONS_USE_PK成功);END;/5. 创建具有目标分区结构的临时表Interim TableCREATETABLESZR.CUSTOMER_ORDERS_INTTABLESPACEUSERSPARTITIONBYRANGE(ORDER_DATE)INTERVAL(NUMTOYMINTERVAL(1,MONTH))(PARTITIONP_BEFORE_2022VALUESLESS THAN(TO_DATE(2022-01-01,YYYY-MM-DD)))ASSELECT*FROMSZR.CUSTOMER_ORDERSWHERE10;-- 查看临时表当前分区SELECTPARTITION_NAME,HIGH_VALUEFROMUSER_TAB_PARTITIONSWHERETABLE_NAMECUSTOMER_ORDERS_INT;6. 启动重定义过程使用 CONS_USE_PKsetserveroutputon;BEGINDBMS_REDEFINITION.START_REDEF_TABLE(unameSZR,orig_tableCUSTOMER_ORDERS,int_tableCUSTOMER_ORDERS_INT,options_flagDBMS_REDEFINITION.CONS_USE_PK);DBMS_OUTPUT.PUT_LINE(START_REDEF_TABLE 执行完成);END;/大表场景可在 START_REDEF_TABLE 前开启并行如ALTER SESSION FORCE PARALLEL DML PARALLEL 4;。回退操作如果执行过程中发生错误可以使用以下语句回退BEGINDBMS_REDEFINITION.ABORT_REDEF_TABLE(unameSZR,orig_tableCUSTOMER_ORDERS,int_tableCUSTOMER_ORDERS_INT);END;/7. 复制原表的依赖对象setserveroutputon;DECLAREl_num_errors PLS_INTEGER;BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(unameSZR,orig_tableCUSTOMER_ORDERS,int_tableCUSTOMER_ORDERS_INT,copy_indexes0,-- 不自动复制索引主键索引已存在copy_triggersTRUE,copy_constraintsFALSE,-- 关键关闭约束复制避免 NOT NULL 冲突copy_privilegesTRUE,ignore_errorsTRUE,num_errorsl_num_errors,copy_statisticsFALSE);DBMS_OUTPUT.PUT_LINE(COPY_TABLE_DEPENDENTS 执行完成错误数: ||l_num_errors);END;/8. 同步期间产生的新 DML 数据推荐执行BEGINDBMS_REDEFINITION.SYNC_INTERIM_TABLE(unameSZR,orig_tableCUSTOMER_ORDERS,int_tableCUSTOMER_ORDERS_INT);DBMS_OUTPUT.PUT_LINE(SYNC_INTERIM_TABLE 执行完成);END;/9. 完成重定义BEGINDBMS_REDEFINITION.FINISH_REDEF_TABLE(unameSZR,orig_tableCUSTOMER_ORDERS,int_tableCUSTOMER_ORDERS_INT);DBMS_OUTPUT.PUT_LINE(FINISH_REDEF_TABLE 执行完成表已成功转换为分区表);END;/10. 验证结果SELECTTABLE_NAME,PARTITIONING_TYPE,INTERVALFROMUSER_PART_TABLESWHERETABLE_NAMECUSTOMER_ORDERS;SELECTPARTITION_NAME,HIGH_VALUE,NUM_ROWSFROMUSER_TAB_PARTITIONSWHERETABLE_NAMECUSTOMER_ORDERSORDERBYPARTITION_POSITION;SELECTCOUNT(*)FROMSZR.CUSTOMER_ORDERS;-- 删除临时表DROPTABLESZR.CUSTOMER_ORDERS_INTPURGE;-- 收集统计信息BEGINDBMS_STATS.GATHER_TABLE_STATS(SZR,CUSTOMER_ORDERS,cascadeTRUE);END;/总结通过以上步骤我们成功使用在线表重定义技术将普通表CUSTOMER_ORDERS转换为了按月间隔分区表。整个过程无需停机对业务影响最小特别适合需要高可用和7x24运行的生产环境。在线重定义的优势在于✅ 零停机时间✅ 完整的依赖对象迁移✅ 支持回滚操作✅ 数据一致性有保障关注我学习更多的数据库知识