You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2026/06/22 10:30:17 UTC

(shardingsphere) branch master updated: Improve generated sharding index names to reduce name inflation (#38449)

This is an automated email from the ASF dual-hosted git repository.

terrymanu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 798a3bfe10e Improve generated sharding index names to reduce name inflation (#38449)
798a3bfe10e is described below

commit 798a3bfe10e3abc9d59d614d214889887edfe325
Author: ym0506 <at...@naver.com>
AuthorDate: Mon Jun 22 19:30:10 2026 +0900

    Improve generated sharding index names to reduce name inflation (#38449)
    
    * Improve sharding actual index naming to reduce name inflation
    
    * Format MySQL sharding show create table merge test
    
    * Adjust sharding rewriter expectations for shortened index names
    
    * Address index naming compatibility and length limits
    
    * Fix infra common style checks for index metadata utils
    
    * Fix sharding core spotless formatting
    
    * Fix pipeline decorator spotless formatting
    
    * Fix reverse index lookup edge cases and schema-aware pipeline mapping
    
    * Fix sharding index metadata revise recovery
    
    * Fix sharding index revision candidates
    
    * Add create table index revision candidates
---
 .../reviser/index/EncryptIndexReviser.java         |   4 +-
 .../reviser/index/EncryptIndexReviserTest.java     |   6 +-
 .../reviser/index/ShardingIndexReviser.java        |  69 +++++-
 .../sharding/rewrite/token/pojo/IndexToken.java    |   2 +-
 .../reviser/index/ShardingIndexReviserTest.java    | 117 +++++++++-
 .../rewrite/token/pojo/IndexTokenTest.java         |  18 +-
 .../MySQLShardingShowCreateTableMergedResult.java  |   6 +-
 .../type/MySQLShardingShowIndexMergedResult.java   |  11 +-
 ...SQLShardingShowCreateTableMergedResultTest.java |  43 ++++
 .../MySQLShardingShowIndexMergedResultTest.java    |  47 +++-
 .../database/ShardingSphereDatabaseFactory.java    |  34 ++-
 .../builder/GenericSchemaBuilderMaterial.java      |  22 +-
 .../schema/reviser/MetaDataReviseEngine.java       |   3 +-
 .../schema/reviser/index/IndexReviseEngine.java    |  36 ++-
 .../schema/reviser/index/IndexReviser.java         |  22 +-
 .../reviser/schema/SchemaMetaDataReviseEngine.java |  43 +++-
 .../reviser/table/TableMetaDataReviseEngine.java   |  29 ++-
 .../database/schema/util/IndexMetaDataUtils.java   | 243 ++++++++++++++++++++-
 .../ShardingSphereDatabaseFactoryTest.java         |  23 ++
 .../reviser/index/IndexReviseEngineTest.java       |  32 ++-
 .../schema/SchemaMetaDataReviseEngineTest.java     |  38 ++++
 .../schema/util/IndexMetaDataUtilsTest.java        |  99 ++++++++-
 .../metadata/generator/PipelineDDLDecorator.java   |  39 +++-
 .../datasource/PipelineJobDataSourcePreparer.java  |   2 +-
 .../generator/PipelineDDLDecoratorTest.java        | 106 +++++++++
 .../mode/manager/ContextManager.java               |   6 +-
 .../metadata/factory/MetaDataContextsFactory.java  |   3 +-
 .../metadata/DatabaseMetaDataPersistFacade.java    |   4 +-
 .../CreateTablePushDownMetaDataRefresher.java      |  36 ++-
 .../type/table/TableMetaDataRefresherLoader.java   |  28 ++-
 .../type/view/ViewMetaDataRefresherLoader.java     |   4 +-
 .../factory/MetaDataContextsFactoryTest.java       |  19 ++
 .../CreateTablePushDownMetaDataRefresherTest.java  | 229 ++++++++++++++++++-
 .../ClusterMetaDataManagerPersistService.java      |   3 +-
 .../StandaloneMetaDataManagerPersistService.java   |   3 +-
 .../resources/scenario/sharding/case/ddl/index.xml |  28 ++-
 36 files changed, 1383 insertions(+), 74 deletions(-)

diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/reviser/index/EncryptIndexReviser.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/reviser/index/EncryptIndexReviser.java
index aa3e08ebb18..5e042121f7e 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/reviser/index/EncryptIndexReviser.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/reviser/index/EncryptIndexReviser.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.encrypt.metadata.reviser.index;
 
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.encrypt.rule.table.EncryptTable;
 import org.apache.shardingsphere.infra.metadata.database.schema.reviser.index.IndexReviser;
@@ -36,7 +37,8 @@ public final class EncryptIndexReviser implements IndexReviser<EncryptRule> {
     private final EncryptTable encryptTable;
     
     @Override
-    public Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final EncryptRule rule) {
+    public Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final Collection<TableMetaData> originalTableMetaDataList,
+                                          final EncryptRule rule) {
         if (originalMetaData.getColumns().isEmpty()) {
             return Optional.empty();
         }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/metadata/reviser/index/EncryptIndexReviserTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/metadata/reviser/index/EncryptIndexReviserTest.java
index e55b3886d56..8101a8edfbd 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/metadata/reviser/index/EncryptIndexReviserTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/metadata/reviser/index/EncryptIndexReviserTest.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.encrypt.rule.table.EncryptTable;
 import org.junit.jupiter.api.Test;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.Optional;
 
@@ -37,13 +38,14 @@ class EncryptIndexReviserTest {
     
     @Test
     void assertReviseWithEmptyColumn() {
-        assertFalse(new EncryptIndexReviser(mock(EncryptTable.class)).revise("foo_tbl", new IndexMetaData("foo_idx"), mock(EncryptRule.class)).isPresent());
+        assertFalse(new EncryptIndexReviser(mock(EncryptTable.class))
+                .revise("foo_tbl", new IndexMetaData("foo_idx"), Collections.emptyList(), mock(EncryptRule.class)).isPresent());
     }
     
     @Test
     void assertReviseWithColumns() {
         Optional<IndexMetaData> actual = new EncryptIndexReviser(mockEncryptTable())
-                .revise("foo_tbl", new IndexMetaData("foo_idx", Arrays.asList("cipher_col", "assisted_col", "other_col")), mock(EncryptRule.class));
+                .revise("foo_tbl", new IndexMetaData("foo_idx", Arrays.asList("cipher_col", "assisted_col", "other_col")), Collections.emptyList(), mock(EncryptRule.class));
         assertTrue(actual.isPresent());
         assertThat(actual.get().getName(), is("foo_idx"));
         assertThat(actual.get().getColumns(), is(new LinkedHashSet<>(Arrays.asList("col_1", "col_2", "other_col"))));
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/reviser/index/ShardingIndexReviser.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/reviser/index/ShardingIndexReviser.java
index aa906fd464e..fad32a7b728 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/reviser/index/ShardingIndexReviser.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/reviser/index/ShardingIndexReviser.java
@@ -19,12 +19,18 @@ package org.apache.shardingsphere.sharding.metadata.reviser.index;
 
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
+import org.apache.shardingsphere.infra.datanode.DataNode;
 import org.apache.shardingsphere.infra.metadata.database.schema.reviser.index.IndexReviser;
 import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
 import org.apache.shardingsphere.sharding.rule.ShardingRule;
 import org.apache.shardingsphere.sharding.rule.ShardingTable;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * Sharding index reviser.
@@ -35,13 +41,72 @@ public final class ShardingIndexReviser implements IndexReviser<ShardingRule> {
     private final ShardingTable shardingTable;
     
     @Override
-    public Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final ShardingRule rule) {
+    public Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final Collection<TableMetaData> originalTableMetaDataList,
+                                          final ShardingRule rule) {
+        return revise(tableName, originalMetaData, originalTableMetaDataList, Collections.emptyList(), rule);
+    }
+    
+    @Override
+    public Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final Collection<TableMetaData> originalTableMetaDataList,
+                                          final Collection<TableMetaData> schemaMetaDataRevisionCandidateTableMetaDataList, final ShardingRule rule) {
         if (shardingTable.getActualDataNodes().isEmpty()) {
             return Optional.empty();
         }
+        String actualTableName = tableName;
+        String logicIndexName = IndexMetaDataUtils.findGeneratedLogicIndexName(
+                originalMetaData.getName(), actualTableName,
+                findCandidateLogicIndexNames(originalMetaData, originalTableMetaDataList, schemaMetaDataRevisionCandidateTableMetaDataList)).orElse(originalMetaData.getName());
         IndexMetaData result = new IndexMetaData(
-                IndexMetaDataUtils.getLogicIndexName(originalMetaData.getName(), shardingTable.getActualDataNodes().iterator().next().getTableName()), originalMetaData.getColumns());
+                logicIndexName, originalMetaData.getColumns());
         result.setUnique(originalMetaData.isUnique());
         return Optional.of(result);
     }
+    
+    private Collection<String> findCandidateLogicIndexNames(final IndexMetaData originalMetaData, final Collection<TableMetaData> originalTableMetaDataList,
+                                                            final Collection<TableMetaData> schemaMetaDataRevisionCandidateTableMetaDataList) {
+        Collection<String> result = new LinkedHashSet<>();
+        result.add(getGeneratedAnonymousIndexName(originalMetaData));
+        for (TableMetaData eachTable : originalTableMetaDataList) {
+            if (isActualTable(eachTable.getName())) {
+                result.addAll(findCandidateLogicIndexNames(eachTable));
+            }
+        }
+        for (TableMetaData each : schemaMetaDataRevisionCandidateTableMetaDataList) {
+            if (isLogicTable(each.getName())) {
+                result.addAll(findCandidateLogicIndexNamesFromRevisionCandidate(each));
+            }
+        }
+        return result;
+    }
+    
+    private Collection<String> findCandidateLogicIndexNames(final TableMetaData tableMetaData) {
+        Collection<String> result = new LinkedHashSet<>();
+        for (IndexMetaData each : tableMetaData.getIndexes()) {
+            IndexMetaDataUtils.findGeneratedLogicIndexName(each.getName(), tableMetaData.getName(), Collections.emptyList())
+                    .filter(optional -> !optional.equals(each.getName())).ifPresent(result::add);
+            result.add(getGeneratedAnonymousIndexName(each));
+        }
+        return result;
+    }
+    
+    private Collection<String> findCandidateLogicIndexNamesFromRevisionCandidate(final TableMetaData tableMetaData) {
+        Collection<String> result = new LinkedHashSet<>();
+        for (IndexMetaData each : tableMetaData.getIndexes()) {
+            result.add(each.getName());
+            result.add(getGeneratedAnonymousIndexName(each));
+        }
+        return result;
+    }
+    
+    private boolean isActualTable(final String tableName) {
+        return shardingTable.getActualDataNodes().stream().map(DataNode::getTableName).anyMatch(each -> each.equalsIgnoreCase(tableName));
+    }
+    
+    private boolean isLogicTable(final String tableName) {
+        return shardingTable.getLogicTable().equalsIgnoreCase(tableName);
+    }
+    
+    private String getGeneratedAnonymousIndexName(final IndexMetaData originalMetaData) {
+        return originalMetaData.getColumns().stream().map(each -> each + "_").collect(Collectors.joining("", "", "idx"));
+    }
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/pojo/IndexToken.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/pojo/IndexToken.java
index 7c14604f2af..1f2ece72d73 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/pojo/IndexToken.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/pojo/IndexToken.java
@@ -76,7 +76,7 @@ public final class IndexToken extends SQLToken implements Substitutable, RouteUn
         }
         Map<String, String> logicAndActualTables = ShardingTokenUtils.getLogicAndActualTableMap(routeUnit, sqlStatementContext, rule);
         String actualTableName = logicTableName.map(logicAndActualTables::get).orElseGet(() -> logicAndActualTables.isEmpty() ? null : logicAndActualTables.values().iterator().next());
-        return IndexMetaDataUtils.getActualIndexName(identifier.getValue(), actualTableName);
+        return IndexMetaDataUtils.getActualIndexName(identifier.getValue(), actualTableName, sqlStatementContext.getSqlStatement().getDatabaseType());
     }
     
     private Optional<String> findLogicTableNameFromMetaData(final String logicIndexName) {
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/metadata/reviser/index/ShardingIndexReviserTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/metadata/reviser/index/ShardingIndexReviserTest.java
index 56ae9aa7ef5..de6d13666e0 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/metadata/reviser/index/ShardingIndexReviserTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/metadata/reviser/index/ShardingIndexReviserTest.java
@@ -17,13 +17,20 @@
 
 package org.apache.shardingsphere.sharding.metadata.reviser.index;
 
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
 import org.apache.shardingsphere.infra.datanode.DataNode;
+import org.apache.shardingsphere.infra.metadata.database.schema.reviser.MetaDataReviseEntry;
+import org.apache.shardingsphere.infra.metadata.database.schema.reviser.index.IndexReviseEngine;
+import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.sharding.rule.ShardingRule;
 import org.apache.shardingsphere.sharding.rule.ShardingTable;
 import org.junit.jupiter.api.Test;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Optional;
 
@@ -35,21 +42,123 @@ import static org.mockito.Mockito.when;
 
 class ShardingIndexReviserTest {
     
+    private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");
+    
     @Test
     void assertReviseWithEmptyActualDataNode() {
-        assertThat(new ShardingIndexReviser(mock(ShardingTable.class)).revise("foo_tbl", new IndexMetaData("foo_idx"), mock(ShardingRule.class)), is(Optional.empty()));
+        assertThat(new ShardingIndexReviser(mock(ShardingTable.class)).revise("foo_tbl", new IndexMetaData("foo_idx"), Collections.emptyList(), mock(ShardingRule.class)),
+                is(Optional.empty()));
     }
     
     @Test
-    void assertReviseWithActualDataNodes() {
-        Optional<IndexMetaData> actual = new ShardingIndexReviser(mockShardingTable()).revise("tbl_0", new IndexMetaData("foo_idx", Collections.singletonList("foo_col")), mock(ShardingRule.class));
+    void assertReviseWithHashedActualIndexName() {
+        Optional<IndexMetaData> actual = revise("tbl_0", new IndexMetaData(IndexMetaDataUtils.getActualIndexName(
+                "named_index_boundary_case_abcdefghijklmnopqrstuvwxyz", "tbl_0", databaseType), Collections.singletonList("foo_col")));
         assertTrue(actual.isPresent());
-        assertThat(actual.get().getName(), is("foo_idx"));
+        assertThat(actual.get().getName(), is("named_index_boundary_case_abcdefghijklmnopqrstuvwxyz"));
         assertThat(actual.get().getColumns().size(), is(1));
     }
     
+    @Test
+    void assertReviseWithTruncatedNamedActualIndexNameUsingCandidates() {
+        String logicIndexName = "named_index_boundary_case_abcdefghijklmnopqrstuvwxyz_0123456789";
+        IndexMetaData truncatedActualIndexMetaData = new IndexMetaData(
+                IndexMetaDataUtils.getActualIndexName(logicIndexName, "tbl_0", databaseType), Collections.singletonList("foo_col"));
+        IndexMetaData legacyActualIndexMetaData = new IndexMetaData(IndexMetaDataUtils.getLegacyActualIndexName(logicIndexName, "tbl_1"), Collections.singletonList("foo_col"));
+        Optional<IndexMetaData> actual = revise("tbl_0", truncatedActualIndexMetaData,
+                tableMetaData("tbl_0", truncatedActualIndexMetaData), tableMetaData("tbl_1", legacyActualIndexMetaData));
+        assertTrue(actual.isPresent());
+        assertThat(actual.get().getName(), is(logicIndexName));
+    }
+    
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Test
+    void assertReviseThroughSharedIndexReviseEngineWithTruncatedNamedActualIndexName() {
+        String logicIndexName = "named_index_boundary_case_abcdefghijklmnopqrstuvwxyz_0123456789";
+        IndexMetaData truncatedActualIndexMetaData = new IndexMetaData(
+                IndexMetaDataUtils.getActualIndexName(logicIndexName, "tbl_0", databaseType), Collections.singletonList("foo_col"));
+        IndexMetaData legacyActualIndexMetaData = new IndexMetaData(IndexMetaDataUtils.getLegacyActualIndexName(logicIndexName, "tbl_1"), Collections.singletonList("foo_col"));
+        ShardingRule rule = mock(ShardingRule.class);
+        MetaDataReviseEntry reviseEntry = mock(MetaDataReviseEntry.class);
+        ShardingIndexReviser indexReviser = new ShardingIndexReviser(mockShardingTable());
+        when(reviseEntry.getIndexReviser(rule, "tbl_0")).thenReturn(Optional.of(indexReviser));
+        Collection<IndexMetaData> actual = new IndexReviseEngine<>(rule, reviseEntry).revise("tbl_0", Collections.singleton(truncatedActualIndexMetaData),
+                Arrays.asList(tableMetaData("tbl_0", truncatedActualIndexMetaData), tableMetaData("tbl_1", legacyActualIndexMetaData)));
+        assertThat(actual.size(), is(1));
+        assertThat(actual.iterator().next().getName(), is(logicIndexName));
+    }
+    
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Test
+    void assertReviseThroughSharedIndexReviseEngineWithAllTruncatedNamedActualIndexNamesUsingRevisionCandidates() {
+        String logicIndexName = "named_index_boundary_case_abcdefghijklmnopqrstuvwxyz_0123456789";
+        IndexMetaData firstTruncatedActualIndexMetaData = new IndexMetaData(
+                IndexMetaDataUtils.getActualIndexName(logicIndexName, "tbl_0", databaseType), Collections.singletonList("foo_col"));
+        IndexMetaData secondTruncatedActualIndexMetaData = new IndexMetaData(
+                IndexMetaDataUtils.getActualIndexName(logicIndexName, "tbl_1", databaseType), Collections.singletonList("foo_col"));
+        ShardingRule rule = mock(ShardingRule.class);
+        MetaDataReviseEntry reviseEntry = mock(MetaDataReviseEntry.class);
+        ShardingIndexReviser indexReviser = new ShardingIndexReviser(mockShardingTable());
+        when(reviseEntry.getIndexReviser(rule, "tbl_0")).thenReturn(Optional.of(indexReviser));
+        Collection<IndexMetaData> actual = new IndexReviseEngine<>(rule, reviseEntry).revise("tbl_0", Collections.singleton(firstTruncatedActualIndexMetaData),
+                Arrays.asList(tableMetaData("tbl_0", firstTruncatedActualIndexMetaData), tableMetaData("tbl_1", secondTruncatedActualIndexMetaData)),
+                Collections.singleton(tableMetaData("tbl", new IndexMetaData(logicIndexName, Collections.singletonList("foo_col")))));
+        assertThat(actual.size(), is(1));
+        assertThat(actual.iterator().next().getName(), is(logicIndexName));
+    }
+    
+    @Test
+    void assertReviseWithExactHashLikeIndexName() {
+        Optional<IndexMetaData> actual = revise("tbl_0", new IndexMetaData("foo_h12345678", Collections.singletonList("foo_col")));
+        assertTrue(actual.isPresent());
+        assertThat(actual.get().getName(), is("foo_h12345678"));
+    }
+    
+    @Test
+    void assertReviseWithExactTruncationLikeIndexName() {
+        Optional<IndexMetaData> actual = revise("tbl_0", new IndexMetaData("foo_t12345678", Collections.singletonList("foo_col")));
+        assertTrue(actual.isPresent());
+        assertThat(actual.get().getName(), is("foo_t12345678"));
+    }
+    
+    @Test
+    void assertReviseWithLegacyActualIndexName() {
+        Optional<IndexMetaData> actual = revise("tbl_0",
+                new IndexMetaData(IndexMetaDataUtils.getLegacyActualIndexName("foo_idx", "tbl_0"), Collections.singletonList("foo_col")));
+        assertTrue(actual.isPresent());
+        assertThat(actual.get().getName(), is("foo_idx"));
+    }
+    
+    @Test
+    void assertReviseWithLegacyActualIndexNameForSecondActualTable() {
+        Optional<IndexMetaData> actual = revise("tbl_1",
+                new IndexMetaData(IndexMetaDataUtils.getLegacyActualIndexName("foo_idx", "tbl_1"), Collections.singletonList("foo_col")));
+        assertTrue(actual.isPresent());
+        assertThat(actual.get().getName(), is("foo_idx"));
+    }
+    
+    @Test
+    void assertReviseWithTruncatedAnonymousActualIndexName() {
+        String logicIndexName = "very_long_status_column_name_for_sharding_rewrite_validation_account_identifier_idx";
+        Optional<IndexMetaData> actual = revise("tbl_0", new IndexMetaData(IndexMetaDataUtils.getActualIndexName(logicIndexName, "tbl_0", databaseType),
+                Arrays.asList("very_long_status_column_name_for_sharding_rewrite_validation", "account_identifier")));
+        assertTrue(actual.isPresent());
+        assertThat(actual.get().getName(), is(logicIndexName));
+    }
+    
+    private Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final TableMetaData... originalTableMetaDataList) {
+        return new ShardingIndexReviser(mockShardingTable()).revise(tableName, originalMetaData,
+                0 == originalTableMetaDataList.length ? Collections.singleton(tableMetaData(tableName, originalMetaData)) : Arrays.asList(originalTableMetaDataList),
+                mock(ShardingRule.class));
+    }
+    
+    private static TableMetaData tableMetaData(final String tableName, final IndexMetaData... indexes) {
+        return new TableMetaData(tableName, Collections.emptyList(), Arrays.asList(indexes), Collections.emptyList());
+    }
+    
     private static ShardingTable mockShardingTable() {
         ShardingTable result = mock(ShardingTable.class);
+        when(result.getLogicTable()).thenReturn("tbl");
         when(result.getActualDataNodes()).thenReturn(Arrays.asList(new DataNode("foo_schema", (String) null, "tbl_0"), new DataNode("foo_schema", (String) null, "tbl_1")));
         return result;
     }
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/pojo/IndexTokenTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/pojo/IndexTokenTest.java
index 1488e493606..267482f8110 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/pojo/IndexTokenTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/pojo/IndexTokenTest.java
@@ -22,6 +22,7 @@ import org.apache.shardingsphere.infra.binder.context.statement.type.CommonSQLSt
 import org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
 import org.apache.shardingsphere.infra.route.context.RouteMapper;
 import org.apache.shardingsphere.infra.route.context.RouteUnit;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
@@ -41,12 +42,13 @@ import static org.mockito.Mockito.when;
 
 class IndexTokenTest {
     
-    private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");
     
     @Test
     void assertToStringWithNotShardingTable() {
         SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
         when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.emptyList());
+        when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
         IndexToken indexToken = new IndexToken(0, 0, new IdentifierValue("foo_idx"), selectStatementContext, mock(ShardingRule.class), mockSchema());
         assertThat(indexToken.toString(mockRouteUnit()), is("foo_idx"));
     }
@@ -55,10 +57,11 @@ class IndexTokenTest {
     void assertToStringWithShardingTable() {
         SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
         when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.emptyList());
+        when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
         ShardingRule rule = mock(ShardingRule.class);
         when(rule.isShardingTable("foo_tbl")).thenReturn(true);
         IndexToken indexToken = new IndexToken(0, 0, new IdentifierValue("foo_idx"), selectStatementContext, rule, mockSchema());
-        assertThat(indexToken.toString(mockRouteUnit()), is("foo_idx_foo_tbl_0"));
+        assertThat(indexToken.toString(mockRouteUnit()), is(IndexMetaDataUtils.getActualIndexName("foo_idx", "foo_tbl_0", databaseType)));
     }
     
     @Test
@@ -66,7 +69,16 @@ class IndexTokenTest {
         CreateIndexStatement sqlStatement = CreateIndexStatement.builder().databaseType(databaseType).build();
         CommonSQLStatementContext sqlStatementContext = new CommonSQLStatementContext(sqlStatement);
         IndexToken indexToken = new IndexToken(0, 0, new IdentifierValue("bar_idx"), sqlStatementContext, mock(ShardingRule.class), mockSchema());
-        assertThat(indexToken.toString(mockRouteUnit()), is(" bar_idx_foo_tbl_0 "));
+        assertThat(indexToken.toString(mockRouteUnit()), is(" " + IndexMetaDataUtils.getActualIndexName("bar_idx", "foo_tbl_0", databaseType) + " "));
+    }
+    
+    @Test
+    void assertToStringWithLongGeneratedIndex() {
+        CreateIndexStatement sqlStatement = CreateIndexStatement.builder().databaseType(databaseType).build();
+        CommonSQLStatementContext sqlStatementContext = new CommonSQLStatementContext(sqlStatement);
+        String logicIndexName = "very_long_generated_index_boundary_case_for_sharding_length_safety_validation";
+        IndexToken indexToken = new IndexToken(0, 0, new IdentifierValue(logicIndexName), sqlStatementContext, mock(ShardingRule.class), mockSchema());
+        assertThat(indexToken.toString(mockRouteUnit()), is(" " + IndexMetaDataUtils.getActualIndexName(logicIndexName, "foo_tbl_0", databaseType) + " "));
     }
     
     private ShardingSphereSchema mockSchema() {
diff --git a/features/sharding/dialect/mysql/src/main/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowCreateTableMergedResult.java b/features/sharding/dialect/mysql/src/main/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowCreateTableMergedResult.java
index 9c5c5b5736d..2464fdb7702 100644
--- a/features/sharding/dialect/mysql/src/main/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowCreateTableMergedResult.java
+++ b/features/sharding/dialect/mysql/src/main/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowCreateTableMergedResult.java
@@ -81,14 +81,16 @@ public final class MySQLShardingShowCreateTableMergedResult extends MySQLShardin
     
     private void replaceIndexes(final MemoryQueryResultRow memoryResultSetRow, final String actualTableName, final ShardingSphereTable table) {
         for (ShardingSphereIndex each : table.getAllIndexes()) {
-            String actualIndexName = IndexMetaDataUtils.getActualIndexName(each.getName(), actualTableName);
+            String actualIndexName = IndexMetaDataUtils.getShortenedActualIndexName(each.getName(), actualTableName);
             memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replace(actualIndexName, each.getName()));
+            String legacyActualIndexName = IndexMetaDataUtils.getLegacyActualIndexName(each.getName(), actualTableName);
+            memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replace(legacyActualIndexName, each.getName()));
         }
     }
     
     private void replaceConstraints(final MemoryQueryResultRow memoryResultSetRow, final String actualTableName, final ShardingSphereTable table, final ShardingRule rule) {
         for (ShardingSphereConstraint each : table.getAllConstraints()) {
-            String actualIndexName = IndexMetaDataUtils.getActualIndexName(each.getName(), actualTableName);
+            String actualIndexName = IndexMetaDataUtils.getLegacyActualIndexName(each.getName(), actualTableName);
             memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replace(actualIndexName, each.getName()));
             Optional<ShardingTable> shardingTable = rule.findShardingTable(each.getReferencedTableName());
             if (!shardingTable.isPresent()) {
diff --git a/features/sharding/dialect/mysql/src/main/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowIndexMergedResult.java b/features/sharding/dialect/mysql/src/main/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowIndexMergedResult.java
index 1b1e930f909..653894332e6 100644
--- a/features/sharding/dialect/mysql/src/main/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowIndexMergedResult.java
+++ b/features/sharding/dialect/mysql/src/main/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowIndexMergedResult.java
@@ -27,9 +27,11 @@ import org.apache.shardingsphere.sharding.rule.ShardingRule;
 import org.apache.shardingsphere.sharding.rule.ShardingTable;
 
 import java.sql.SQLException;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * Sharding merged result for show index for MySQL.
@@ -51,8 +53,13 @@ public final class MySQLShardingShowIndexMergedResult extends MemoryMergedResult
                 String actualTableName = memoryResultSetRow.getCell(1).toString();
                 String actualIndexName = memoryResultSetRow.getCell(3).toString();
                 Optional<ShardingTable> shardingTable = shardingRule.findShardingTableByActualTable(actualTableName);
-                shardingTable.ifPresent(optional -> memoryResultSetRow.setCell(1, optional.getLogicTable()));
-                memoryResultSetRow.setCell(3, IndexMetaDataUtils.getLogicIndexName(actualIndexName, actualTableName));
+                Collection<String> candidateLogicIndexNames = new LinkedList<>();
+                if (shardingTable.isPresent()) {
+                    String logicTableName = shardingTable.get().getLogicTable();
+                    memoryResultSetRow.setCell(1, logicTableName);
+                    candidateLogicIndexNames = schema.getTable(logicTableName).getAllIndexes().stream().map(eachIndex -> eachIndex.getName()).collect(Collectors.toList());
+                }
+                memoryResultSetRow.setCell(3, IndexMetaDataUtils.findGeneratedLogicIndexName(actualIndexName, actualTableName, candidateLogicIndexNames).orElse(actualIndexName));
                 result.add(memoryResultSetRow);
             }
         }
diff --git a/features/sharding/dialect/mysql/src/test/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowCreateTableMergedResultTest.java b/features/sharding/dialect/mysql/src/test/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowCreateTableMergedResultTest.java
index e72aa5cde51..26e4d0cc201 100644
--- a/features/sharding/dialect/mysql/src/test/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowCreateTableMergedResultTest.java
+++ b/features/sharding/dialect/mysql/src/test/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowCreateTableMergedResultTest.java
@@ -23,8 +23,10 @@ import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementCont
 import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
 import org.apache.shardingsphere.infra.instance.ComputeNodeInstanceContext;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereConstraint;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
 import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
 import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
 import org.apache.shardingsphere.sharding.rule.ShardingRule;
@@ -132,6 +134,29 @@ class MySQLShardingShowCreateTableMergedResultTest {
                 + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin"));
     }
     
+    @Test
+    void assertGetValueWithLegacyIndexName() throws SQLException {
+        MySQLShardingShowCreateTableMergedResult actual = new MySQLShardingShowCreateTableMergedResult(
+                rule, mock(SQLStatementContext.class), createSchemaWithIndex(),
+                Collections.singletonList(mockQueryResultWithIndex(IndexMetaDataUtils.getLegacyActualIndexName("foo_idx", "foo_tbl_0"))));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(2, String.class), is("CREATE TABLE `foo_tbl` (\n"
+                + "  `id` int(11) NOT NULL,\n"
+                + "  KEY `foo_idx` (`id`)\n"
+                + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin"));
+    }
+    
+    @Test
+    void assertGetValueWithShortenedIndexName() throws SQLException {
+        MySQLShardingShowCreateTableMergedResult actual = new MySQLShardingShowCreateTableMergedResult(
+                rule, mock(SQLStatementContext.class), createSchemaWithIndex(), Collections.singletonList(mockQueryResultWithIndex(IndexMetaDataUtils.getActualIndexName("foo_idx", "foo_tbl_0"))));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(2, String.class), is("CREATE TABLE `foo_tbl` (\n"
+                + "  `id` int(11) NOT NULL,\n"
+                + "  KEY `foo_idx` (`id`)\n"
+                + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin"));
+    }
+    
     private QueryResult mockQueryResultWithoutTableRule() throws SQLException {
         QueryResult result = mock(QueryResult.class, RETURNS_DEEP_STUBS);
         when(result.getMetaData().getColumnCount()).thenReturn(2);
@@ -148,4 +173,22 @@ class MySQLShardingShowCreateTableMergedResultTest {
                 + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin");
         return result;
     }
+    
+    private ShardingSphereSchema createSchemaWithIndex() {
+        ShardingSphereTable table =
+                new ShardingSphereTable("foo_tbl", Collections.emptyList(), Collections.singleton(new ShardingSphereIndex("foo_idx", Collections.emptyList(), false)), Collections.emptyList());
+        return new ShardingSphereSchema("foo_db", mock(DatabaseType.class), Collections.singleton(table), Collections.emptyList());
+    }
+    
+    private QueryResult mockQueryResultWithIndex(final String actualIndexName) throws SQLException {
+        QueryResult result = mock(QueryResult.class, RETURNS_DEEP_STUBS);
+        when(result.getMetaData().getColumnCount()).thenReturn(2);
+        when(result.next()).thenReturn(true, false);
+        when(result.getValue(1, Object.class)).thenReturn("foo_tbl_0");
+        when(result.getValue(2, Object.class)).thenReturn("CREATE TABLE `foo_tbl_0` (\n"
+                + "  `id` int(11) NOT NULL,\n"
+                + "  KEY `" + actualIndexName + "` (`id`)\n"
+                + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin");
+        return result;
+    }
 }
diff --git a/features/sharding/dialect/mysql/src/test/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowIndexMergedResultTest.java b/features/sharding/dialect/mysql/src/test/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowIndexMergedResultTest.java
index 165a17c5f44..ea2d05e434e 100644
--- a/features/sharding/dialect/mysql/src/test/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowIndexMergedResultTest.java
+++ b/features/sharding/dialect/mysql/src/test/java/org/apache/shardingsphere/sharding/merge/mysql/type/MySQLShardingShowIndexMergedResultTest.java
@@ -19,8 +19,12 @@ package org.apache.shardingsphere.sharding.merge.mysql.type;
 
 import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
 import org.apache.shardingsphere.sharding.rule.ShardingRule;
+import org.apache.shardingsphere.sharding.rule.ShardingTable;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
@@ -28,7 +32,10 @@ import org.mockito.junit.jupiter.MockitoExtension;
 
 import java.sql.SQLException;
 import java.util.Collections;
+import java.util.Optional;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -54,13 +61,51 @@ class MySQLShardingShowIndexMergedResultTest {
         assertTrue(new MySQLShardingShowIndexMergedResult(rule, mock(SQLStatementContext.class), schema, Collections.singletonList(mockQueryResult())).next());
     }
     
+    @Test
+    void assertGetValueWithShortenedIndexName() throws SQLException {
+        MySQLShardingShowIndexMergedResult actual = new MySQLShardingShowIndexMergedResult(rule, mock(SQLStatementContext.class), schema,
+                Collections.singletonList(mockQueryResult(IndexMetaDataUtils.getActualIndexName("t_order_index", "t_order_0"))));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(3, String.class), is("t_order_index"));
+    }
+    
+    @Test
+    void assertGetValueWithLogicalIndexNameEndingWithHashLikeSuffix() throws SQLException {
+        ShardingTable shardingTable = mock(ShardingTable.class);
+        when(rule.findShardingTableByActualTable("t_order_0")).thenReturn(Optional.of(shardingTable));
+        when(shardingTable.getLogicTable()).thenReturn("t_order");
+        when(schema.getTable("t_order")).thenReturn(new ShardingSphereTable("t_order", Collections.emptyList(),
+                Collections.singleton(new ShardingSphereIndex("foo_h12345678", Collections.emptyList(), false)), Collections.emptyList()));
+        MySQLShardingShowIndexMergedResult actual = new MySQLShardingShowIndexMergedResult(rule, mock(SQLStatementContext.class), schema,
+                Collections.singletonList(mockQueryResult("foo_h12345678")));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(3, String.class), is("foo_h12345678"));
+    }
+    
+    @Test
+    void assertGetValueWithLogicalIndexNameEndingWithTruncationLikeSuffix() throws SQLException {
+        ShardingTable shardingTable = mock(ShardingTable.class);
+        when(rule.findShardingTableByActualTable("t_order_0")).thenReturn(Optional.of(shardingTable));
+        when(shardingTable.getLogicTable()).thenReturn("t_order");
+        when(schema.getTable("t_order")).thenReturn(new ShardingSphereTable("t_order", Collections.emptyList(),
+                Collections.singleton(new ShardingSphereIndex("foo_t12345678", Collections.emptyList(), false)), Collections.emptyList()));
+        MySQLShardingShowIndexMergedResult actual = new MySQLShardingShowIndexMergedResult(rule, mock(SQLStatementContext.class), schema,
+                Collections.singletonList(mockQueryResult("foo_t12345678")));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(3, String.class), is("foo_t12345678"));
+    }
+    
     private QueryResult mockQueryResult() throws SQLException {
+        return mockQueryResult("t_order_index_t_order_0");
+    }
+    
+    private QueryResult mockQueryResult(final String actualIndexName) throws SQLException {
         QueryResult result = mock(QueryResult.class, RETURNS_DEEP_STUBS);
         when(result.getMetaData().getColumnCount()).thenReturn(3);
         when(result.next()).thenReturn(true, false);
         when(result.getValue(1, Object.class)).thenReturn("t_order_0");
         when(result.getValue(2, Object.class)).thenReturn(1);
-        when(result.getValue(3, Object.class)).thenReturn("t_order_index_t_order_0");
+        when(result.getValue(3, Object.class)).thenReturn(actualIndexName);
         return result;
     }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseFactory.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseFactory.java
index 3f974f7b9e6..d42d3d8a4c2 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseFactory.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseFactory.java
@@ -38,6 +38,7 @@ import org.apache.shardingsphere.infra.rule.builder.database.DatabaseRulesBuilde
 
 import java.sql.SQLException;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.Map;
@@ -82,13 +83,7 @@ public final class ShardingSphereDatabaseFactory {
      */
     public static ShardingSphereDatabase create(final String name, final DatabaseType protocolType, final DatabaseConfiguration databaseConfig,
                                                 final ConfigurationProperties props, final ComputeNodeInstanceContext computeNodeInstanceContext) throws SQLException {
-        ResourceMetaData resourceMetaData = new ResourceMetaData(databaseConfig.getDataSources(), databaseConfig.getStorageUnits());
-        DatabaseIdentifierContext identifierContext = DatabaseIdentifierContextFactory.create(protocolType, resourceMetaData, props);
-        Collection<ShardingSphereRule> databaseRules = DatabaseRulesBuilder.build(name, protocolType, databaseConfig, computeNodeInstanceContext, resourceMetaData);
-        Map<String, ShardingSphereSchema> schemas = new ConcurrentHashMap<>(GenericSchemaBuilder.build(protocolType,
-                new GenericSchemaBuilderMaterial(resourceMetaData.getStorageUnits(), databaseRules, props, new DatabaseTypeRegistry(protocolType).getDefaultSchemaName(name), identifierContext)));
-        SystemSchemaBuilder.build(name, protocolType, props).forEach(schemas::putIfAbsent);
-        return new ShardingSphereDatabase(name, protocolType, resourceMetaData, new RuleMetaData(databaseRules), schemas.values(), props);
+        return createWithSchemaMetaDataRevisionCandidates(name, protocolType, databaseConfig, props, computeNodeInstanceContext, Collections.emptyList());
     }
     
     /**
@@ -124,4 +119,29 @@ public final class ShardingSphereDatabaseFactory {
         Collection<ShardingSphereRule> rules = DatabaseRulesBuilder.build(name, protocolType, databaseConfig, computeNodeInstanceContext, resourceMetaData);
         return new ShardingSphereDatabase(name, protocolType, resourceMetaData, new RuleMetaData(rules), schemas, props);
     }
+    
+    /**
+     * Create database with schema meta data revision candidate schemas.
+     *
+     * @param name database name
+     * @param protocolType database protocol type
+     * @param databaseConfig database configuration
+     * @param props configuration properties
+     * @param computeNodeInstanceContext compute node instance context
+     * @param schemaMetaDataRevisionCandidateSchemas schema meta data revision candidate schemas
+     * @return created database
+     * @throws SQLException SQL exception
+     */
+    public static ShardingSphereDatabase createWithSchemaMetaDataRevisionCandidates(final String name, final DatabaseType protocolType, final DatabaseConfiguration databaseConfig,
+                                                                                    final ConfigurationProperties props, final ComputeNodeInstanceContext computeNodeInstanceContext,
+                                                                                    final Collection<ShardingSphereSchema> schemaMetaDataRevisionCandidateSchemas) throws SQLException {
+        ResourceMetaData resourceMetaData = new ResourceMetaData(databaseConfig.getDataSources(), databaseConfig.getStorageUnits());
+        DatabaseIdentifierContext identifierContext = DatabaseIdentifierContextFactory.create(protocolType, resourceMetaData, props);
+        Collection<ShardingSphereRule> databaseRules = DatabaseRulesBuilder.build(name, protocolType, databaseConfig, computeNodeInstanceContext, resourceMetaData);
+        Map<String, ShardingSphereSchema> schemas = new ConcurrentHashMap<>(GenericSchemaBuilder.build(protocolType,
+                new GenericSchemaBuilderMaterial(resourceMetaData.getStorageUnits(), databaseRules, props, new DatabaseTypeRegistry(protocolType).getDefaultSchemaName(name),
+                        identifierContext, schemaMetaDataRevisionCandidateSchemas)));
+        SystemSchemaBuilder.build(name, protocolType, props).forEach(schemas::putIfAbsent);
+        return new ShardingSphereDatabase(name, protocolType, resourceMetaData, new RuleMetaData(databaseRules), schemas.values(), props);
+    }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/builder/GenericSchemaBuilderMaterial.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/builder/GenericSchemaBuilderMaterial.java
index 4ea14362620..19deec6a6fd 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/builder/GenericSchemaBuilderMaterial.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/builder/GenericSchemaBuilderMaterial.java
@@ -18,19 +18,19 @@
 package org.apache.shardingsphere.infra.metadata.database.schema.builder;
 
 import lombok.Getter;
-import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Map;
 
 /**
  * ShardingSphere schema builder material.
  */
-@RequiredArgsConstructor
 @Getter
 public final class GenericSchemaBuilderMaterial {
     
@@ -43,4 +43,22 @@ public final class GenericSchemaBuilderMaterial {
     private final String defaultSchemaName;
     
     private final DatabaseIdentifierContext identifierContext;
+    
+    private final Collection<ShardingSphereSchema> schemaMetaDataRevisionCandidateSchemas;
+    
+    public GenericSchemaBuilderMaterial(final Map<String, StorageUnit> storageUnits, final Collection<ShardingSphereRule> rules, final ConfigurationProperties props,
+                                        final String defaultSchemaName, final DatabaseIdentifierContext identifierContext) {
+        this(storageUnits, rules, props, defaultSchemaName, identifierContext, Collections.emptyList());
+    }
+    
+    public GenericSchemaBuilderMaterial(final Map<String, StorageUnit> storageUnits, final Collection<ShardingSphereRule> rules, final ConfigurationProperties props,
+                                        final String defaultSchemaName, final DatabaseIdentifierContext identifierContext,
+                                        final Collection<ShardingSphereSchema> schemaMetaDataRevisionCandidateSchemas) {
+        this.storageUnits = storageUnits;
+        this.rules = rules;
+        this.props = props;
+        this.defaultSchemaName = defaultSchemaName;
+        this.identifierContext = identifierContext;
+        this.schemaMetaDataRevisionCandidateSchemas = schemaMetaDataRevisionCandidateSchemas;
+    }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/MetaDataReviseEngine.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/MetaDataReviseEngine.java
index d1d510d7f3d..ea91c641b70 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/MetaDataReviseEngine.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/MetaDataReviseEngine.java
@@ -64,7 +64,8 @@ public final class MetaDataReviseEngine {
         }
         Map<String, ShardingSphereSchema> result = new HashMap<>(schemaMetaDataMap.size(), 1F);
         for (Entry<String, SchemaMetaData> entry : schemaMetaDataMap.entrySet()) {
-            SchemaMetaData schemaMetaData = new SchemaMetaDataReviseEngine(rules, material.getProps()).revise(entry.getValue());
+            SchemaMetaData schemaMetaData = new SchemaMetaDataReviseEngine(
+                    rules, material.getProps(), material.getSchemaMetaDataRevisionCandidateSchemas()).revise(entry.getValue());
             result.put(entry.getKey(), new ShardingSphereSchema(entry.getKey(), protocolType, convertToTables(schemaMetaData.getTables()), new LinkedList<>()));
         }
         return result;
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviseEngine.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviseEngine.java
index d04155ebd84..a1ace5193f8 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviseEngine.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviseEngine.java
@@ -19,16 +19,18 @@ package org.apache.shardingsphere.infra.metadata.database.schema.reviser.index;
 
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
 import org.apache.shardingsphere.infra.metadata.database.schema.reviser.MetaDataReviseEntry;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
 /**
  * Index revise engine.
- * 
+ *
  * @param <T> type of rule
  */
 @RequiredArgsConstructor
@@ -46,10 +48,40 @@ public final class IndexReviseEngine<T extends ShardingSphereRule> {
      * @return revised index meta data
      */
     public Collection<IndexMetaData> revise(final String tableName, final Collection<IndexMetaData> originalMetaDataList) {
+        return revise(tableName, originalMetaDataList,
+                Collections.singleton(new TableMetaData(tableName, Collections.emptyList(), originalMetaDataList, Collections.emptyList())));
+    }
+    
+    /**
+     * Revise index meta data.
+     *
+     * @param tableName table name
+     * @param originalMetaDataList original index meta data list
+     * @param originalTableMetaDataList original table meta data list
+     * @return revised index meta data
+     */
+    public Collection<IndexMetaData> revise(final String tableName, final Collection<IndexMetaData> originalMetaDataList,
+                                            final Collection<TableMetaData> originalTableMetaDataList) {
+        return revise(tableName, originalMetaDataList, originalTableMetaDataList, Collections.emptyList());
+    }
+    
+    /**
+     * Revise index meta data.
+     *
+     * @param tableName table name
+     * @param originalMetaDataList original index meta data list
+     * @param originalTableMetaDataList original table meta data list
+     * @param schemaMetaDataRevisionCandidateTableMetaDataList schema meta data revision candidate table meta data list
+     * @return revised index meta data
+     */
+    public Collection<IndexMetaData> revise(final String tableName, final Collection<IndexMetaData> originalMetaDataList,
+                                            final Collection<TableMetaData> originalTableMetaDataList,
+                                            final Collection<TableMetaData> schemaMetaDataRevisionCandidateTableMetaDataList) {
         Optional<? extends IndexReviser<T>> reviser = reviseEntry.getIndexReviser(rule, tableName);
         return reviser.isPresent()
                 ? originalMetaDataList.stream()
-                        .map(each -> reviser.get().revise(tableName, each, rule)).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList())
+                        .map(each -> reviser.get().revise(tableName, each, originalTableMetaDataList, schemaMetaDataRevisionCandidateTableMetaDataList, rule))
+                        .filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList())
                 : originalMetaDataList;
     }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviser.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviser.java
index 40e20c193bf..035a63aa4f5 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviser.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviser.java
@@ -18,13 +18,15 @@
 package org.apache.shardingsphere.infra.metadata.database.schema.reviser.index;
 
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
+import java.util.Collection;
 import java.util.Optional;
 
 /**
  * Index reviser.
- * 
+ *
  * @param <T> type of rule
  */
 public interface IndexReviser<T extends ShardingSphereRule> {
@@ -34,8 +36,24 @@ public interface IndexReviser<T extends ShardingSphereRule> {
      *
      * @param tableName table name
      * @param originalMetaData original index meta data
+     * @param originalTableMetaDataList original table meta data list
+     * @param schemaMetaDataRevisionCandidateTableMetaDataList schema meta data revision candidate table meta data list
+     * @param rule rule
+     * @return revised index meta data
+     */
+    default Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final Collection<TableMetaData> originalTableMetaDataList,
+                                           final Collection<TableMetaData> schemaMetaDataRevisionCandidateTableMetaDataList, final T rule) {
+        return revise(tableName, originalMetaData, originalTableMetaDataList, rule);
+    }
+    
+    /**
+     * Revise index meta data.
+     *
+     * @param tableName table name
+     * @param originalMetaData original index meta data
+     * @param originalTableMetaDataList original table meta data list
      * @param rule rule
      * @return revised index meta data
      */
-    Optional<IndexMetaData> revise(String tableName, IndexMetaData originalMetaData, T rule);
+    Optional<IndexMetaData> revise(String tableName, IndexMetaData originalMetaData, Collection<TableMetaData> originalTableMetaDataList, T rule);
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/schema/SchemaMetaDataReviseEngine.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/schema/SchemaMetaDataReviseEngine.java
index 6d6be090085..3de3069497a 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/schema/SchemaMetaDataReviseEngine.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/schema/SchemaMetaDataReviseEngine.java
@@ -17,16 +17,20 @@
 
 package org.apache.shardingsphere.infra.metadata.database.schema.reviser.schema;
 
-import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.SchemaMetaData;
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
 import org.apache.shardingsphere.infra.metadata.database.schema.reviser.MetaDataReviseEntry;
 import org.apache.shardingsphere.infra.metadata.database.schema.reviser.table.TableMetaDataReviseEngine;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.stream.Collectors;
@@ -34,13 +38,25 @@ import java.util.stream.Collectors;
 /**
  * Schema meta data revise engine.
  */
-@RequiredArgsConstructor
 public final class SchemaMetaDataReviseEngine {
     
     private final Collection<ShardingSphereRule> rules;
     
     private final ConfigurationProperties props;
     
+    private final Collection<ShardingSphereSchema> schemaMetaDataRevisionCandidateSchemas;
+    
+    public SchemaMetaDataReviseEngine(final Collection<ShardingSphereRule> rules, final ConfigurationProperties props) {
+        this(rules, props, Collections.emptyList());
+    }
+    
+    public SchemaMetaDataReviseEngine(final Collection<ShardingSphereRule> rules, final ConfigurationProperties props,
+                                      final Collection<ShardingSphereSchema> schemaMetaDataRevisionCandidateSchemas) {
+        this.rules = rules;
+        this.props = props;
+        this.schemaMetaDataRevisionCandidateSchemas = schemaMetaDataRevisionCandidateSchemas;
+    }
+    
     /**
      * Revise schema meta data.
      *
@@ -58,13 +74,32 @@ public final class SchemaMetaDataReviseEngine {
     
     private <T extends ShardingSphereRule> SchemaMetaData revise(final SchemaMetaData originalMetaData, final T rule, final MetaDataReviseEntry<T> reviseEntry) {
         TableMetaDataReviseEngine<T> tableMetaDataReviseEngine = new TableMetaDataReviseEngine<>(rule, reviseEntry);
+        Collection<TableMetaData> schemaMetaDataRevisionCandidateTableMetaDataList = createSchemaMetaDataRevisionCandidateTableMetaDataList(originalMetaData);
         Optional<? extends SchemaTableAggregationReviser<T>> aggregationReviser = reviseEntry.getSchemaTableAggregationReviser(props);
         if (!aggregationReviser.isPresent()) {
-            return new SchemaMetaData(originalMetaData.getName(), originalMetaData.getTables().stream().map(tableMetaDataReviseEngine::revise).collect(Collectors.toList()));
+            return new SchemaMetaData(originalMetaData.getName(), originalMetaData.getTables().stream()
+                    .map(each -> tableMetaDataReviseEngine.revise(each, originalMetaData.getTables(), schemaMetaDataRevisionCandidateTableMetaDataList)).collect(Collectors.toList()));
         }
         for (TableMetaData each : originalMetaData.getTables()) {
-            aggregationReviser.get().add(tableMetaDataReviseEngine.revise(each));
+            aggregationReviser.get().add(tableMetaDataReviseEngine.revise(each, originalMetaData.getTables(), schemaMetaDataRevisionCandidateTableMetaDataList));
         }
         return new SchemaMetaData(originalMetaData.getName(), aggregationReviser.get().aggregate(rule));
     }
+    
+    private Collection<TableMetaData> createSchemaMetaDataRevisionCandidateTableMetaDataList(final SchemaMetaData originalMetaData) {
+        return schemaMetaDataRevisionCandidateSchemas.stream().filter(each -> each.getName().equalsIgnoreCase(originalMetaData.getName()))
+                .flatMap(each -> each.getAllTables().stream()).map(SchemaMetaDataReviseEngine::convertToTableMetaData).collect(Collectors.toList());
+    }
+    
+    private static TableMetaData convertToTableMetaData(final ShardingSphereTable table) {
+        return new TableMetaData(table.getName(), Collections.emptyList(), convertToIndexMetaData(table.getAllIndexes()), Collections.emptyList(), table.getType());
+    }
+    
+    private static Collection<IndexMetaData> convertToIndexMetaData(final Collection<ShardingSphereIndex> indexes) {
+        return indexes.stream().map(each -> {
+            IndexMetaData result = new IndexMetaData(each.getName(), each.getColumns());
+            result.setUnique(each.isUnique());
+            return result;
+        }).collect(Collectors.toList());
+    }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/table/TableMetaDataReviseEngine.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/table/TableMetaDataReviseEngine.java
index b304ea62d70..fc43829c2e4 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/table/TableMetaDataReviseEngine.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/table/TableMetaDataReviseEngine.java
@@ -25,6 +25,8 @@ import org.apache.shardingsphere.infra.metadata.database.schema.reviser.constrai
 import org.apache.shardingsphere.infra.metadata.database.schema.reviser.index.IndexReviseEngine;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Optional;
 
 /**
@@ -46,10 +48,35 @@ public final class TableMetaDataReviseEngine<T extends ShardingSphereRule> {
      * @return revised table meta data
      */
     public TableMetaData revise(final TableMetaData originalMetaData) {
+        return revise(originalMetaData, Collections.singleton(originalMetaData));
+    }
+    
+    /**
+     * Revise table meta data.
+     *
+     * @param originalMetaData original table meta data
+     * @param originalMetaDataList original table meta data list
+     * @return revised table meta data
+     */
+    public TableMetaData revise(final TableMetaData originalMetaData, final Collection<TableMetaData> originalMetaDataList) {
+        return revise(originalMetaData, originalMetaDataList, Collections.emptyList());
+    }
+    
+    /**
+     * Revise table meta data.
+     *
+     * @param originalMetaData original table meta data
+     * @param originalMetaDataList original table meta data list
+     * @param schemaMetaDataRevisionCandidateTableMetaDataList schema meta data revision candidate table meta data list
+     * @return revised table meta data
+     */
+    public TableMetaData revise(final TableMetaData originalMetaData, final Collection<TableMetaData> originalMetaDataList,
+                                final Collection<TableMetaData> schemaMetaDataRevisionCandidateTableMetaDataList) {
         Optional<? extends TableNameReviser<T>> tableNameReviser = reviseEntry.getTableNameReviser();
         String revisedTableName = tableNameReviser.map(optional -> optional.revise(originalMetaData.getName(), rule)).orElse(originalMetaData.getName());
         return new TableMetaData(revisedTableName, new ColumnReviseEngine<>(rule, reviseEntry).revise(originalMetaData.getName(), originalMetaData.getColumns()),
-                new IndexReviseEngine<>(rule, reviseEntry).revise(originalMetaData.getName(), originalMetaData.getIndexes()),
+                new IndexReviseEngine<>(rule, reviseEntry).revise(originalMetaData.getName(), originalMetaData.getIndexes(), originalMetaDataList,
+                        schemaMetaDataRevisionCandidateTableMetaDataList),
                 new ConstraintReviseEngine<>(rule, reviseEntry).revise(originalMetaData.getName(), originalMetaData.getConstraints()), originalMetaData.getType());
     }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/util/IndexMetaDataUtils.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/util/IndexMetaDataUtils.java
index ef9c401faf9..44fb15f8848 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/util/IndexMetaDataUtils.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/util/IndexMetaDataUtils.java
@@ -29,9 +29,13 @@ import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp
 import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Optional;
+import java.util.regex.Pattern;
 
 /**
  * Index meta data utility class.
@@ -41,6 +45,28 @@ public final class IndexMetaDataUtils {
     
     private static final String UNDERLINE = "_";
     
+    private static final String SHORTENED_INDEX_SUFFIX_PREFIX = "_s";
+    
+    private static final String HASHED_INDEX_SUFFIX_PREFIX = "_h";
+    
+    private static final String TRUNCATED_INDEX_SUFFIX_PREFIX = "_t";
+    
+    private static final String HASH_ALGORITHM = "SHA-256";
+    
+    private static final int SHORTENED_INDEX_SUFFIX_HASH_BYTES = 5;
+    
+    private static final int LENGTH_SAFE_INDEX_SUFFIX_HASH_LENGTH = 8;
+    
+    private static final Pattern HASHED_INDEX_NAME_SUFFIX_PATTERN = Pattern.compile("_h[0-9a-z]{8}$");
+    
+    private static final Pattern TRUNCATED_INDEX_NAME_SUFFIX_PATTERN = Pattern.compile("_t[0-9a-z]{8}$");
+    
+    private static final int POSTGRESQL_INDEX_NAME_MAX_LENGTH = 63;
+    
+    private static final int OPENGAUSS_INDEX_NAME_MAX_LENGTH = 63;
+    
+    private static final int ORACLE_INDEX_NAME_MAX_LENGTH = 30;
+    
     /**
      * Get logic index name.
      *
@@ -49,8 +75,7 @@ public final class IndexMetaDataUtils {
      * @return logic index name
      */
     public static String getLogicIndexName(final String actualIndexName, final String actualTableName) {
-        String indexNameSuffix = UNDERLINE + actualTableName;
-        return actualIndexName.endsWith(indexNameSuffix) ? actualIndexName.substring(0, actualIndexName.lastIndexOf(indexNameSuffix)) : actualIndexName;
+        return stripActualIndexNameSuffix(actualIndexName, getLegacyActualIndexNameSuffix(actualTableName));
     }
     
     /**
@@ -61,7 +86,110 @@ public final class IndexMetaDataUtils {
      * @return actual index name
      */
     public static String getActualIndexName(final String logicIndexName, final String actualTableName) {
-        return Strings.isNullOrEmpty(actualTableName) ? logicIndexName : logicIndexName + UNDERLINE + actualTableName;
+        return getLegacyActualIndexName(logicIndexName, actualTableName);
+    }
+    
+    /**
+     * Get actual index name with database identifier budget.
+     *
+     * @param logicIndexName logic index name
+     * @param actualTableName actual table name
+     * @param databaseType database type
+     * @return actual index name
+     */
+    public static String getActualIndexName(final String logicIndexName, final String actualTableName, final DatabaseType databaseType) {
+        if (Strings.isNullOrEmpty(actualTableName)) {
+            return logicIndexName;
+        }
+        String legacyActualIndexName = getLegacyActualIndexName(logicIndexName, actualTableName);
+        int maxLength = getIndexNameMaxLength(databaseType);
+        if (getUtf8Length(legacyActualIndexName) <= maxLength) {
+            return legacyActualIndexName;
+        }
+        String hashedActualIndexName = logicIndexName + getHashedActualIndexNameSuffix(logicIndexName, actualTableName);
+        if (getUtf8Length(hashedActualIndexName) <= maxLength) {
+            return hashedActualIndexName;
+        }
+        String truncatedSuffix = getTruncatedActualIndexNameSuffix(logicIndexName, actualTableName);
+        return truncateToUtf8Bytes(logicIndexName, Math.max(0, maxLength - getUtf8Length(truncatedSuffix))) + truncatedSuffix;
+    }
+    
+    /**
+     * Get shortened actual index name for compatibility with the previous shortened suffix format.
+     *
+     * @param logicIndexName logic index name
+     * @param actualTableName actual table name
+     * @return shortened actual index name
+     */
+    public static String getShortenedActualIndexName(final String logicIndexName, final String actualTableName) {
+        return Strings.isNullOrEmpty(actualTableName) ? logicIndexName : logicIndexName + getShortenedActualIndexNameSuffix(actualTableName);
+    }
+    
+    /**
+     * Get legacy actual index name.
+     *
+     * @param logicIndexName logic index name
+     * @param actualTableName actual table name
+     * @return legacy actual index name
+     */
+    public static String getLegacyActualIndexName(final String logicIndexName, final String actualTableName) {
+        return Strings.isNullOrEmpty(actualTableName) ? logicIndexName : logicIndexName + getLegacyActualIndexNameSuffix(actualTableName);
+    }
+    
+    /**
+     * Get logic index name from generated actual index name.
+     *
+     * @param actualIndexName actual index name
+     * @param actualTableName actual table name
+     * @return logic index name
+     */
+    public static String getGeneratedLogicIndexName(final String actualIndexName, final String actualTableName) {
+        if (HASHED_INDEX_NAME_SUFFIX_PATTERN.matcher(actualIndexName).find()) {
+            return actualIndexName.substring(0, actualIndexName.length() - getLengthSafeGeneratedSuffixLength());
+        }
+        if (TRUNCATED_INDEX_NAME_SUFFIX_PATTERN.matcher(actualIndexName).find()) {
+            return actualIndexName.substring(0, actualIndexName.length() - getLengthSafeGeneratedSuffixLength());
+        }
+        String result = stripActualIndexNameSuffix(actualIndexName, getShortenedActualIndexNameSuffix(actualTableName));
+        return result.equals(actualIndexName) ? getLogicIndexName(actualIndexName, actualTableName) : result;
+    }
+    
+    /**
+     * Find logic index name from generated actual index name.
+     *
+     * @param actualIndexName actual index name
+     * @param actualTableName actual table name
+     * @param candidateLogicIndexNames candidate logic index names
+     * @return matched logic index name
+     */
+    public static Optional<String> findGeneratedLogicIndexName(final String actualIndexName, final String actualTableName, final Collection<String> candidateLogicIndexNames) {
+        if (candidateLogicIndexNames.contains(actualIndexName)) {
+            return Optional.of(actualIndexName);
+        }
+        Optional<String> result = candidateLogicIndexNames.stream().filter(each -> isGeneratedActualIndexNameMatch(actualIndexName, each, actualTableName)).findFirst();
+        if (result.isPresent()) {
+            return result;
+        }
+        String generatedLogicIndexName = getGeneratedLogicIndexName(actualIndexName, actualTableName);
+        if (isProvablyGeneratedActualIndexName(actualIndexName, generatedLogicIndexName, actualTableName)) {
+            return Optional.of(generatedLogicIndexName);
+        }
+        return Optional.of(actualIndexName);
+    }
+    
+    /**
+     * Check whether actual index name matches generated format of the logic index.
+     *
+     * @param actualIndexName actual index name
+     * @param logicIndexName logic index name
+     * @param actualTableName actual table name
+     * @return whether actual index name matches generated format or not
+     */
+    public static boolean isGeneratedActualIndexNameMatch(final String actualIndexName, final String logicIndexName, final String actualTableName) {
+        return actualIndexName.equals(getLegacyActualIndexName(logicIndexName, actualTableName))
+                || actualIndexName.equals(getShortenedActualIndexName(logicIndexName, actualTableName))
+                || (logicIndexName + getHashedActualIndexNameSuffix(logicIndexName, actualTableName)).equals(actualIndexName)
+                || isTruncatedActualIndexNameMatch(actualIndexName, logicIndexName, actualTableName);
     }
     
     /**
@@ -86,4 +214,113 @@ public final class IndexMetaDataUtils {
     private static Optional<String> findLogicTableNameFromMetaData(final ShardingSphereSchema schema, final IdentifierValue logicIndexName) {
         return schema.getAllTables().stream().filter(table -> table.containsIndex(logicIndexName)).findFirst().map(ShardingSphereTable::getName);
     }
+    
+    private static String getLegacyActualIndexNameSuffix(final String actualTableName) {
+        return Strings.isNullOrEmpty(actualTableName) ? "" : UNDERLINE + actualTableName;
+    }
+    
+    private static String getShortenedActualIndexNameSuffix(final String actualTableName) {
+        return Strings.isNullOrEmpty(actualTableName) ? "" : SHORTENED_INDEX_SUFFIX_PREFIX + shortenActualTableName(actualTableName);
+    }
+    
+    private static String getHashedActualIndexNameSuffix(final String logicIndexName, final String actualTableName) {
+        return HASHED_INDEX_SUFFIX_PREFIX + shortenIndexIdentity(logicIndexName, actualTableName);
+    }
+    
+    private static String getTruncatedActualIndexNameSuffix(final String logicIndexName, final String actualTableName) {
+        return TRUNCATED_INDEX_SUFFIX_PREFIX + shortenIndexIdentity(logicIndexName, actualTableName);
+    }
+    
+    private static String stripActualIndexNameSuffix(final String actualIndexName, final String indexNameSuffix) {
+        return Strings.isNullOrEmpty(indexNameSuffix) || !actualIndexName.endsWith(indexNameSuffix)
+                ? actualIndexName
+                : actualIndexName.substring(0, actualIndexName.length() - indexNameSuffix.length());
+    }
+    
+    private static String shortenActualTableName(final String actualTableName) {
+        return toVariableLengthRadixHash(digest(actualTableName));
+    }
+    
+    private static String shortenIndexIdentity(final String logicIndexName, final String actualTableName) {
+        return toFixedLengthRadixHash(digest(logicIndexName + '\0' + actualTableName));
+    }
+    
+    private static String toVariableLengthRadixHash(final byte[] digest) {
+        long result = 0L;
+        for (int i = 0; i < SHORTENED_INDEX_SUFFIX_HASH_BYTES; i++) {
+            result = result << Byte.SIZE | digest[i] & 0xFF;
+        }
+        return Long.toString(result, Character.MAX_RADIX);
+    }
+    
+    private static String toFixedLengthRadixHash(final byte[] digest) {
+        long result = 0L;
+        for (int i = 0; i < SHORTENED_INDEX_SUFFIX_HASH_BYTES; i++) {
+            result = result << Byte.SIZE | digest[i] & 0xFF;
+        }
+        String value = Long.toString(result, Character.MAX_RADIX);
+        return Strings.padStart(value, LENGTH_SAFE_INDEX_SUFFIX_HASH_LENGTH, '0');
+    }
+    
+    private static boolean isTruncatedActualIndexNameMatch(final String actualIndexName, final String logicIndexName, final String actualTableName) {
+        String suffix = getTruncatedActualIndexNameSuffix(logicIndexName, actualTableName);
+        if (!actualIndexName.endsWith(suffix)) {
+            return false;
+        }
+        String actualPrefix = actualIndexName.substring(0, actualIndexName.length() - suffix.length());
+        return actualPrefix.equals(truncateToUtf8Bytes(logicIndexName, getUtf8Length(actualPrefix)));
+    }
+    
+    private static boolean isProvablyGeneratedActualIndexName(final String actualIndexName, final String generatedLogicIndexName, final String actualTableName) {
+        return !generatedLogicIndexName.equals(actualIndexName) && (getLegacyActualIndexName(generatedLogicIndexName, actualTableName).equals(actualIndexName)
+                || getShortenedActualIndexName(generatedLogicIndexName, actualTableName).equals(actualIndexName)
+                || (generatedLogicIndexName + getHashedActualIndexNameSuffix(generatedLogicIndexName, actualTableName)).equals(actualIndexName));
+    }
+    
+    private static int getIndexNameMaxLength(final DatabaseType databaseType) {
+        if (null == databaseType) {
+            return Integer.MAX_VALUE;
+        }
+        switch (databaseType.getType()) {
+            case "PostgreSQL":
+                return POSTGRESQL_INDEX_NAME_MAX_LENGTH;
+            case "openGauss":
+                return OPENGAUSS_INDEX_NAME_MAX_LENGTH;
+            case "Oracle":
+                return ORACLE_INDEX_NAME_MAX_LENGTH;
+            default:
+                return Integer.MAX_VALUE;
+        }
+    }
+    
+    private static int getLengthSafeGeneratedSuffixLength() {
+        return HASHED_INDEX_SUFFIX_PREFIX.length() + LENGTH_SAFE_INDEX_SUFFIX_HASH_LENGTH;
+    }
+    
+    private static String truncateToUtf8Bytes(final String value, final int maxBytes) {
+        if (Strings.isNullOrEmpty(value) || maxBytes <= 0 || getUtf8Length(value) <= maxBytes) {
+            return maxBytes <= 0 ? "" : value;
+        }
+        int endIndex = 0;
+        while (endIndex < value.length()) {
+            int nextEndIndex = value.offsetByCodePoints(endIndex, 1);
+            if (getUtf8Length(value.substring(0, nextEndIndex)) > maxBytes) {
+                break;
+            }
+            endIndex = nextEndIndex;
+        }
+        return value.substring(0, endIndex);
+    }
+    
+    private static int getUtf8Length(final String value) {
+        return value.getBytes(StandardCharsets.UTF_8).length;
+    }
+    
+    private static byte[] digest(final String value) {
+        try {
+            return MessageDigest.getInstance(HASH_ALGORITHM).digest(value.getBytes(StandardCharsets.UTF_8));
+        } catch (final NoSuchAlgorithmException ex) {
+            throw new IllegalStateException(String.format("Could not find message digest algorithm `%s`.", HASH_ALGORITHM), ex);
+        }
+    }
 }
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseFactoryTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseFactoryTest.java
index 5b2128a6bd4..7b65c6fed65 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseFactoryTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseFactoryTest.java
@@ -50,6 +50,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockConstruction;
@@ -103,6 +104,28 @@ class ShardingSphereDatabaseFactoryTest {
         }
     }
     
+    @Test
+    void assertCreateWithDatabaseConfigurationAndSchemaMetaDataRevisionCandidates() throws SQLException {
+        DatabaseType protocolType = mock(DatabaseType.class);
+        ShardingSphereSchema candidateSchema = new ShardingSphereSchema("candidate_schema", protocolType);
+        try (
+                MockedConstruction<DatabaseTypeRegistry> ignored = mockConstruction(DatabaseTypeRegistry.class, (mock, context) -> when(mock.getDefaultSchemaName("foo_db")).thenReturn("foo_schema"));
+                MockedStatic<DatabaseRulesBuilder> mockedRulesBuilder = mockStatic(DatabaseRulesBuilder.class);
+                MockedStatic<GenericSchemaBuilder> mockedGenericSchemaBuilder = mockStatic(GenericSchemaBuilder.class);
+                MockedStatic<SystemSchemaBuilder> mockedSystemSchemaBuilder = mockStatic(SystemSchemaBuilder.class)) {
+            ComputeNodeInstanceContext computeNodeInstanceContext = mock(ComputeNodeInstanceContext.class);
+            mockedRulesBuilder.when(() -> DatabaseRulesBuilder.build(eq("foo_db"), eq(protocolType), eq(databaseConfig), eq(computeNodeInstanceContext), any(ResourceMetaData.class)))
+                    .thenReturn(Collections.singleton(mock(ShardingSphereRule.class)));
+            mockedGenericSchemaBuilder.when(() -> GenericSchemaBuilder.build(eq(protocolType),
+                    argThat(material -> material.getSchemaMetaDataRevisionCandidateSchemas().contains(candidateSchema))))
+                    .thenReturn(Collections.singletonMap("foo_schema", new ShardingSphereSchema("foo_schema", protocolType)));
+            mockedSystemSchemaBuilder.when(() -> SystemSchemaBuilder.build("foo_db", protocolType, props)).thenReturn(Collections.emptyMap());
+            ShardingSphereDatabase actual = ShardingSphereDatabaseFactory.createWithSchemaMetaDataRevisionCandidates(
+                    "foo_db", protocolType, databaseConfig, props, computeNodeInstanceContext, Collections.singleton(candidateSchema));
+            assertTrue(actual.containsSchema("foo_schema"));
+        }
+    }
+    
     @Test
     void assertCreateWithSchemas() {
         ShardingSphereDatabase actual = ShardingSphereDatabaseFactory.create(
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviseEngineTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviseEngineTest.java
index eb677d88bf6..2e57cb89dc4 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviseEngineTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/index/IndexReviseEngineTest.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.infra.metadata.database.schema.reviser.index;
 
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
 import org.apache.shardingsphere.infra.metadata.database.schema.reviser.MetaDataReviseEntry;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -33,6 +34,7 @@ import java.util.Optional;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyCollection;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -58,7 +60,7 @@ class IndexReviseEngineTest {
     @Test
     void assertReviseWithIndexReviser() {
         IndexReviser reviser = mock(IndexReviser.class);
-        when(reviser.revise(eq("foo_tbl"), any(), any())).thenReturn(Optional.of(new IndexMetaData("foo_idx")));
+        when(reviser.revise(eq("foo_tbl"), any(), any(), anyCollection(), any())).thenReturn(Optional.of(new IndexMetaData("foo_idx")));
         when(metaDataReviseEntry.getIndexReviser(any(), eq("foo_tbl"))).thenReturn(Optional.of(reviser));
         Collection<IndexMetaData> actual = indexReviseEngine.revise("foo_tbl", Arrays.asList(new IndexMetaData("idx_0"), new IndexMetaData("idx_1")));
         assertThat(actual.size(), is(2));
@@ -66,6 +68,34 @@ class IndexReviseEngineTest {
         assertIndexMetaData(actual.iterator().next(), new IndexMetaData("foo_idx"));
     }
     
+    @Test
+    void assertReviseWithOriginalTableMetaDataList() {
+        IndexReviser reviser = mock(IndexReviser.class);
+        Collection<IndexMetaData> originalIndexes = Arrays.asList(new IndexMetaData("idx_0"), new IndexMetaData("idx_1"));
+        Collection<TableMetaData> originalTables = Collections.singleton(new TableMetaData("foo_tbl", Collections.emptyList(), originalIndexes, Collections.emptyList()));
+        when(reviser.revise(eq("foo_tbl"), any(), eq(originalTables), anyCollection(), any())).thenReturn(Optional.of(new IndexMetaData("foo_idx")));
+        when(metaDataReviseEntry.getIndexReviser(any(), eq("foo_tbl"))).thenReturn(Optional.of(reviser));
+        Collection<IndexMetaData> actual = indexReviseEngine.revise("foo_tbl", originalIndexes, originalTables);
+        assertThat(actual.size(), is(2));
+        assertIndexMetaData(actual.iterator().next(), new IndexMetaData("foo_idx"));
+        assertIndexMetaData(actual.iterator().next(), new IndexMetaData("foo_idx"));
+    }
+    
+    @Test
+    void assertReviseWithSchemaMetaDataRevisionCandidateTableMetaDataList() {
+        IndexReviser reviser = mock(IndexReviser.class);
+        Collection<IndexMetaData> originalIndexes = Arrays.asList(new IndexMetaData("idx_0"), new IndexMetaData("idx_1"));
+        Collection<TableMetaData> originalTables = Collections.singleton(new TableMetaData("foo_tbl", Collections.emptyList(), originalIndexes, Collections.emptyList()));
+        Collection<TableMetaData> candidates =
+                Collections.singleton(new TableMetaData("logic_tbl", Collections.emptyList(), Collections.singleton(new IndexMetaData("logic_idx")), Collections.emptyList()));
+        when(reviser.revise(eq("foo_tbl"), any(), eq(originalTables), eq(candidates), any())).thenReturn(Optional.of(new IndexMetaData("foo_idx")));
+        when(metaDataReviseEntry.getIndexReviser(any(), eq("foo_tbl"))).thenReturn(Optional.of(reviser));
+        Collection<IndexMetaData> actual = indexReviseEngine.revise("foo_tbl", originalIndexes, originalTables, candidates);
+        assertThat(actual.size(), is(2));
+        assertIndexMetaData(actual.iterator().next(), new IndexMetaData("foo_idx"));
+        assertIndexMetaData(actual.iterator().next(), new IndexMetaData("foo_idx"));
+    }
+    
     private void assertIndexMetaData(final IndexMetaData actual, final IndexMetaData expected) {
         assertThat(actual.getName(), is(expected.getName()));
         assertThat(actual.getColumns(), is(expected.getColumns()));
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/schema/SchemaMetaDataReviseEngineTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/schema/SchemaMetaDataReviseEngineTest.java
index 24006a8ce8c..b6f23a3b4ba 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/schema/SchemaMetaDataReviseEngineTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/reviser/schema/SchemaMetaDataReviseEngineTest.java
@@ -23,7 +23,11 @@ import org.apache.shardingsphere.database.connector.core.metadata.data.model.Ind
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.SchemaMetaData;
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
 import org.apache.shardingsphere.infra.metadata.database.schema.reviser.MetaDataReviseEntry;
+import org.apache.shardingsphere.infra.metadata.database.schema.reviser.index.IndexReviser;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.infra.rule.builder.fixture.FixtureGlobalRule;
 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
@@ -37,10 +41,15 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Properties;
 
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.when;
@@ -81,6 +90,35 @@ class SchemaMetaDataReviseEngineTest {
         }
     }
     
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @Test
+    void assertRevisePassesSameSchemaRevisionCandidateTableMetaDataToIndexReviser() {
+        TableMetaData actualTableMetaData = new TableMetaData("actual_tbl", Collections.emptyList(),
+                Collections.singleton(new IndexMetaData("actual_idx")), Collections.emptyList());
+        SchemaMetaData schemaMetaData = new SchemaMetaData("foo_schema", Collections.singleton(actualTableMetaData));
+        ShardingSphereTable candidateTable = new ShardingSphereTable(
+                "logic_tbl", Collections.emptyList(), Collections.singleton(new ShardingSphereIndex("logic_idx", Collections.singleton("foo_col"), true)), Collections.emptyList());
+        ShardingSphereSchema candidateSchema = new ShardingSphereSchema("foo_schema", mock(), Collections.singleton(candidateTable), Collections.emptyList());
+        ShardingSphereSchema ignoredCandidateSchema = new ShardingSphereSchema("bar_schema", mock(), Collections.singleton(candidateTable), Collections.emptyList());
+        FixtureGlobalRule rule = new FixtureGlobalRule();
+        MetaDataReviseEntry<FixtureGlobalRule> reviseEntry = mock(MetaDataReviseEntry.class);
+        IndexReviser<FixtureGlobalRule> indexReviser = mock(IndexReviser.class);
+        when(reviseEntry.getTypeClass()).thenReturn(FixtureGlobalRule.class);
+        doReturn(Optional.of(indexReviser)).when(reviseEntry).getIndexReviser(rule, "actual_tbl");
+        when(indexReviser.revise(eq("actual_tbl"), any(), eq(schemaMetaData.getTables()), argThat(candidates -> {
+            TableMetaData candidate = candidates.iterator().next();
+            IndexMetaData index = candidate.getIndexes().iterator().next();
+            return 1 == candidates.size() && "logic_tbl".equals(candidate.getName()) && "logic_idx".equals(index.getName()) && index.isUnique();
+        }), eq(rule))).thenReturn(Optional.of(new IndexMetaData("revised_idx")));
+        Map<ShardingSphereRule, MetaDataReviseEntry<?>> entries = Collections.singletonMap(rule, reviseEntry);
+        try (MockedStatic<OrderedSPILoader> mocked = mockStatic(OrderedSPILoader.class)) {
+            mocked.when(() -> OrderedSPILoader.getServices(MetaDataReviseEntry.class, Collections.singleton(rule))).thenReturn(entries);
+            SchemaMetaData actual = new SchemaMetaDataReviseEngine(
+                    Collections.singleton(rule), new ConfigurationProperties(new Properties()), Arrays.asList(candidateSchema, ignoredCandidateSchema)).revise(schemaMetaData);
+            assertThat(actual.getTables().iterator().next().getIndexes().iterator().next().getName(), is("revised_idx"));
+        }
+    }
+    
     private TableMetaData createTableMetaData() {
         Collection<ColumnMetaData> columns = new LinkedHashSet<>(Arrays.asList(new ColumnMetaData("id", Types.INTEGER, true, true, true, true, false, false),
                 new ColumnMetaData("pwd_cipher", Types.VARCHAR, false, false, true, true, false, false),
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/util/IndexMetaDataUtilsTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/util/IndexMetaDataUtilsTest.java
index a65563e4394..15aec39871a 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/util/IndexMetaDataUtilsTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/util/IndexMetaDataUtilsTest.java
@@ -33,16 +33,26 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.Ind
 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 import org.junit.jupiter.api.Test;
 
+import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Properties;
 
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.lessThan;
+import static org.hamcrest.Matchers.startsWith;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
 
 class IndexMetaDataUtilsTest {
     
+    private final DatabaseType fixtureDatabaseType = TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    private final DatabaseType postgreSQLDatabaseType = TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");
+    
+    private final DatabaseType oracleDatabaseType = TypedSPILoader.getService(DatabaseType.class, "Oracle");
+    
     @Test
     void assertGetLogicIndexNameWithIndexNameSuffix() {
         assertThat(IndexMetaDataUtils.getLogicIndexName("order_index_t_order", "t_order"), is("order_index"));
@@ -63,15 +73,102 @@ class IndexMetaDataUtilsTest {
         assertThat(IndexMetaDataUtils.getActualIndexName("order_index", "t_order"), is("order_index_t_order"));
     }
     
+    @Test
+    void assertGetShortenedActualIndexNameReducesLengthForLongActualTableName() {
+        String actualTableName = "order_detail_archive_20260316_0001";
+        assertThat(IndexMetaDataUtils.getShortenedActualIndexName("order_index", actualTableName).length(),
+                lessThan(IndexMetaDataUtils.getLegacyActualIndexName("order_index", actualTableName).length()));
+    }
+    
+    @Test
+    void assertGetLegacyActualIndexNameWithActualTableName() {
+        assertThat(IndexMetaDataUtils.getLegacyActualIndexName("order_index", "t_order"), is("order_index_t_order"));
+    }
+    
     @Test
     void assertGetActualIndexNameWithoutActualTableName() {
         assertThat(IndexMetaDataUtils.getActualIndexName("order_index", null), is("order_index"));
     }
     
+    @Test
+    void assertGetGeneratedLogicIndexNameWithShortenedIndexNameSuffix() {
+        String actualIndexName = IndexMetaDataUtils.getShortenedActualIndexName("order_index", "t_order");
+        assertThat(IndexMetaDataUtils.getGeneratedLogicIndexName(actualIndexName, "t_order"), is("order_index"));
+    }
+    
+    @Test
+    void assertGetGeneratedLogicIndexNameWithLegacyIndexNameSuffix() {
+        assertThat(IndexMetaDataUtils.getGeneratedLogicIndexName("order_index_t_order", "t_order"), is("order_index"));
+    }
+    
+    @Test
+    void assertGetActualIndexNameKeepsLegacyFormatWhenLegacyNameFitsWithinBudget() {
+        assertThat(IndexMetaDataUtils.getActualIndexName("status_idx", "t_account_0", postgreSQLDatabaseType), is("status_idx_t_account_0"));
+    }
+    
+    @Test
+    void assertGetActualIndexNameUsesHashedSuffixWhenLegacyNameExceedsBudget() {
+        String logicIndexName = "named_index_boundary_case_abcdefghijklmnopqrstuvwxyz";
+        String actual = IndexMetaDataUtils.getActualIndexName(logicIndexName, "t_account_0", postgreSQLDatabaseType);
+        assertThat(actual, startsWith(logicIndexName));
+        assertTrue(actual.matches(".*_h[0-9a-z]{8}$"));
+        assertThat(IndexMetaDataUtils.getGeneratedLogicIndexName(actual, "t_account_0"), is(logicIndexName));
+        assertThat(actual.getBytes(StandardCharsets.UTF_8).length, is(62));
+    }
+    
+    @Test
+    void assertGetActualIndexNameTruncatesPrefixWhenHashedNameStillExceedsBudget() {
+        String logicIndexName = "very_long_named_index_boundary_case_for_sharding_length_safety_validation";
+        String actual = IndexMetaDataUtils.getActualIndexName(logicIndexName, "t_account_0", postgreSQLDatabaseType);
+        assertTrue(actual.matches(".*_t[0-9a-z]{8}$"));
+        assertThat(actual.getBytes(StandardCharsets.UTF_8).length, is(63));
+        assertTrue(IndexMetaDataUtils.isGeneratedActualIndexNameMatch(actual, logicIndexName, "t_account_0"));
+    }
+    
+    @Test
+    void assertGetActualIndexNameUsesDialectSpecificBudget() {
+        String logicIndexName = "oracle_length_budget";
+        String actual = IndexMetaDataUtils.getActualIndexName(logicIndexName, "t_account_0", oracleDatabaseType);
+        assertTrue(actual.matches(".*_h[0-9a-z]{8}$"));
+        assertThat(actual.getBytes(StandardCharsets.UTF_8).length, is(30));
+    }
+    
+    @Test
+    void assertFindGeneratedLogicIndexNameWithTruncatedActualIndexName() {
+        String logicIndexName = "very_long_named_index_boundary_case_for_sharding_length_safety_validation";
+        String actualIndexName = IndexMetaDataUtils.getActualIndexName(logicIndexName, "t_account_0", postgreSQLDatabaseType);
+        assertThat(IndexMetaDataUtils.findGeneratedLogicIndexName(actualIndexName, "t_account_0", Collections.singleton(logicIndexName)).orElse(""),
+                is(logicIndexName));
+    }
+    
+    @Test
+    void assertFindGeneratedLogicIndexNameKeepsExactCandidateWithHashLikeSuffix() {
+        assertThat(IndexMetaDataUtils.findGeneratedLogicIndexName("foo_h12345678", "t_account_0", Collections.singleton("foo_h12345678")).orElse(""),
+                is("foo_h12345678"));
+    }
+    
+    @Test
+    void assertFindGeneratedLogicIndexNameKeepsExactCandidateWithTruncationLikeSuffix() {
+        assertThat(IndexMetaDataUtils.findGeneratedLogicIndexName("foo_t12345678", "t_account_0", Collections.singleton("foo_t12345678")).orElse(""),
+                is("foo_t12345678"));
+    }
+    
+    @Test
+    void assertFindGeneratedLogicIndexNameKeepsUnprovableHashLikeSuffixWithoutCandidate() {
+        assertThat(IndexMetaDataUtils.findGeneratedLogicIndexName("foo_h12345678", "t_account_0", Collections.emptyList()).orElse(""),
+                is("foo_h12345678"));
+    }
+    
+    @Test
+    void assertFindGeneratedLogicIndexNameKeepsUnprovableTruncationLikeSuffixWithoutCandidate() {
+        assertThat(IndexMetaDataUtils.findGeneratedLogicIndexName("foo_t12345678", "t_account_0", Collections.emptyList()).orElse(""),
+                is("foo_t12345678"));
+    }
+    
     @Test
     void assertGetTableNames() {
         IndexSegment indexSegment = new IndexSegment(0, 0, new IndexNameSegment(0, 0, new IdentifierValue("foo_idx")));
-        Collection<QualifiedTable> actual = IndexMetaDataUtils.getTableNames(buildDatabase(), TypedSPILoader.getService(DatabaseType.class, "FIXTURE"), Collections.singleton(indexSegment));
+        Collection<QualifiedTable> actual = IndexMetaDataUtils.getTableNames(buildDatabase(), fixtureDatabaseType, Collections.singleton(indexSegment));
         assertThat(actual.size(), is(1));
         assertThat(actual.iterator().next().getSchemaName(), is("foo_db"));
         assertThat(actual.iterator().next().getTableName(), is("foo_tbl"));
diff --git a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLDecorator.java b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLDecorator.java
index 72edeb7558b..a5101fdfbfa 100644
--- a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLDecorator.java
+++ b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLDecorator.java
@@ -23,6 +23,8 @@ import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.binder.context.SQLStatementContextFactory;
 import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
 import org.apache.shardingsphere.infra.parser.SQLParserEngine;
 import org.apache.shardingsphere.sql.parser.statement.core.extractor.TableExtractor;
@@ -40,12 +42,14 @@ import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.in
 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.AlterTableStatement;
 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.TreeMap;
+import java.util.stream.Collectors;
 
 /**
  * Pipeline DDL decorator.
@@ -73,7 +77,7 @@ public final class PipelineDDLDecorator {
         if (Strings.isNullOrEmpty(sql)) {
             return Optional.empty();
         }
-        String result = decorateActualSQL(targetDatabaseName, targetTableName, parserEngine, sql.trim());
+        String result = decorateActualSQL(targetDatabaseName, schemaName, targetTableName, parserEngine, sql.trim());
         // TODO remove it after set search_path is supported.
         if ("openGauss".equals(databaseType.getType())) {
             return decorateOpenGauss(schemaName, result, parserEngine);
@@ -81,11 +85,11 @@ public final class PipelineDDLDecorator {
         return Optional.of(result);
     }
     
-    private String decorateActualSQL(final String databaseName, final String targetTableName, final SQLParserEngine parserEngine, final String sql) {
+    private String decorateActualSQL(final String databaseName, final String schemaName, final String targetTableName, final SQLParserEngine parserEngine, final String sql) {
         SQLStatementContext sqlStatementContext = parseSQL(databaseName, parserEngine, sql);
         Map<SQLSegment, String> replaceMap = new TreeMap<>(Comparator.comparing(SQLSegment::getStartIndex));
         if (sqlStatementContext.getSqlStatement() instanceof CreateTableStatement) {
-            appendFromIndexAndConstraint(replaceMap, targetTableName, sqlStatementContext);
+            appendFromIndexAndConstraint(replaceMap, databaseName, schemaName, targetTableName, sqlStatementContext);
             appendFromTable(replaceMap, targetTableName, sqlStatementContext);
         }
         if (sqlStatementContext.getSqlStatement() instanceof CommentStatement) {
@@ -93,10 +97,10 @@ public final class PipelineDDLDecorator {
         }
         if (sqlStatementContext.getSqlStatement() instanceof CreateIndexStatement) {
             appendFromTable(replaceMap, targetTableName, sqlStatementContext);
-            appendFromIndexAndConstraint(replaceMap, targetTableName, sqlStatementContext);
+            appendFromIndexAndConstraint(replaceMap, databaseName, schemaName, targetTableName, sqlStatementContext);
         }
         if (sqlStatementContext.getSqlStatement() instanceof AlterTableStatement) {
-            appendFromIndexAndConstraint(replaceMap, targetTableName, sqlStatementContext);
+            appendFromIndexAndConstraint(replaceMap, databaseName, schemaName, targetTableName, sqlStatementContext);
             appendFromTable(replaceMap, targetTableName, sqlStatementContext);
         }
         return doDecorateActualTable(replaceMap, sql);
@@ -106,15 +110,18 @@ public final class PipelineDDLDecorator {
         return SQLStatementContextFactory.newInstance(metaData, parserEngine.parse(sql, true), currentDatabaseName);
     }
     
-    private void appendFromIndexAndConstraint(final Map<SQLSegment, String> replaceMap, final String targetTableName, final SQLStatementContext sqlStatementContext) {
+    private void appendFromIndexAndConstraint(final Map<SQLSegment, String> replaceMap, final String databaseName, final String schemaName,
+                                              final String targetTableName, final SQLStatementContext sqlStatementContext) {
         if (sqlStatementContext.getTablesContext().getSimpleTables().isEmpty()) {
             return;
         }
         TableNameSegment tableNameSegment = sqlStatementContext.getTablesContext().getSimpleTables().iterator().next().getTableName();
         if (!tableNameSegment.getIdentifier().getValue().equals(targetTableName)) {
             SQLStatementAttributes attributes = sqlStatementContext.getSqlStatement().getAttributes();
+            Collection<String> candidateLogicIndexNames = findCandidateLogicIndexNames(databaseName, schemaName, targetTableName);
             for (IndexSegment each : attributes.findAttribute(IndexSQLStatementAttribute.class).map(IndexSQLStatementAttribute::getIndexes).orElse(Collections.emptyList())) {
-                String logicIndexName = IndexMetaDataUtils.getLogicIndexName(each.getIndexName().getIdentifier().getValue(), tableNameSegment.getIdentifier().getValue());
+                String logicIndexName = IndexMetaDataUtils.findGeneratedLogicIndexName(
+                        each.getIndexName().getIdentifier().getValue(), tableNameSegment.getIdentifier().getValue(), candidateLogicIndexNames).orElse(each.getIndexName().getIdentifier().getValue());
                 replaceMap.put(each.getIndexName(), logicIndexName);
             }
             for (ConstraintSegment each : attributes.findAttribute(ConstraintSQLStatementAttribute.class).map(ConstraintSQLStatementAttribute::getConstraints).orElse(Collections.emptyList())) {
@@ -124,6 +131,24 @@ public final class PipelineDDLDecorator {
         }
     }
     
+    private Collection<String> findCandidateLogicIndexNames(final String databaseName, final String schemaName, final String targetTableName) {
+        if (Strings.isNullOrEmpty(databaseName)) {
+            return Collections.emptyList();
+        }
+        ShardingSphereDatabase database = metaData.getDatabase(databaseName);
+        if (null == database) {
+            return Collections.emptyList();
+        }
+        if (!Strings.isNullOrEmpty(schemaName)) {
+            return database.containsSchema(schemaName) && database.getSchema(schemaName).containsTable(targetTableName)
+                    ? database.getSchema(schemaName).getTable(targetTableName).getAllIndexes().stream().map(each -> each.getName()).collect(Collectors.toList())
+                    : Collections.emptyList();
+        }
+        Collection<ShardingSphereSchema> matchedSchemas = database.getAllSchemas().stream().filter(each -> each.containsTable(targetTableName)).collect(Collectors.toList());
+        return 1 == matchedSchemas.size() ? matchedSchemas.iterator().next().getTable(targetTableName).getAllIndexes().stream()
+                .map(each -> each.getName()).collect(Collectors.toList()) : Collections.emptyList();
+    }
+    
     private void appendFromTable(final Map<SQLSegment, String> replaceMap, final String targetTableName, final SQLStatementContext sqlStatementContext) {
         for (SimpleTableSegment each : sqlStatementContext.getTablesContext().getSimpleTables()) {
             if (!targetTableName.equals(each.getTableName().getIdentifier().getValue())) {
diff --git a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparer.java b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparer.java
index a5638f53a61..a0070324ec5 100644
--- a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparer.java
+++ b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/datasource/PipelineJobDataSourcePreparer.java
@@ -142,7 +142,7 @@ public final class PipelineJobDataSourcePreparer {
     
     private Optional<String> decorateTargetTableSQL(final CreateTableConfiguration createTableConfig, final SQLParserEngine sqlParserEngine,
                                                     final ShardingSphereMetaData metaData, final String targetDatabaseName, final String sql) {
-        String schemaName = createTableConfig.getSourceName().getSchemaName();
+        String schemaName = createTableConfig.getTargetName().getSchemaName();
         String targetTableName = createTableConfig.getTargetName().getTableName();
         Optional<String> decoratedSQL = new PipelineDDLDecorator(metaData).decorate(databaseType, targetDatabaseName, schemaName, targetTableName, sqlParserEngine, sql);
         return decoratedSQL.map(String::trim).filter(trimmedSql -> !Strings.isNullOrEmpty(trimmedSql));
diff --git a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLDecoratorTest.java b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLDecoratorTest.java
new file mode 100644
index 00000000000..42d572f41ff
--- /dev/null
+++ b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/metadata/generator/PipelineDDLDecoratorTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.data.pipeline.core.metadata.generator;
+
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
+import org.apache.shardingsphere.infra.parser.SQLParserEngine;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexNameSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.index.CreateIndexStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class PipelineDDLDecoratorTest {
+    
+    private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");
+    
+    @Test
+    void assertDecorateUsesSchemaSpecificCandidatesForSameNamedTables() {
+        String logicIndexName = "very_long_named_index_boundary_case_for_sharding_length_safety_validation";
+        String actualIndexName = IndexMetaDataUtils.getActualIndexName(logicIndexName, "t_order_0", databaseType);
+        assertTrue(actualIndexName.matches(".*_t[0-9a-z]{8}$"));
+        String actualSQL = String.format("CREATE INDEX %s ON t_order_0 (order_id)", actualIndexName);
+        String expected = String.format("CREATE INDEX %s ON t_order (order_id)", logicIndexName);
+        assertThat(
+                new PipelineDDLDecorator(mockMetaData(logicIndexName)).decorate(databaseType, "foo_db", "schema_b", "t_order", createParserEngine(actualSQL, actualIndexName), actualSQL).orElse(""),
+                is(expected));
+    }
+    
+    private ShardingSphereMetaData mockMetaData(final String logicIndexName) {
+        ShardingSphereMetaData result = mock(ShardingSphereMetaData.class);
+        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
+        ShardingSphereSchema schemaA = new ShardingSphereSchema("schema_a", databaseType, Collections.singleton(
+                new ShardingSphereTable("t_order", Collections.emptyList(),
+                        Collections.singleton(new ShardingSphereIndex("another_very_long_named_index_for_schema_a_validation", Collections.emptyList(), false)), Collections.emptyList())),
+                Collections.emptyList());
+        ShardingSphereSchema schemaB = new ShardingSphereSchema("schema_b", databaseType, Collections.singleton(
+                new ShardingSphereTable("t_order", Collections.emptyList(),
+                        Collections.singleton(new ShardingSphereIndex(logicIndexName, Collections.emptyList(), false)), Collections.emptyList())),
+                Collections.emptyList());
+        when(result.getDatabase("foo_db")).thenReturn(database);
+        when(database.containsSchema("schema_b")).thenReturn(true);
+        when(database.getSchema("schema_b")).thenReturn(schemaB);
+        when(database.getAllSchemas()).thenReturn(Arrays.asList(schemaA, schemaB));
+        return result;
+    }
+    
+    private SQLParserEngine createParserEngine(final String actualSQL, final String actualIndexName) {
+        SQLParserEngine result = mock(SQLParserEngine.class);
+        when(result.parse(actualSQL, true)).thenReturn(CreateIndexStatement.builder()
+                .databaseType(databaseType)
+                .index(new IndexSegment(getIndexStartIndex(), getIndexStopIndex(actualIndexName),
+                        new IndexNameSegment(getIndexStartIndex(), getIndexStopIndex(actualIndexName), new IdentifierValue(actualIndexName))))
+                .table(new SimpleTableSegment(new TableNameSegment(getTableStartIndex(actualSQL), getTableStopIndex(actualSQL), new IdentifierValue("t_order_0"))))
+                .build());
+        return result;
+    }
+    
+    private int getIndexStartIndex() {
+        return "CREATE INDEX ".length();
+    }
+    
+    private int getIndexStopIndex(final String actualIndexName) {
+        return getIndexStartIndex() + actualIndexName.length() - 1;
+    }
+    
+    private int getTableStartIndex(final String actualSQL) {
+        return actualSQL.indexOf("t_order_0");
+    }
+    
+    private int getTableStopIndex(final String actualSQL) {
+        return getTableStartIndex(actualSQL) + "t_order_0".length() - 1;
+    }
+}
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
index 4eabfe64fe3..509fe78f026 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
@@ -204,7 +204,7 @@ public final class ContextManager implements AutoCloseable {
     private ShardingSphereSchema loadSchema(final ShardingSphereDatabase database, final String schemaName, final String dataSourceName) throws SQLException {
         database.reloadRules();
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(Collections.singletonMap(dataSourceName, database.getResourceMetaData().getStorageUnits().get(dataSourceName)),
-                database.getRuleMetaData().getRules(), metaDataContexts.getMetaData().getProps(), schemaName, database.getIdentifierContext());
+                database.getRuleMetaData().getRules(), metaDataContexts.getMetaData().getProps(), schemaName, database.getIdentifierContext(), database.getAllSchemas());
         ShardingSphereSchema result = GenericSchemaBuilder.build(database.getProtocolType(), material).get(schemaName);
         persistServiceFacade.getMetaDataFacade().getDatabaseMetaDataFacade().getView().load(database.getName(), schemaName).forEach(result::putView);
         return result;
@@ -231,7 +231,7 @@ public final class ContextManager implements AutoCloseable {
     public void reloadTable(final ShardingSphereDatabase database, final String schemaName, final IdentifierValue tableName) {
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(
                 database.getResourceMetaData().getStorageUnits(), database.getRuleMetaData().getRules(), metaDataContexts.getMetaData().getProps(), schemaName,
-                database.getIdentifierContext());
+                database.getIdentifierContext(), database.getAllSchemas());
         try {
             persistTable(database, schemaName, tableName, material);
         } catch (final SQLException ex) {
@@ -263,7 +263,7 @@ public final class ContextManager implements AutoCloseable {
         StorageUnit storageUnit = database.getResourceMetaData().getStorageUnits().get(dataSourceName);
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(
                 Collections.singletonMap(dataSourceName, storageUnit), database.getRuleMetaData().getRules(), metaDataContexts.getMetaData().getProps(), schemaName,
-                database.getIdentifierContext());
+                database.getIdentifierContext(), database.getAllSchemas());
         try {
             persistTable(database, schemaName, tableName, material);
         } catch (final SQLException ex) {
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/factory/MetaDataContextsFactory.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/factory/MetaDataContextsFactory.java
index f9edbb60785..eee666b978d 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/factory/MetaDataContextsFactory.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/factory/MetaDataContextsFactory.java
@@ -172,7 +172,8 @@ public final class MetaDataContextsFactory {
                                                                   final MetaDataContexts originalMetaDataContext) throws SQLException {
         ConfigurationProperties props = originalMetaDataContext.getMetaData().getProps();
         DatabaseType protocolType = DatabaseTypeEngine.getProtocolType(databaseConfig, props);
-        return ShardingSphereDatabaseFactory.create(databaseName, protocolType, databaseConfig, props, instanceContext);
+        return ShardingSphereDatabaseFactory.createWithSchemaMetaDataRevisionCandidates(databaseName, protocolType, databaseConfig, props, instanceContext,
+                originalMetaDataContext.getMetaData().getDatabase(databaseName).getAllSchemas());
     }
     
     private ResourceMetaData getEffectiveResourceMetaData(final ShardingSphereDatabase database, final SwitchingResource switchingResource) {
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/metadata/DatabaseMetaDataPersistFacade.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/metadata/DatabaseMetaDataPersistFacade.java
index 8322b168074..08a92298998 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/metadata/DatabaseMetaDataPersistFacade.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/metadata/DatabaseMetaDataPersistFacade.java
@@ -106,7 +106,7 @@ public final class DatabaseMetaDataPersistFacade {
         ShardingSphereDatabase database = reloadMetaDataContexts.getMetaData().getDatabase(databaseName);
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getResourceMetaData().getStorageUnits(),
                 database.getRuleMetaData().getRules(), reloadMetaDataContexts.getMetaData().getProps(), new DatabaseTypeRegistry(database.getProtocolType()).getDefaultSchemaName(databaseName),
-                database.getIdentifierContext());
+                database.getIdentifierContext(), database.getAllSchemas());
         try {
             Map<String, ShardingSphereSchema> schemas = GenericSchemaBuilder.build(database.getProtocolType(), material);
             for (Entry<String, ShardingSphereSchema> entry : schemas.entrySet()) {
@@ -130,7 +130,7 @@ public final class DatabaseMetaDataPersistFacade {
         ShardingSphereDatabase database = reloadMetaDataContexts.getMetaData().getDatabase(databaseName);
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getResourceMetaData().getStorageUnits(),
                 database.getRuleMetaData().getRules(), reloadMetaDataContexts.getMetaData().getProps(),
-                new DatabaseTypeRegistry(database.getProtocolType()).getDefaultSchemaName(databaseName), database.getIdentifierContext());
+                new DatabaseTypeRegistry(database.getProtocolType()).getDefaultSchemaName(databaseName), database.getIdentifierContext(), database.getAllSchemas());
         try {
             Map<String, ShardingSphereSchema> schemas = GenericSchemaBuilder.build(needReloadTables, database.getProtocolType(), material);
             Map<String, Collection<ShardingSphereTable>> result = new HashMap<>(schemas.size(), 1F);
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresher.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresher.java
index 1bd58c4346e..ff926da6e4b 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresher.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresher.java
@@ -20,12 +20,21 @@ package org.apache.shardingsphere.mode.metadata.refresher.pushdown.type.table;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
+import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
 import org.apache.shardingsphere.mode.metadata.refresher.pushdown.PushDownMetaDataRefresher;
+import org.apache.shardingsphere.mode.metadata.refresher.util.TableRefreshUtils;
 import org.apache.shardingsphere.mode.persist.service.MetaDataManagerPersistService;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.constraint.ConstraintDefinitionSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
 
 import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.stream.Collectors;
 
 /**
  * Create table push down meta data refresher.
@@ -37,7 +46,8 @@ public final class CreateTablePushDownMetaDataRefresher implements PushDownMetaD
     @Override
     public void refresh(final MetaDataManagerPersistService metaDataManagerPersistService, final ShardingSphereDatabase database, final String logicDataSourceName,
                         final String schemaName, final DatabaseType databaseType, final CreateTableStatement sqlStatement, final ConfigurationProperties props) throws SQLException {
-        ShardingSphereTable loadedTable = metaDataLoader.loadCreatedTable(database, logicDataSourceName, schemaName, sqlStatement.getTable().getTableName().getIdentifier(), props);
+        ShardingSphereTable loadedTable = metaDataLoader.loadCreatedTable(database, logicDataSourceName, schemaName, sqlStatement.getTable().getTableName().getIdentifier(), props,
+                createSchemaMetaDataRevisionCandidateSchemas(database, schemaName, sqlStatement, props));
         metaDataManagerPersistService.createTable(database, schemaName, loadedTable);
     }
     
@@ -45,4 +55,28 @@ public final class CreateTablePushDownMetaDataRefresher implements PushDownMetaD
     public Class<CreateTableStatement> getType() {
         return CreateTableStatement.class;
     }
+    
+    private Collection<ShardingSphereSchema> createSchemaMetaDataRevisionCandidateSchemas(final ShardingSphereDatabase database, final String schemaName,
+                                                                                          final CreateTableStatement sqlStatement, final ConfigurationProperties props) {
+        Collection<ShardingSphereIndex> indexes = createIndexMetaDataRevisionCandidates(sqlStatement);
+        if (indexes.isEmpty()) {
+            return database.getAllSchemas();
+        }
+        Collection<ShardingSphereSchema> result = new LinkedList<>(database.getAllSchemas());
+        String tableName = TableRefreshUtils.getTableLoadCandidateName(database, sqlStatement.getTable().getTableName().getIdentifier(), props);
+        result.add(new ShardingSphereSchema(schemaName, database.getProtocolType(),
+                Collections.singleton(new ShardingSphereTable(tableName, Collections.emptyList(), indexes, Collections.emptyList())), Collections.emptyList()));
+        return result;
+    }
+    
+    private Collection<ShardingSphereIndex> createIndexMetaDataRevisionCandidates(final CreateTableStatement sqlStatement) {
+        Collection<ShardingSphereIndex> result = new LinkedList<>();
+        for (ConstraintDefinitionSegment each : sqlStatement.getConstraintDefinitions()) {
+            each.getIndexName().ifPresent(optional -> result.add(new ShardingSphereIndex(
+                    optional.getIndexName().getIdentifier().getValue(), each.getIndexColumns().stream()
+                            .map(ColumnSegment::getIdentifier).map(optionalColumn -> optionalColumn.getValue()).collect(Collectors.toList()),
+                    each.isUniqueKey() || optional.isUniqueKey())));
+        }
+        return result;
+    }
 }
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/TableMetaDataRefresherLoader.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/TableMetaDataRefresherLoader.java
index 3a20f9d7e98..f0c88f60ca0 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/TableMetaDataRefresherLoader.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/TableMetaDataRefresherLoader.java
@@ -29,6 +29,7 @@ import org.apache.shardingsphere.mode.metadata.refresher.util.TableRefreshUtils;
 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 
 import java.sql.SQLException;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.Map;
@@ -52,7 +53,25 @@ public final class TableMetaDataRefresherLoader {
      */
     public ShardingSphereTable loadCreatedTable(final ShardingSphereDatabase database, final String logicDataSourceName,
                                                 final String schemaName, final IdentifierValue tableIdentifierValue, final ConfigurationProperties props) throws SQLException {
-        return loadTable(database, logicDataSourceName, schemaName, tableIdentifierValue, props, false);
+        return loadCreatedTable(database, logicDataSourceName, schemaName, tableIdentifierValue, props, database.getAllSchemas());
+    }
+    
+    /**
+     * Load created table meta data.
+     *
+     * @param database database
+     * @param logicDataSourceName logic data source name
+     * @param schemaName schema name
+     * @param tableIdentifierValue table identifier value
+     * @param props configuration properties
+     * @param schemaMetaDataRevisionCandidateSchemas schema meta data revision candidate schemas
+     * @return loaded table meta data
+     * @throws SQLException SQL exception
+     */
+    public ShardingSphereTable loadCreatedTable(final ShardingSphereDatabase database, final String logicDataSourceName, final String schemaName,
+                                                final IdentifierValue tableIdentifierValue, final ConfigurationProperties props,
+                                                final Collection<ShardingSphereSchema> schemaMetaDataRevisionCandidateSchemas) throws SQLException {
+        return loadTable(database, logicDataSourceName, schemaName, tableIdentifierValue, props, false, schemaMetaDataRevisionCandidateSchemas);
     }
     
     /**
@@ -68,11 +87,12 @@ public final class TableMetaDataRefresherLoader {
      */
     public ShardingSphereTable loadAlteredTable(final ShardingSphereDatabase database, final String logicDataSourceName,
                                                 final String schemaName, final IdentifierValue tableIdentifierValue, final ConfigurationProperties props) throws SQLException {
-        return loadTable(database, logicDataSourceName, schemaName, tableIdentifierValue, props, true);
+        return loadTable(database, logicDataSourceName, schemaName, tableIdentifierValue, props, true, database.getAllSchemas());
     }
     
     private ShardingSphereTable loadTable(final ShardingSphereDatabase database, final String logicDataSourceName, final String schemaName,
-                                          final IdentifierValue tableIdentifierValue, final ConfigurationProperties props, final boolean fallbackWhenMissing) throws SQLException {
+                                          final IdentifierValue tableIdentifierValue, final ConfigurationProperties props, final boolean fallbackWhenMissing,
+                                          final Collection<ShardingSphereSchema> schemaMetaDataRevisionCandidateSchemas) throws SQLException {
         String candidateTableName = TableRefreshUtils.getTableLoadCandidateName(database, tableIdentifierValue, props);
         RuleMetaData ruleMetaData = new RuleMetaData(new LinkedList<>(database.getRuleMetaData().getRules()));
         boolean singleTable = TableRefreshUtils.isSingleTable(candidateTableName, database);
@@ -80,7 +100,7 @@ public final class TableMetaDataRefresherLoader {
             ruleMetaData.getAttributes(MutableDataNodeRuleAttribute.class).forEach(each -> each.put(logicDataSourceName, schemaName, candidateTableName));
         }
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getResourceMetaData().getStorageUnits(), ruleMetaData.getRules(), props, schemaName,
-                database.getIdentifierContext());
+                database.getIdentifierContext(), schemaMetaDataRevisionCandidateSchemas);
         Map<String, ShardingSphereSchema> schemas = GenericSchemaBuilder.build(Collections.singletonList(candidateTableName), database.getProtocolType(), material);
         ShardingSphereTable result = Optional.ofNullable(schemas.get(schemaName)).map(optional -> optional.getTable(candidateTableName))
                 .orElseGet(() -> fallbackWhenMissing ? new ShardingSphereTable(candidateTableName, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()) : null);
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/view/ViewMetaDataRefresherLoader.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/view/ViewMetaDataRefresherLoader.java
index 8162040e1ce..4858e749805 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/view/ViewMetaDataRefresherLoader.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/view/ViewMetaDataRefresherLoader.java
@@ -61,7 +61,7 @@ public final class ViewMetaDataRefresherLoader {
             ruleMetaData.getAttributes(MutableDataNodeRuleAttribute.class).forEach(each -> each.put(logicDataSourceName, schemaName, candidateViewName));
         }
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getResourceMetaData().getStorageUnits(), ruleMetaData.getRules(), props, schemaName,
-                database.getIdentifierContext());
+                database.getIdentifierContext(), database.getAllSchemas());
         Map<String, ShardingSphereSchema> schemas = GenericSchemaBuilder.build(Collections.singletonList(candidateViewName), database.getProtocolType(), material);
         Optional<ShardingSphereTable> actualTableMetaData = Optional.ofNullable(schemas.get(schemaName)).map(optional -> optional.getTable(candidateViewName));
         Preconditions.checkState(actualTableMetaData.isPresent(), "Load actual view metadata '%s' failed.", candidateViewName);
@@ -96,7 +96,7 @@ public final class ViewMetaDataRefresherLoader {
             ruleMetaData.getAttributes(MutableDataNodeRuleAttribute.class).forEach(each -> each.put(logicDataSourceName, schemaName, candidateViewName));
         }
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getResourceMetaData().getStorageUnits(), ruleMetaData.getRules(), props, schemaName,
-                database.getIdentifierContext());
+                database.getIdentifierContext(), database.getAllSchemas());
         Map<String, ShardingSphereSchema> schemas = GenericSchemaBuilder.build(Collections.singletonList(candidateViewName), database.getProtocolType(), material);
         Optional<ShardingSphereTable> actualViewMetaData = Optional.ofNullable(schemas.get(schemaName)).map(optional -> optional.getTable(candidateViewName));
         ShardingSphereSchema result = new ShardingSphereSchema(schemaName, database.getProtocolType());
diff --git a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/factory/MetaDataContextsFactoryTest.java b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/factory/MetaDataContextsFactoryTest.java
index 545a7e650ff..d53d9f49e5e 100644
--- a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/factory/MetaDataContextsFactoryTest.java
+++ b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/factory/MetaDataContextsFactoryTest.java
@@ -109,6 +109,9 @@ class MetaDataContextsFactoryTest {
         when(ShardingSphereDatabaseFactory.create(anyString(), any(DatabaseType.class), any(DatabaseConfiguration.class),
                 any(ConfigurationProperties.class), any(ComputeNodeInstanceContext.class), anyCollection()))
                 .thenAnswer(invocation -> createDatabaseFromConfiguration(invocation.getArgument(0), invocation.getArgument(1), invocation.getArgument(2), invocation.getArgument(5)));
+        when(ShardingSphereDatabaseFactory.createWithSchemaMetaDataRevisionCandidates(anyString(), any(DatabaseType.class), any(DatabaseConfiguration.class),
+                any(ConfigurationProperties.class), any(ComputeNodeInstanceContext.class), anyCollection()))
+                .thenAnswer(invocation -> createDatabaseFromConfiguration(invocation.getArgument(0), invocation.getArgument(1), invocation.getArgument(2), invocation.getArgument(5)));
         when(GlobalRulesBuilder.buildRules(anyCollection(), anyCollection(), any(ConfigurationProperties.class))).thenReturn(Collections.singleton(new MockedRule()));
         when(DatabaseTypeEngine.getProtocolType(any(DatabaseConfiguration.class), any(ConfigurationProperties.class))).thenReturn(databaseType);
         when(DatabaseTypeFactory.get(anyString())).thenReturn(databaseType);
@@ -208,6 +211,22 @@ class MetaDataContextsFactoryTest {
         assertTrue(actual.getMetaData().containsDatabase("foo_db"));
     }
     
+    @Test
+    void assertCreateByAlterRuleWithReloadedSchemasPassesCurrentSchemasAsRevisionCandidates() throws SQLException {
+        ShardingSphereSchema currentSchema = createSchemaWithTable("foo_schema", "current_table");
+        ShardingSphereDatabase database = new ShardingSphereDatabase(
+                "foo_db", databaseType, createResourceMetaDataWithSingleUnit(), new RuleMetaData(Collections.emptyList()), Collections.singleton(currentSchema),
+                new ConfigurationProperties(new Properties()));
+        ShardingSphereMetaData metaData = new ShardingSphereMetaData(
+                Collections.singleton(database), new ResourceMetaData(Collections.emptyMap(), Collections.emptyMap()), new RuleMetaData(Collections.emptyList()),
+                new ConfigurationProperties(new Properties()));
+        MetaDataContexts originalMetaDataContexts = new MetaDataContexts(metaData, new ShardingSphereStatistics());
+        ShardingSphereDatabase actualDatabase = new MetaDataContextsFactory(metaDataPersistFacade, mock())
+                .createChangedDatabaseByRebuild("foo_db", null, Collections.singleton(new MockedRuleConfiguration("alter_rule")), originalMetaDataContexts);
+        assertTrue(actualDatabase.containsSchema("foo_schema"));
+        assertTrue(actualDatabase.getSchema("foo_schema").containsTable("current_table"));
+    }
+    
     @Test
     void assertCreateWithProxyInstanceMetaData() throws SQLException {
         ComputeNodeInstanceContext computeNodeInstanceContext = mock(ComputeNodeInstanceContext.class, RETURNS_DEEP_STUBS);
diff --git a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresherTest.java b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresherTest.java
index fe3db02acfb..19588f005ad 100644
--- a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresherTest.java
+++ b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresherTest.java
@@ -17,28 +17,61 @@
 
 package org.apache.shardingsphere.mode.metadata.refresher.pushdown.type.table;
 
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
+import org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
+import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
+import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
+import org.apache.shardingsphere.infra.datanode.DataNode;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
 import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.metadata.database.schema.reviser.MetaDataReviseEntry;
+import org.apache.shardingsphere.infra.metadata.database.schema.reviser.index.IndexReviser;
+import org.apache.shardingsphere.infra.metadata.database.schema.reviser.table.TableNameReviser;
+import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
+import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
+import org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
+import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute;
+import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.mode.metadata.refresher.pushdown.PushDownMetaDataManagerPersistServiceFixture;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.constraint.ConstraintDefinitionSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexNameSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 import org.h2.jdbcx.JdbcDataSource;
 import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
 
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.Properties;
+import java.util.stream.Collectors;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.mockito.ArgumentMatchers.anyCollection;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
 
 class CreateTablePushDownMetaDataRefresherTest {
     
@@ -64,9 +97,44 @@ class CreateTablePushDownMetaDataRefresherTest {
         assertThat(persistService.getCreatedTable().getName(), is("Foo_Tbl"));
     }
     
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @Test
+    void assertRefreshCreatedShardingTableRestoresTruncatedNamedIndexFromCreateTableStatementCandidate() throws SQLException {
+        String logicTableName = "tbl";
+        String firstActualTableName = "tbl_0";
+        String secondActualTableName = "tbl_1";
+        String logicIndexName = "named_index_boundary_case_abcdefghijklmnopqrstuvwxyz_0123456789";
+        DatabaseType postgreSQLDatabaseType = mock(DatabaseType.class);
+        when(postgreSQLDatabaseType.getType()).thenReturn("PostgreSQL");
+        String firstActualIndexName = IndexMetaDataUtils.getActualIndexName(logicIndexName, firstActualTableName, postgreSQLDatabaseType);
+        String secondActualIndexName = IndexMetaDataUtils.getActualIndexName(logicIndexName, secondActualTableName, postgreSQLDatabaseType);
+        JdbcDataSource dataSource = createDataSource("create_sharding_table_with_truncated_index");
+        executeUpdate(dataSource,
+                String.format("CREATE TABLE \"%s\" (\"foo_col\" INT)", firstActualTableName),
+                String.format("CREATE INDEX \"%s\" ON \"%s\" (\"foo_col\")", firstActualIndexName, firstActualTableName),
+                String.format("CREATE TABLE \"%s\" (\"foo_col\" INT)", secondActualTableName),
+                String.format("CREATE INDEX \"%s\" ON \"%s\" (\"foo_col\")", secondActualIndexName, secondActualTableName));
+        CreateTableCandidateRule rule = new CreateTableCandidateRule(logicTableName, Arrays.asList(
+                new DataNode(LOGIC_DATA_SOURCE_NAME, SCHEMA_NAME, firstActualTableName), new DataNode(LOGIC_DATA_SOURCE_NAME, SCHEMA_NAME, secondActualTableName)));
+        Map<ShardingSphereRule, MetaDataReviseEntry<?>> reviseEntries = Collections.singletonMap(rule, new CreateTableCandidateMetaDataReviseEntry());
+        PushDownMetaDataManagerPersistServiceFixture persistService = new PushDownMetaDataManagerPersistServiceFixture();
+        try (MockedStatic<OrderedSPILoader> mockedLoader = mockStatic(OrderedSPILoader.class, CALLS_REAL_METHODS)) {
+            mockedLoader.when(() -> OrderedSPILoader.getServices(eq(MetaDataReviseEntry.class), anyCollection())).thenReturn((Map) reviseEntries);
+            new CreateTablePushDownMetaDataRefresher().refresh(persistService, createDatabase(dataSource, new RuleMetaData(Collections.singleton(rule))), LOGIC_DATA_SOURCE_NAME, SCHEMA_NAME,
+                    databaseType, createCreateTableStatement(logicTableName, logicIndexName), createPropertiesWithCheckMetaDataEnabled());
+        }
+        assertThat(persistService.getCreatedTableSchemaName(), is(SCHEMA_NAME));
+        assertThat(persistService.getCreatedTable().getName(), is(logicTableName));
+        assertThat(persistService.getCreatedTable().getAllIndexes().iterator().next().getName(), is(logicIndexName));
+    }
+    
     private ShardingSphereDatabase createDatabase(final JdbcDataSource dataSource) {
+        return createDatabase(dataSource, new RuleMetaData(Collections.emptyList()));
+    }
+    
+    private ShardingSphereDatabase createDatabase(final JdbcDataSource dataSource, final RuleMetaData ruleMetaData) {
         return new ShardingSphereDatabase("foo_db", databaseType, new ResourceMetaData(Collections.singletonMap(LOGIC_DATA_SOURCE_NAME, dataSource)),
-                new RuleMetaData(Collections.emptyList()), Collections.emptyList(), new ConfigurationProperties(new Properties()));
+                ruleMetaData, Collections.emptyList(), new ConfigurationProperties(new Properties()));
     }
     
     private JdbcDataSource createDataSource(final String databaseName) {
@@ -86,4 +154,163 @@ class CreateTablePushDownMetaDataRefresherTest {
             }
         }
     }
+    
+    private CreateTableStatement createCreateTableStatement(final String logicTableName, final String logicIndexName) {
+        ConstraintDefinitionSegment constraintDefinition = new ConstraintDefinitionSegment(0, 0);
+        constraintDefinition.setIndexName(new IndexSegment(0, 0, new IndexNameSegment(0, 0, new IdentifierValue(logicIndexName))));
+        constraintDefinition.getIndexColumns().add(new ColumnSegment(0, 0, new IdentifierValue("foo_col")));
+        return CreateTableStatement.builder()
+                .databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue(logicTableName))))
+                .constraintDefinitions(Collections.singleton(constraintDefinition))
+                .build();
+    }
+    
+    private ConfigurationProperties createPropertiesWithCheckMetaDataEnabled() {
+        Properties result = new Properties();
+        result.setProperty(ConfigurationPropertyKey.CHECK_TABLE_METADATA_ENABLED.getKey(), Boolean.TRUE.toString());
+        return new ConfigurationProperties(result);
+    }
+    
+    private static final class CreateTableCandidateRule implements ShardingSphereRule {
+        
+        private final String logicTableName;
+        
+        private final CreateTableCandidateRuleAttribute ruleAttribute;
+        
+        private CreateTableCandidateRule(final String logicTableName, final Collection<DataNode> dataNodes) {
+            this.logicTableName = logicTableName;
+            ruleAttribute = new CreateTableCandidateRuleAttribute(logicTableName, dataNodes);
+        }
+        
+        @Override
+        public RuleConfiguration getConfiguration() {
+            return new CreateTableCandidateRuleConfiguration();
+        }
+        
+        @Override
+        public RuleAttributes getAttributes() {
+            return new RuleAttributes(ruleAttribute);
+        }
+        
+        @Override
+        public int getOrder() {
+            return 0;
+        }
+        
+        private String reviseTableName(final String tableName) {
+            return ruleAttribute.findLogicTableByActualTable(tableName).orElse(tableName);
+        }
+    }
+    
+    private static final class CreateTableCandidateRuleConfiguration implements RuleConfiguration {
+    }
+    
+    private static final class CreateTableCandidateRuleAttribute implements TableMapperRuleAttribute, DataNodeRuleAttribute {
+        
+        private final String logicTableName;
+        
+        private final Map<String, Collection<DataNode>> dataNodes;
+        
+        private CreateTableCandidateRuleAttribute(final String logicTableName, final Collection<DataNode> dataNodes) {
+            this.logicTableName = logicTableName;
+            this.dataNodes = new LinkedHashMap<>(1, 1F);
+            this.dataNodes.put(logicTableName, dataNodes);
+        }
+        
+        @Override
+        public Collection<String> getLogicTableNames() {
+            return Collections.singleton(logicTableName);
+        }
+        
+        @Override
+        public Collection<String> getDistributedTableNames() {
+            return Collections.emptyList();
+        }
+        
+        @Override
+        public Collection<String> getEnhancedTableNames() {
+            return Collections.emptyList();
+        }
+        
+        @Override
+        public Map<String, Collection<DataNode>> getAllDataNodes() {
+            return dataNodes;
+        }
+        
+        @Override
+        public Collection<DataNode> getDataNodesByTableName(final String tableName) {
+            return dataNodes.getOrDefault(tableName, Collections.emptyList());
+        }
+        
+        @Override
+        public Optional<String> findFirstActualTable(final String logicTable) {
+            return getDataNodesByTableName(logicTable).stream().findFirst().map(DataNode::getTableName);
+        }
+        
+        @Override
+        public boolean isNeedAccumulate(final Collection<String> tables) {
+            return false;
+        }
+        
+        @Override
+        public Optional<String> findLogicTableByActualTable(final String actualTable) {
+            return dataNodes.entrySet().stream().filter(entry -> entry.getValue().stream().map(DataNode::getTableName).anyMatch(each -> each.equalsIgnoreCase(actualTable)))
+                    .map(Entry::getKey).findFirst();
+        }
+        
+        @Override
+        public Optional<String> findActualTableByCatalog(final String catalog, final String logicTable) {
+            return findFirstActualTable(logicTable);
+        }
+        
+        @Override
+        public boolean isReplicaBasedDistribution() {
+            return false;
+        }
+    }
+    
+    private static final class CreateTableCandidateMetaDataReviseEntry implements MetaDataReviseEntry<CreateTableCandidateRule> {
+        
+        @Override
+        public Optional<TableNameReviser<CreateTableCandidateRule>> getTableNameReviser() {
+            return Optional.of((originalName, rule) -> rule.reviseTableName(originalName));
+        }
+        
+        @Override
+        public Optional<IndexReviser<CreateTableCandidateRule>> getIndexReviser(final CreateTableCandidateRule rule, final String tableName) {
+            return Optional.of(new CreateTableCandidateIndexReviser());
+        }
+        
+        @Override
+        public int getOrder() {
+            return 0;
+        }
+        
+        @Override
+        public Class<CreateTableCandidateRule> getTypeClass() {
+            return CreateTableCandidateRule.class;
+        }
+    }
+    
+    private static final class CreateTableCandidateIndexReviser implements IndexReviser<CreateTableCandidateRule> {
+        
+        @Override
+        public Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final Collection<TableMetaData> originalTableMetaDataList,
+                                              final CreateTableCandidateRule rule) {
+            return revise(tableName, originalMetaData, originalTableMetaDataList, Collections.emptyList(), rule);
+        }
+        
+        @Override
+        public Optional<IndexMetaData> revise(final String tableName, final IndexMetaData originalMetaData, final Collection<TableMetaData> originalTableMetaDataList,
+                                              final Collection<TableMetaData> schemaMetaDataRevisionCandidateTableMetaDataList, final CreateTableCandidateRule rule) {
+            Collection<String> candidateIndexNames = schemaMetaDataRevisionCandidateTableMetaDataList.stream()
+                    .filter(each -> rule.logicTableName.equalsIgnoreCase(each.getName())).flatMap(each -> each.getIndexes().stream()).map(IndexMetaData::getName)
+                    .collect(Collectors.toCollection(LinkedHashSet::new));
+            IndexMetaData result = new IndexMetaData(IndexMetaDataUtils.findGeneratedLogicIndexName(
+                    originalMetaData.getName(), tableName, candidateIndexNames).orElse(originalMetaData.getName()), originalMetaData.getColumns());
+            result.setUnique(originalMetaData.isUnique());
+            return Optional.of(result);
+        }
+    }
 }
