注册
dm聚集索引设计
专栏/技术分享/ 文章详情 /

dm聚集索引设计

DM_336625 2026/05/28 208 0 0
摘要

在达梦数据库中:

  • 聚集主键数据行本身会按照主键值的顺序物理存储。主键既是数据的唯一标识,也是数据的“组织者”。
  • 普通主键:主键仅仅是一个逻辑约束(确保唯一),数据的物理存储顺序与之无关,由另一个隐藏的ROWID负责。

达梦一个核心设计:表就是索引,索引就是表

🧱 底层原理:达梦是“索引组织表”

达梦默认创建的是索引组织表(IOT) 。这意味着表的数据本身就是一棵巨大的B+树(聚集索引),所有数据行都存放在这棵树的叶子节点上。

因此,任何达梦表(非堆表)必须且只能有一个聚集索引来组织物理存储。这个“组织者”可以是:

  1. 你指定的聚集主键
  2. 你手动指定的聚集键(CLUSTER KEY)
  3. 默认的隐藏列ROWID(如果你什么都没指定)

⚖️ 核心差异对比:一张表把事说清

对比维度 聚集主键 (CLUSTER PRIMARY KEY) 普通主键 (NON CLUSTER PRIMARY KEY)
物理存储 决定物理顺序:数据行按主键值的顺序排列并存储。 不决定存储:数据的物理顺序由ROWID决定。
表数据组织者 主键列。数据存储的B+树直接以主键值作为Key构建。 隐藏列ROWID。系统自动创建一个以ROWID为Key的聚集索引来存储数据。
查询性能 主键查询极快:直接在主键B+树上就能找到所有列数据,无需额外操作(即不回表)。 主键查询需回表:先通过主键索引找到对应的ROWID,再根据ROWID去表的聚集索引中找到完整数据行(即回表)。
唯一性 保证主键列值唯一。 保证主键列值唯一。
数量限制 一个表有且只有一个聚集索引(无论是主键还是手动指定的)。 一个表可以有很多个(普通主键就是一个带唯一约束的非聚集索引)。
适用场景 经常通过主键进行精确查询范围扫描的表(如订单表查订单详情)。 主键无业务含义(如自增ID),或频繁通过其他列查询,希望由该列来组织数据存储。

💡 为什么达梦默认使用“普通主键”?

既然聚集主键查询更快,为什么不默认用它?

这背后是达梦为了兼容性灵活性做出的取舍,完全由PK_WITH_CLUSTER参数控制(默认为0,即非聚集)。

主要原因有两个:

  1. 兼容Oracle:Oracle默认主键就是非聚集索引。达梦为了降低Oracle应用迁移的改造成本,默认行为与Oracle保持一致。
  2. 应对不良设计:很多应用(特别是框架自动生成的)喜欢用一个无意义的自增ID作主键。这种主键很少被用作查询条件,如果把它设为聚集索引,既浪费了“快速定位”的优势,还可能因为乱序插入导致性能问题。因此,达梦默认把“组织数据”的宝贵机会留给了其他有意义的业务列。

🛠️ 实战指南:如何操控这两种主键?

1. 显式创建聚集主键

如果你明确需要让数据按主键存储,在建表时使用CLUSTER PRIMARY KEY关键字即可:

sql

-- 创建一个以STUNO列为聚集索引主键的表
CREATE TABLE STUDENT( 
    STUNO INT CLUSTER PRIMARY KEY,  -- 这就是聚集主键
    STUNAME VARCHAR(15) NOT NULL
);

2. 改变全局默认行为

如果你希望所有新创建的表,默认主键就是聚集主键(像MySQL InnoDB一样),可以修改参数:

sql

-- 查询当前设置
SELECT * FROM V$DM_INI WHERE PARA_NAME = 'PK_WITH_CLUSTER';

-- 动态修改参数,使之后创建的主键默认为聚集主键 (需相应权限)
ALTER SYSTEM SET 'PK_WITH_CLUSTER' = 1 BOTH;

设置后,普通的PRIMARY KEY就会自动变成聚集主键。

3. 查看现有表的组织方式

想知道一张表的数据到底是以什么作为聚集索引组织的?可以查询系统表:

sql

-- 查看表的主键是否为聚集索引
SELECT 
    T.TABLE_NAME,
    I.INDEX_NAME,
    I.UNIQUE_FLAG,
    I.CLUSTER_FLAG  -- 1表示聚集索引
FROM 
    USER_TABLES T 
    JOIN USER_INDEXES I ON T.TABLE_NAME = I.TABLE_NAME
WHERE 
    T.TABLE_NAME = 'YOUR_TABLE_NAME';

🎯 总结与一句话记住

  • 普通主键 = 一个独立的唯一目录(逻辑约束),书的内容按默认页码(ROWID) 排列。
  • 聚集主键 = 书的内容本身就按目录顺序排列(物理存储),翻开目录就能直接翻到那一页。

建议:

  1. 如果你的主键有明确业务含义(如订单号、学号、身份证号),并且主要通过它查询:强烈建议使用聚集主键
  2. 如果你的主键是无意义的自增ID:建议使用普通主键,但务必为业务上高频查询的字段(如时间、用户ID)单独创建一个聚集索引,让数据按业务查询的顺序来组织存储。

达梦社区技术 https://eco.dameng.com

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服