You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by tu...@apache.org on 2022/09/08 02:01:07 UTC

[shardingsphere] branch master updated: Governance center support view changed (#20856)

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

tuichenchuxin 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 909c064dfbd Governance center support view changed (#20856)
909c064dfbd is described below

commit 909c064dfbdbd3e1daae8791dda4066a5dd7fd4d
Author: zhaojinchao <zh...@apache.org>
AuthorDate: Thu Sep 8 10:00:59 2022 +0800

    Governance center support view changed (#20856)
    
    * Extract SchemaManager for schema meta data changed
    
    * Refactor CREATE/DROP view refresh
    
    * Add view meta data logic for governance center
    
    * Finish view governance logic
    
    * Fix checkstyle
    
    * Fix unit test
---
 .../decorator/model/ShardingSphereSchema.java      |  9 ++++
 .../database/schema/event/SchemaAlteredEvent.java  |  5 ++
 .../type/CreateViewStatementSchemaRefresher.java   | 13 +++--
 .../type/DropViewStatementSchemaRefresher.java     | 10 ++--
 .../mode/manager/ContextManager.java               | 52 +++++++++++++-------
 .../persist/node/DatabaseMetaDataNode.java         | 12 +++++
 .../schema/TableMetaDataPersistService.java        |  1 -
 .../mode/manager/ContextManagerTest.java           | 29 +++++++++--
 .../persist/node/DatabaseMetaDataNodeTest.java     |  7 +++
 .../ClusterContextManagerCoordinator.java          | 24 +++++++---
 ...edEvent.java => TableMetaDataChangedEvent.java} |  4 +-
 ...gedEvent.java => ViewMetaDataChangedEvent.java} | 10 ++--
 .../SchemaMetaDataRegistrySubscriber.java          | 10 +++-
 .../metadata/watcher/MetaDataChangedWatcher.java   | 56 +++++++++++++---------
 .../ClusterContextManagerCoordinatorTest.java      | 19 ++++++--
 .../watcher/GlobalRuleChangedWatcherTest.java      |  6 +--
 .../SchemaMetaDataRegistrySubscriberTest.java      |  9 ++--
 .../watcher/MetaDataChangedWatcherTest.java        | 20 ++++++--
 18 files changed, 213 insertions(+), 83 deletions(-)

diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/decorator/model/ShardingSphereSchema.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/decorator/model/ShardingSphereSchema.java
index 5ea2b254d47..ca3a83fd7ea 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/decorator/model/ShardingSphereSchema.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/decorator/model/ShardingSphereSchema.java
@@ -127,6 +127,15 @@ public final class ShardingSphereSchema {
         tables.remove(tableName.toLowerCase());
     }
     
+    /**
+     * Remove view meta data.
+     *
+     * @param viewName view name
+     */
+    public void removeView(final String viewName) {
+        views.remove(viewName.toLowerCase());
+    }
+    
     /**
      * Judge contains table from table meta data or not.
      *
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/event/SchemaAlteredEvent.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/event/SchemaAlteredEvent.java
index 5c6fee35f6c..4957395d697 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/event/SchemaAlteredEvent.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/event/SchemaAlteredEvent.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.infra.metadata.database.schema.event;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereView;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -37,5 +38,9 @@ public final class SchemaAlteredEvent implements MetaDataRefreshedEvent {
     
     private final Collection<ShardingSphereTable> alteredTables = new ArrayList<>();
     
+    private final Collection<ShardingSphereView> alteredViews = new ArrayList<>();
+    
     private final Collection<String> droppedTables = new ArrayList<>();
+    
+    private final Collection<String> droppedViews = new ArrayList<>();
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/CreateViewStatementSchemaRefresher.java b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/CreateViewStatementSchemaRefresher.java
index 47c955a75f7..8360071ef11 100644
--- a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/CreateViewStatementSchemaRefresher.java
+++ b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/CreateViewStatementSchemaRefresher.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericS
 import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilderMaterials;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereView;
 import org.apache.shardingsphere.infra.metadata.database.schema.event.MetaDataRefreshedEvent;
 import org.apache.shardingsphere.infra.metadata.database.schema.event.SchemaAlteredEvent;
 import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule;
@@ -51,12 +52,14 @@ public final class CreateViewStatementSchemaRefresher implements MetaDataRefresh
         GenericSchemaBuilderMaterials materials = new GenericSchemaBuilderMaterials(database.getProtocolType(),
                 database.getResource().getDatabaseType(), database.getResource().getDataSources(), database.getRuleMetaData().getRules(), props, schemaName);
         Map<String, ShardingSphereSchema> schemaMap = GenericSchemaBuilder.build(Collections.singletonList(viewName), materials);
-        Optional<ShardingSphereTable> actualViewMetaData = Optional.ofNullable(schemaMap.get(schemaName)).map(optional -> optional.getTable(viewName));
-        // TODO Put view meta data to ShardingSphereSchema 's views
-        if (actualViewMetaData.isPresent()) {
-            database.getSchema(schemaName).putTable(viewName, actualViewMetaData.get());
+        Optional<ShardingSphereTable> actualTableMetaData = Optional.ofNullable(schemaMap.get(schemaName)).map(optional -> optional.getTable(viewName));
+        Optional<ShardingSphereView> actualViewMetaData = Optional.ofNullable(schemaMap.get(schemaName)).map(optional -> optional.getView(viewName));
+        if (actualTableMetaData.isPresent() && actualViewMetaData.isPresent()) {
+            database.getSchema(schemaName).putTable(viewName, actualTableMetaData.get());
+            database.getSchema(schemaName).putView(viewName, actualViewMetaData.get());
             SchemaAlteredEvent event = new SchemaAlteredEvent(database.getName(), schemaName);
-            event.getAlteredTables().add(actualViewMetaData.get());
+            event.getAlteredTables().add(actualTableMetaData.get());
+            event.getAlteredViews().add(actualViewMetaData.get());
             return Optional.of(event);
         }
         return Optional.empty();
diff --git a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/DropViewStatementSchemaRefresher.java b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/DropViewStatementSchemaRefresher.java
index 25bcb23596c..f421c6fdd61 100644
--- a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/DropViewStatementSchemaRefresher.java
+++ b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/DropViewStatementSchemaRefresher.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.infra.context.refresher.type;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.context.refresher.MetaDataRefresher;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.event.MetaDataRefreshedEvent;
 import org.apache.shardingsphere.infra.metadata.database.schema.event.SchemaAlteredEvent;
 import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule;
@@ -39,10 +40,13 @@ public final class DropViewStatementSchemaRefresher implements MetaDataRefresher
     public Optional<MetaDataRefreshedEvent> refresh(final ShardingSphereDatabase database, final Collection<String> logicDataSourceNames,
                                                     final String schemaName, final DropViewStatement sqlStatement, final ConfigurationProperties props) throws SQLException {
         SchemaAlteredEvent event = new SchemaAlteredEvent(database.getName(), schemaName);
-        // TODO Drop view meta data from views
         sqlStatement.getViews().forEach(each -> {
-            database.getSchema(schemaName).removeTable(each.getTableName().getIdentifier().getValue());
-            event.getDroppedTables().add(each.getTableName().getIdentifier().getValue());
+            ShardingSphereSchema schema = database.getSchema(schemaName);
+            String viewName = each.getTableName().getIdentifier().getValue();
+            schema.removeTable(viewName);
+            event.getDroppedTables().add(viewName);
+            schema.removeView(viewName);
+            event.getDroppedViews().add(viewName);
         });
         Collection<MutableDataNodeRule> rules = database.getRuleMetaData().findRules(MutableDataNodeRule.class);
         for (SimpleTableSegment each : sqlStatement.getViews()) {
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
index 2c47ab3d551..d6eb16dc0fc 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
@@ -39,6 +39,7 @@ import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericS
 import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilderMaterials;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereView;
 import org.apache.shardingsphere.infra.rule.builder.global.GlobalRulesBuilder;
 import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule;
 import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule;
@@ -145,11 +146,15 @@ public final class ContextManager implements AutoCloseable {
      * @param databaseName database name
      * @param schemaName schema name
      * @param toBeDeletedTableName to be deleted table name
+     * @param toBeDeletedViewName to be deleted view name
      */
-    public synchronized void alterSchema(final String databaseName, final String schemaName, final String toBeDeletedTableName) {
-        if (metaDataContexts.getMetaData().containsDatabase(databaseName)) {
-            Optional.ofNullable(toBeDeletedTableName).ifPresent(optional -> dropTable(databaseName, schemaName, optional));
+    public synchronized void alterSchema(final String databaseName, final String schemaName, final String toBeDeletedTableName,
+                                         final String toBeDeletedViewName) {
+        if (!metaDataContexts.getMetaData().containsDatabase(databaseName) || !metaDataContexts.getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
+            return;
         }
+        Optional.ofNullable(toBeDeletedTableName).ifPresent(optional -> dropTable(databaseName, schemaName, optional));
+        Optional.ofNullable(toBeDeletedViewName).ifPresent(optional -> dropView(databaseName, schemaName, optional));
     }
     
     /**
@@ -158,37 +163,50 @@ public final class ContextManager implements AutoCloseable {
      * @param databaseName database name
      * @param schemaName schema name
      * @param toBeChangedTable to be changed table
+     * @param toBeChangedView to be changed view
      */
-    public synchronized void alterSchema(final String databaseName, final String schemaName, final ShardingSphereTable toBeChangedTable) {
-        if (metaDataContexts.getMetaData().containsDatabase(databaseName)) {
-            Optional.ofNullable(toBeChangedTable).ifPresent(optional -> alterTable(databaseName, schemaName, optional));
+    public synchronized void alterSchema(final String databaseName, final String schemaName, final ShardingSphereTable toBeChangedTable,
+                                         final ShardingSphereView toBeChangedView) {
+        if (!metaDataContexts.getMetaData().containsDatabase(databaseName) || !metaDataContexts.getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
+            return;
         }
+        Optional.ofNullable(toBeChangedTable).ifPresent(optional -> alterTable(databaseName, schemaName, optional));
+        Optional.ofNullable(toBeChangedView).ifPresent(optional -> alterView(databaseName, schemaName, optional));
     }
     
-    private synchronized void alterTable(final String databaseName, final String schemaName, final ShardingSphereTable beBoChangedTable) {
-        alterTable(metaDataContexts.getMetaData().getDatabase(databaseName), schemaName, beBoChangedTable);
+    private synchronized void dropTable(final String databaseName, final String schemaName, final String toBeDeletedTableName) {
+        metaDataContexts.getMetaData().getDatabase(databaseName).getSchema(schemaName).removeTable(toBeDeletedTableName);
+        metaDataContexts.getMetaData().getDatabase(databaseName).getRuleMetaData().getRules().stream().filter(each -> each instanceof MutableDataNodeRule).findFirst()
+                .ifPresent(optional -> ((MutableDataNodeRule) optional).remove(schemaName, toBeDeletedTableName));
     }
     
-    private synchronized void alterTable(final ShardingSphereDatabase database, final String schemaName, final ShardingSphereTable beBoChangedTable) {
+    private synchronized void dropView(final String databaseName, final String schemaName, final String toBeDeletedViewName) {
+        metaDataContexts.getMetaData().getDatabase(databaseName).getSchema(schemaName).removeView(toBeDeletedViewName);
+        metaDataContexts.getMetaData().getDatabase(databaseName).getRuleMetaData().getRules().stream().filter(each -> each instanceof MutableDataNodeRule).findFirst()
+                .ifPresent(optional -> ((MutableDataNodeRule) optional).remove(schemaName, toBeDeletedViewName));
+    }
+    
+    private synchronized void alterTable(final String databaseName, final String schemaName, final ShardingSphereTable beBoChangedTable) {
+        ShardingSphereDatabase database = metaDataContexts.getMetaData().getDatabase(databaseName);
         if (!containsMutableDataNodeRule(database, beBoChangedTable.getName())) {
             database.reloadRules(MutableDataNodeRule.class);
         }
         database.getSchema(schemaName).putTable(beBoChangedTable.getName(), beBoChangedTable);
     }
     
+    private synchronized void alterView(final String databaseName, final String schemaName, final ShardingSphereView beBoChangedView) {
+        ShardingSphereDatabase database = metaDataContexts.getMetaData().getDatabase(databaseName);
+        if (!containsMutableDataNodeRule(database, beBoChangedView.getName())) {
+            database.reloadRules(MutableDataNodeRule.class);
+        }
+        database.getSchema(schemaName).putView(beBoChangedView.getName(), beBoChangedView);
+    }
+    
     private boolean containsMutableDataNodeRule(final ShardingSphereDatabase database, final String tableName) {
         return database.getRuleMetaData().findRules(DataNodeContainedRule.class).stream()
                 .filter(each -> !(each instanceof MutableDataNodeRule)).anyMatch(each -> each.getAllTables().contains(tableName));
     }
     
-    private void dropTable(final String databaseName, final String schemaName, final String toBeDeletedTableName) {
-        if (metaDataContexts.getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
-            metaDataContexts.getMetaData().getDatabase(databaseName).getSchema(schemaName).removeTable(toBeDeletedTableName);
-            metaDataContexts.getMetaData().getDatabase(databaseName).getRuleMetaData().getRules().stream().filter(each -> each instanceof MutableDataNodeRule)
-                    .findFirst().ifPresent(optional -> ((MutableDataNodeRule) optional).remove(schemaName, toBeDeletedTableName));
-        }
-    }
-    
     /**
      * Drop schema.
      *
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/node/DatabaseMetaDataNode.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/node/DatabaseMetaDataNode.java
index ebd622163b4..d78278066b4 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/node/DatabaseMetaDataNode.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/node/DatabaseMetaDataNode.java
@@ -218,6 +218,18 @@ public final class DatabaseMetaDataNode {
         return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
     }
     
+    /**
+     * Get view meta data path.
+     *
+     * @param viewMetaDataPath view meta data path
+     * @return view name
+     */
+    public static Optional<String> getViewName(final String viewMetaDataPath) {
+        Pattern pattern = Pattern.compile(getMetaDataNodePath() + "/([\\w\\-]+)/([\\w\\-]+)/([\\w\\-]+)/views" + "/([\\w\\-]+)$", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(viewMetaDataPath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
     /**
      * Get active version path.
      * 
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/service/schema/TableMetaDataPersistService.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/service/schema/TableMetaDataPersistService.java
index f4335fa3544..53a154d591a 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/service/schema/TableMetaDataPersistService.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/metadata/persist/service/schema/TableMetaDataPersistService.java
@@ -51,7 +51,6 @@ public final class TableMetaDataPersistService implements SchemaMetaDataPersistS
     public void persist(final String databaseName, final String schemaName, final Map<String, ShardingSphereTable> tables) {
         tables.forEach((key, value) -> repository.persist(DatabaseMetaDataNode.getTableMetaDataPath(databaseName, schemaName, key.toLowerCase()),
                 YamlEngine.marshal(new YamlTableSwapper().swapToYamlConfiguration(value))));
-        
     }
     
     @Override
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
index 872f1aa4c43..c29c74326a6 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
@@ -32,6 +32,7 @@ import org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRule
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereColumn;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereView;
 import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule;
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistService;
@@ -81,6 +82,7 @@ public final class ContextManagerTest {
         ShardingSphereDatabase database = mockDatabase();
         when(metaDataContexts.getMetaData().containsDatabase("foo_db")).thenReturn(true);
         when(metaDataContexts.getMetaData().getDatabase("foo_db")).thenReturn(database);
+        when(metaDataContexts.getMetaData().getDatabase("foo_db").containsSchema("foo_schema")).thenReturn(true);
         contextManager = new ContextManager(metaDataContexts, mock(InstanceContext.class));
     }
     
@@ -157,25 +159,44 @@ public final class ContextManagerTest {
         when(metaDataContexts.getMetaData().getDatabase("foo_db").getSchema("foo_schema")).thenReturn(toBeAlteredSchema);
         ShardingSphereColumn toBeChangedColumn = new ShardingSphereColumn("foo_col", Types.VARCHAR, false, false, false, true);
         ShardingSphereTable toBeChangedTable = new ShardingSphereTable("foo_tbl", Collections.singleton(toBeChangedColumn), Collections.emptyList(), Collections.emptyList());
-        contextManager.alterSchema("foo_db", "foo_schema", toBeChangedTable);
+        contextManager.alterSchema("foo_db", "foo_schema", toBeChangedTable, null);
         ShardingSphereTable table = contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db").getSchema("foo_schema").getTables().get("foo_tbl");
         assertThat(table.getColumns().size(), is(1));
         assertTrue(table.getColumns().containsKey("foo_col"));
     }
     
+    @Test
+    public void assertAlterSchemaForViewAltered() {
+        ShardingSphereSchema toBeAlteredSchema = createToBeAlteredSchema();
+        when(metaDataContexts.getMetaData().getDatabase("foo_db").getSchemas()).thenReturn(Collections.singletonMap("foo_schema", toBeAlteredSchema));
+        when(metaDataContexts.getMetaData().getDatabase("foo_db").getSchema("foo_schema")).thenReturn(toBeAlteredSchema);
+        ShardingSphereView toBeChangedView = new ShardingSphereView("foo_view", "select `foo_view`.`foo_view`.`id` AS `id` from `foo_view`.`foo_view`");
+        contextManager.alterSchema("foo_db", "foo_schema", null, toBeChangedView);
+        ShardingSphereView view = contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db").getSchema("foo_schema").getView("foo_view");
+        assertThat(view.getName(), is("foo_view"));
+        assertThat(view.getViewDefinition(), is("select `foo_view`.`foo_view`.`id` AS `id` from `foo_view`.`foo_view`"));
+    }
+    
     @Test
     public void assertAlterSchemaForTableDropped() {
         when(metaDataContexts.getMetaData().getDatabase("foo_db").getSchemas()).thenReturn(Collections.singletonMap("foo_schema", createToBeAlteredSchema()));
-        contextManager.alterSchema("foo_db", "foo_schema", "foo_tbl");
+        contextManager.alterSchema("foo_db", "foo_schema", "foo_tbl", null);
         assertFalse(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db").getSchema("foo_schema").getTables().containsKey("foo_tbl"));
     }
     
+    @Test
+    public void assertAlterSchemaForViewDropped() {
+        when(metaDataContexts.getMetaData().getDatabase("foo_db").getSchemas()).thenReturn(Collections.singletonMap("foo_schema", createToBeAlteredSchema()));
+        contextManager.alterSchema("foo_db", "foo_schema", "foo_view", null);
+        assertFalse(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db").getSchema("foo_schema").getViews().containsKey("foo_view"));
+    }
+    
     private ShardingSphereSchema createToBeAlteredSchema() {
         ShardingSphereTable beforeChangedTable = new ShardingSphereTable("foo_tbl", Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
-        return new ShardingSphereSchema(Collections.singletonMap("foo_tbl", beforeChangedTable), Collections.emptyMap());
+        ShardingSphereView beforeChangedView = new ShardingSphereView("foo_tbl", "");
+        return new ShardingSphereSchema(Collections.singletonMap("foo_tbl", beforeChangedTable), Collections.singletonMap("foo_view", beforeChangedView));
     }
     
-    // TODO fix me
     @Ignore
     @Test
     public void assertUpdateResources() throws SQLException {
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/metadata/persist/node/DatabaseMetaDataNodeTest.java b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/metadata/persist/node/DatabaseMetaDataNodeTest.java
index 9c12bb332cd..5d7c3f57b15 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/metadata/persist/node/DatabaseMetaDataNodeTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/metadata/persist/node/DatabaseMetaDataNodeTest.java
@@ -76,6 +76,13 @@ public class DatabaseMetaDataNodeTest {
         assertThat(actualTableName.get(), is("t_order"));
     }
     
+    @Test
+    public void assertGetViewName() {
+        Optional<String> actualViewName = DatabaseMetaDataNode.getViewName("/metadata/logic_db/schemas/logic_schema/views/foo_view");
+        assertTrue(actualViewName.isPresent());
+        assertThat(actualViewName.get(), is("foo_view"));
+    }
+    
     @Test
     public void assertGetSchemaName() {
         Optional<String> actualSchemaName = DatabaseMetaDataNode.getSchemaName("/metadata/logic_db/schemas/logic_schema");
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinator.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinator.java
index 39b53befad5..647fde5cce2 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinator.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinator.java
@@ -33,7 +33,8 @@ import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.confi
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.props.PropertiesChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.rule.GlobalRuleConfigurationsChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.rule.RuleConfigurationsChangedEvent;
-import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.SchemaChangedEvent;
+import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.TableMetaDataChangedEvent;
+import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.ViewMetaDataChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.version.DatabaseVersionChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.event.DatabaseAddedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.event.DatabaseDeletedEvent;
@@ -128,14 +129,25 @@ public final class ClusterContextManagerCoordinator {
     }
     
     /**
-     * Renew meta data of the schema.
+     * Renew meta data of the table.
      *
-     * @param event meta data changed event
+     * @param event table meta data changed event
      */
     @Subscribe
-    public synchronized void renew(final SchemaChangedEvent event) {
-        contextManager.alterSchema(event.getDatabaseName(), event.getSchemaName(), event.getChangedTableMetaData());
-        contextManager.alterSchema(event.getDatabaseName(), event.getSchemaName(), event.getDeletedTable());
+    public synchronized void renew(final TableMetaDataChangedEvent event) {
+        contextManager.alterSchema(event.getDatabaseName(), event.getSchemaName(), event.getChangedTableMetaData(), null);
+        contextManager.alterSchema(event.getDatabaseName(), event.getSchemaName(), event.getDeletedTable(), null);
+    }
+    
+    /**
+     * Renew meta data of the view.
+     *
+     * @param event view meta data changed event
+     */
+    @Subscribe
+    public synchronized void renew(final ViewMetaDataChangedEvent event) {
+        contextManager.alterSchema(event.getDatabaseName(), event.getSchemaName(), null, event.getChangedViewMetaData());
+        contextManager.alterSchema(event.getDatabaseName(), event.getSchemaName(), null, event.getDeletedView());
     }
     
     /**
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/SchemaChangedEvent.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/TableMetaDataChangedEvent.java
similarity index 92%
copy from shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/SchemaChangedEvent.java
copy to shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/TableMetaDataChangedEvent.java
index b99f7f56589..2bf92118ab4 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/SchemaChangedEvent.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/TableMetaDataChangedEvent.java
@@ -23,11 +23,11 @@ import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.GovernanceEvent;
 
 /**
- * Schema changed event.
+ * Table meta data changed event.
  */
 @RequiredArgsConstructor
 @Getter
-public final class SchemaChangedEvent implements GovernanceEvent {
+public final class TableMetaDataChangedEvent implements GovernanceEvent {
     
     private final String databaseName;
     
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/SchemaChangedEvent.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/ViewMetaDataChangedEvent.java
similarity index 84%
rename from shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/SchemaChangedEvent.java
rename to shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/ViewMetaDataChangedEvent.java
index b99f7f56589..11e3d10f6c0 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/SchemaChangedEvent.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/event/schema/ViewMetaDataChangedEvent.java
@@ -19,21 +19,21 @@ package org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.conf
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereView;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.GovernanceEvent;
 
 /**
- * Schema changed event.
+ * View meta data changed event.
  */
 @RequiredArgsConstructor
 @Getter
-public final class SchemaChangedEvent implements GovernanceEvent {
+public final class ViewMetaDataChangedEvent implements GovernanceEvent {
     
     private final String databaseName;
     
     private final String schemaName;
     
-    private final ShardingSphereTable changedTableMetaData;
+    private final ShardingSphereView changedViewMetaData;
     
-    private final String deletedTable;
+    private final String deletedView;
 }
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/subscriber/SchemaMetaDataRegistrySubscriber.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/subscriber/SchemaMetaDataRegistrySu [...]
index 130d0eec7f0..1cdaff8b41e 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/subscriber/SchemaMetaDataRegistrySubscriber.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/subscriber/SchemaMetaDataRegistrySubscriber.java
@@ -18,7 +18,9 @@
 package org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.subscriber;
 
 import com.google.common.eventbus.Subscribe;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereView;
 import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
 import org.apache.shardingsphere.infra.metadata.database.schema.event.AddSchemaEvent;
 import org.apache.shardingsphere.infra.metadata.database.schema.event.AlterSchemaEvent;
@@ -51,9 +53,13 @@ public final class SchemaMetaDataRegistrySubscriber {
      */
     @Subscribe
     public void update(final SchemaAlteredEvent event) {
+        String databaseName = event.getDatabaseName();
+        String schemaName = event.getSchemaName();
         Map<String, ShardingSphereTable> tables = event.getAlteredTables().stream().collect(Collectors.toMap(ShardingSphereTable::getName, table -> table));
-        persistService.getTableMetaDataPersistService().persist(event.getDatabaseName(), event.getSchemaName(), tables);
-        event.getDroppedTables().forEach(each -> persistService.getTableMetaDataPersistService().delete(event.getDatabaseName(), event.getSchemaName(), each));
+        Map<String, ShardingSphereView> views = event.getAlteredViews().stream().collect(Collectors.toMap(ShardingSphereView::getName, table -> table));
+        persistService.persist(databaseName, schemaName, new ShardingSphereSchema(tables, views));
+        event.getDroppedTables().forEach(each -> persistService.getTableMetaDataPersistService().delete(databaseName, schemaName, each));
+        event.getDroppedViews().forEach(each -> persistService.getViewMetaDataPersistService().delete(databaseName, schemaName, each));
     }
     
     /**
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcher.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcher.java
index 82e02b7f8cd..a1ddc6fba74 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcher.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcher.java
@@ -27,12 +27,15 @@ import org.apache.shardingsphere.infra.yaml.config.swapper.resource.YamlDataSour
 import org.apache.shardingsphere.infra.yaml.config.swapper.rule.YamlRuleConfigurationSwapperEngine;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import org.apache.shardingsphere.infra.yaml.schema.pojo.YamlShardingSphereTable;
+import org.apache.shardingsphere.infra.yaml.schema.pojo.YamlShardingSphereView;
 import org.apache.shardingsphere.infra.yaml.schema.swapper.YamlTableSwapper;
+import org.apache.shardingsphere.infra.yaml.schema.swapper.YamlViewSwapper;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.GovernanceEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.GovernanceWatcher;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.datasource.DataSourceChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.rule.RuleConfigurationsChangedEvent;
-import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.SchemaChangedEvent;
+import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.TableMetaDataChangedEvent;
+import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.ViewMetaDataChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.version.DatabaseVersionChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.event.DatabaseAddedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.event.DatabaseDeletedEvent;
@@ -71,36 +74,36 @@ public final class MetaDataChangedWatcher implements GovernanceWatcher<Governanc
     
     @Override
     public Optional<GovernanceEvent> createGovernanceEvent(final DataChangedEvent event) {
-        // TODO Maybe can reduce once regular
-        if (isLogicDatabaseChanged(event)) {
-            return createLogicDatabaseChangedEvent(event);
+        if (databaseChanged(event)) {
+            return createDatabaseChangedEvent(event);
         }
-        if (isLogicSchemaChanged(event)) {
-            return createLogicSchemaChangedEvent(event);
-        }
-        if (isTableMetaDataChanged(event)) {
+        if (schemaChanged(event)) {
             return createSchemaChangedEvent(event);
         }
+        if (schemaMetaDataChanged(event)) {
+            return createSchemaMetaDataChangedEvent(event);
+        }
         return createRuleAndDataSourceChangedEvent(event);
     }
     
-    private boolean isLogicDatabaseChanged(final DataChangedEvent event) {
+    private boolean databaseChanged(final DataChangedEvent event) {
         return DatabaseMetaDataNode.getDatabaseName(event.getKey()).isPresent();
     }
     
-    private boolean isLogicSchemaChanged(final DataChangedEvent event) {
+    private boolean schemaChanged(final DataChangedEvent event) {
         return DatabaseMetaDataNode.getDatabaseNameByDatabasePath(event.getKey()).isPresent() && DatabaseMetaDataNode.getSchemaName(event.getKey()).isPresent();
     }
     
-    private boolean isTableMetaDataChanged(final DataChangedEvent event) {
+    private boolean schemaMetaDataChanged(final DataChangedEvent event) {
         Optional<String> databaseName = DatabaseMetaDataNode.getDatabaseNameByDatabasePath(event.getKey());
         Optional<String> schemaName = DatabaseMetaDataNode.getSchemaNameBySchemaPath(event.getKey());
         Optional<String> tableName = DatabaseMetaDataNode.getTableName(event.getKey());
-        return databaseName.isPresent() && tableName.isPresent() && schemaName.isPresent()
-                && !SystemSchemaBuilderRule.isSystemTable(databaseName.get(), tableName.get()) && !Strings.isNullOrEmpty(event.getValue());
+        Optional<String> viewName = DatabaseMetaDataNode.getViewName(event.getKey());
+        return databaseName.isPresent() && schemaName.isPresent() && !Strings.isNullOrEmpty(event.getValue())
+                && ((tableName.isPresent() && !SystemSchemaBuilderRule.isSystemTable(databaseName.get(), tableName.get()) || viewName.isPresent()));
     }
     
-    private Optional<GovernanceEvent> createLogicDatabaseChangedEvent(final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createDatabaseChangedEvent(final DataChangedEvent event) {
         Optional<String> databaseName = DatabaseMetaDataNode.getDatabaseName(event.getKey());
         Preconditions.checkState(databaseName.isPresent());
         if (Type.ADDED == event.getType() || Type.UPDATED == event.getType()) {
@@ -112,7 +115,7 @@ public final class MetaDataChangedWatcher implements GovernanceWatcher<Governanc
         return Optional.empty();
     }
     
-    private Optional<GovernanceEvent> createLogicSchemaChangedEvent(final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createSchemaChangedEvent(final DataChangedEvent event) {
         Optional<String> databaseName = DatabaseMetaDataNode.getDatabaseNameByDatabasePath(event.getKey());
         Preconditions.checkState(databaseName.isPresent());
         Optional<String> schemaName = DatabaseMetaDataNode.getSchemaName(event.getKey());
@@ -161,19 +164,26 @@ public final class MetaDataChangedWatcher implements GovernanceWatcher<Governanc
         return new YamlRuleConfigurationSwapperEngine().swapToRuleConfigurations(rules);
     }
     
-    private Optional<GovernanceEvent> createSchemaChangedEvent(final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createSchemaMetaDataChangedEvent(final DataChangedEvent event) {
         Optional<String> databaseName = DatabaseMetaDataNode.getDatabaseNameByDatabasePath(event.getKey());
         Preconditions.checkState(databaseName.isPresent());
         Optional<String> schemaName = DatabaseMetaDataNode.getSchemaNameBySchemaPath(event.getKey());
         Preconditions.checkState(schemaName.isPresent());
-        Optional<String> tableName = DatabaseMetaDataNode.getTableName(event.getKey());
-        Preconditions.checkState(tableName.isPresent());
-        return Optional.of(createSchemaChangedEvent(event, databaseName.get(), schemaName.get(), tableName.get()));
+        return Optional.of(createSchemaMetaDataChangedEvent(event, databaseName.get(), schemaName.get()));
     }
     
-    private SchemaChangedEvent createSchemaChangedEvent(final DataChangedEvent event, final String databaseName, final String schemaName, final String tableName) {
-        return Type.DELETED == event.getType()
-                ? new SchemaChangedEvent(databaseName, schemaName, null, tableName)
-                : new SchemaChangedEvent(databaseName, schemaName, new YamlTableSwapper().swapToObject(YamlEngine.unmarshal(event.getValue(), YamlShardingSphereTable.class)), null);
+    private GovernanceEvent createSchemaMetaDataChangedEvent(final DataChangedEvent event, final String databaseName, final String schemaName) {
+        Optional<String> tableName = DatabaseMetaDataNode.getTableName(event.getKey());
+        Optional<String> viewName = DatabaseMetaDataNode.getViewName(event.getKey());
+        Preconditions.checkState(tableName.isPresent() || viewName.isPresent());
+        if (tableName.isPresent()) {
+            return Type.DELETED == event.getType()
+                    ? new TableMetaDataChangedEvent(databaseName, schemaName, null, tableName.get())
+                    : new TableMetaDataChangedEvent(databaseName, schemaName, new YamlTableSwapper().swapToObject(YamlEngine.unmarshal(event.getValue(), YamlShardingSphereTable.class)), null);
+        } else {
+            return Type.DELETED == event.getType()
+                    ? new ViewMetaDataChangedEvent(databaseName, schemaName, null, viewName.get())
+                    : new ViewMetaDataChangedEvent(databaseName, schemaName, new YamlViewSwapper().swapToObject(YamlEngine.unmarshal(event.getValue(), YamlShardingSphereView.class)), null);
+        }
     }
 }
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinatorTest.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinatorTest.java
index df01975c962..e0e242ddd16 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinatorTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinatorTest.java
@@ -38,6 +38,7 @@ import org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRule
 import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedDatabase;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereView;
 import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.infra.rule.identifier.type.DynamicDataSourceContainedRule;
@@ -52,7 +53,8 @@ import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.confi
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.props.PropertiesChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.rule.GlobalRuleConfigurationsChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.rule.RuleConfigurationsChangedEvent;
-import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.SchemaChangedEvent;
+import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.TableMetaDataChangedEvent;
+import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.ViewMetaDataChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.version.DatabaseVersionChangedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.event.DatabaseAddedEvent;
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.event.DatabaseDeletedEvent;
@@ -193,14 +195,23 @@ public final class ClusterContextManagerCoordinatorTest {
     }
     
     @Test
-    public void assertRenewForSchemaChanged() {
+    public void assertRenewForTableMetaDataChangedChanged() {
+        when(contextManager.getMetaDataContexts().getMetaData().getDatabase("db").containsSchema("db")).thenReturn(true);
         ShardingSphereTable changedTableMetaData = new ShardingSphereTable("t_order", Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
-        SchemaChangedEvent event = new SchemaChangedEvent("db", "db", changedTableMetaData, null);
+        TableMetaDataChangedEvent event = new TableMetaDataChangedEvent("db", "db", changedTableMetaData, null);
         coordinator.renew(event);
-        // assertTrue(contextManager.getMetaDataContexts().getMetaData().containsKey("db"));
         verify(contextManager.getMetaDataContexts().getMetaData().getDatabase("db").getSchema("db")).putTable("t_order", event.getChangedTableMetaData());
     }
     
+    @Test
+    public void assertRenewForViewMetaDataChanged() {
+        when(contextManager.getMetaDataContexts().getMetaData().getDatabase("db").containsSchema("db")).thenReturn(true);
+        ShardingSphereView changedViewMetaData = new ShardingSphereView("t_order_view", "");
+        ViewMetaDataChangedEvent event = new ViewMetaDataChangedEvent("db", "db", changedViewMetaData, null);
+        coordinator.renew(event);
+        verify(contextManager.getMetaDataContexts().getMetaData().getDatabase("db").getSchema("db")).putView("t_order_view", event.getChangedViewMetaData());
+    }
+    
     @Test
     public void assertRenewForRuleConfigurationsChanged() {
         when(persistService.getMetaDataVersionPersistService().isActiveVersion("db", "0")).thenReturn(true);
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/watcher/GlobalRuleChangedWatcherTest.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/watcher/GlobalRuleChangedWatcherTest.java
index 0a5bc18b998..d8269b3ddd5 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/watcher/GlobalRuleChangedWatcherTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/config/watcher/GlobalRuleChangedWatcherTest.java
@@ -38,13 +38,13 @@ public final class GlobalRuleChangedWatcherTest {
     
     @Test
     public void assertCreateEvent() {
-        Optional<GlobalRuleConfigurationsChangedEvent> event = new GlobalRuleChangedWatcher().createGovernanceEvent(new DataChangedEvent("/rules", readYAML("yaml/authority-rule.yaml"), Type.UPDATED));
+        Optional<GlobalRuleConfigurationsChangedEvent> event = new GlobalRuleChangedWatcher().createGovernanceEvent(new DataChangedEvent("/rules", readYAML(), Type.UPDATED));
         assertTrue(event.isPresent());
         assertThat(event.get(), instanceOf(GlobalRuleConfigurationsChangedEvent.class));
     }
     
     @SneakyThrows({IOException.class, URISyntaxException.class})
-    protected String readYAML(final String yamlFile) {
-        return Files.readAllLines(Paths.get(ClassLoader.getSystemResource(yamlFile).toURI())).stream().map(each -> each + System.lineSeparator()).collect(Collectors.joining());
+    protected String readYAML() {
+        return Files.readAllLines(Paths.get(ClassLoader.getSystemResource("yaml/authority-rule.yaml").toURI())).stream().map(each -> each + System.lineSeparator()).collect(Collectors.joining());
     }
 }
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/subscriber/SchemaMetaDataRegistrySubscriberTest.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/subscriber/SchemaMetaDataRegist [...]
index dd1bb0569d4..b4b529a971d 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/subscriber/SchemaMetaDataRegistrySubscriberTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/subscriber/SchemaMetaDataRegistrySubscriberTest.java
@@ -37,10 +37,10 @@ import java.lang.reflect.Field;
 import java.util.Collections;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.anyMap;
 
 @RunWith(MockitoJUnitRunner.class)
 public final class SchemaMetaDataRegistrySubscriberTest {
@@ -66,9 +66,8 @@ public final class SchemaMetaDataRegistrySubscriberTest {
         event.getDroppedTables().add("foo_table");
         when(persistService.getTableMetaDataPersistService()).thenReturn(mock(TableMetaDataPersistService.class));
         schemaMetaDataRegistrySubscriber.update(event);
-        TableMetaDataPersistService tableMetaDataPersistService = persistService.getTableMetaDataPersistService();
-        verify(tableMetaDataPersistService).persist(anyString(), anyString(), anyMap());
-        verify(tableMetaDataPersistService).delete("foo_db", "foo_schema", "foo_table");
+        verify(persistService).persist(anyString(), anyString(), any());
+        verify(persistService.getTableMetaDataPersistService()).delete("foo_db", "foo_schema", "foo_table");
     }
     
     @Test
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcherTest.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcherTest.java
index 3fda06df10f..fe6cd003dfa 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcherTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcherTest.java
@@ -18,7 +18,7 @@
 package org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.metadata.watcher;
 
 import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.GovernanceEvent;
-import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.SchemaChangedEvent;
+import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.config.event.schema.TableMetaDataChangedEvent;
 import org.apache.shardingsphere.mode.repository.cluster.listener.DataChangedEvent;
 import org.apache.shardingsphere.mode.repository.cluster.listener.DataChangedEvent.Type;
 import org.junit.Test;
@@ -66,7 +66,7 @@ public final class MetaDataChangedWatcherTest {
     }
     
     @Test
-    public void assertCreateDeletedEvent() {
+    public void assertCreateDatabaseDeletedEvent() {
         String key = "/metadata/sharding_db";
         String value = "encrypt_db";
         Optional<GovernanceEvent> actual = createEvent(key, value, Type.DELETED);
@@ -115,7 +115,21 @@ public final class MetaDataChangedWatcherTest {
         String key = "/metadata/sharding_db/schemas/sharding_schema/tables/t_order";
         Optional<GovernanceEvent> actual = createEvent(key, "{}", Type.DELETED);
         assertTrue(actual.isPresent());
-        assertThat(((SchemaChangedEvent) actual.get()).getDeletedTable(), is("t_order"));
+        assertThat(((TableMetaDataChangedEvent) actual.get()).getDeletedTable(), is("t_order"));
+    }
+    
+    @Test
+    public void assertCreateViewMetaDataChangedEvent() {
+        String key = "/metadata/sharding_db/schemas/sharding_schema/views/foo_view";
+        Optional<GovernanceEvent> actual = createEvent(key, "{}", Type.UPDATED);
+        assertTrue(actual.isPresent());
+    }
+    
+    @Test
+    public void assertCreateViewMetaDataDeletedEvent() {
+        String key = "/metadata/sharding_db/schemas/sharding_schema/views/foo_view";
+        Optional<GovernanceEvent> actual = createEvent(key, "{}", Type.DELETED);
+        assertTrue(actual.isPresent());
     }
     
     private Optional<GovernanceEvent> createEvent(final String key, final String value, final Type type) {