为什么PostgreSQL将主键索引存放在pg_default表空间中?

后端开发 2026-07-09

请看下列在特定表空间中创建的表:

CREATE TABLE example 
(
    example_id int4 NOT NULL,
    name VARCHAR(12) NOT NULL,
    CONSTRAINT example_pkey 
       PRIMARY KEY (example_id)
) TABLESPACE tbspc01;

通过访问 pg_classpg_tablespace 时,可以验证结果良好:

SELECT c.relname, 
       t.spcname
  FROM pg_class c 
  JOIN pg_tablespace t 
    ON c.reltablespace = t.oid 
 WHERE c.relname LIKE '%example%';

结果:

 relname |   spcname
---------+-------------
 example | chinook_spc
(1 row)

然而,随着表的规模增大,由 pg_total_relation_size() 报告的表大小与由 pg_tablespace_size() 报告的表大小之间会出现不匹配,因为表的实际大小超过了表空间。

That is so for the primary key is stored in the default tablespace:

SELECT indexname, 
       tablespace
  FROM pg_indexes 
 WHERE indexname LIKE '%example%';

结果:

  indexname   | tablespace
--------------+------------
 example_pkey |
(1 row)

可以使用 ALTER INDEX [...] SET TABLESPACE 将主键移动到所需的表空间。

但为什么主键没有与表存放在同一个表空间?

CREATE TABLE 指令中,如何强制将主键存放在与表相同的表空间?

解决方案

表和索引可以位于不同的表空间,因此必须分别指定。

我测试了两种解决方案,均能将主键索引放入目标表空间。

第一种方案:指定表空间。

CREATE TABLE example 
(
    example_id int4 NOT NULL,
    name VARCHAR(12) NOT NULL,
    CONSTRAINT example_pkey 
       PRIMARY KEY (example_id) USING INDEX TABLESPACE tbspc01
) TABLESPACE tbspc01;

第二种方案:在创建表之前设置默认表空间,这样就不需要为表或索引指定表空间,两者都位于新的默认表空间中。

SET default_tablespace=tbspc01;

CREATE TABLE example 
(                
    example_id int4 NOT NULL,
    name VARCHAR(12) NOT NULL,
    CONSTRAINT example_pkey 
       PRIMARY KEY (example_id)                             
);
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章