diff --git a/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/persist/service/ClusterMetaDataManagerPersistService.java b/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/persist/service/ClusterMetaDataManagerPersistService.java
index 19de9d7d056..31baf237ac6 100644
--- a/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/persist/service/ClusterMetaDataManagerPersistService.java
+++ b/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/persist/service/ClusterMetaDataManagerPersistService.java
@@ -268,7 +268,8 @@ public final class ClusterMetaDataManagerPersistService implements MetaDataManag
     private ShardingSphereDatabase rebuildDatabaseSchemaIndex(final String databaseName, final MetaDataContexts reloadMetaDataContexts) {
         ShardingSphereDatabase database = reloadMetaDataContexts.getMetaData().getDatabase(databaseName);
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getResourceMetaData().getStorageUnits(), database.getRuleMetaData().getRules(),
-                reloadMetaDataContexts.getMetaData().getProps(), new DatabaseTypeRegistry(database.getProtocolType()).getDefaultSchemaName(databaseName), database.getIdentifierContext());
+                reloadMetaDataContexts.getMetaData().getProps(), new DatabaseTypeRegistry(database.getProtocolType()).getDefaultSchemaName(databaseName), database.getIdentifierContext(),
+                database.getAllSchemas());
         Collection<ShardingSphereSchema> schemas = new LinkedList<>(GenericSchemaBuilder.build(database.getProtocolType(), material).values());
         return new ShardingSphereDatabase(database.getName(), database.getProtocolType(), database.getResourceMetaData(),
                 database.getRuleMetaData(), schemas, reloadMetaDataContexts.getMetaData().getProps());
