oracle引用分区要求父表主键必须包含分区键且为前导列,子表外键列须与父表分区键严格一致并显式命名约束,建表时一步完成partition by reference,否则报ora-14035或ora-14650。

Oracle 分区表中主键和外键的引用完整性不能靠普通外键自动保障——必须用 REFERENCE PARTITIONING,且父表主键必须是分区键的一部分,否则外键约束建得再严,数据物理分布也跟不上去。
父表主键必须包含分区键列
引用分区不是“加个外键就行”,它强制要求:父表的分区键必须是主键(或唯一键)的**前导列**。比如按 order_date RANGE 分区,那主键就得是 (order_date, order_id) 或单独 order_date(如果业务允许),不能只是 order_id。
- ORA-14035 报错就说明分区键没进主键/唯一键:检查
USER_CONSTRAINTS和USER_PART_KEY_COLUMNS - 如果已有单列主键
order_id,又想按日期分区,得先改主键为联合主键,再重建分区——不能只改分区策略 - 主键含分区键,才能保证每条父记录归属唯一分区,子表才能按同一逻辑路由
子表外键必须严格匹配父表分区键
子表建外键时,FOREIGN KEY (col) 的 col 必须和父表的分区键列**同名、同类型、同精度、同顺序**。常见翻车点是:父表用 DATE,子表误用 TIMESTAMP;或父表分区键是 (region, order_date),子表只外键到 order_date。
- 错误示例:
FOREIGN KEY (order_id) REFERENCES orders(order_id)→ 即使order_id是父表主键,只要它不是分区键,建表直接报ORA-14650 - 正确写法必须是:
FOREIGN KEY (order_date) REFERENCES orders(order_date),且该列在子表中必须存在并定义一致 - 外键约束名(如
fk_oi_order)要显式命名,PARTITION BY REFERENCE后面括号里填的就是这个名,不是列名也不是表名
子表建表语句必须一步到位,不能事后添加
PARTITION BY REFERENCE 只能在 CREATE TABLE 时声明,ALTER TABLE 不支持追加。而且子表不能同时指定其他分区方式(比如再写 PARTITION BY RANGE),否则报 ORA-14035: invalid partitioning method。
- 建表语句必须包含三要素:外键定义 + 外键列存在且类型一致 +
PARTITION BY REFERENCE (constraint_name) - 子表的分区数、分区名、边界值全部继承自父表,无法自定义;新增父分区(如
ADD PARTITION)也不会自动同步到子表 - 删/截断/拆分父分区会自动级联到子表对应分区;但合并父分区(
MERGE PARTITIONS)需手动处理子表,Oracle 不自动干预
数据没进预期分区?先查外键状态和分区键值
插入子表后查不到数据,最可能是:外键列值与父表某行匹配,但那一行不在你查的分区里——比如父表按月分区,order_date = DATE'2025-06-15' 落在 p_2025_q2,但你却查 PARTITION (p_2025_q1)。
- 确认外键约束是
ENABLE VALIDATE状态:SELECT status, validated FROM user_constraints WHERE constraint_name = 'FK_OI_ORDER'; - 查父表该值落在哪个分区:
SELECT partition_name FROM user_tab_partitions WHERE table_name = 'ORDERS' AND DATE'2025-06-15' (注意 <code>HIGH_VALUE是 RAW,需用DBMS_METADATA解析) - 子表分区名默认继承父表,但若父表用了
INTERVAL,子表可能生成系统命名分区(如SYS_P123),不能硬写名字去查
引用分区本质是“复用分区逻辑”,不是“同步结构”。所有约束条件都卡在建表那一刻,运行时不会校验父表分区键是否仍被主键覆盖,也不会提醒你外键列类型悄悄变了——这些都得靠建表前人工对齐。











