如何在 Java 中使用 liquibase 为表和索引使用不同的表空间

How to use different tablespaces for tables and indexes with liquibase in Java

我在 Spring Boot (2.1.8) java (1.8) 应用程序中使用 liquibase (3.6.3) 来管理数据库 (Oracle 12.2) 架构更改。我的 liquibase 变更集不包含 'tablespace' 参数,所有数据(包括索引)都在默认表空间 'USERS' 中创建。现在我需要将所有现有索引重新定位到另一个表空间 'INDX' 并创建所有未来的索引,而不是在默认 'USERS' 表空间中,而是在新的 'INDX' 表空间中。

所以,我的问题:

  1. 如何将旧索引从 'USERS' 表空间迁移到 'INDX' 表空间?

  2. 如何在 'INDX' 表空间中创建新索引?我知道 column/constraint 元素的 'primaryKeyTablespace' 参数和 createIndex 元素的 'tablespace' 参数,还有其他解决方案吗?也许我可以为所有集中索引指定 'INDX' 表空间?

谢谢!

第一个问题的答案是按如下方式重建索引:

alter index [index_name] rebuild tablespace [tablespace_name];

这将锁定您的 table 完成重建所需的时间。如果您需要保持 table 可用于更新,请使用 "online" 命令:

alter index [index_name] rebuild tablespace [tablespace_name] online;

如果索引中有大量数据,您可以添加 "parallel" 子句来加快速度。通常不要将并行度设置为高于系统上 CPU 个内核的数量:

alter index [index_name] rebuild tablespace [tablespace_name] online parallel [x];

对于关于默认 table 空间的第二个问题,您可以根据您的 Oracle 版本以不同的方式处理此问题。 Oracle 19c 有一个新特性,允许数据库自动索引你的 table(即你不需要做任何事情!),你可以在这里阅读:https://blogs.oracle.com/oraclemagazine/autonomous-indexing

如果您使用的是旧版本的 Oracle,那么您将只能使用 liquibase 中可用的任何配置选项。

如果您想集中表空间的定义,请在更改日志的开头使用 属性。

<property name="index_tablespace" value="INDEX" dbms="oracle"/>
<property name="index_tablespace" value="" dbms="postgresql"/>

您还可以使用另一个 属性 来定义表的表空间。

在 Postgres 中通常不使用表空间 - 至少在 Oracle 中不是以您需要的方式使用,因此您可以将其留空。

然后在 createIndex 更改中使用 属性:

<createIndex indexName="idx_firstname" tableName="person" tablespace="${index_tablespace}"/>

要修改现有索引以使用不同的表空间,您必须使用特定于数据库的 SQL(请参阅 pmdba 的回答)。你必须使它依赖于 dbms:

<changeSet id="fix-index-tablespace" author="arthur" dbms="oracle">
  <sql> 
    alter index ...
  </sql>
</changeSet>