diff --git a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistService.java b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistService.java
index 514f7cc1251..f8ba591c4da 100644
--- a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistService.java
+++ b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistService.java
@@ -334,7 +334,8 @@ public final class StandaloneMetaDataManagerPersistService implements MetaDataMa
     private ShardingSphereDatabase rebuildDatabaseSchemaIndex(final String databaseName, final MetaDataContexts metaDataContexts) {
         ShardingSphereDatabase database = metaDataContexts.getMetaData().getDatabase(databaseName);
         GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getResourceMetaData().getStorageUnits(), database.getRuleMetaData().getRules(),
-                metaDataContexts.getMetaData().getProps(), new DatabaseTypeRegistry(database.getProtocolType()).getDefaultSchemaName(databaseName), database.getIdentifierContext());
+                metaDataContexts.getMetaData().getProps(), new DatabaseTypeRegistry(database.getProtocolType()).getDefaultSchemaName(databaseName), database.getIdentifierContext(),
+                database.getAllSchemas());
         Collection<ShardingSphereSchema> schemas = new LinkedList<>(GenericSchemaBuilder.build(database.getProtocolType(), material).values());
         return new ShardingSphereDatabase(database.getName(), database.getProtocolType(), database.getResourceMetaData(), database.getRuleMetaData(), schemas,
                 metaDataContexts.getMetaData().getProps());
diff --git a/test/it/rewriter/src/test/resources/scenario/sharding/case/ddl/index.xml b/test/it/rewriter/src/test/resources/scenario/sharding/case/ddl/index.xml
index d1c86054bec..b5a9f5d78a2 100644
--- a/test/it/rewriter/src/test/resources/scenario/sharding/case/ddl/index.xml
+++ b/test/it/rewriter/src/test/resources/scenario/sharding/case/ddl/index.xml
@@ -22,7 +22,7 @@
         <output sql="CREATE INDEX status_idx ON t_account_0 (status)" />
         <output sql="CREATE INDEX status_idx ON t_account_1 (status)" />
     </rewrite-assertion>
-    
+
     <rewrite-assertion id="create_index_for_schema_uniqueness_level_db" db-types="PostgreSQL,openGauss">
         <input sql="CREATE INDEX status_idx ON t_account (status)" />
         <output sql="CREATE INDEX status_idx_t_account_0 ON t_account_0 (status)" />
@@ -34,7 +34,13 @@
         <output sql="CREATE INDEX status_idx_t_account_0 ON public.t_account_0 (status)" />
         <output sql="CREATE INDEX status_idx_t_account_1 ON public.t_account_1 (status)" />
     </rewrite-assertion>
-    
+
+    <rewrite-assertion id="create_index_near_identifier_limit_with_named_index" db-types="PostgreSQL,openGauss">
+        <input sql="CREATE INDEX named_index_boundary_case_abcdefghijklmnopqrstuvwxyz ON t_account (status)" />
+        <output sql="CREATE INDEX named_index_boundary_case_abcdefghijklmnopqrstuvwxyz_h5n59w5zl ON t_account_0 (status)" />
+        <output sql="CREATE INDEX named_index_boundary_case_abcdefghijklmnopqrstuvwxyz_h11kmgp1d ON t_account_1 (status)" />
+    </rewrite-assertion>
+
     <rewrite-assertion id="create_index_without_index_name_with_single_column" db-types="PostgreSQL,openGauss">
         <input sql="/* SHARDINGSPHERE_HINT: SKIP_METADATA_VALIDATE=true */ CREATE INDEX ON t_account (status)" />
         <output sql="CREATE INDEX status_idx_t_account_0 ON t_account_0 (status)" />
@@ -59,6 +65,12 @@
         <output sql="CREATE INDEX status_account_id_idx_t_account_1 ON public.t_account_1 (status, account_id)" />
     </rewrite-assertion>
 
+    <rewrite-assertion id="create_index_without_index_name_near_identifier_limit" db-types="PostgreSQL,openGauss">
+        <input sql="/* SHARDINGSPHERE_HINT: SKIP_METADATA_VALIDATE=true */ CREATE INDEX ON t_account (status, status, status, status, status, status, status, status, status)" />
+        <output sql="CREATE INDEX status_status_status_status_status_status_status_stat_t0dgoa155 ON t_account_0 (status, status, status, status, status, status, status, status, status)" />
+        <output sql="CREATE INDEX status_status_status_status_status_status_status_stat_t6hp20jb3 ON t_account_1 (status, status, status, status, status, status, status, status, status)" />
+    </rewrite-assertion>
+
     <rewrite-assertion id="alter_index_rename" db-types="PostgreSQL,openGauss">
         <input sql="ALTER INDEX status_idx_exist RENAME TO status_idx_new" />
         <output sql="ALTER INDEX status_idx_exist_t_account_0 RENAME TO status_idx_new_t_account_0" />
@@ -70,34 +82,34 @@
         <output sql="ALTER INDEX public.status_idx_exist_t_account_0 RENAME TO status_idx_new_t_account_0" />
         <output sql="ALTER INDEX public.status_idx_exist_t_account_1 RENAME TO status_idx_new_t_account_1" />
     </rewrite-assertion>
-    
+
     <rewrite-assertion id="drop_index_for_table_uniqueness_level_db" db-types="MySQL">
         <input sql="DROP INDEX status_idx_exist ON t_account" />
         <output sql="DROP INDEX status_idx_exist ON t_account_0" />
         <output sql="DROP INDEX status_idx_exist ON t_account_1" />
     </rewrite-assertion>
-    
+
     <rewrite-assertion id="drop_index_with_single_table_for_table_uniqueness_level_db" db-types="MySQL">
         <input sql="DROP INDEX single_id_idx ON t_single" />
         <output sql="DROP INDEX single_id_idx ON t_single" />
     </rewrite-assertion>
-    
+
     <rewrite-assertion id="drop_index_with_broadcast_table_for_table_uniqueness_level_db" db-types="MySQL">
         <input sql="DROP INDEX broadcast_id_idx ON t_config" />
         <output sql="DROP INDEX broadcast_id_idx ON t_config" />
     </rewrite-assertion>
-    
+
     <rewrite-assertion id="drop_index_for_schema_uniqueness_level_db" db-types="PostgreSQL,openGauss">
         <input sql="DROP INDEX status_idx_exist" />
         <output sql="DROP INDEX status_idx_exist_t_account_0" />
         <output sql="DROP INDEX status_idx_exist_t_account_1" />
     </rewrite-assertion>
-    
+
     <rewrite-assertion id="drop_index_with_single_table_for_schema_uniqueness_level_db" db-types="PostgreSQL,openGauss">
         <input sql="DROP INDEX single_id_idx" />
         <output sql="DROP INDEX single_id_idx" />
     </rewrite-assertion>
-    
+
     <rewrite-assertion id="drop_index_with_broadcast_table_for_schema_uniqueness_level_db" db-types="PostgreSQL,openGauss">
         <input sql="DROP INDEX broadcast_id_idx" />
         <output sql="DROP INDEX broadcast_id_idx" />