You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by qi...@apache.org on 2021/11/16 10:48:16 UTC

[iotdb] branch master updated: New architecture of aligned timeseries (#4382)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 60e92f9  New architecture of aligned timeseries (#4382)
60e92f9 is described below

commit 60e92f908792ed99a384019f656b5f0064cb353d
Author: Jackie Tien <Ja...@foxmail.com>
AuthorDate: Tue Nov 16 18:47:45 2021 +0800

    New architecture of aligned timeseries (#4382)
---
 .../cluster/client/sync/SyncClientAdaptor.java     |   2 +-
 .../iotdb/cluster/coordinator/Coordinator.java     |   2 +-
 .../cluster/log/applier/AsyncDataLogApplier.java   |   4 +-
 .../iotdb/cluster/log/applier/BaseApplier.java     |   4 +-
 .../iotdb/cluster/log/applier/DataLogApplier.java  |   8 +-
 .../manage/FilePartitionedSnapshotLogManager.java  |   2 +-
 .../log/manage/MetaSingleSnapshotLogManager.java   |   2 +-
 .../log/manage/PartitionedSnapshotLogManager.java  |   2 +-
 .../iotdb/cluster/log/snapshot/FileSnapshot.java   |   2 +-
 .../cluster/log/snapshot/MetaSimpleSnapshot.java   |   2 +-
 .../apache/iotdb/cluster/metadata/CMManager.java   | 138 +++----
 .../apache/iotdb/cluster/metadata/MetaPuller.java  |   2 +-
 .../iotdb/cluster/partition/PartitionTable.java    |   2 +-
 .../cluster/query/ClusterDataQueryExecutor.java    |   4 +-
 .../cluster/query/ClusterPhysicalGenerator.java    |  16 +-
 .../iotdb/cluster/query/ClusterPlanExecutor.java   |   5 +-
 .../iotdb/cluster/query/ClusterPlanRouter.java     |  16 +-
 .../iotdb/cluster/query/LocalQueryExecutor.java    |  40 +-
 .../query/aggregate/ClusterAggregateExecutor.java  |   2 +-
 .../cluster/query/aggregate/ClusterAggregator.java |   2 +-
 .../cluster/query/fill/ClusterFillExecutor.java    |   2 +-
 .../cluster/query/fill/ClusterPreviousFill.java    |   2 +-
 .../cluster/query/fill/PreviousFillArguments.java  |   2 +-
 .../ClusterGroupByFillNoVFilterDataSet.java        |   2 +-
 .../groupby/ClusterGroupByNoVFilterDataSet.java    |   2 +-
 .../groupby/ClusterGroupByVFilterDataSet.java      |   2 +-
 .../query/groupby/MergeGroupByExecutor.java        |   2 +-
 .../query/last/ClusterLastQueryExecutor.java       |   4 +-
 .../cluster/query/reader/ClusterReaderFactory.java |  15 +-
 .../cluster/query/reader/ClusterTimeGenerator.java |   2 +-
 .../query/reader/mult/MultDataSourceInfo.java      |   2 +-
 .../query/reader/mult/RemoteMultSeriesReader.java  |   2 +-
 .../cluster/server/member/DataGroupMember.java     |   2 +-
 .../cluster/server/member/MetaGroupMember.java     |   2 +-
 .../iotdb/cluster/utils/ClusterQueryUtils.java     |  57 +--
 .../apache/iotdb/cluster/utils/ClusterUtils.java   |   2 +-
 .../apache/iotdb/cluster/utils/PartitionUtils.java |   2 +-
 .../cluster/utils/nodetool/ClusterMonitor.java     |   2 +-
 .../cluster/client/sync/SyncClientAdaptorTest.java |  18 +-
 .../org/apache/iotdb/cluster/common/IoTDBTest.java |  18 +-
 .../iotdb/cluster/common/TestLogApplier.java       |   2 +-
 .../org/apache/iotdb/cluster/common/TestUtils.java |  10 +-
 .../apache/iotdb/cluster/log/LogParserTest.java    |   2 +-
 .../log/applier/AsyncDataLogApplierTest.java       |   2 +-
 .../cluster/log/applier/DataLogApplierTest.java    |  12 +-
 .../cluster/log/applier/MetaLogApplierTest.java    |   2 +-
 .../cluster/log/logtypes/SerializeLogTest.java     |   4 +-
 .../FilePartitionedSnapshotLogManagerTest.java     |   2 +-
 .../manage/MetaSingleSnapshotLogManagerTest.java   |   2 +-
 .../cluster/log/snapshot/DataSnapshotTest.java     |   2 +-
 .../cluster/log/snapshot/FileSnapshotTest.java     |   2 +-
 .../log/snapshot/MetaSimpleSnapshotTest.java       |   2 +-
 .../log/snapshot/PartitionedSnapshotTest.java      |   2 +-
 .../cluster/log/snapshot/PullSnapshotTaskTest.java |   2 +-
 .../cluster/partition/SlotPartitionTableTest.java  |   2 +-
 .../apache/iotdb/cluster/query/BaseQueryTest.java  |   9 +-
 .../query/ClusterAggregateExecutorTest.java        |  49 +--
 .../query/ClusterDataQueryExecutorTest.java        |   7 +-
 .../query/ClusterPhysicalGeneratorTest.java        |   3 +-
 .../cluster/query/ClusterPlanExecutorTest.java     |   8 +-
 .../iotdb/cluster/query/ClusterPlannerTest.java    |   1 -
 .../cluster/query/ClusterQueryRouterTest.java      |  54 +--
 .../query/fill/ClusterFillExecutorTest.java        |  17 +-
 .../ClusterGroupByNoVFilterDataSetTest.java        |   9 +-
 .../groupby/ClusterGroupByVFilterDataSetTest.java  |  15 +-
 .../query/groupby/MergeGroupByExecutorTest.java    |   7 +-
 .../query/groupby/RemoteGroupByExecutorTest.java   |   7 +-
 .../query/reader/ClusterReaderFactoryTest.java     |  11 +-
 .../query/reader/ClusterTimeGeneratorTest.java     |   9 +-
 .../mult/AssignPathManagedMergeReaderTest.java     |   2 +-
 .../reader/mult/RemoteMultSeriesReaderTest.java    |   2 +-
 .../clusterinfo/ClusterInfoServiceImplTest.java    |   2 +-
 .../handlers/forwarder/ForwardPlanHandlerTest.java |   2 +-
 .../iotdb/cluster/server/member/BaseMember.java    |   2 +-
 .../cluster/server/member/DataGroupMemberTest.java |  23 +-
 .../cluster/server/member/MetaGroupMemberTest.java |  15 +-
 .../iotdb/cluster/utils/SerializeUtilTest.java     |   2 +-
 docs/UserGuide/Advanced-Features/Triggers.md       |   2 +-
 docs/zh/UserGuide/Advanced-Features/Triggers.md    |   2 +-
 .../iotdb/hadoop/tsfile/TSMRWriteExample.java      |   6 +-
 .../apache/iotdb/hadoop/tsfile/TsFileHelper.java   |   8 +-
 .../iotdb/hadoop/tsfile/TsFileWriteToHDFS.java     |   6 +-
 .../iotdb/AlignedTimeseriesSessionExample.java     | 174 ++++----
 .../iotdb/HybridTimeseriesSessionExample.java      |  11 +-
 .../org/apache/iotdb/trigger/TriggerExample.java   |   2 +-
 .../iotdb/tsfile/TsFileForceAppendWrite.java       |  12 +-
 .../apache/iotdb/tsfile/TsFileSequenceRead.java    |  85 +++-
 .../tsfile/TsFileWriteAlignedWithTSRecord.java     |  89 +++++
 .../iotdb/tsfile/TsFileWriteAlignedWithTablet.java | 141 +++++++
 .../iotdb/tsfile/TsFileWriteVectorWithTablet.java  | 118 ------
 .../iotdb/tsfile/TsFileWriteWithTSRecord.java      |  66 +--
 .../apache/iotdb/tsfile/TsFileWriteWithTablet.java | 106 +++--
 .../iotdb/hadoop/tsfile/TsFileTestHelper.java      |   2 +-
 .../org/apache/iotdb/hive/TsFileTestHelper.java    |   2 +-
 .../apache/iotdb/jdbc/IoTDBDatabaseMetadata.java   |   3 +-
 .../org/apache/iotdb/db/auth/AuthorityChecker.java |   7 +-
 .../apache/iotdb/db/cq/ContinuousQueryTask.java    |   2 +-
 .../org/apache/iotdb/db/engine/StorageEngine.java  |  25 +-
 .../db/engine/cache/TimeSeriesMetadataCache.java   | 187 ---------
 .../inplace/manage/CrossSpaceMergeContext.java     |   2 +-
 .../inplace/manage/CrossSpaceMergeResource.java    |   7 +-
 .../cross/inplace/recover/LogAnalyzer.java         |   7 +-
 .../cross/inplace/recover/MergeLogger.java         |   2 +-
 .../cross/inplace/selector/IMergePathSelector.java |   2 +-
 .../cross/inplace/selector/NaivePathSelector.java  |   2 +-
 .../cross/inplace/task/CrossSpaceMergeTask.java    |   2 +-
 .../cross/inplace/task/MergeFileTask.java          |   2 +-
 .../cross/inplace/task/MergeMultiChunkTask.java    |  14 +-
 .../cross/inplace/task/RecoverCrossMergeTask.java  |   2 +-
 .../inner/utils/InnerSpaceCompactionUtils.java     |   7 +-
 .../iotdb/db/engine/flush/MemTableFlushTask.java   | 150 +------
 .../iotdb/db/engine/flush/NotifyFlushMemTable.java |   5 +
 .../iotdb/db/engine/memtable/AbstractMemTable.java | 280 +++++++------
 .../engine/memtable/AlignedWritableMemChunk.java   | 313 +++++++++++++++
 .../apache/iotdb/db/engine/memtable/IMemTable.java |  18 +-
 .../db/engine/memtable/IWritableMemChunk.java      |  31 +-
 .../db/engine/memtable/PrimitiveMemTable.java      |  15 +-
 .../iotdb/db/engine/memtable/WritableMemChunk.java | 124 ++++--
 .../iotdb/db/engine/modification/Deletion.java     |   2 +-
 .../iotdb/db/engine/modification/Modification.java |   2 +-
 .../io/LocalTextModificationAccessor.java          |   2 +-
 .../querycontext/AlignedReadOnlyMemChunk.java      | 165 ++++++++
 .../db/engine/querycontext/ReadOnlyMemChunk.java   | 147 +------
 .../selectinto/InsertTabletPlanGenerator.java      |   2 +-
 .../selectinto/InsertTabletPlansIterator.java      |   2 +-
 .../engine/storagegroup/StorageGroupProcessor.java | 109 ++---
 .../db/engine/storagegroup/TsFileProcessor.java    | 298 +++++++-------
 .../db/engine/storagegroup/TsFileResource.java     | 123 +-----
 .../virtualSg/HashVirtualPartitioner.java          |   2 +-
 .../storagegroup/virtualSg/VirtualPartitioner.java |   2 +-
 .../virtualSg/VirtualStorageGroupManager.java      |   2 +-
 .../service/TriggerRegistrationInformation.java    |   2 +-
 .../service/TriggerRegistrationService.java        |   2 +-
 .../sink/local/LocalIoTDBConfiguration.java        |   2 +-
 .../trigger/sink/local/LocalIoTDBHandler.java      |   6 +-
 .../trigger/sink/mqtt/MQTTConfiguration.java       |   2 +-
 .../org/apache/iotdb/db/metadata/MManager.java     | 442 ++++++---------------
 .../iotdb/db/metadata/VectorPartialPath.java       | 122 ------
 .../db/metadata/lastCache/LastCacheManager.java    | 142 ++-----
 .../lastCache/container/ILastCacheContainer.java   |  13 -
 .../lastCache/container/LastCacheContainer.java    |  52 +--
 .../lastCache/container/value/ILastCacheValue.java |  12 -
 .../{ILastCacheValue.java => LastCacheValue.java}  |  38 +-
 .../container/value/UnaryLastCacheValue.java       | 106 -----
 .../container/value/VectorLastCacheValue.java      |  86 ----
 .../iotdb/db/metadata/logfile/MLogUpgrader.java    |   2 +-
 .../iotdb/db/metadata/logfile/MLogWriter.java      |   2 +-
 .../iotdb/db/metadata/mnode/EntityMNode.java       |  11 +
 .../iotdb/db/metadata/mnode/IEntityMNode.java      |   4 +
 .../org/apache/iotdb/db/metadata/mnode/IMNode.java |   2 +-
 .../iotdb/db/metadata/mnode/IMeasurementMNode.java |  13 +-
 .../org/apache/iotdb/db/metadata/mnode/MNode.java  |   2 +-
 .../iotdb/db/metadata/mnode/MeasurementMNode.java  |  69 ++--
 .../db/metadata/mnode/MultiMeasurementMNode.java   |  65 ---
 .../db/metadata/mnode/UnaryMeasurementMNode.java   |  63 ---
 .../org/apache/iotdb/db/metadata/mtree/MTree.java  | 373 ++++++++++-------
 .../mtree/traverser/PathGrouperByStorageGroup.java | 103 -----
 .../db/metadata/mtree/traverser/Traverser.java     |   2 +-
 .../collector/BelongedEntityPathCollector.java     |  83 ----
 .../traverser/collector/CollectorTraverser.java    |   8 +-
 ...tityPathCollector.java => EntityCollector.java} |  26 +-
 .../collector/FlatMeasurementCollector.java        | 138 -------
 .../collector/FlatMeasurementPathCollector.java    |  60 ---
 .../collector/FlatMeasurementSchemaCollector.java  | 117 ------
 .../mtree/traverser/collector/MNodeCollector.java  |   2 +-
 .../traverser/collector/MeasurementCollector.java  |  23 +-
 ...thCollector.java => StorageGroupCollector.java} |  19 +-
 .../mtree/traverser/counter/CounterTraverser.java  |   2 +-
 .../mtree/traverser/counter/EntityCounter.java     |   2 +-
 .../traverser/counter/FlatMeasurementCounter.java  |  78 ----
 .../mtree/traverser/counter/MNodeLevelCounter.java |   2 +-
 .../traverser/counter/MeasurementCounter.java      |   2 +-
 .../traverser/counter/StorageGroupCounter.java     |   2 +-
 .../apache/iotdb/db/metadata/path/AlignedPath.java | 396 ++++++++++++++++++
 .../iotdb/db/metadata/path/MeasurementPath.java    | 296 ++++++++++++++
 .../iotdb/db/metadata/{ => path}/PartialPath.java  | 117 +++++-
 .../apache/iotdb/db/metadata/tag/TagManager.java   |   2 +-
 .../iotdb/db/metadata/template/Template.java       |  32 +-
 .../db/metadata/template/TemplateManager.java      |   2 +-
 .../iotdb/db/metadata/utils/MetaFormatUtils.java   |   2 +-
 .../apache/iotdb/db/metadata/utils/MetaUtils.java  |  36 +-
 .../org/apache/iotdb/db/monitor/StatMonitor.java   |  32 +-
 .../org/apache/iotdb/db/mqtt/PublishHandler.java   |   4 +-
 .../apache/iotdb/db/qp/constant/SQLConstant.java   |   2 +-
 .../apache/iotdb/db/qp/executor/IPlanExecutor.java |   2 +-
 .../apache/iotdb/db/qp/executor/PlanExecutor.java  |  30 +-
 .../qp/logical/crud/AggregationQueryOperator.java  |   2 +-
 .../db/qp/logical/crud/BasicFunctionOperator.java  |   6 +-
 .../db/qp/logical/crud/DeleteDataOperator.java     |   2 +-
 .../iotdb/db/qp/logical/crud/FilterOperator.java   |   7 +-
 .../iotdb/db/qp/logical/crud/FromComponent.java    |   2 +-
 .../iotdb/db/qp/logical/crud/FunctionOperator.java |   3 +-
 .../iotdb/db/qp/logical/crud/InOperator.java       |   8 +-
 .../iotdb/db/qp/logical/crud/InsertOperator.java   |   2 +-
 .../iotdb/db/qp/logical/crud/LikeOperator.java     |   5 +-
 .../iotdb/db/qp/logical/crud/QueryOperator.java    |  83 ++--
 .../iotdb/db/qp/logical/crud/RegexpOperator.java   |   5 +-
 .../iotdb/db/qp/logical/crud/SelectComponent.java  |   2 +-
 .../db/qp/logical/crud/SelectIntoOperator.java     |   2 +-
 .../db/qp/logical/sys/AlterTimeSeriesOperator.java |   2 +-
 .../iotdb/db/qp/logical/sys/AuthorOperator.java    |   2 +-
 .../iotdb/db/qp/logical/sys/CountOperator.java     |   2 +-
 .../logical/sys/CreateContinuousQueryOperator.java |   2 +-
 .../db/qp/logical/sys/CreateIndexOperator.java     |   2 +-
 .../qp/logical/sys/CreateTimeSeriesOperator.java   |   2 +-
 .../db/qp/logical/sys/CreateTriggerOperator.java   |   2 +-
 .../db/qp/logical/sys/DeletePartitionOperator.java |   2 +-
 .../qp/logical/sys/DeleteStorageGroupOperator.java |   2 +-
 .../qp/logical/sys/DeleteTimeSeriesOperator.java   |   2 +-
 .../iotdb/db/qp/logical/sys/DropIndexOperator.java |   2 +-
 .../iotdb/db/qp/logical/sys/FlushOperator.java     |   2 +-
 .../db/qp/logical/sys/SetStorageGroupOperator.java |   2 +-
 .../iotdb/db/qp/logical/sys/SetTTLOperator.java    |   2 +-
 .../iotdb/db/qp/logical/sys/SettleOperator.java    |   2 +-
 .../db/qp/logical/sys/ShowChildNodesOperator.java  |   2 +-
 .../db/qp/logical/sys/ShowChildPathsOperator.java  |   2 +-
 .../db/qp/logical/sys/ShowDevicesOperator.java     |   2 +-
 .../db/qp/logical/sys/ShowLockInfoOperator.java    |   2 +-
 .../qp/logical/sys/ShowStorageGroupOperator.java   |   2 +-
 .../iotdb/db/qp/logical/sys/ShowTTLOperator.java   |   2 +-
 .../db/qp/logical/sys/ShowTimeSeriesOperator.java  |   2 +-
 .../iotdb/db/qp/logical/sys/UnSetTTLOperator.java  |   2 +-
 .../org/apache/iotdb/db/qp/physical/BatchPlan.java |   2 +-
 .../apache/iotdb/db/qp/physical/PhysicalPlan.java  |   6 +-
 .../iotdb/db/qp/physical/crud/AggregationPlan.java |   6 +-
 .../db/qp/physical/crud/AlignByDevicePlan.java     |  13 +-
 .../db/qp/physical/crud/AppendTemplatePlan.java    |   2 +-
 .../db/qp/physical/crud/CreateTemplatePlan.java    |  21 +-
 .../db/qp/physical/crud/DeletePartitionPlan.java   |   2 +-
 .../iotdb/db/qp/physical/crud/DeletePlan.java      |   2 +-
 .../db/qp/physical/crud/InsertMultiTabletPlan.java |   6 +-
 .../iotdb/db/qp/physical/crud/InsertPlan.java      |  29 +-
 .../iotdb/db/qp/physical/crud/InsertRowPlan.java   |  46 +--
 .../physical/crud/InsertRowsOfOneDevicePlan.java   |  20 +-
 .../iotdb/db/qp/physical/crud/InsertRowsPlan.java  |   6 +-
 .../db/qp/physical/crud/InsertTabletPlan.java      |  30 +-
 .../iotdb/db/qp/physical/crud/LastQueryPlan.java   |   1 -
 .../db/qp/physical/crud/PruneTemplatePlan.java     |   2 +-
 .../iotdb/db/qp/physical/crud/QueryPlan.java       |  28 +-
 .../db/qp/physical/crud/RawDataQueryPlan.java      |  53 +--
 .../iotdb/db/qp/physical/crud/SelectIntoPlan.java  |   5 +-
 .../db/qp/physical/crud/SetSchemaTemplatePlan.java |   2 +-
 .../apache/iotdb/db/qp/physical/crud/UDTFPlan.java |   9 +-
 .../qp/physical/crud/UnsetSchemaTemplatePlan.java  |   2 +-
 .../db/qp/physical/sys/AlterTimeSeriesPlan.java    |   2 +-
 .../iotdb/db/qp/physical/sys/AuthorPlan.java       |   2 +-
 .../qp/physical/sys/AutoCreateDeviceMNodePlan.java |   2 +-
 .../iotdb/db/qp/physical/sys/ChangeAliasPlan.java  |   2 +-
 .../db/qp/physical/sys/ChangeTagOffsetPlan.java    |   2 +-
 .../iotdb/db/qp/physical/sys/ClearCachePlan.java   |   2 +-
 .../apache/iotdb/db/qp/physical/sys/CountPlan.java |   2 +-
 .../physical/sys/CreateAlignedTimeSeriesPlan.java  |   2 +-
 .../qp/physical/sys/CreateContinuousQueryPlan.java |   2 +-
 .../db/qp/physical/sys/CreateFunctionPlan.java     |   2 +-
 .../iotdb/db/qp/physical/sys/CreateIndexPlan.java  |   2 +-
 .../qp/physical/sys/CreateMultiTimeSeriesPlan.java |   2 +-
 .../db/qp/physical/sys/CreateSnapshotPlan.java     |   2 +-
 .../db/qp/physical/sys/CreateTimeSeriesPlan.java   |   2 +-
 .../db/qp/physical/sys/CreateTriggerPlan.java      |   2 +-
 .../iotdb/db/qp/physical/sys/DataAuthPlan.java     |   2 +-
 .../db/qp/physical/sys/DeleteStorageGroupPlan.java |   2 +-
 .../db/qp/physical/sys/DeleteTimeSeriesPlan.java   |   2 +-
 .../qp/physical/sys/DropContinuousQueryPlan.java   |   2 +-
 .../iotdb/db/qp/physical/sys/DropFunctionPlan.java |   2 +-
 .../iotdb/db/qp/physical/sys/DropIndexPlan.java    |   2 +-
 .../iotdb/db/qp/physical/sys/DropTriggerPlan.java  |   2 +-
 .../apache/iotdb/db/qp/physical/sys/FlushPlan.java |   2 +-
 .../iotdb/db/qp/physical/sys/KillQueryPlan.java    |   2 +-
 .../db/qp/physical/sys/LoadConfigurationPlan.java  |   2 +-
 .../iotdb/db/qp/physical/sys/LoadDataPlan.java     |   2 +-
 .../apache/iotdb/db/qp/physical/sys/LogPlan.java   |   2 +-
 .../apache/iotdb/db/qp/physical/sys/MNodePlan.java |   2 +-
 .../db/qp/physical/sys/MeasurementMNodePlan.java   |   2 +-
 .../apache/iotdb/db/qp/physical/sys/MergePlan.java |   2 +-
 .../iotdb/db/qp/physical/sys/OperateFilePlan.java  |   2 +-
 .../db/qp/physical/sys/SetStorageGroupPlan.java    |   2 +-
 .../db/qp/physical/sys/SetSystemModePlan.java      |   2 +-
 .../iotdb/db/qp/physical/sys/SetTTLPlan.java       |   2 +-
 .../physical/sys/SetUsingSchemaTemplatePlan.java   |   2 +-
 .../iotdb/db/qp/physical/sys/SettlePlan.java       |   2 +-
 .../db/qp/physical/sys/ShowChildNodesPlan.java     |   2 +-
 .../db/qp/physical/sys/ShowChildPathsPlan.java     |   2 +-
 .../iotdb/db/qp/physical/sys/ShowDevicesPlan.java  |   2 +-
 .../iotdb/db/qp/physical/sys/ShowLockInfoPlan.java |   2 +-
 .../apache/iotdb/db/qp/physical/sys/ShowPlan.java  |   2 +-
 .../db/qp/physical/sys/ShowStorageGroupPlan.java   |   2 +-
 .../iotdb/db/qp/physical/sys/ShowTTLPlan.java      |   2 +-
 .../db/qp/physical/sys/ShowTimeSeriesPlan.java     |   2 +-
 .../iotdb/db/qp/physical/sys/StartTriggerPlan.java |   2 +-
 .../iotdb/db/qp/physical/sys/StopTriggerPlan.java  |   2 +-
 .../db/qp/physical/sys/StorageGroupMNodePlan.java  |   2 +-
 .../iotdb/db/qp/physical/sys/TracingPlan.java      |   2 +-
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    |   2 +-
 .../iotdb/db/qp/strategy/LogicalGenerator.java     |   2 +-
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    |  12 +-
 .../qp/strategy/optimizer/ConcatPathOptimizer.java |  21 +-
 .../optimizer/MergeSingleFilterOptimizer.java      |   2 +-
 .../qp/strategy/optimizer/RemoveNotOptimizer.java  |   2 +-
 .../iotdb/db/qp/utils/GroupByLevelController.java  |   4 +-
 .../apache/iotdb/db/qp/utils/WildcardsRemover.java |  10 +-
 .../iotdb/db/query/context/QueryContext.java       |  21 +-
 .../db/query/control/QueryResourceManager.java     |  11 +-
 .../db/query/dataset/AlignByDeviceDataSet.java     |  71 +---
 .../apache/iotdb/db/query/dataset/ListDataSet.java |   2 +-
 .../db/query/dataset/NonAlignEngineDataSet.java    |   2 +-
 .../dataset/RawQueryDataSetWithValueFilter.java    |  15 +-
 .../dataset/RawQueryDataSetWithoutValueFilter.java |  16 +-
 .../query/dataset/ShowContinuousQueriesResult.java |   2 +-
 .../iotdb/db/query/dataset/ShowDevicesDataSet.java |   2 +-
 .../db/query/dataset/ShowTimeseriesDataSet.java    |   2 +-
 .../iotdb/db/query/dataset/SingleDataSet.java      |   6 +-
 .../apache/iotdb/db/query/dataset/UDTFDataSet.java |   2 +-
 .../GroupByFillWithoutValueFilterDataSet.java      |   2 +-
 .../query/dataset/groupby/GroupByLevelDataSet.java |   6 +-
 .../groupby/GroupByWithValueFilterDataSet.java     |   2 +-
 .../groupby/GroupByWithoutValueFilterDataSet.java  |   2 +-
 .../dataset/groupby/LocalGroupByExecutor.java      |   2 +-
 .../db/query/executor/AggregationExecutor.java     |  27 +-
 .../iotdb/db/query/executor/FillQueryExecutor.java |   2 +-
 .../iotdb/db/query/executor/LastQueryExecutor.java |  57 +--
 .../iotdb/db/query/executor/QueryRouter.java       |   8 +-
 .../db/query/executor/RawDataQueryExecutor.java    |   8 +-
 .../executor/fill/AlignedLastPointReader.java      |  58 +++
 .../apache/iotdb/db/query/executor/fill/IFill.java |   2 +-
 .../db/query/executor/fill/LastPointReader.java    |  55 ++-
 .../iotdb/db/query/executor/fill/LinearFill.java   |   2 +-
 .../iotdb/db/query/executor/fill/PreviousFill.java |   2 +-
 .../iotdb/db/query/executor/fill/ValueFill.java    |   2 +-
 .../iotdb/db/query/expression/Expression.java      |   2 +-
 .../iotdb/db/query/expression/ResultColumn.java    |   2 +-
 .../query/expression/binary/BinaryExpression.java  |   2 +-
 .../db/query/expression/unary/ConstantOperand.java |   2 +-
 .../query/expression/unary/FunctionExpression.java |   2 +-
 .../query/expression/unary/NegationExpression.java |   2 +-
 .../query/expression/unary/TimeSeriesOperand.java  |   5 +-
 .../query/reader/chunk/DiskAlignedChunkLoader.java |  67 ++++
 .../db/query/reader/chunk/DiskChunkLoader.java     |  12 +
 .../db/query/reader/chunk/MemChunkLoader.java      |   8 +-
 .../iotdb/db/query/reader/chunk/MemPageReader.java |  10 +-
 ...er.java => DiskAlignedChunkMetadataLoader.java} |  86 ++--
 .../chunk/metadata/DiskChunkMetadataLoader.java    |  68 ++--
 ...der.java => MemAlignedChunkMetadataLoader.java} |  36 +-
 .../chunk/metadata/MemChunkMetadataLoader.java     |  31 +-
 .../query/reader/series/AlignedSeriesReader.java   |  95 +++++
 .../query/reader/series/SeriesAggregateReader.java |   5 +-
 .../reader/series/SeriesRawDataBatchReader.java    |   8 +-
 .../iotdb/db/query/reader/series/SeriesReader.java |  43 +-
 .../reader/series/SeriesReaderByTimestamp.java     |  18 +-
 .../reader/series/VectorSeriesAggregateReader.java |   8 +-
 .../query/timegenerator/ServerTimeGenerator.java   |  29 +-
 .../api/customizer/parameter/UDFParameters.java    |   2 +-
 .../query/udf/core/layer/RawQueryInputLayer.java   |   2 +-
 .../apache/iotdb/db/rescon/TVListAllocator.java    |  19 +-
 .../handler/PhysicalPlanConstructionHandler.java   |   2 +-
 .../org/apache/iotdb/db/service/SettleService.java |   2 +-
 .../org/apache/iotdb/db/service/TSServiceImpl.java |  29 +-
 .../db/service/basic/BasicServiceProvider.java     |   8 +-
 .../apache/iotdb/db/tools/TsFileRewriteTool.java   |  14 +-
 .../org/apache/iotdb/db/tools/mlog/MLogParser.java |   2 +-
 .../db/tools/virtualsg/DeviceMappingViewer.java    |   2 +-
 .../org/apache/iotdb/db/utils/FileLoaderUtils.java | 149 +++----
 .../java/org/apache/iotdb/db/utils/MemUtils.java   |  49 +--
 .../java/org/apache/iotdb/db/utils/MergeUtils.java |  37 +-
 .../apache/iotdb/db/utils/QueryDataSetUtils.java   |   3 +-
 .../java/org/apache/iotdb/db/utils/QueryUtils.java |  72 +++-
 .../org/apache/iotdb/db/utils/SchemaUtils.java     |  16 +-
 .../{VectorTVList.java => AlignedTVList.java}      | 416 ++++++++++++++-----
 .../iotdb/db/utils/datastructure/TVList.java       |  79 +---
 .../iotdb/db/writelog/recover/LogReplayer.java     |  25 +-
 .../apache/iotdb/db/auth/AuthorityCheckerTest.java |   2 +-
 .../iotdb/db/engine/MetadataManagerHelper.java     |   2 +-
 .../db/engine/cache/BloomFilterCacheTest.java      |   2 +-
 .../iotdb/db/engine/cache/ChunkCacheTest.java      |   5 +-
 .../engine/compaction/CompactionSchedulerTest.java |   2 +-
 .../compaction/cross/CrossSpaceCompactionTest.java |   2 +-
 .../engine/compaction/cross/MergeOverLapTest.java  |  10 +-
 .../db/engine/compaction/cross/MergeTaskTest.java  |  40 +-
 .../db/engine/compaction/cross/MergeTest.java      |   5 +-
 .../engine/compaction/cross/MergeUpgradeTest.java  |   3 +-
 .../inner/InnerCompactionMoreDataTest.java         |  14 +-
 .../compaction/inner/InnerCompactionTest.java      |  11 +-
 .../compaction/inner/InnerSeqCompactionTest.java   |   2 +-
 .../compaction/inner/InnerUnseqCompactionTest.java |   2 +-
 .../SizeTieredCompactionRecoverTest.java           |  46 +--
 .../inner/sizetiered/SizeTieredCompactionTest.java |   2 +-
 .../compaction/utils/CompactionCheckerUtils.java   |   2 +-
 .../utils/CompactionFileGeneratorUtils.java        |  11 +-
 .../db/engine/memtable/MemTableFlushTaskTest.java  |  22 +-
 .../db/engine/memtable/MemTableTestUtils.java      |  18 +-
 .../db/engine/memtable/PrimitiveMemTableTest.java  | 120 +++---
 .../engine/modification/DeletionFileNodeTest.java  |  17 +-
 .../db/engine/modification/DeletionQueryTest.java  | 101 ++---
 .../engine/modification/ModificationFileTest.java  |   2 +-
 .../io/LocalTextModificationAccessorTest.java      |   2 +-
 .../storagegroup/FileNodeManagerBenchmark.java     |   2 +-
 .../storagegroup/StorageGroupProcessorTest.java    |  27 +-
 .../iotdb/db/engine/storagegroup/TTLTest.java      |  18 +-
 .../engine/storagegroup/TsFileProcessorTest.java   | 123 ++----
 .../virtualSg/HashVirtualPartitionerTest.java      |   2 +-
 .../iotdb/db/integration/IoTDBArithmeticIT.java    |   2 +-
 .../db/integration/IoTDBEngineTimeGeneratorIT.java |  42 +-
 .../iotdb/db/integration/IoTDBFilePathUtilsIT.java |   2 +-
 .../apache/iotdb/db/integration/IoTDBLastIT.java   |   2 +-
 ...IoTDBLoadExternalTsFileWithTimePartitionIT.java |   4 +-
 .../db/integration/IoTDBLoadExternalTsfileIT.java  |   2 +-
 .../integration/IoTDBManageTsFileResourceIT.java   |   2 +-
 .../iotdb/db/integration/IoTDBMultiSeriesIT.java   |   2 +-
 .../iotdb/db/integration/IoTDBNestedQueryIT.java   |   2 +-
 .../db/integration/IoTDBNewTsFileCompactionIT.java |   2 +-
 .../db/integration/IoTDBRemovePartitionIT.java     |   2 +-
 .../iotdb/db/integration/IoTDBSelectIntoIT.java    |   2 +-
 .../db/integration/IoTDBSequenceDataQueryIT.java   |  91 ++---
 .../iotdb/db/integration/IoTDBSeriesReaderIT.java  |  83 ++--
 .../iotdb/db/integration/IoTDBSimpleQueryIT.java   |   2 +-
 .../db/integration/IoTDBTriggerExecutionIT.java    |   2 +-
 .../db/integration/IoTDBTriggerManagementIT.java   |   2 +-
 .../iotdb/db/integration/IoTDBUDFManagementIT.java |   2 +-
 .../db/integration/IoTDBUDFWindowQueryIT.java      |   2 +-
 .../integration/IoTDBUDTFAlignByTimeQueryIT.java   |   2 +-
 .../db/integration/IoTDBUDTFBuiltinFunctionIT.java |   2 +-
 .../db/integration/IoTDBUDTFHybridQueryIT.java     |   2 +-
 .../db/integration/IoTDBUDTFNonAlignQueryIT.java   |   2 +-
 .../iotdb/db/metadata/MManagerAdvancedTest.java    |  30 +-
 .../iotdb/db/metadata/MManagerBasicTest.java       | 326 ++++++++++-----
 .../iotdb/db/metadata/MManagerImproveTest.java     |   1 +
 .../org/apache/iotdb/db/metadata/MTreeTest.java    |  24 +-
 .../apache/iotdb/db/metadata/MetaUtilsTest.java    |  31 ++
 .../apache/iotdb/db/metadata/PartialPathTest.java  |   1 +
 .../org/apache/iotdb/db/metadata/TemplateTest.java |   9 +-
 .../iotdb/db/metadata/mlog/MLogUpgraderTest.java   |   2 +-
 .../java/org/apache/iotdb/db/qp/PlannerTest.java   |   2 +-
 .../iotdb/db/qp/logical/LogicalPlanSmallTest.java  |   2 +-
 .../iotdb/db/qp/other/TSPlanContextAuthorTest.java |   2 +-
 .../iotdb/db/qp/physical/ConcatOptimizerTest.java  |   2 +-
 .../iotdb/db/qp/physical/InsertRowPlanTest.java    | 134 +++++--
 .../qp/physical/InsertRowsOfOneDevicePlanTest.java |   2 +-
 .../db/qp/physical/InsertTabletMultiPlanTest.java  |   2 +-
 .../iotdb/db/qp/physical/InsertTabletPlanTest.java |  77 +---
 .../db/qp/physical/PhysicalPlanSerializeTest.java  |   2 +-
 .../iotdb/db/qp/physical/PhysicalPlanTest.java     |   4 +-
 .../iotdb/db/qp/physical/SerializationTest.java    |   2 +-
 .../query/dataset/UDTFAlignByTimeDataSetTest.java  |   2 +-
 .../reader/series/SeriesAggregateReaderTest.java   |   9 +-
 .../reader/series/SeriesReaderByTimestampTest.java |   7 +-
 .../db/query/reader/series/SeriesReaderTest.java   |   2 +-
 .../query/reader/series/SeriesReaderTestUtil.java  |   7 +-
 .../iotdb/db/rescon/ResourceManagerTest.java       |   5 +-
 .../org/apache/iotdb/db/sink/MQTTSinkTest.java     |   2 +-
 .../db/sync/receiver/load/FileLoaderTest.java      |   2 +-
 .../recover/SyncReceiverLogAnalyzerTest.java       |   2 +-
 .../db/sync/sender/manage/SyncFileManagerTest.java |   2 +-
 .../sender/recover/SyncSenderLogAnalyzerTest.java  |   2 +-
 .../org/apache/iotdb/db/tools/MLogParserTest.java  |   2 +-
 .../iotdb/db/tools/TsFileAndModSettleToolTest.java |   4 +-
 .../iotdb/db/tools/TsFileSketchToolTest.java       |   2 +-
 .../org/apache/iotdb/db/tools/WalCheckerTest.java  |   2 +-
 .../org/apache/iotdb/db/utils/MemUtilsTest.java    |   2 +-
 .../apache/iotdb/db/utils/SchemaTestUtils.java}    |  25 +-
 .../org/apache/iotdb/db/utils/SchemaUtilsTest.java |   2 +-
 .../iotdb/db/utils/TsFileRewriteToolTest.java      |   9 +-
 .../db/utils/datastructure/VectorTVListTest.java   |  65 ++-
 .../apache/iotdb/db/writelog/PerformanceTest.java  |   2 +-
 .../iotdb/db/writelog/WriteLogNodeManagerTest.java |   2 +-
 .../apache/iotdb/db/writelog/WriteLogNodeTest.java |   2 +-
 .../iotdb/db/writelog/io/LogWriterReaderTest.java  |   2 +-
 .../db/writelog/io/MultiFileLogReaderTest.java     |   2 +-
 .../db/writelog/recover/DeviceStringTest.java      |   8 +-
 .../iotdb/db/writelog/recover/LogReplayerTest.java |  27 +-
 .../recover/RecoverResourceFromReaderTest.java     |  10 +-
 .../db/writelog/recover/SeqTsFileRecoverTest.java  |  14 +-
 .../writelog/recover/UnseqTsFileRecoverTest.java   |  10 +-
 .../java/org/apache/iotdb/session/Session.java     | 126 +++---
 .../org/apache/iotdb/session/pool/SessionPool.java |  53 +++
 .../apache/iotdb/session/IoTDBSessionSimpleIT.java |  35 +-
 .../session/IoTDBSessionVectorABDeviceIT.java      |  73 ++--
 .../session/IoTDBSessionVectorAggregationIT.java   |  15 +-
 .../iotdb/session/IoTDBSessionVectorInsertIT.java  |  18 +-
 .../iotdb/spark/tsfile/NarrowConverter.scala       |   2 +-
 .../apache/iotdb/spark/tsfile/WideConverter.scala  |   2 +-
 .../org/apache/iotdb/spark/tool/TsFileExample.java |  29 +-
 .../apache/iotdb/spark/tool/TsFileWriteTool.java   |  87 ++--
 .../test/java/org/apache/iotdb/db/sql/Cases.java   |  76 +---
 thrift-cluster/src/main/thrift/cluster.thrift      |   9 +-
 .../iotdb/tsfile/file/header/PageHeader.java       |  12 +
 ...hunkMetadata.java => AlignedChunkMetadata.java} |  82 ++--
 ...etadata.java => AlignedTimeSeriesMetadata.java} |  63 +--
 .../iotdb/tsfile/file/metadata/ChunkMetadata.java  |  13 +-
 .../iotdb/tsfile/file/metadata/IChunkMetadata.java |   4 -
 .../tsfile/file/metadata/ITimeSeriesMetadata.java  |   3 +-
 .../file/metadata/MetadataIndexConstructor.java    |   6 +-
 .../tsfile/file/metadata/TimeseriesMetadata.java   |  11 +-
 .../fileOutputFactory/LocalFSOutputFactory.java    |   5 +-
 .../iotdb/tsfile/read/TsFileSequenceReader.java    |  41 +-
 .../apache/iotdb/tsfile/read/common/BatchData.java |  15 +-
 .../org/apache/iotdb/tsfile/read/common/Path.java  |   5 +
 .../read/controller/CachedChunkLoaderImpl.java     |  18 +
 .../iotdb/tsfile/read/controller/IChunkLoader.java |   5 +
 .../read/controller/IChunkMetadataLoader.java      |   4 +-
 .../tsfile/read/query/dataset/QueryDataSet.java    |  12 +
 ...torChunkReader.java => AlignedChunkReader.java} |  91 +++--
 ...ectorPageReader.java => AlignedPageReader.java} |  51 ++-
 .../iotdb/tsfile/read/reader/page/PageReader.java  |   1 -
 .../tsfile/read/reader/page/TimePageReader.java    |  17 +
 .../tsfile/read/reader/page/ValuePageReader.java   |   3 +
 .../iotdb/tsfile/utils/MeasurementGroup.java       |  65 +++
 .../iotdb/tsfile/utils/ReadWriteIOUtils.java       |   4 +-
 .../apache/iotdb/tsfile/write/TsFileWriter.java    | 335 ++++++++++++----
 .../write/chunk/AlignedChunkGroupWriterImpl.java   | 299 ++++++++++++++
 ...WriterImpl.java => AlignedChunkWriterImpl.java} |  69 +---
 .../tsfile/write/chunk/ChunkGroupWriterImpl.java   | 241 -----------
 .../iotdb/tsfile/write/chunk/ChunkWriterImpl.java  |  41 +-
 .../tsfile/write/chunk/IChunkGroupWriter.java      |  17 +-
 .../iotdb/tsfile/write/chunk/IChunkWriter.java     |  45 ---
 .../chunk/NonAlignedChunkGroupWriterImpl.java      | 184 +++++++++
 .../iotdb/tsfile/write/chunk/TimeChunkWriter.java  |   4 +
 .../iotdb/tsfile/write/chunk/ValueChunkWriter.java |  67 +++-
 .../iotdb/tsfile/write/page/ValuePageWriter.java   |   4 +
 .../apache/iotdb/tsfile/write/record/Tablet.java   |  55 +--
 .../write/record/datapoint/BooleanDataPoint.java   |   6 +-
 .../tsfile/write/record/datapoint/DataPoint.java   |   9 +-
 .../write/record/datapoint/DoubleDataPoint.java    |   6 +-
 .../write/record/datapoint/FloatDataPoint.java     |   6 +-
 .../write/record/datapoint/IntDataPoint.java       |   6 +-
 .../write/record/datapoint/LongDataPoint.java      |   6 +-
 .../write/record/datapoint/StringDataPoint.java    |   6 +-
 .../tsfile/write/schema/IMeasurementSchema.java    |   2 +
 .../apache/iotdb/tsfile/write/schema/Schema.java   |  69 ++--
 .../write/schema/UnaryMeasurementSchema.java       |   5 +
 .../write/schema/VectorMeasurementSchema.java      |  92 +++--
 .../write/writer/RestorableTsFileIOWriter.java     |   6 +-
 .../iotdb/tsfile/write/writer/TsFileIOWriter.java  |  61 +--
 ...tadataTest.java => TimeseriesMetadataTest.java} |   2 +-
 .../iotdb/tsfile/read/ReadOnlyTsFileTest.java      |   2 +-
 .../tsfile/read/TimeSeriesMetadataReadTest.java    |   7 +-
 .../TsFileGeneratorForSeriesReaderByTimestamp.java |  23 +-
 .../apache/iotdb/tsfile/utils/FileGenerator.java   |  45 +--
 .../org/apache/iotdb/tsfile/utils/RecordUtils.java |  17 +-
 .../apache/iotdb/tsfile/utils/RecordUtilsTest.java |  13 +-
 .../iotdb/tsfile/utils/TsFileGeneratorForTest.java |  25 +-
 .../tsfile/write/DefaultSchemaTemplateTest.java    |   4 +-
 .../tsfile/write/MetadataIndexConstructorTest.java |  73 ++--
 .../org/apache/iotdb/tsfile/write/PerfTest.java    |  16 +-
 .../iotdb/tsfile/write/ReadPageInMemTest.java      |  16 +-
 .../iotdb/tsfile/write/TsFileIOWriterTest.java     |  91 +++--
 .../iotdb/tsfile/write/TsFileReadWriteTest.java    |   7 +-
 .../iotdb/tsfile/write/TsFileWriteApiTest.java     | 257 ++++++++++++
 .../iotdb/tsfile/write/TsFileWriterTest.java       |  97 +++--
 .../org/apache/iotdb/tsfile/write/WriteTest.java   |  10 +-
 .../write/schema/converter/SchemaBuilderTest.java  |  45 ++-
 ...plTest.java => AlignedChunkWriterImplTest.java} |  46 ++-
 .../write/writer/ForceAppendTsFileWriterTest.java  |   8 +-
 .../write/writer/RestorableTsFileIOWriterTest.java |  48 +--
 .../write/writer/VectorMeasurementSchemaStub.java  |   6 +-
 .../zeppelin/iotdb/IoTDBInterpreterTest.java       |   6 +-
 554 files changed, 7752 insertions(+), 6909 deletions(-)

diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/client/sync/SyncClientAdaptor.java b/cluster/src/main/java/org/apache/iotdb/cluster/client/sync/SyncClientAdaptor.java
index 7f4f3aa..016185e 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/client/sync/SyncClientAdaptor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/client/sync/SyncClientAdaptor.java
@@ -52,7 +52,7 @@ import org.apache.iotdb.cluster.server.handlers.caller.PullSnapshotHandler;
 import org.apache.iotdb.cluster.server.handlers.caller.PullTimeseriesSchemaHandler;
 import org.apache.iotdb.cluster.server.handlers.forwarder.ForwardPlanHandler;
 import org.apache.iotdb.cluster.utils.PlanSerializer;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowDevicesPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/coordinator/Coordinator.java b/cluster/src/main/java/org/apache/iotdb/cluster/coordinator/Coordinator.java
index 9110ce5..f5c84d6 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/coordinator/Coordinator.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/coordinator/Coordinator.java
@@ -44,7 +44,7 @@ import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.BatchPlan;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertMultiTabletPlan;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplier.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplier.java
index b0a6f0d..f4677f3 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplier.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplier.java
@@ -27,7 +27,7 @@ import org.apache.iotdb.cluster.server.monitor.Timer;
 import org.apache.iotdb.cluster.server.monitor.Timer.Statistic;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertMultiTabletPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
@@ -159,7 +159,7 @@ public class AsyncDataLogApplier implements LogApplier {
       PartialPath path = ((InsertRowsPlan) plan).getFirstDeviceId();
       sgPath = IoTDB.metaManager.getBelongedStorageGroup(path);
     } else if (plan instanceof InsertPlan) {
-      PartialPath deviceId = ((InsertPlan) plan).getPrefixPath();
+      PartialPath deviceId = ((InsertPlan) plan).getDeviceId();
       sgPath = IoTDB.metaManager.getBelongedStorageGroup(deviceId);
     } else if (plan instanceof CreateTimeSeriesPlan) {
       PartialPath path = ((CreateTimeSeriesPlan) plan).getPath();
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/BaseApplier.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/BaseApplier.java
index 3adc36d..3e4f641 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/BaseApplier.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/BaseApplier.java
@@ -34,7 +34,7 @@ import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.metadata.UndefinedTemplateException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.BatchPlan;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
@@ -240,7 +240,7 @@ abstract class BaseApplier implements LogApplier {
         MetaPuller.getInstance()
             .pullTimeSeriesSchemas(((BatchPlan) plan).getPrefixPaths(), ignoredGroup);
       } else {
-        PartialPath path = plan.getPrefixPath();
+        PartialPath path = plan.getDeviceId();
         MetaPuller.getInstance()
             .pullTimeSeriesSchemas(Collections.singletonList(path), ignoredGroup);
       }
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/DataLogApplier.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/DataLogApplier.java
index 9a8b81a..0c8ed54 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/DataLogApplier.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/applier/DataLogApplier.java
@@ -34,7 +34,7 @@ import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertMultiTabletPlan;
@@ -128,7 +128,7 @@ public class DataLogApplier extends BaseApplier {
     boolean hasSync = false;
     for (InsertTabletPlan insertTabletPlan : plan.getInsertTabletPlanList()) {
       try {
-        IoTDB.metaManager.getBelongedStorageGroup(insertTabletPlan.getPrefixPath());
+        IoTDB.metaManager.getBelongedStorageGroup(insertTabletPlan.getDeviceId());
       } catch (StorageGroupNotSetException e) {
         try {
           if (!hasSync) {
@@ -150,7 +150,7 @@ public class DataLogApplier extends BaseApplier {
     boolean hasSync = false;
     for (InsertRowPlan insertRowPlan : plan.getInsertRowPlanList()) {
       try {
-        IoTDB.metaManager.getBelongedStorageGroup(insertRowPlan.getPrefixPath());
+        IoTDB.metaManager.getBelongedStorageGroup(insertRowPlan.getDeviceId());
       } catch (StorageGroupNotSetException e) {
         try {
           if (!hasSync) {
@@ -170,7 +170,7 @@ public class DataLogApplier extends BaseApplier {
   private void applyInsert(InsertPlan plan)
       throws StorageGroupNotSetException, QueryProcessException, StorageEngineException {
     try {
-      IoTDB.metaManager.getBelongedStorageGroup(plan.getPrefixPath());
+      IoTDB.metaManager.getBelongedStorageGroup(plan.getDeviceId());
     } catch (StorageGroupNotSetException e) {
       // the sg may not exist because the node does not catch up with the leader, retry after
       // synchronization
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/FilePartitionedSnapshotLogManager.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/FilePartitionedSnapshotLogManager.java
index 5e61874..06e16dd 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/FilePartitionedSnapshotLogManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/FilePartitionedSnapshotLogManager.java
@@ -33,7 +33,7 @@ import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.cluster.server.member.DataGroupMember;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.write.schema.TimeseriesSchema;
 
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/MetaSingleSnapshotLogManager.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/MetaSingleSnapshotLogManager.java
index 87789ff..97198b9 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/MetaSingleSnapshotLogManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/MetaSingleSnapshotLogManager.java
@@ -29,7 +29,7 @@ import org.apache.iotdb.db.auth.authorizer.BasicAuthorizer;
 import org.apache.iotdb.db.auth.authorizer.IAuthorizer;
 import org.apache.iotdb.db.auth.entity.Role;
 import org.apache.iotdb.db.auth.entity.User;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.template.TemplateManager;
 import org.apache.iotdb.db.service.IoTDB;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/PartitionedSnapshotLogManager.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/PartitionedSnapshotLogManager.java
index 71ba5c93..56713d1 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/PartitionedSnapshotLogManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/PartitionedSnapshotLogManager.java
@@ -29,7 +29,7 @@ import org.apache.iotdb.cluster.partition.PartitionTable;
 import org.apache.iotdb.cluster.partition.slot.SlotPartitionTable;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.cluster.server.member.DataGroupMember;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.write.schema.TimeseriesSchema;
 
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/FileSnapshot.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/FileSnapshot.java
index 6822219..edcf507 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/FileSnapshot.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/FileSnapshot.java
@@ -40,7 +40,7 @@ import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.LoadFileException;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.utils.SchemaUtils;
 import org.apache.iotdb.tsfile.utils.FilePathUtils;
 import org.apache.iotdb.tsfile.utils.Pair;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/MetaSimpleSnapshot.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/MetaSimpleSnapshot.java
index 23c5d7c..adca4aa 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/MetaSimpleSnapshot.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/MetaSimpleSnapshot.java
@@ -31,7 +31,7 @@ import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupAlreadySetException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.template.TemplateManager;
 import org.apache.iotdb.db.service.IoTDB;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
index 644a869..c221efa 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
@@ -35,6 +35,7 @@ import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.cluster.rpc.thrift.RaftNode;
 import org.apache.iotdb.cluster.server.member.DataGroupMember;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
+import org.apache.iotdb.cluster.utils.ClusterQueryUtils;
 import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
@@ -43,13 +44,14 @@ import org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.metadata.MManager;
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.VectorPartialPath;
 import org.apache.iotdb.db.metadata.lastCache.LastCacheManager;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.InternalMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.utils.MetaUtils;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.physical.BatchPlan;
@@ -118,8 +120,6 @@ import java.util.stream.Collectors;
 import static org.apache.iotdb.cluster.query.ClusterPlanExecutor.LOG_FAIL_CONNECT;
 import static org.apache.iotdb.cluster.query.ClusterPlanExecutor.THREAD_POOL_SIZE;
 import static org.apache.iotdb.cluster.query.ClusterPlanExecutor.waitForThreadPool;
-import static org.apache.iotdb.cluster.utils.ClusterQueryUtils.getAssembledPathFromRequest;
-import static org.apache.iotdb.cluster.utils.ClusterQueryUtils.getPathStrListForRequest;
 import static org.apache.iotdb.db.utils.EncodingInferenceUtils.getDefaultEncoding;
 
 @SuppressWarnings("java:S1135") // ignore todos
@@ -199,11 +199,11 @@ public class CMManager extends MManager {
     }
 
     String measurement = fullPath.getMeasurement();
-    if (fullPath instanceof VectorPartialPath) {
-      if (((VectorPartialPath) fullPath).getSubSensorsList().size() != 1) {
+    if (fullPath instanceof AlignedPath) {
+      if (((AlignedPath) fullPath).getMeasurementList().size() != 1) {
         return TSDataType.VECTOR;
       } else {
-        measurement = ((VectorPartialPath) fullPath).getSubSensor(0);
+        measurement = ((AlignedPath) fullPath).getMeasurement(0);
       }
     }
 
@@ -234,9 +234,7 @@ public class CMManager extends MManager {
         if (measurementSchema instanceof VectorMeasurementSchema) {
           for (String subMeasurement : measurementSchema.getSubMeasurementsList()) {
             cacheMeta(
-                new VectorPartialPath(fullPath.getDevice(), subMeasurement),
-                measurementMNode,
-                false);
+                new AlignedPath(fullPath.getDevice(), subMeasurement), measurementMNode, false);
           }
         } else {
           cacheMeta(fullPath, measurementMNode, true);
@@ -250,11 +248,6 @@ public class CMManager extends MManager {
   }
 
   @Override
-  public IMeasurementSchema getSeriesSchema(PartialPath fullPath) throws MetadataException {
-    return super.getSeriesSchema(fullPath, getMeasurementMNode(fullPath));
-  }
-
-  @Override
   public IMeasurementMNode getMeasurementMNode(PartialPath fullPath) throws MetadataException {
     IMeasurementMNode node = null;
     // try remote cache first
@@ -391,7 +384,7 @@ public class CMManager extends MManager {
       IMeasurementMNode measurementMNode = mRemoteMetaCache.get(seriesPath);
       if (measurementMNode != null) {
         LastCacheManager.updateLastCache(
-            seriesPath, timeValuePair, highPriorityUpdate, latestFlushedTime, measurementMNode);
+            measurementMNode, timeValuePair, highPriorityUpdate, latestFlushedTime);
       }
     } finally {
       cacheLock.writeLock().unlock();
@@ -404,7 +397,7 @@ public class CMManager extends MManager {
   public TimeValuePair getLastCache(PartialPath seriesPath) {
     IMeasurementMNode measurementMNode = mRemoteMetaCache.get(seriesPath);
     if (measurementMNode != null) {
-      return LastCacheManager.getLastCache(seriesPath, measurementMNode);
+      return LastCacheManager.getLastCache(measurementMNode);
     }
 
     return super.getLastCache(seriesPath);
@@ -415,55 +408,16 @@ public class CMManager extends MManager {
       throws MetadataException, IOException {
     IMeasurementMNode[] measurementMNodes = new IMeasurementMNode[plan.getMeasurements().length];
     int nonExistSchemaIndex =
-        getMNodesLocally(plan.getPrefixPath(), plan.getMeasurements(), measurementMNodes);
+        getMNodesLocally(plan.getDeviceId(), plan.getMeasurements(), measurementMNodes);
     if (nonExistSchemaIndex == -1) {
       plan.setMeasurementMNodes(measurementMNodes);
-      return new InternalMNode(null, plan.getPrefixPath().getDevice());
+      return new InternalMNode(null, plan.getDeviceId().getDevice());
     }
     // auto-create schema in IoTDBConfig is always disabled in the cluster version, and we have
     // another config in ClusterConfig to do this
     return super.getSeriesSchemasAndReadLockDevice(plan);
   }
 
-  @Override
-  public IMeasurementSchema getSeriesSchema(PartialPath device, String measurement)
-      throws MetadataException {
-    try {
-      IMeasurementSchema measurementSchema = super.getSeriesSchema(device, measurement);
-      if (measurementSchema != null) {
-        return measurementSchema;
-      }
-    } catch (PathNotExistException e) {
-      // not found in local
-    }
-
-    // try cache
-    cacheLock.readLock().lock();
-    try {
-      IMeasurementMNode measurementMNode = mRemoteMetaCache.get(device.concatNode(measurement));
-      if (measurementMNode != null) {
-        return measurementMNode.getSchema();
-      }
-    } finally {
-      cacheLock.readLock().unlock();
-    }
-
-    // pull from remote
-    pullSeriesSchemas(device, new String[] {measurement});
-
-    // try again
-    cacheLock.readLock().lock();
-    try {
-      IMeasurementMNode measurementMeta = mRemoteMetaCache.get(device.concatNode(measurement));
-      if (measurementMeta != null) {
-        return measurementMeta.getSchema();
-      }
-    } finally {
-      cacheLock.readLock().unlock();
-    }
-    return super.getSeriesSchema(device, measurement);
-  }
-
   /**
    * Check whether the path exists.
    *
@@ -541,7 +495,7 @@ public class CMManager extends MManager {
       storageGroups.addAll(getStorageGroups(getValidStorageGroups((BatchPlan) plan)));
     } else if (plan instanceof InsertRowPlan || plan instanceof InsertTabletPlan) {
       storageGroups.addAll(
-          getStorageGroups(Collections.singletonList(((InsertPlan) plan).getPrefixPath())));
+          getStorageGroups(Collections.singletonList(((InsertPlan) plan).getDeviceId())));
     } else if (plan instanceof CreateTimeSeriesPlan) {
       storageGroups.addAll(
           getStorageGroups(Collections.singletonList(((CreateTimeSeriesPlan) plan).getPath())));
@@ -583,7 +537,8 @@ public class CMManager extends MManager {
   }
 
   /** return storage groups paths for given deviceIds or timeseries. */
-  private List<PartialPath> getStorageGroups(List<PartialPath> paths) throws MetadataException {
+  private List<PartialPath> getStorageGroups(List<? extends PartialPath> paths)
+      throws MetadataException {
     Set<PartialPath> storageGroups = new HashSet<>();
     for (PartialPath path : paths) {
       storageGroups.add(
@@ -661,7 +616,7 @@ public class CMManager extends MManager {
       if (!success) {
         logger.error(
             "create timeseries for device={} failed, plan={}",
-            insertTabletPlan.getPrefixPath(),
+            insertTabletPlan.getDeviceId(),
             insertTabletPlan);
       }
     }
@@ -677,7 +632,7 @@ public class CMManager extends MManager {
       if (!success) {
         logger.error(
             "create timeseries for device={} failed, plan={}",
-            insertRowPlan.getPrefixPath(),
+            insertRowPlan.getDeviceId(),
             insertRowPlan);
       }
     }
@@ -693,7 +648,7 @@ public class CMManager extends MManager {
       if (!success) {
         logger.error(
             "create timeseries for device={} failed, plan={}",
-            insertRowPlan.getPrefixPath(),
+            insertRowPlan.getDeviceId(),
             insertRowPlan);
       }
     }
@@ -721,7 +676,7 @@ public class CMManager extends MManager {
     }
 
     List<String> seriesList = new ArrayList<>();
-    PartialPath deviceId = insertPlan.getPrefixPath();
+    PartialPath deviceId = insertPlan.getDeviceId();
     PartialPath storageGroupName;
     try {
       storageGroupName =
@@ -775,7 +730,7 @@ public class CMManager extends MManager {
 
     CreateAlignedTimeSeriesPlan plan =
         new CreateAlignedTimeSeriesPlan(
-            insertPlan.getPrefixPath(),
+            insertPlan.getDeviceId(),
             measurements,
             dataTypes,
             encodings,
@@ -980,9 +935,9 @@ public class CMManager extends MManager {
    *     storage group added
    * @return a collection of all queried paths
    */
-  private List<PartialPath> getMatchedPaths(Map<String, String> sgPathMap, boolean withAlias)
+  private List<MeasurementPath> getMatchedPaths(Map<String, String> sgPathMap, boolean withAlias)
       throws MetadataException {
-    List<PartialPath> result = new ArrayList<>();
+    List<MeasurementPath> result = new ArrayList<>();
     // split the paths by the data group they belong to
     Map<PartitionGroup, List<String>> remoteGroupPathMap = new HashMap<>();
     for (Entry<String, String> sgPathEntry : sgPathMap.entrySet()) {
@@ -1001,7 +956,7 @@ public class CMManager extends MManager {
         } catch (CheckConsistencyException e) {
           logger.warn("Failed to check consistency.", e);
         }
-        List<PartialPath> allTimeseriesName = getMatchedPathsLocally(pathUnderSG, withAlias);
+        List<MeasurementPath> allTimeseriesName = getMatchedPathsLocally(pathUnderSG, withAlias);
         logger.debug(
             "{}: get matched paths of {} locally, result {}",
             metaGroupMember.getName(),
@@ -1027,23 +982,23 @@ public class CMManager extends MManager {
     return result;
   }
 
-  private List<PartialPath> getMatchedPathsLocally(PartialPath partialPath, boolean withAlias)
+  private List<MeasurementPath> getMatchedPathsLocally(PartialPath partialPath, boolean withAlias)
       throws MetadataException {
     if (!withAlias) {
-      return getFlatMeasurementPaths(partialPath);
+      return getMeasurementPaths(partialPath);
     } else {
-      return super.getFlatMeasurementPathsWithAlias(partialPath, -1, -1).left;
+      return super.getMeasurementPathsWithAlias(partialPath, -1, -1).left;
     }
   }
 
-  private List<PartialPath> getMatchedPaths(
+  private List<MeasurementPath> getMatchedPaths(
       PartitionGroup partitionGroup, List<String> pathsToQuery, boolean withAlias)
       throws MetadataException {
     // choose the node with lowest latency or highest throughput
     List<Node> coordinatedNodes = QueryCoordinator.getINSTANCE().reorderNodes(partitionGroup);
     for (Node node : coordinatedNodes) {
       try {
-        List<PartialPath> paths =
+        List<MeasurementPath> paths =
             getMatchedPaths(node, partitionGroup.getHeader(), pathsToQuery, withAlias);
         if (logger.isDebugEnabled()) {
           logger.debug(
@@ -1071,7 +1026,7 @@ public class CMManager extends MManager {
   }
 
   @SuppressWarnings("java:S1168") // null and empty list are different
-  private List<PartialPath> getMatchedPaths(
+  private List<MeasurementPath> getMatchedPaths(
       Node node, RaftNode header, List<String> pathsToQuery, boolean withAlias)
       throws IOException, TException, InterruptedException {
     GetAllPathsResult result;
@@ -1101,15 +1056,17 @@ public class CMManager extends MManager {
     if (result != null) {
       // paths may be empty, implying that the group does not contain matched paths, so we do not
       // need to query other nodes in the group
-      List<PartialPath> partialPaths = new ArrayList<>();
+      List<MeasurementPath> measurementPaths = new ArrayList<>();
       for (int i = 0; i < result.paths.size(); i++) {
-        PartialPath matchedPath = getAssembledPathFromRequest(result.paths.get(i));
-        partialPaths.add(matchedPath);
+        MeasurementPath matchedPath =
+            ClusterQueryUtils.getAssembledPathFromRequest(
+                result.getPaths().get(i), result.getDataTypes().get(i));
+        measurementPaths.add(matchedPath);
         if (withAlias && matchedPath != null) {
           matchedPath.setMeasurementAlias(result.aliasList.get(i));
         }
       }
-      return partialPaths;
+      return measurementPaths;
     } else {
       // a null implies a network failure, so we have to query other nodes in the group
       return null;
@@ -1235,10 +1192,10 @@ public class CMManager extends MManager {
 
   /** Similar to method getAllTimeseriesPath(), but return Path with alias alias. */
   @Override
-  public Pair<List<PartialPath>, Integer> getFlatMeasurementPathsWithAlias(
+  public Pair<List<MeasurementPath>, Integer> getMeasurementPathsWithAlias(
       PartialPath pathPattern, int limit, int offset) throws MetadataException {
     Map<String, String> sgPathMap = groupPathByStorageGroup(pathPattern);
-    List<PartialPath> result = getMatchedPaths(sgPathMap, true);
+    List<MeasurementPath> result = getMatchedPaths(sgPathMap, true);
 
     int skippedOffset = 0;
     // apply offset and limit
@@ -1263,9 +1220,9 @@ public class CMManager extends MManager {
    * @param originPath a path potentially with wildcard
    * @return all paths after removing wildcards in the path
    */
-  public List<PartialPath> getMatchedPaths(PartialPath originPath) throws MetadataException {
+  public List<MeasurementPath> getMatchedPaths(PartialPath originPath) throws MetadataException {
     Map<String, String> sgPathMap = groupPathByStorageGroup(originPath);
-    List<PartialPath> ret = getMatchedPaths(sgPathMap, false);
+    List<MeasurementPath> ret = getMatchedPaths(sgPathMap, false);
     logger.debug("The paths of path {} are {}", originPath, ret);
     return ret;
   }
@@ -1278,7 +1235,7 @@ public class CMManager extends MManager {
    *     original paths
    */
   public Pair<List<PartialPath>, List<PartialPath>> getMatchedPaths(
-      List<PartialPath> originalPaths) {
+      List<? extends PartialPath> originalPaths) {
     ConcurrentSkipListSet<PartialPath> fullPaths = new ConcurrentSkipListSet<>();
     ConcurrentSkipListSet<PartialPath> nonExistPaths = new ConcurrentSkipListSet<>();
     // TODO it is not suitable for register and deregister an Object to JMX to such a frequent
@@ -1290,7 +1247,7 @@ public class CMManager extends MManager {
       getAllPathsService.submit(
           () -> {
             try {
-              List<PartialPath> fullPathStrs = getMatchedPaths(pathStr);
+              List<MeasurementPath> fullPathStrs = getMatchedPaths(pathStr);
               if (fullPathStrs.isEmpty()) {
                 nonExistPaths.add(pathStr);
                 logger.debug("Path {} is not found.", pathStr);
@@ -1713,14 +1670,16 @@ public class CMManager extends MManager {
 
   public GetAllPathsResult getAllPaths(List<String> paths, boolean withAlias)
       throws MetadataException {
-    List<List<String>> retPaths = new ArrayList<>();
+    List<String> retPaths = new ArrayList<>();
+    List<Byte> dataTypes = new ArrayList<>();
     List<String> alias = withAlias ? new ArrayList<>() : null;
 
     for (String path : paths) {
-      List<PartialPath> allTimeseriesPathWithAlias =
-          super.getFlatMeasurementPathsWithAlias(new PartialPath(path), -1, -1).left;
-      for (PartialPath timeseriesPathWithAlias : allTimeseriesPathWithAlias) {
-        retPaths.add(getPathStrListForRequest(timeseriesPathWithAlias));
+      List<MeasurementPath> allTimeseriesPathWithAlias =
+          super.getMeasurementPathsWithAlias(new PartialPath(path), -1, -1).left;
+      for (MeasurementPath timeseriesPathWithAlias : allTimeseriesPathWithAlias) {
+        retPaths.add(timeseriesPathWithAlias.getFullPath());
+        dataTypes.add(timeseriesPathWithAlias.getSeriesTypeInByte());
         if (withAlias) {
           alias.add(timeseriesPathWithAlias.getMeasurementAlias());
         }
@@ -1729,6 +1688,7 @@ public class CMManager extends MManager {
 
     GetAllPathsResult getAllPathsResult = new GetAllPathsResult();
     getAllPathsResult.setPaths(retPaths);
+    getAllPathsResult.setDataTypes(dataTypes);
     getAllPathsResult.setAliasList(alias);
     return getAllPathsResult;
   }
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/MetaPuller.java b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/MetaPuller.java
index 66425df..ce58c08 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/MetaPuller.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/MetaPuller.java
@@ -35,7 +35,7 @@ import org.apache.iotdb.cluster.rpc.thrift.RaftNode;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.cluster.utils.ClusterUtils;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.SchemaUtils;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/partition/PartitionTable.java b/cluster/src/main/java/org/apache/iotdb/cluster/partition/PartitionTable.java
index 4b4129a..0d704ae 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/partition/PartitionTable.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/partition/PartitionTable.java
@@ -24,7 +24,7 @@ import org.apache.iotdb.cluster.rpc.thrift.RaftNode;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 
 import org.apache.commons.collections4.map.MultiKeyMap;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutor.java
index b12faa3..c9eddd8 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutor.java
@@ -30,7 +30,7 @@ import org.apache.iotdb.cluster.server.member.DataGroupMember;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.dataset.RawQueryDataSetWithoutValueFilter;
@@ -129,7 +129,7 @@ public class ClusterDataQueryExecutor extends RawDataQueryExecutor {
     for (int i = 0; i < queryPlan.getDeduplicatedPaths().size(); i++) {
       PartialPath partialPath = queryPlan.getDeduplicatedPaths().get(i);
       TSDataType dataType = queryPlan.getDeduplicatedDataTypes().get(i);
-      String fullPath = partialPath.getExactFullPath();
+      String fullPath = partialPath.getFullPath();
       AssignPathManagedMergeReader assignPathManagedMergeReader =
           new AssignPathManagedMergeReader(fullPath, dataType);
       for (AbstractMultPointReader multPointReader : multPointReaders) {
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPhysicalGenerator.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPhysicalGenerator.java
index 80a6a94..67ea518 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPhysicalGenerator.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPhysicalGenerator.java
@@ -24,7 +24,8 @@ import org.apache.iotdb.cluster.metadata.CMManager;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
+import org.apache.iotdb.db.metadata.utils.MetaUtils;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
 import org.apache.iotdb.db.qp.logical.sys.LoadConfigurationOperator.LoadConfigurationOperatorType;
@@ -33,7 +34,6 @@ import org.apache.iotdb.db.qp.physical.sys.LoadConfigurationPlan;
 import org.apache.iotdb.db.qp.physical.sys.LoadConfigurationPlan.LoadConfigurationPlanType;
 import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
 import org.apache.iotdb.db.service.IoTDB;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,7 +43,6 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
 
@@ -56,17 +55,8 @@ public class ClusterPhysicalGenerator extends PhysicalGenerator {
   }
 
   @Override
-  public List<TSDataType> getSeriesTypes(List<PartialPath> paths) throws MetadataException {
-    List<TSDataType> dataTypes = new ArrayList<>();
-    for (PartialPath path : paths) {
-      dataTypes.add(path == null ? null : IoTDB.metaManager.getSeriesType(path));
-    }
-    return dataTypes;
-  }
-
-  @Override
   public List<PartialPath> groupVectorPaths(List<PartialPath> paths) throws MetadataException {
-    return getCMManager().groupVectorPaths(paths);
+    return MetaUtils.groupAlignedPaths(paths);
   }
 
   @Override
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
index e62a1af..e849787 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
@@ -41,8 +41,9 @@ import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
@@ -118,7 +119,7 @@ public class ClusterPlanExecutor extends PlanExecutor {
 
   @Override
   @TestOnly
-  protected List<PartialPath> getPathsName(PartialPath path) throws MetadataException {
+  protected List<MeasurementPath> getPathsName(PartialPath path) throws MetadataException {
     return ((CMManager) IoTDB.metaManager).getMatchedPaths(path);
   }
 
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanRouter.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanRouter.java
index 598046a..6afec36 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanRouter.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanRouter.java
@@ -31,7 +31,7 @@ import org.apache.iotdb.cluster.utils.PartitionUtils;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.MManager;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertMultiTabletPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
@@ -98,7 +98,7 @@ public class ClusterPlanRouter {
   }
 
   private PartitionGroup routePlan(InsertRowPlan plan) throws MetadataException {
-    return partitionTable.partitionByPathTime(plan.getPrefixPath(), plan.getTime());
+    return partitionTable.partitionByPathTime(plan.getDeviceId(), plan.getTime());
   }
 
   private PartitionGroup routePlan(CreateTimeSeriesPlan plan) throws MetadataException {
@@ -175,7 +175,7 @@ public class ClusterPlanRouter {
   private Map<PhysicalPlan, PartitionGroup> splitAndRoutePlan(InsertRowPlan plan)
       throws MetadataException {
     PartitionGroup partitionGroup =
-        partitionTable.partitionByPathTime(plan.getPrefixPath(), plan.getTime());
+        partitionTable.partitionByPathTime(plan.getDeviceId(), plan.getTime());
     return Collections.singletonMap(plan, partitionGroup);
   }
 
@@ -218,7 +218,7 @@ public class ClusterPlanRouter {
         InsertTabletPlan tmpPlan = (InsertTabletPlan) entry.getKey();
         PartitionGroup tmpPg = entry.getValue();
         // 1.1 the sg that the plan(actually calculated based on device) belongs to
-        PartialPath tmpSgPath = IoTDB.metaManager.getBelongedStorageGroup(tmpPlan.getPrefixPath());
+        PartialPath tmpSgPath = IoTDB.metaManager.getBelongedStorageGroup(tmpPlan.getDeviceId());
         Map<PartialPath, InsertMultiTabletPlan> sgPathPlanMap = pgSgPathPlanMap.get(tmpPg);
         if (sgPathPlanMap == null) {
           // 2.1 construct the InsertMultiTabletPlan
@@ -279,7 +279,7 @@ public class ClusterPlanRouter {
     Map<PartitionGroup, InsertRowsPlan> groupPlanMap = new HashMap<>();
     for (int i = 0; i < insertRowsPlan.getInsertRowPlanList().size(); i++) {
       InsertRowPlan rowPlan = insertRowsPlan.getInsertRowPlanList().get(i);
-      PartialPath storageGroup = getMManager().getBelongedStorageGroup(rowPlan.getPrefixPath());
+      PartialPath storageGroup = getMManager().getBelongedStorageGroup(rowPlan.getDeviceId());
       PartitionGroup group = partitionTable.route(storageGroup.getFullPath(), rowPlan.getTime());
       if (groupPlanMap.containsKey(group)) {
         InsertRowsPlan tmpPlan = groupPlanMap.get(group);
@@ -300,7 +300,7 @@ public class ClusterPlanRouter {
   @SuppressWarnings("SuspiciousSystemArraycopy")
   private Map<PhysicalPlan, PartitionGroup> splitAndRoutePlan(InsertTabletPlan plan)
       throws MetadataException {
-    PartialPath storageGroup = getMManager().getBelongedStorageGroup(plan.getPrefixPath());
+    PartialPath storageGroup = getMManager().getBelongedStorageGroup(plan.getDeviceId());
     Map<PhysicalPlan, PartitionGroup> result = new HashMap<>();
     long[] times = plan.getTimes();
     if (times.length == 0) {
@@ -481,7 +481,7 @@ public class ClusterPlanRouter {
     Map<PhysicalPlan, PartitionGroup> result = new HashMap<>();
     Map<PartitionGroup, List<InsertRowPlan>> groupPlanMap = new HashMap<>();
     Map<PartitionGroup, List<Integer>> groupPlanIndexMap = new HashMap<>();
-    PartialPath storageGroup = getMManager().getBelongedStorageGroup(plan.getPrefixPath());
+    PartialPath storageGroup = getMManager().getBelongedStorageGroup(plan.getDeviceId());
     for (int i = 0; i < plan.getRowPlans().length; i++) {
       InsertRowPlan p = plan.getRowPlans()[i];
       PartitionGroup group = partitionTable.route(storageGroup.getFullPath(), p.getTime());
@@ -496,7 +496,7 @@ public class ClusterPlanRouter {
     for (Entry<PartitionGroup, List<InsertRowPlan>> entry : groupPlanMap.entrySet()) {
       PhysicalPlan reducedPlan =
           new InsertRowsOfOneDevicePlan(
-              plan.getPrefixPath(),
+              plan.getDeviceId(),
               entry.getValue().toArray(new InsertRowPlan[0]),
               groupPlanIndexMap.get(entry.getKey()).stream().mapToInt(i -> i).toArray());
       result.put(reducedPlan, entry.getKey());
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/LocalQueryExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/LocalQueryExecutor.java
index 5081687..088773b 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/LocalQueryExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/LocalQueryExecutor.java
@@ -40,13 +40,13 @@ import org.apache.iotdb.cluster.rpc.thrift.PullSchemaResp;
 import org.apache.iotdb.cluster.rpc.thrift.RaftNode;
 import org.apache.iotdb.cluster.rpc.thrift.SingleSeriesQueryRequest;
 import org.apache.iotdb.cluster.server.member.DataGroupMember;
-import org.apache.iotdb.cluster.utils.ClusterQueryUtils;
 import org.apache.iotdb.cluster.utils.ClusterUtils;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowDevicesPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
@@ -218,7 +218,8 @@ public class LocalQueryExecutor {
         request.getQueryId());
     dataGroupMember.syncLeaderWithConsistencyCheck(false);
 
-    PartialPath path = getAssembledPathFromRequest(request.getPath());
+    MeasurementPath path =
+        getAssembledPathFromRequest(request.getPath(), (byte) request.getDataTypeOrdinal());
     TSDataType dataType = TSDataType.values()[request.getDataTypeOrdinal()];
     Filter timeFilter = null;
     Filter valueFilter = null;
@@ -296,12 +297,14 @@ public class LocalQueryExecutor {
         request.getQueryId());
     dataGroupMember.syncLeaderWithConsistencyCheck(false);
 
-    List<PartialPath> paths = Lists.newArrayList();
-    request.getPath().forEach(path -> paths.add(getAssembledPathFromRequest(path)));
-
+    List<MeasurementPath> paths = Lists.newArrayList();
     List<TSDataType> dataTypes = Lists.newArrayList();
-    request.getDataTypeOrdinal().forEach(dataType -> dataTypes.add(TSDataType.values()[dataType]));
-
+    for (int i = 0; i < request.getPath().size(); i++) {
+      paths.add(
+          getAssembledPathFromRequest(
+              request.getPath().get(i), request.getDataTypeOrdinal().get(i).byteValue()));
+      dataTypes.add(TSDataType.values()[request.getDataTypeOrdinal().get(i)]);
+    }
     Filter timeFilter = null;
     Filter valueFilter = null;
     if (request.isSetTimeFilterBytes()) {
@@ -538,7 +541,8 @@ public class LocalQueryExecutor {
         request.getQueryId());
     dataGroupMember.syncLeaderWithConsistencyCheck(false);
 
-    PartialPath path = getAssembledPathFromRequest(request.getPath());
+    MeasurementPath path =
+        getAssembledPathFromRequest(request.getPath(), (byte) request.getDataTypeOrdinal());
     TSDataType dataType = TSDataType.values()[request.dataTypeOrdinal];
     Set<String> deviceMeasurements = request.getDeviceMeasurements();
 
@@ -636,7 +640,7 @@ public class LocalQueryExecutor {
     TSDataType dataType = TSDataType.values()[request.getDataTypeOrdinal()];
     PartialPath path;
     try {
-      path = new PartialPath(request.getPath());
+      path = new MeasurementPath(request.getPath(), dataType);
     } catch (IllegalPathException e) {
       logger.error(
           "{}: aggregation has error path: {}, queryId: {}",
@@ -705,7 +709,6 @@ public class LocalQueryExecutor {
       throw new QueryProcessException(e.getMessage());
     }
 
-    ClusterQueryUtils.checkPathExistence(path);
     List<AggregateResult> results = new ArrayList<>();
     List<AggregateResult> ascResults = new ArrayList<>();
     List<AggregateResult> descResults = new ArrayList<>();
@@ -746,8 +749,8 @@ public class LocalQueryExecutor {
     List<String> result = new ArrayList<>();
     for (String seriesPath : timeseriesList) {
       try {
-        List<PartialPath> path =
-            getCMManager().getFlatMeasurementPaths(new PartialPath(seriesPath));
+        List<MeasurementPath> path =
+            getCMManager().getMeasurementPaths(new PartialPath(seriesPath));
         if (path.size() != 1) {
           throw new MetadataException(
               String.format("Timeseries number of the name [%s] is not 1.", seriesPath));
@@ -787,7 +790,6 @@ public class LocalQueryExecutor {
       throw new StorageEngineException(e);
     }
 
-    ClusterQueryUtils.checkPathExistence(path);
     List<Integer> nodeSlots =
         ((SlotPartitionTable) dataGroupMember.getMetaGroupMember().getPartitionTable())
             .getNodeSlots(dataGroupMember.getHeader());
@@ -817,14 +819,14 @@ public class LocalQueryExecutor {
    */
   public long getGroupByExecutor(GroupByRequest request)
       throws QueryProcessException, StorageEngineException {
+    List<Integer> aggregationTypeOrdinals = request.getAggregationTypeOrdinals();
+    TSDataType dataType = TSDataType.values()[request.getDataTypeOrdinal()];
     PartialPath path;
     try {
-      path = new PartialPath(request.getPath());
+      path = new MeasurementPath(request.getPath(), dataType);
     } catch (IllegalPathException e) {
       throw new QueryProcessException(e);
     }
-    List<Integer> aggregationTypeOrdinals = request.getAggregationTypeOrdinals();
-    TSDataType dataType = TSDataType.values()[request.getDataTypeOrdinal()];
     Filter timeFilter = null;
     if (request.isSetTimeFilterBytes()) {
       timeFilter = FilterFactory.deserialize(request.timeFilterBytes);
@@ -925,8 +927,8 @@ public class LocalQueryExecutor {
 
   public ByteBuffer previousFill(PreviousFillRequest request)
       throws QueryProcessException, StorageEngineException, IOException, IllegalPathException {
-    PartialPath path = new PartialPath(request.getPath());
     TSDataType dataType = TSDataType.values()[request.getDataTypeOrdinal()];
+    PartialPath path = new MeasurementPath(request.getPath(), dataType);
     long queryId = request.getQueryId();
     long queryTime = request.getQueryTime();
     long beforeRange = request.getBeforeRange();
@@ -1017,7 +1019,7 @@ public class LocalQueryExecutor {
     for (Integer dataTypeOrdinal : request.dataTypeOrdinals) {
       dataTypes.add(TSDataType.values()[dataTypeOrdinal]);
     }
-    ClusterQueryUtils.checkPathExistence(partialPaths);
+
     IExpression expression = null;
     if (request.isSetFilterBytes()) {
       Filter filter = FilterFactory.deserialize(request.filterBytes);
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/aggregate/ClusterAggregateExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/aggregate/ClusterAggregateExecutor.java
index af12e5a..022da56 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/aggregate/ClusterAggregateExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/aggregate/ClusterAggregateExecutor.java
@@ -24,7 +24,7 @@ import org.apache.iotdb.cluster.query.reader.ClusterTimeGenerator;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.AggregationPlan;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.aggregation.AggregateResult;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/aggregate/ClusterAggregator.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/aggregate/ClusterAggregator.java
index 39760b6..4ca6e23 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/aggregate/ClusterAggregator.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/aggregate/ClusterAggregator.java
@@ -38,7 +38,7 @@ import org.apache.iotdb.cluster.server.member.DataGroupMember;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.aggregation.AggregateResult;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.utils.SerializeUtils;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/ClusterFillExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/ClusterFillExecutor.java
index 6e05352..1a45a9f 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/ClusterFillExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/ClusterFillExecutor.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.cluster.query.reader.ClusterReaderFactory;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.FillQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.executor.FillQueryExecutor;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/ClusterPreviousFill.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/ClusterPreviousFill.java
index 5872fcb..05919cd 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/ClusterPreviousFill.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/ClusterPreviousFill.java
@@ -35,7 +35,7 @@ import org.apache.iotdb.cluster.server.member.DataGroupMember;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.executor.fill.PreviousFill;
 import org.apache.iotdb.db.utils.TimeValuePairUtils.Intervals;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/PreviousFillArguments.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/PreviousFillArguments.java
index 8bb8c3a..6cde065 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/PreviousFillArguments.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/fill/PreviousFillArguments.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.cluster.query.fill;
 
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.util.Set;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByFillNoVFilterDataSet.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByFillNoVFilterDataSet.java
index 1776734..fe339f7 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByFillNoVFilterDataSet.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByFillNoVFilterDataSet.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.cluster.query.groupby;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.GroupByTimeFillPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.dataset.groupby.GroupByExecutor;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByNoVFilterDataSet.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByNoVFilterDataSet.java
index 0577be2..41fe36d 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByNoVFilterDataSet.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByNoVFilterDataSet.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.cluster.query.groupby;
 
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.dataset.groupby.GroupByExecutor;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByVFilterDataSet.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByVFilterDataSet.java
index 151e0c7..bd1fb12 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByVFilterDataSet.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByVFilterDataSet.java
@@ -25,7 +25,7 @@ import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/MergeGroupByExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/MergeGroupByExecutor.java
index c1baa21..7cc9ee2 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/MergeGroupByExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/groupby/MergeGroupByExecutor.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.cluster.query.reader.ClusterReaderFactory;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.aggregation.AggregateResult;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.dataset.groupby.GroupByExecutor;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/last/ClusterLastQueryExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/last/ClusterLastQueryExecutor.java
index 1f038ef..3bb71fd 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/last/ClusterLastQueryExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/last/ClusterLastQueryExecutor.java
@@ -31,11 +31,10 @@ import org.apache.iotdb.cluster.rpc.thrift.LastQueryRequest;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.cluster.server.member.DataGroupMember;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
-import org.apache.iotdb.cluster.utils.ClusterQueryUtils;
 import org.apache.iotdb.db.concurrent.IoTDBThreadPoolFactory;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.LastQueryPlan;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -180,7 +179,6 @@ public class ClusterLastQueryExecutor extends LastQueryExecutor {
         PartitionGroup group, List<PartialPath> seriesPaths, QueryContext context)
         throws QueryProcessException, StorageEngineException, IOException {
       if (group.contains(metaGroupMember.getThisNode())) {
-        ClusterQueryUtils.checkPathExistence(seriesPaths);
         return calculateSeriesLastLocally(group, seriesPaths, context);
       } else {
         return calculateSeriesLastRemotely(group, seriesPaths, context);
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
index 078c95a..f74b406 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
@@ -52,7 +52,8 @@ import org.apache.iotdb.cluster.utils.ClusterQueryUtils;
 import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.aggregation.AggregationType;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
@@ -333,7 +334,7 @@ public class ClusterReaderFactory {
                 dataGroupMember,
                 ascending,
                 null);
-        partialPathPointReaderMap.put(partialPath.getExactFullPath(), seriesPointReader);
+        partialPathPointReaderMap.put(partialPath.getFullPath(), seriesPointReader);
       }
 
       if (logger.isDebugEnabled()) {
@@ -540,7 +541,6 @@ public class ClusterReaderFactory {
       boolean ascending,
       Set<Integer> requiredSlots)
       throws StorageEngineException, QueryProcessException {
-    ClusterQueryUtils.checkPathExistence(path);
     // If requiredSlots is null, it means that this node should provide data of all slots about
     // required paths.
     if (requiredSlots == null) {
@@ -553,8 +553,7 @@ public class ClusterReaderFactory {
     QueryDataSource queryDataSource =
         QueryResourceManager.getInstance().getQueryDataSource(path, context, timeFilter);
     valueFilter = queryDataSource.updateFilterUsingTTL(valueFilter);
-    return new SeriesReader(
-        path,
+    return path.createSeriesReader(
         allSensors,
         dataType,
         context,
@@ -687,7 +686,7 @@ public class ClusterReaderFactory {
       request.setValueFilterBytes(SerializeUtils.serializeFilter(valueFilter));
     }
 
-    List<List<String>> fullPaths = Lists.newArrayList();
+    List<String> fullPaths = Lists.newArrayList();
     paths.forEach(path -> fullPaths.add(getPathStrListForRequest(path)));
 
     List<Integer> dataTypeOrdinals = Lists.newArrayList();
@@ -1077,7 +1076,7 @@ public class ClusterReaderFactory {
    * @throws StorageEngineException
    */
   public IBatchReader getMultSeriesBatchReader(
-      List<PartialPath> paths,
+      List<MeasurementPath> paths,
       Map<String, Set<String>> allSensors,
       List<TSDataType> dataTypes,
       Filter timeFilter,
@@ -1109,7 +1108,7 @@ public class ClusterReaderFactory {
               ascending,
               null,
               false);
-      partialPathBatchReaderMap.put(partialPath.getExactFullPath(), batchReader);
+      partialPathBatchReaderMap.put(partialPath.getFullPath(), batchReader);
     }
     return new MultBatchReader(partialPathBatchReaderMap);
   }
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterTimeGenerator.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterTimeGenerator.java
index d1b38e7..4d63f99 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterTimeGenerator.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterTimeGenerator.java
@@ -24,7 +24,7 @@ import org.apache.iotdb.cluster.partition.PartitionGroup;
 import org.apache.iotdb.cluster.server.member.DataGroupMember;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.reader.series.ManagedSeriesReader;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/MultDataSourceInfo.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/MultDataSourceInfo.java
index 1521ba3..5ab2abf 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/MultDataSourceInfo.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/MultDataSourceInfo.java
@@ -30,7 +30,7 @@ import org.apache.iotdb.cluster.rpc.thrift.MultSeriesQueryRequest;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.cluster.rpc.thrift.RaftNode;
 import org.apache.iotdb.cluster.server.handlers.caller.GenericHandler;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.utils.SerializeUtils;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.filter.TimeFilter;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReader.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReader.java
index 2b5282c..0221e99 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReader.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReader.java
@@ -73,7 +73,7 @@ public class RemoteMultSeriesReader extends AbstractMultPointReader {
     this.cachedBatchs = Maps.newHashMap();
     this.pathToDataType = Maps.newHashMap();
     for (int i = 0; i < sourceInfo.getPartialPaths().size(); i++) {
-      String fullPath = sourceInfo.getPartialPaths().get(i).getExactFullPath();
+      String fullPath = sourceInfo.getPartialPaths().get(i).getFullPath();
       this.cachedBatchs.put(fullPath, new ConcurrentLinkedQueue<>());
       this.pathToDataType.put(fullPath, sourceInfo.getDataTypes().get(i));
     }
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/server/member/DataGroupMember.java b/cluster/src/main/java/org/apache/iotdb/cluster/server/member/DataGroupMember.java
index f611683..e7fcf92 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/server/member/DataGroupMember.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/server/member/DataGroupMember.java
@@ -82,7 +82,7 @@ import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.BatchPlan;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/server/member/MetaGroupMember.java b/cluster/src/main/java/org/apache/iotdb/cluster/server/member/MetaGroupMember.java
index 87e5aeb..ac419c2 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/server/member/MetaGroupMember.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/server/member/MetaGroupMember.java
@@ -79,7 +79,7 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.service.IService;
 import org.apache.iotdb.db.service.IoTDB;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/utils/ClusterQueryUtils.java b/cluster/src/main/java/org/apache/iotdb/cluster/utils/ClusterQueryUtils.java
index e6fc88f..3cec0a8 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/utils/ClusterQueryUtils.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/utils/ClusterQueryUtils.java
@@ -23,17 +23,17 @@ import org.apache.iotdb.cluster.metadata.MetaPuller;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.VectorPartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.common.Path;
+import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.List;
 
 public class ClusterQueryUtils {
 
@@ -43,20 +43,6 @@ public class ClusterQueryUtils {
     // util class
   }
 
-  /**
-   * Check if the given path exists locally or can be pulled from a remote node.
-   *
-   * @param path
-   * @throws QueryProcessException
-   */
-  public static void checkPathExistence(String path) throws QueryProcessException {
-    try {
-      checkPathExistence(new PartialPath(path));
-    } catch (IllegalPathException e) {
-      throw new QueryProcessException(e);
-    }
-  }
-
   public static void checkPathExistence(PartialPath path) throws QueryProcessException {
     if (!IoTDB.metaManager.isPathExist(path)) {
       try {
@@ -67,27 +53,15 @@ public class ClusterQueryUtils {
     }
   }
 
-  public static void checkPathExistence(List<PartialPath> paths) throws QueryProcessException {
-    for (PartialPath path : paths) {
-      checkPathExistence(path);
-    }
-  }
-
   /**
    * Generate path string list for RPC request.
    *
-   * <p>If vector path, return its vectorId with all subSensors. Else just return path string.
+   * <p>If vector path, return its vectorId with all subSensors. Else just return path string. TODO
+   * aligned path
    */
-  public static List<String> getPathStrListForRequest(Path path) {
-    if (path instanceof VectorPartialPath) {
-      List<String> pathWithSubSensors =
-          new ArrayList<>(((VectorPartialPath) path).getSubSensorsList().size() + 1);
-      pathWithSubSensors.add(path.getFullPath());
-      pathWithSubSensors.addAll(((VectorPartialPath) path).getSubSensorsList());
-      return pathWithSubSensors;
-    } else {
-      return Collections.singletonList(path.getFullPath());
-    }
+  public static String getPathStrListForRequest(Path path) {
+    // TODO aligned Path
+    return path.getFullPath();
   }
 
   /**
@@ -95,13 +69,14 @@ public class ClusterQueryUtils {
    *
    * <p>This method is corresponding to getPathStringListForRequest().
    */
-  public static PartialPath getAssembledPathFromRequest(List<String> pathString) {
+  public static MeasurementPath getAssembledPathFromRequest(String pathString, byte dataType) {
+    // TODO aligned path
     try {
-      if (pathString.size() == 1) {
-        return new PartialPath(pathString.get(0));
-      } else {
-        return new VectorPartialPath(pathString.get(0), pathString.subList(1, pathString.size()));
-      }
+      MeasurementPath matchedPath = new MeasurementPath(pathString);
+      matchedPath.setMeasurementSchema(
+          new UnaryMeasurementSchema(
+              matchedPath.getMeasurement(), TSDataType.deserialize(dataType)));
+      return matchedPath;
     } catch (IllegalPathException e) {
       logger.error("Failed to create partial path, fullPath is {}.", pathString, e);
       return null;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/utils/ClusterUtils.java b/cluster/src/main/java/org/apache/iotdb/cluster/utils/ClusterUtils.java
index 82ecc3a..f631958 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/utils/ClusterUtils.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/utils/ClusterUtils.java
@@ -31,7 +31,7 @@ import org.apache.iotdb.cluster.rpc.thrift.StartUpStatus;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 
 import org.slf4j.Logger;
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/utils/PartitionUtils.java b/cluster/src/main/java/org/apache/iotdb/cluster/utils/PartitionUtils.java
index 3c6a8db..8b79624 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/utils/PartitionUtils.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/utils/PartitionUtils.java
@@ -135,7 +135,7 @@ public class PartitionUtils {
 
   public static InsertTabletPlan copy(
       InsertTabletPlan plan, long[] times, Object[] values, BitMap[] bitMaps) {
-    InsertTabletPlan newPlan = new InsertTabletPlan(plan.getPrefixPath(), plan.getMeasurements());
+    InsertTabletPlan newPlan = new InsertTabletPlan(plan.getDeviceId(), plan.getMeasurements());
     newPlan.setDataTypes(plan.getDataTypes());
     // according to TSServiceImpl.insertBatch(), only the deviceId, measurements, dataTypes,
     // times, columns, and rowCount are need to be maintained.
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/utils/nodetool/ClusterMonitor.java b/cluster/src/main/java/org/apache/iotdb/cluster/utils/nodetool/ClusterMonitor.java
index e63adbe..efcebef 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/utils/nodetool/ClusterMonitor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/utils/nodetool/ClusterMonitor.java
@@ -34,7 +34,7 @@ import org.apache.iotdb.cluster.utils.nodetool.function.NodeToolCmd;
 import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.exception.StartupException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IService;
 import org.apache.iotdb.db.service.JMXService;
 import org.apache.iotdb.db.service.ServiceType;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/client/sync/SyncClientAdaptorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/client/sync/SyncClientAdaptorTest.java
index ca8c677..1247c4c 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/client/sync/SyncClientAdaptorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/client/sync/SyncClientAdaptorTest.java
@@ -45,7 +45,7 @@ import org.apache.iotdb.cluster.rpc.thrift.TNodeStatus;
 import org.apache.iotdb.cluster.server.Response;
 import org.apache.iotdb.cluster.utils.StatusUtils;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.sys.FlushPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -245,11 +245,11 @@ public class SyncClientAdaptorTest {
               List<String> path,
               boolean withAlias,
               AsyncMethodCallback<GetAllPathsResult> resultHandler) {
-            List<List<String>> pathString = new ArrayList<>();
-            for (String s : path) {
-              pathString.add(Collections.singletonList(s));
+            List<Byte> dataTypes = new ArrayList<>();
+            for (int i = 0; i < path.size(); i++) {
+              dataTypes.add(TSDataType.DOUBLE.serialize());
             }
-            resultHandler.onComplete(new GetAllPathsResult(pathString));
+            resultHandler.onComplete(new GetAllPathsResult(path, dataTypes));
           }
 
           @Override
@@ -395,10 +395,10 @@ public class SyncClientAdaptorTest {
         paths.subList(0, paths.size() / 2),
         SyncClientAdaptor.getUnregisteredMeasurements(
             dataClient, TestUtils.getRaftNode(0, 0), paths));
-    List<String> result = new ArrayList<>();
-    SyncClientAdaptor.getAllPaths(dataClient, TestUtils.getRaftNode(0, 0), paths, false)
-        .paths
-        .forEach(p -> result.add(p.get(0)));
+    List<String> result =
+        new ArrayList<>(
+            SyncClientAdaptor.getAllPaths(dataClient, TestUtils.getRaftNode(0, 0), paths, false)
+                .paths);
     assertEquals(paths, result);
     assertEquals(
         paths.size(),
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/common/IoTDBTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/common/IoTDBTest.java
index 479b96c..cabf0d9 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/common/IoTDBTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/common/IoTDBTest.java
@@ -28,8 +28,9 @@ import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
@@ -37,13 +38,13 @@ import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
-import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.expression.IExpression;
 import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
 
 import org.junit.After;
 import org.junit.Before;
@@ -100,7 +101,7 @@ public abstract class IoTDBTest {
   protected void prepareData(int sgNum, int timeOffset, int size)
       throws QueryProcessException, IllegalPathException {
     InsertRowPlan insertPlan = new InsertRowPlan();
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(sgNum)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(sgNum)));
     String[] measurements = new String[10];
     for (int i = 0; i < measurements.length; i++) {
       measurements[i] = TestUtils.getTestMeasurement(i);
@@ -163,16 +164,13 @@ public abstract class IoTDBTest {
     queryPlan.setExpression(expression);
     List<PartialPath> paths = new ArrayList<>();
     for (String pathStr : pathStrs) {
-      paths.add(new PartialPath(pathStr));
+      MeasurementPath path = new MeasurementPath(pathStr);
+      path.setMeasurementSchema(
+          new UnaryMeasurementSchema(path.getMeasurement(), TSDataType.DOUBLE));
+      paths.add(path);
     }
     queryPlan.setDeduplicatedPathsAndUpdate(paths);
     queryPlan.setPaths(paths);
-    List<TSDataType> dataTypes = new ArrayList<>();
-    for (PartialPath path : paths) {
-      dataTypes.add(IoTDB.metaManager.getSeriesType(path));
-    }
-    queryPlan.setDeduplicatedDataTypes(dataTypes);
-    queryPlan.setDataTypes(dataTypes);
     queryPlan.setExpression(expression);
 
     return planExecutor.processQuery(queryPlan, context);
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/common/TestLogApplier.java b/cluster/src/test/java/org/apache/iotdb/cluster/common/TestLogApplier.java
index 3b223cc..6ebed66 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/common/TestLogApplier.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/common/TestLogApplier.java
@@ -27,7 +27,7 @@ import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 
 public class TestLogApplier implements LogApplier {
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/common/TestUtils.java b/cluster/src/test/java/org/apache/iotdb/cluster/common/TestUtils.java
index 0b99f2e..25c2f17 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/common/TestUtils.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/common/TestUtils.java
@@ -37,9 +37,9 @@ import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
@@ -307,7 +307,7 @@ public class TestUtils {
     // data for raw data query and aggregation
     // 10 devices (storage groups)
     for (int j = 0; j < 10; j++) {
-      insertPlan.setPrefixPath(new PartialPath(getTestSg(j)));
+      insertPlan.setDeviceId(new PartialPath(getTestSg(j)));
       String[] measurements = new String[10];
       IMeasurementMNode[] mNodes = new IMeasurementMNode[10];
       // 10 series each device, all double
@@ -360,7 +360,7 @@ public class TestUtils {
     }
 
     // data for fill
-    insertPlan.setPrefixPath(new PartialPath(getTestSg(0)));
+    insertPlan.setDeviceId(new PartialPath(getTestSg(0)));
     String[] measurements = new String[] {getTestMeasurement(10)};
     IMeasurementMNode[] schemas = new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(10)};
     insertPlan.setMeasurements(measurements);
@@ -407,8 +407,8 @@ public class TestUtils {
       file.getParentFile().mkdirs();
       try (TsFileWriter writer = new TsFileWriter(file)) {
         for (int k = 0; k < seriesNum; k++) {
-          IMeasurementSchema schema = getTestMeasurementSchema(k);
-          writer.registerTimeseries(new Path(getTestSg(sgNum), schema.getMeasurementId()), schema);
+          UnaryMeasurementSchema schema = (UnaryMeasurementSchema) getTestMeasurementSchema(k);
+          writer.registerTimeseries(new Path(getTestSg(sgNum)), schema);
         }
 
         for (int j = 0; j < ptNum; j++) {
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/LogParserTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/LogParserTest.java
index c7c2656..76f9e30 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/LogParserTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/LogParserTest.java
@@ -28,7 +28,7 @@ import org.apache.iotdb.cluster.log.logtypes.PhysicalPlanLog;
 import org.apache.iotdb.cluster.log.logtypes.RemoveNodeLog;
 import org.apache.iotdb.cluster.utils.PlanSerializer;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.LogPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplierTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplierTest.java
index 22db72d..c1fec06 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplierTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplierTest.java
@@ -25,7 +25,7 @@ import org.apache.iotdb.cluster.log.LogApplier;
 import org.apache.iotdb.cluster.log.logtypes.EmptyContentLog;
 import org.apache.iotdb.cluster.log.logtypes.PhysicalPlanLog;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.service.IoTDB;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/DataLogApplierTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/DataLogApplierTest.java
index e4f3fc2..8cf5feb 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/DataLogApplierTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/DataLogApplierTest.java
@@ -59,8 +59,8 @@ import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupAlreadySetException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
@@ -304,7 +304,7 @@ public class DataLogApplierTest extends IoTDBTest {
     log.setPlan(insertPlan);
 
     // this series is already created
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(1)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(1)));
     insertPlan.setTime(1);
     insertPlan.setMeasurements(new String[] {TestUtils.getTestMeasurement(0)});
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
@@ -322,7 +322,7 @@ public class DataLogApplierTest extends IoTDBTest {
     assertFalse(dataSet.hasNext());
 
     // this series is not created but can be fetched
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(4)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(4)));
     applier.apply(log);
     dataSet = query(Collections.singletonList(TestUtils.getTestSeries(4, 0)), null);
     assertTrue(dataSet.hasNext());
@@ -333,14 +333,14 @@ public class DataLogApplierTest extends IoTDBTest {
     assertFalse(dataSet.hasNext());
 
     // this series does not exists any where
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(5)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(5)));
     applier.apply(log);
     assertEquals(
         "org.apache.iotdb.db.exception.metadata.PathNotExistException: Path [root.test5.s0] does not exist",
         log.getException().getMessage());
 
     // this storage group is not even set
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(16)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(16)));
     applier.apply(log);
     assertEquals(
         "org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException: Storage group is not set for current seriesPath: [root.test16]",
@@ -357,7 +357,7 @@ public class DataLogApplierTest extends IoTDBTest {
 
     for (int i = 1; i <= 4; i++) {
       InsertRowPlan insertPlan = new InsertRowPlan();
-      insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(i)));
+      insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(i)));
       insertPlan.setTime(1);
       insertPlan.setNeedInferType(true);
       insertPlan.setMeasurements(new String[] {TestUtils.getTestMeasurement(0)});
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/MetaLogApplierTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/MetaLogApplierTest.java
index 1115aaf..8d3ffe8 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/MetaLogApplierTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/MetaLogApplierTest.java
@@ -31,7 +31,7 @@ import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.cluster.utils.Constants;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.sys.CreateSnapshotPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/logtypes/SerializeLogTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/logtypes/SerializeLogTest.java
index d5bfde1..1390bba 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/logtypes/SerializeLogTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/logtypes/SerializeLogTest.java
@@ -26,8 +26,8 @@ import org.apache.iotdb.cluster.log.LogParser;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.cluster.utils.Constants;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
@@ -52,7 +52,7 @@ public class SerializeLogTest {
     log.setCurrLogIndex(2);
     log.setCurrLogTerm(2);
     InsertRowPlan plan = new InsertRowPlan();
-    plan.setPrefixPath(new PartialPath("root.d1"));
+    plan.setDeviceId(new PartialPath("root.d1"));
     plan.setMeasurements(new String[] {"s1", "s2", "s3"});
     plan.setNeedInferType(true);
     plan.setDataTypes(new TSDataType[plan.getMeasurements().length]);
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/manage/FilePartitionedSnapshotLogManagerTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/manage/FilePartitionedSnapshotLogManagerTest.java
index 6a85895..bb7883f 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/manage/FilePartitionedSnapshotLogManagerTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/manage/FilePartitionedSnapshotLogManagerTest.java
@@ -32,7 +32,7 @@ import org.apache.iotdb.cluster.partition.PartitionTable;
 import org.apache.iotdb.cluster.partition.slot.SlotPartitionTable;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.exception.StorageEngineException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.sys.FlushPlan;
 import org.apache.iotdb.tsfile.utils.Pair;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/manage/MetaSingleSnapshotLogManagerTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/manage/MetaSingleSnapshotLogManagerTest.java
index 6f3a604..1b33fbd 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/manage/MetaSingleSnapshotLogManagerTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/manage/MetaSingleSnapshotLogManagerTest.java
@@ -31,7 +31,7 @@ import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StartupException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/DataSnapshotTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/DataSnapshotTest.java
index a181792..937a77a 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/DataSnapshotTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/DataSnapshotTest.java
@@ -36,7 +36,7 @@ import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.cluster.utils.IOUtils;
 import org.apache.iotdb.db.exception.StartupException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/FileSnapshotTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/FileSnapshotTest.java
index e08798f..2cd60e2 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/FileSnapshotTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/FileSnapshotTest.java
@@ -32,7 +32,7 @@ import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.LoadFileException;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
 import org.apache.iotdb.tsfile.write.schema.TimeseriesSchema;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/MetaSimpleSnapshotTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/MetaSimpleSnapshotTest.java
index d1f06e8..487a1a6 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/MetaSimpleSnapshotTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/MetaSimpleSnapshotTest.java
@@ -33,7 +33,7 @@ import org.apache.iotdb.db.auth.entity.User;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.UndefinedTemplateException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.template.TemplateManager;
 import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/PartitionedSnapshotTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/PartitionedSnapshotTest.java
index fd30c65..f55b9cd 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/PartitionedSnapshotTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/PartitionedSnapshotTest.java
@@ -27,7 +27,7 @@ import org.apache.iotdb.db.engine.storagegroup.StorageGroupProcessor;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
 import org.apache.iotdb.tsfile.write.schema.TimeseriesSchema;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/PullSnapshotTaskTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/PullSnapshotTaskTest.java
index 37152f0..eee4320 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/PullSnapshotTaskTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/snapshot/PullSnapshotTaskTest.java
@@ -42,7 +42,7 @@ import org.apache.iotdb.db.exception.StartupException;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
 import org.apache.iotdb.tsfile.write.schema.TimeseriesSchema;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/partition/SlotPartitionTableTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/partition/SlotPartitionTableTest.java
index 115b48c..d131e8e 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/partition/SlotPartitionTableTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/partition/SlotPartitionTableTest.java
@@ -34,7 +34,7 @@ import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.MManager;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
 import org.apache.iotdb.db.qp.logical.sys.AuthorOperator.AuthorType;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/BaseQueryTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/BaseQueryTest.java
index fd30399..2ce9652 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/BaseQueryTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/BaseQueryTest.java
@@ -23,7 +23,8 @@ import org.apache.iotdb.cluster.common.TestUtils;
 import org.apache.iotdb.cluster.server.member.BaseMember;
 import org.apache.iotdb.cluster.server.monitor.NodeStatusManager;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.aggregation.AggregateResult;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.common.Field;
@@ -50,7 +51,6 @@ import static org.junit.Assert.assertNull;
 public class BaseQueryTest extends BaseMember {
 
   protected List<PartialPath> pathList;
-  protected List<TSDataType> dataTypes;
   protected int defaultCompactionThread =
       IoTDBDescriptor.getInstance().getConfig().getConcurrentCompactionThread();
 
@@ -76,10 +76,9 @@ public class BaseQueryTest extends BaseMember {
     IoTDBDescriptor.getInstance().getConfig().setConcurrentCompactionThread(0);
     super.setUp();
     pathList = new ArrayList<>();
-    dataTypes = new ArrayList<>();
     for (int i = 0; i < 10; i++) {
-      pathList.add(new PartialPath(TestUtils.getTestSeries(i, 0)));
-      dataTypes.add(TSDataType.DOUBLE);
+      MeasurementPath path = new MeasurementPath(TestUtils.getTestSeries(i, 0), TSDataType.DOUBLE);
+      pathList.add(path);
     }
     NodeStatusManager.getINSTANCE().setMetaGroupMember(testMetaMember);
     TestUtils.prepareData();
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterAggregateExecutorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterAggregateExecutorTest.java
index ffa461e..9063699 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterAggregateExecutorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterAggregateExecutorTest.java
@@ -24,7 +24,8 @@ import org.apache.iotdb.cluster.query.aggregate.ClusterAggregateExecutor;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.physical.crud.AggregationPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -41,6 +42,7 @@ import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
 import org.junit.Test;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -56,20 +58,13 @@ public class ClusterAggregateExecutorTest extends BaseQueryTest {
   public void testNoFilter()
       throws QueryProcessException, StorageEngineException, IOException, IllegalPathException {
     AggregationPlan plan = new AggregationPlan();
-    List<PartialPath> paths =
-        Arrays.asList(
-            new PartialPath(TestUtils.getTestSeries(0, 0)),
-            new PartialPath(TestUtils.getTestSeries(0, 1)),
-            new PartialPath(TestUtils.getTestSeries(0, 2)),
-            new PartialPath(TestUtils.getTestSeries(0, 3)),
-            new PartialPath(TestUtils.getTestSeries(0, 4)));
-    List<TSDataType> dataTypes =
-        Arrays.asList(
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE);
+    List<PartialPath> paths = new ArrayList<>();
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 1), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 2), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 3), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 4), TSDataType.DOUBLE));
+
     List<String> aggregations =
         Arrays.asList(
             SQLConstant.MIN_TIME,
@@ -79,8 +74,6 @@ public class ClusterAggregateExecutorTest extends BaseQueryTest {
             SQLConstant.SUM);
     plan.setPaths(paths);
     plan.setDeduplicatedPathsAndUpdate(paths);
-    plan.setDataTypes(dataTypes);
-    plan.setDeduplicatedDataTypes(dataTypes);
     plan.setAggregations(aggregations);
     plan.setDeduplicatedAggregations(aggregations);
 
@@ -107,20 +100,12 @@ public class ClusterAggregateExecutorTest extends BaseQueryTest {
   public void testFilter()
       throws StorageEngineException, IOException, QueryProcessException, IllegalPathException {
     AggregationPlan plan = new AggregationPlan();
-    List<PartialPath> paths =
-        Arrays.asList(
-            new PartialPath(TestUtils.getTestSeries(0, 0)),
-            new PartialPath(TestUtils.getTestSeries(0, 1)),
-            new PartialPath(TestUtils.getTestSeries(0, 2)),
-            new PartialPath(TestUtils.getTestSeries(0, 3)),
-            new PartialPath(TestUtils.getTestSeries(0, 4)));
-    List<TSDataType> dataTypes =
-        Arrays.asList(
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE);
+    List<PartialPath> paths = new ArrayList<>();
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 1), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 2), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 3), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 4), TSDataType.DOUBLE));
     List<String> aggregations =
         Arrays.asList(
             SQLConstant.MIN_TIME,
@@ -130,8 +115,6 @@ public class ClusterAggregateExecutorTest extends BaseQueryTest {
             SQLConstant.SUM);
     plan.setPaths(paths);
     plan.setDeduplicatedPathsAndUpdate(paths);
-    plan.setDataTypes(dataTypes);
-    plan.setDeduplicatedDataTypes(dataTypes);
     plan.setAggregations(aggregations);
     plan.setDeduplicatedAggregations(aggregations);
     plan.setExpression(
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutorTest.java
index c2d8f0b..e35bb68 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutorTest.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.cluster.common.TestUtils;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
 import org.apache.iotdb.tsfile.read.expression.IExpression;
@@ -63,7 +63,6 @@ public class ClusterDataQueryExecutorTest extends BaseQueryTest {
   public void testNoFilter() throws IOException, StorageEngineException {
     RawDataQueryPlan plan = new RawDataQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(pathList);
-    plan.setDeduplicatedDataTypes(dataTypes);
     queryExecutor = new ClusterDataQueryExecutor(plan, testMetaMember);
     RemoteQueryContext context =
         new RemoteQueryContext(QueryResourceManager.getInstance().assignQueryId(true));
@@ -83,7 +82,6 @@ public class ClusterDataQueryExecutorTest extends BaseQueryTest {
             new PartialPath(TestUtils.getTestSeries(0, 0)), ValueFilter.gtEq(5.0));
     RawDataQueryPlan plan = new RawDataQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(pathList);
-    plan.setDeduplicatedDataTypes(dataTypes);
     plan.setExpression(expression);
     queryExecutor = new ClusterDataQueryExecutor(plan, testMetaMember);
     RemoteQueryContext context =
@@ -100,7 +98,6 @@ public class ClusterDataQueryExecutorTest extends BaseQueryTest {
   public void testNoFilterWithRedirect() throws StorageEngineException {
     RawDataQueryPlan plan = new RawDataQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(pathList);
-    plan.setDeduplicatedDataTypes(dataTypes);
     plan.setEnableRedirect(true);
     queryExecutor = new ClusterDataQueryExecutor(plan, testMetaMember);
     RemoteQueryContext context =
@@ -121,7 +118,6 @@ public class ClusterDataQueryExecutorTest extends BaseQueryTest {
             new PartialPath(TestUtils.getTestSeries(0, 0)), ValueFilter.gtEq(5.0));
     RawDataQueryPlan plan = new RawDataQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(pathList);
-    plan.setDeduplicatedDataTypes(dataTypes);
     plan.setExpression(expression);
     plan.setEnableRedirect(true);
     queryExecutor = new ClusterDataQueryExecutor(plan, testMetaMember);
@@ -142,7 +138,6 @@ public class ClusterDataQueryExecutorTest extends BaseQueryTest {
         new GlobalTimeExpression(new AndFilter(TimeFilter.gtEq(5), TimeFilter.ltEq(10)));
     RawDataQueryPlan plan = new RawDataQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(pathList.subList(0, 1));
-    plan.setDeduplicatedDataTypes(dataTypes.subList(0, 1));
     plan.setExpression(expression);
     plan.setEnableRedirect(true);
     queryExecutor = new ClusterDataQueryExecutor(plan, testMetaMember);
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
index bdbbe00..fcea051 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
@@ -22,7 +22,7 @@ package org.apache.iotdb.cluster.query;
 import org.apache.iotdb.cluster.common.TestUtils;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.logical.crud.FromComponent;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
@@ -68,6 +68,5 @@ public class ClusterPhysicalGeneratorTest extends BaseQueryTest {
     RawDataQueryPlan plan = (RawDataQueryPlan) physicalGenerator.transformToPhysicalPlan(operator);
 
     assertEquals(pathList, plan.getDeduplicatedPaths());
-    assertEquals(dataTypes, plan.getDeduplicatedDataTypes());
   }
 }
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlanExecutorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlanExecutorTest.java
index 7b29dfe..fd2de79 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlanExecutorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlanExecutorTest.java
@@ -22,8 +22,9 @@ package org.apache.iotdb.cluster.query;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -57,9 +58,7 @@ public class ClusterPlanExecutorTest extends BaseQueryTest {
           IOException, MetadataException, InterruptedException {
     RawDataQueryPlan queryPlan = new RawDataQueryPlan();
     queryPlan.setDeduplicatedPathsAndUpdate(pathList);
-    queryPlan.setDeduplicatedDataTypes(dataTypes);
     queryPlan.setPaths(pathList);
-    queryPlan.setDataTypes(dataTypes);
     QueryContext context =
         new RemoteQueryContext(QueryResourceManager.getInstance().assignQueryId(true));
 
@@ -73,7 +72,8 @@ public class ClusterPlanExecutorTest extends BaseQueryTest {
 
   @Test
   public void testMatchPaths() throws MetadataException {
-    List<PartialPath> allMatchedPaths = queryExecutor.getPathsName(new PartialPath("root.*.s0"));
+    List<MeasurementPath> allMatchedPaths =
+        queryExecutor.getPathsName(new PartialPath("root.*.s0"));
     allMatchedPaths.sort(null);
     for (int i = 0; i < allMatchedPaths.size(); i++) {
       assertEquals(pathList.get(i), allMatchedPaths.get(i));
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlannerTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlannerTest.java
index 9fd1acd..1bd4dee 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlannerTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlannerTest.java
@@ -51,6 +51,5 @@ public class ClusterPlannerTest extends BaseQueryTest {
     String sql = String.format("SELECT s0 FROM %s", String.join(",", sgs));
     RawDataQueryPlan plan = (RawDataQueryPlan) parser.parseSQLToPhysicalPlan(sql);
     assertEquals(pathList, plan.getDeduplicatedPaths());
-    assertEquals(dataTypes, plan.getDeduplicatedDataTypes());
   }
 }
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterQueryRouterTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterQueryRouterTest.java
index f9218e0..c6dfaa4 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterQueryRouterTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterQueryRouterTest.java
@@ -24,7 +24,8 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.AggregationPlan;
@@ -76,7 +77,6 @@ public class ClusterQueryRouterTest extends BaseQueryTest {
   public void test() throws StorageEngineException, IOException, QueryProcessException {
     RawDataQueryPlan queryPlan = new RawDataQueryPlan();
     queryPlan.setDeduplicatedPathsAndUpdate(pathList);
-    queryPlan.setDeduplicatedDataTypes(dataTypes);
     QueryContext context =
         new RemoteQueryContext(QueryResourceManager.getInstance().assignQueryId(true));
 
@@ -93,20 +93,12 @@ public class ClusterQueryRouterTest extends BaseQueryTest {
       throws StorageEngineException, IOException, QueryProcessException,
           QueryFilterOptimizationException, IllegalPathException {
     AggregationPlan plan = new AggregationPlan();
-    List<PartialPath> paths =
-        Arrays.asList(
-            new PartialPath(TestUtils.getTestSeries(0, 0)),
-            new PartialPath(TestUtils.getTestSeries(0, 1)),
-            new PartialPath(TestUtils.getTestSeries(0, 2)),
-            new PartialPath(TestUtils.getTestSeries(0, 3)),
-            new PartialPath(TestUtils.getTestSeries(0, 4)));
-    List<TSDataType> dataTypes =
-        Arrays.asList(
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE,
-            TSDataType.DOUBLE);
+    List<PartialPath> paths = new ArrayList<>();
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 1), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 2), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 3), TSDataType.DOUBLE));
+    paths.add(new MeasurementPath(TestUtils.getTestSeries(0, 4), TSDataType.DOUBLE));
     List<String> aggregations =
         Arrays.asList(
             SQLConstant.MIN_TIME,
@@ -116,8 +108,6 @@ public class ClusterQueryRouterTest extends BaseQueryTest {
             SQLConstant.SUM);
     plan.setPaths(paths);
     plan.setDeduplicatedPathsAndUpdate(paths);
-    plan.setDataTypes(dataTypes);
-    plan.setDeduplicatedDataTypes(dataTypes);
     plan.setAggregations(aggregations);
     plan.setDeduplicatedAggregations(aggregations);
 
@@ -137,10 +127,9 @@ public class ClusterQueryRouterTest extends BaseQueryTest {
       throws QueryProcessException, StorageEngineException, IOException, IllegalPathException {
     FillQueryPlan plan = new FillQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(
-        Collections.singletonList(new PartialPath(TestUtils.getTestSeries(0, 10))));
-    plan.setDeduplicatedDataTypes(Collections.singletonList(TSDataType.DOUBLE));
+        Collections.singletonList(
+            new MeasurementPath(TestUtils.getTestSeries(0, 10), TSDataType.DOUBLE)));
     plan.setPaths(plan.getDeduplicatedPaths());
-    plan.setDataTypes(plan.getDeduplicatedDataTypes());
     long defaultFillInterval = IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
     Map<TSDataType, IFill> tsDataTypeIFillMap =
         Collections.singletonMap(
@@ -176,10 +165,9 @@ public class ClusterQueryRouterTest extends BaseQueryTest {
       throws QueryProcessException, StorageEngineException, IOException, IllegalPathException {
     FillQueryPlan plan = new FillQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(
-        Collections.singletonList(new PartialPath(TestUtils.getTestSeries(0, 10))));
-    plan.setDeduplicatedDataTypes(Collections.singletonList(TSDataType.DOUBLE));
+        Collections.singletonList(
+            new MeasurementPath(TestUtils.getTestSeries(0, 10), TSDataType.DOUBLE)));
     plan.setPaths(plan.getDeduplicatedPaths());
-    plan.setDataTypes(plan.getDeduplicatedDataTypes());
     long defaultFillInterval = IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
     Map<TSDataType, IFill> tsDataTypeIFillMap =
         Collections.singletonMap(
@@ -221,17 +209,13 @@ public class ClusterQueryRouterTest extends BaseQueryTest {
     try {
       GroupByTimePlan groupByPlan = new GroupByTimePlan();
       List<PartialPath> pathList = new ArrayList<>();
-      List<TSDataType> dataTypes = new ArrayList<>();
       List<String> aggregations = new ArrayList<>();
       for (int i = 0; i < 10; i++) {
-        pathList.add(new PartialPath(TestUtils.getTestSeries(i, 0)));
-        dataTypes.add(TSDataType.DOUBLE);
+        pathList.add(new MeasurementPath(TestUtils.getTestSeries(i, 0), TSDataType.DOUBLE));
         aggregations.add(SQLConstant.COUNT);
       }
       groupByPlan.setPaths(pathList);
       groupByPlan.setDeduplicatedPathsAndUpdate(pathList);
-      groupByPlan.setDataTypes(dataTypes);
-      groupByPlan.setDeduplicatedDataTypes(dataTypes);
       groupByPlan.setAggregations(aggregations);
       groupByPlan.setDeduplicatedAggregations(aggregations);
 
@@ -243,9 +227,11 @@ public class ClusterQueryRouterTest extends BaseQueryTest {
       IExpression expression =
           BinaryExpression.and(
               new SingleSeriesExpression(
-                  new PartialPath(TestUtils.getTestSeries(0, 0)), ValueFilter.gtEq(5.0)),
+                  new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE),
+                  ValueFilter.gtEq(5.0)),
               new SingleSeriesExpression(
-                  new PartialPath(TestUtils.getTestSeries(5, 0)), TimeFilter.ltEq(15)));
+                  new MeasurementPath(TestUtils.getTestSeries(5, 0), TSDataType.DOUBLE),
+                  TimeFilter.ltEq(15)));
       groupByPlan.setExpression(expression);
       QueryDataSet queryDataSet = clusterQueryRouter.groupBy(groupByPlan, queryContext);
 
@@ -274,17 +260,13 @@ public class ClusterQueryRouterTest extends BaseQueryTest {
     try {
       GroupByTimePlan groupByPlan = new GroupByTimePlan();
       List<PartialPath> pathList = new ArrayList<>();
-      List<TSDataType> dataTypes = new ArrayList<>();
       List<String> aggregations = new ArrayList<>();
       for (int i = 0; i < 10; i++) {
-        pathList.add(new PartialPath(TestUtils.getTestSeries(i, 0)));
-        dataTypes.add(TSDataType.DOUBLE);
+        pathList.add(new MeasurementPath(TestUtils.getTestSeries(i, 0), TSDataType.DOUBLE));
         aggregations.add(SQLConstant.COUNT);
       }
       groupByPlan.setPaths(pathList);
       groupByPlan.setDeduplicatedPathsAndUpdate(pathList);
-      groupByPlan.setDataTypes(dataTypes);
-      groupByPlan.setDeduplicatedDataTypes(dataTypes);
       groupByPlan.setAggregations(aggregations);
       groupByPlan.setDeduplicatedAggregations(aggregations);
 
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/fill/ClusterFillExecutorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/fill/ClusterFillExecutorTest.java
index 430c456..93ae2fa 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/fill/ClusterFillExecutorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/fill/ClusterFillExecutorTest.java
@@ -26,7 +26,7 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.qp.physical.crud.FillQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
@@ -52,10 +52,9 @@ public class ClusterFillExecutorTest extends BaseQueryTest {
       throws QueryProcessException, StorageEngineException, IOException, IllegalPathException {
     FillQueryPlan plan = new FillQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(
-        Collections.singletonList(new PartialPath(TestUtils.getTestSeries(0, 10))));
-    plan.setDeduplicatedDataTypes(Collections.singletonList(TSDataType.DOUBLE));
+        Collections.singletonList(
+            new MeasurementPath(TestUtils.getTestSeries(0, 10), TSDataType.DOUBLE)));
     plan.setPaths(plan.getDeduplicatedPaths());
-    plan.setDataTypes(plan.getDeduplicatedDataTypes());
     long defaultFillInterval = IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
     Map<TSDataType, IFill> tsDataTypeIFillMap =
         Collections.singletonMap(
@@ -93,10 +92,9 @@ public class ClusterFillExecutorTest extends BaseQueryTest {
       throws QueryProcessException, StorageEngineException, IOException, IllegalPathException {
     FillQueryPlan plan = new FillQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(
-        Collections.singletonList(new PartialPath(TestUtils.getTestSeries(0, 10))));
-    plan.setDeduplicatedDataTypes(Collections.singletonList(TSDataType.DOUBLE));
+        Collections.singletonList(
+            new MeasurementPath(TestUtils.getTestSeries(0, 10), TSDataType.DOUBLE)));
     plan.setPaths(plan.getDeduplicatedPaths());
-    plan.setDataTypes(plan.getDeduplicatedDataTypes());
     long defaultFillInterval = IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
     Map<TSDataType, IFill> tsDataTypeIFillMap =
         Collections.singletonMap(
@@ -135,10 +133,9 @@ public class ClusterFillExecutorTest extends BaseQueryTest {
       throws QueryProcessException, StorageEngineException, IOException, IllegalPathException {
     FillQueryPlan plan = new FillQueryPlan();
     plan.setDeduplicatedPathsAndUpdate(
-        Collections.singletonList(new PartialPath(TestUtils.getTestSeries(0, 10))));
-    plan.setDeduplicatedDataTypes(Collections.singletonList(TSDataType.DOUBLE));
+        Collections.singletonList(
+            new MeasurementPath(TestUtils.getTestSeries(0, 10), TSDataType.DOUBLE)));
     plan.setPaths(plan.getDeduplicatedPaths());
-    plan.setDataTypes(plan.getDeduplicatedDataTypes());
     double fillValue = 1.0D;
     Map<TSDataType, IFill> tsDataTypeIFillMap =
         Collections.singletonMap(
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByNoVFilterDataSetTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByNoVFilterDataSetTest.java
index 3fc21de..fa89e9e 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByNoVFilterDataSetTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByNoVFilterDataSetTest.java
@@ -25,7 +25,8 @@ import org.apache.iotdb.cluster.query.RemoteQueryContext;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -52,17 +53,13 @@ public class ClusterGroupByNoVFilterDataSetTest extends BaseQueryTest {
     try {
       GroupByTimePlan groupByPlan = new GroupByTimePlan();
       List<PartialPath> pathList = new ArrayList<>();
-      List<TSDataType> dataTypes = new ArrayList<>();
       List<String> aggregations = new ArrayList<>();
       for (int i = 0; i < 10; i++) {
-        pathList.add(new PartialPath(TestUtils.getTestSeries(i, 0)));
-        dataTypes.add(TSDataType.DOUBLE);
+        pathList.add(new MeasurementPath(TestUtils.getTestSeries(i, 0), TSDataType.DOUBLE));
         aggregations.add(SQLConstant.COUNT);
       }
       groupByPlan.setPaths(pathList);
       groupByPlan.setDeduplicatedPathsAndUpdate(pathList);
-      groupByPlan.setDataTypes(dataTypes);
-      groupByPlan.setDeduplicatedDataTypes(dataTypes);
       groupByPlan.setAggregations(aggregations);
       groupByPlan.setDeduplicatedAggregations(aggregations);
 
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByVFilterDataSetTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByVFilterDataSetTest.java
index e4b471a..66938e0 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByVFilterDataSetTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/ClusterGroupByVFilterDataSetTest.java
@@ -25,7 +25,8 @@ import org.apache.iotdb.cluster.query.RemoteQueryContext;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -55,17 +56,13 @@ public class ClusterGroupByVFilterDataSetTest extends BaseQueryTest {
     try {
       GroupByTimePlan groupByPlan = new GroupByTimePlan();
       List<PartialPath> pathList = new ArrayList<>();
-      List<TSDataType> dataTypes = new ArrayList<>();
       List<String> aggregations = new ArrayList<>();
       for (int i = 0; i < 10; i++) {
-        pathList.add(new PartialPath(TestUtils.getTestSeries(i, 0)));
-        dataTypes.add(TSDataType.DOUBLE);
+        pathList.add(new MeasurementPath(TestUtils.getTestSeries(i, 0), TSDataType.DOUBLE));
         aggregations.add(SQLConstant.COUNT);
       }
       groupByPlan.setPaths(pathList);
       groupByPlan.setDeduplicatedPathsAndUpdate(pathList);
-      groupByPlan.setDataTypes(dataTypes);
-      groupByPlan.setDeduplicatedDataTypes(dataTypes);
       groupByPlan.setAggregations(aggregations);
       groupByPlan.setDeduplicatedAggregations(aggregations);
 
@@ -77,9 +74,11 @@ public class ClusterGroupByVFilterDataSetTest extends BaseQueryTest {
       IExpression expression =
           BinaryExpression.and(
               new SingleSeriesExpression(
-                  new PartialPath(TestUtils.getTestSeries(0, 0)), ValueFilter.gtEq(5.0)),
+                  new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE),
+                  ValueFilter.gtEq(5.0)),
               new SingleSeriesExpression(
-                  new PartialPath(TestUtils.getTestSeries(5, 0)), TimeFilter.ltEq(15)));
+                  new MeasurementPath(TestUtils.getTestSeries(5, 0), TSDataType.DOUBLE),
+                  TimeFilter.ltEq(15)));
       groupByPlan.setExpression(expression);
 
       ClusterGroupByVFilterDataSet dataSet =
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/MergeGroupByExecutorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/MergeGroupByExecutorTest.java
index 136e392..5f13b6b 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/MergeGroupByExecutorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/MergeGroupByExecutorTest.java
@@ -25,7 +25,8 @@ import org.apache.iotdb.cluster.query.RemoteQueryContext;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.aggregation.AggregateResult;
 import org.apache.iotdb.db.query.aggregation.AggregationType;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -47,7 +48,7 @@ public class MergeGroupByExecutorTest extends BaseQueryTest {
   @Test
   public void testNoTimeFilter()
       throws QueryProcessException, IOException, IllegalPathException, StorageEngineException {
-    PartialPath path = new PartialPath(TestUtils.getTestSeries(0, 0));
+    PartialPath path = new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE);
     TSDataType dataType = TSDataType.DOUBLE;
     QueryContext context =
         new RemoteQueryContext(QueryResourceManager.getInstance().assignQueryId(true));
@@ -82,7 +83,7 @@ public class MergeGroupByExecutorTest extends BaseQueryTest {
   @Test
   public void testTimeFilter()
       throws QueryProcessException, IOException, IllegalPathException, StorageEngineException {
-    PartialPath path = new PartialPath(TestUtils.getTestSeries(0, 0));
+    PartialPath path = new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE);
     TSDataType dataType = TSDataType.DOUBLE;
     QueryContext context =
         new RemoteQueryContext(QueryResourceManager.getInstance().assignQueryId(true));
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/RemoteGroupByExecutorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/RemoteGroupByExecutorTest.java
index 6df7ee7..2ce2e5e 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/RemoteGroupByExecutorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/groupby/RemoteGroupByExecutorTest.java
@@ -27,7 +27,8 @@ import org.apache.iotdb.cluster.query.reader.EmptyReader;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.aggregation.AggregateResult;
 import org.apache.iotdb.db.query.aggregation.AggregationType;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -52,7 +53,7 @@ public class RemoteGroupByExecutorTest extends BaseQueryTest {
   @Test
   public void testNoTimeFilter()
       throws QueryProcessException, IOException, StorageEngineException, IllegalPathException {
-    PartialPath path = new PartialPath(TestUtils.getTestSeries(0, 0));
+    PartialPath path = new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE);
     TSDataType dataType = TSDataType.DOUBLE;
     QueryContext context =
         new RemoteQueryContext(QueryResourceManager.getInstance().assignQueryId(true));
@@ -110,7 +111,7 @@ public class RemoteGroupByExecutorTest extends BaseQueryTest {
   @Test
   public void testTimeFilter()
       throws QueryProcessException, IOException, StorageEngineException, IllegalPathException {
-    PartialPath path = new PartialPath(TestUtils.getTestSeries(0, 0));
+    PartialPath path = new MeasurementPath(TestUtils.getTestSeries(0, 0), TSDataType.DOUBLE);
     TSDataType dataType = TSDataType.DOUBLE;
     QueryContext context =
         new RemoteQueryContext(QueryResourceManager.getInstance().assignQueryId(true));
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactoryTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactoryTest.java
index 33743ee..85147bb 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactoryTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactoryTest.java
@@ -26,13 +26,14 @@ import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
 import org.apache.iotdb.db.query.reader.series.SeriesRawDataBatchReader;
 
 import org.junit.Test;
 
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashSet;
 
 import static org.junit.Assert.assertNotNull;
@@ -53,8 +54,8 @@ public class ClusterReaderFactoryTest extends BaseQueryTest {
           (SeriesRawDataBatchReader)
               readerFactory.getSeriesBatchReader(
                   pathList.get(0),
-                  new HashSet<>(),
-                  dataTypes.get(0),
+                  new HashSet<>(Collections.singletonList(pathList.get(0).getMeasurement())),
+                  pathList.get(0).getSeriesType(),
                   null,
                   null,
                   context,
@@ -67,8 +68,8 @@ public class ClusterReaderFactoryTest extends BaseQueryTest {
           (SeriesRawDataBatchReader)
               readerFactory.getSeriesBatchReader(
                   pathList.get(0),
-                  new HashSet<>(),
-                  dataTypes.get(0),
+                  new HashSet<>(Collections.singletonList(pathList.get(0).getMeasurement())),
+                  pathList.get(0).getSeriesType(),
                   null,
                   null,
                   context,
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/ClusterTimeGeneratorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/ClusterTimeGeneratorTest.java
index fbbee45..3946631 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/ClusterTimeGeneratorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/ClusterTimeGeneratorTest.java
@@ -26,7 +26,8 @@ import org.apache.iotdb.cluster.query.RemoteQueryContext;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
@@ -66,8 +67,8 @@ public class ClusterTimeGeneratorTest extends BaseQueryTest {
               new SingleSeriesExpression(
                   new PartialPath(TestUtils.getTestSeries(1, 1)), ValueFilter.ltEq(8.0)));
       dataQueryPlan.setExpression(expression);
-      dataQueryPlan.addDeduplicatedPaths(new PartialPath(TestUtils.getTestSeries(0, 0)));
-      dataQueryPlan.addDeduplicatedPaths(new PartialPath(TestUtils.getTestSeries(1, 1)));
+      dataQueryPlan.addDeduplicatedPaths(new MeasurementPath(TestUtils.getTestSeries(0, 0)));
+      dataQueryPlan.addDeduplicatedPaths(new MeasurementPath(TestUtils.getTestSeries(1, 1)));
 
       ClusterTimeGenerator timeGenerator =
           new ClusterTimeGenerator(context, testMetaMember, dataQueryPlan, false);
@@ -95,7 +96,7 @@ public class ClusterTimeGeneratorTest extends BaseQueryTest {
               new PartialPath(TestUtils.getTestSeries(0, 0)),
               new AndFilter(valueFilter, timeFilter));
       dataQueryPlan.setExpression(expression);
-      dataQueryPlan.addDeduplicatedPaths(new PartialPath(TestUtils.getTestSeries(0, 0)));
+      dataQueryPlan.addDeduplicatedPaths(new MeasurementPath(TestUtils.getTestSeries(0, 0)));
 
       // capture the time filter used to create a reader
       AtomicReference<Filter> timeFilterRef = new AtomicReference<>(null);
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/mult/AssignPathManagedMergeReaderTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/mult/AssignPathManagedMergeReaderTest.java
index 7bd4ff5..3c96bdf 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/mult/AssignPathManagedMergeReaderTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/mult/AssignPathManagedMergeReaderTest.java
@@ -34,7 +34,7 @@ import org.apache.iotdb.cluster.rpc.thrift.RaftService;
 import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
 import org.apache.iotdb.db.utils.SerializeUtils;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReaderTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReaderTest.java
index 4b42fce..8ea7439 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReaderTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReaderTest.java
@@ -37,7 +37,7 @@ import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.cluster.utils.ClientUtils;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
 import org.apache.iotdb.db.utils.SerializeUtils;
 import org.apache.iotdb.rpc.RpcTransportFactory;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/server/clusterinfo/ClusterInfoServiceImplTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/server/clusterinfo/ClusterInfoServiceImplTest.java
index e234c3e..be2ef05 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/server/clusterinfo/ClusterInfoServiceImplTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/server/clusterinfo/ClusterInfoServiceImplTest.java
@@ -26,7 +26,7 @@ import org.apache.iotdb.cluster.server.member.MetaGroupMember;
 import org.apache.iotdb.cluster.server.member.MetaGroupMemberTest;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 
 import org.apache.thrift.TException;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/server/handlers/forwarder/ForwardPlanHandlerTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/server/handlers/forwarder/ForwardPlanHandlerTest.java
index d13d29c..bdb08dd 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/server/handlers/forwarder/ForwardPlanHandlerTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/server/handlers/forwarder/ForwardPlanHandlerTest.java
@@ -22,7 +22,7 @@ package org.apache.iotdb.cluster.server.handlers.forwarder;
 import org.apache.iotdb.cluster.common.TestException;
 import org.apache.iotdb.cluster.common.TestUtils;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
 import org.apache.iotdb.service.rpc.thrift.TSStatus;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/BaseMember.java b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/BaseMember.java
index dc8c8e9..88ad9cd 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/BaseMember.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/BaseMember.java
@@ -53,7 +53,7 @@ import org.apache.iotdb.cluster.server.Response;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.service.RegisterManager;
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/DataGroupMemberTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/DataGroupMemberTest.java
index a4cd06a..aa15f79 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/DataGroupMemberTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/DataGroupMemberTest.java
@@ -71,8 +71,8 @@ import org.apache.iotdb.db.exception.WriteProcessException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
@@ -509,7 +509,7 @@ public class DataGroupMemberTest extends BaseMember {
     }
 
     InsertRowPlan insertPlan = new InsertRowPlan();
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(0)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(0)));
     insertPlan.setTime(0);
     insertPlan.setMeasurements(new String[] {"s0"});
     insertPlan.setNeedInferType(true);
@@ -716,7 +716,7 @@ public class DataGroupMemberTest extends BaseMember {
           IllegalPathException {
     System.out.println("Start testQuerySingleSeries()");
     InsertRowPlan insertPlan = new InsertRowPlan();
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(0)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(0)));
     insertPlan.setNeedInferType(true);
     insertPlan.setMeasurements(new String[] {getTestMeasurement(0)});
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
@@ -735,7 +735,7 @@ public class DataGroupMemberTest extends BaseMember {
         partitionTable.getHeaderGroup(new RaftNode(TestUtils.getNode(10), raftId)));
     dataGroupMember.setCharacter(NodeCharacter.LEADER);
     SingleSeriesQueryRequest request = new SingleSeriesQueryRequest();
-    request.setPath(Collections.singletonList(TestUtils.getTestSeries(0, 0)));
+    request.setPath(TestUtils.getTestSeries(0, 0));
     request.setDataTypeOrdinal(TSDataType.DOUBLE.ordinal());
     request.setRequester(TestUtils.getNode(1));
     request.setQueryId(0);
@@ -784,7 +784,7 @@ public class DataGroupMemberTest extends BaseMember {
           IllegalPathException {
     System.out.println("Start testQuerySingleSeriesWithValueFilter()");
     InsertRowPlan insertPlan = new InsertRowPlan();
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(0)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(0)));
     insertPlan.setNeedInferType(true);
     insertPlan.setMeasurements(new String[] {getTestMeasurement(0)});
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
@@ -803,7 +803,7 @@ public class DataGroupMemberTest extends BaseMember {
         partitionTable.getHeaderGroup(new RaftNode(TestUtils.getNode(10), raftId)));
     dataGroupMember.setCharacter(NodeCharacter.LEADER);
     SingleSeriesQueryRequest request = new SingleSeriesQueryRequest();
-    request.setPath(Collections.singletonList(TestUtils.getTestSeries(0, 0)));
+    request.setPath(TestUtils.getTestSeries(0, 0));
     request.setDataTypeOrdinal(TSDataType.DOUBLE.ordinal());
     request.setRequester(TestUtils.getNode(1));
     request.setQueryId(0);
@@ -852,7 +852,7 @@ public class DataGroupMemberTest extends BaseMember {
           IllegalPathException {
     System.out.println("Start testQuerySingleSeriesByTimestamp()");
     InsertRowPlan insertPlan = new InsertRowPlan();
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(0)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(0)));
     insertPlan.setNeedInferType(true);
     insertPlan.setMeasurements(new String[] {getTestMeasurement(0)});
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
@@ -871,7 +871,7 @@ public class DataGroupMemberTest extends BaseMember {
         partitionTable.getHeaderGroup(new RaftNode(TestUtils.getNode(10), 0)));
     dataGroupMember.setCharacter(NodeCharacter.LEADER);
     SingleSeriesQueryRequest request = new SingleSeriesQueryRequest();
-    request.setPath(Collections.singletonList(TestUtils.getTestSeries(0, 0)));
+    request.setPath(TestUtils.getTestSeries(0, 0));
     request.setDataTypeOrdinal(TSDataType.DOUBLE.ordinal());
     request.setRequester(TestUtils.getNode(1));
     request.setQueryId(0);
@@ -920,7 +920,7 @@ public class DataGroupMemberTest extends BaseMember {
           IllegalPathException {
     System.out.println("Start testQuerySingleSeriesByTimestampWithValueFilter()");
     InsertRowPlan insertPlan = new InsertRowPlan();
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(0)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(0)));
     insertPlan.setNeedInferType(true);
     insertPlan.setMeasurements(new String[] {getTestMeasurement(0)});
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
@@ -939,7 +939,7 @@ public class DataGroupMemberTest extends BaseMember {
         partitionTable.getHeaderGroup(new RaftNode(TestUtils.getNode(10), 0)));
     dataGroupMember.setCharacter(NodeCharacter.LEADER);
     SingleSeriesQueryRequest request = new SingleSeriesQueryRequest();
-    request.setPath(Collections.singletonList(TestUtils.getTestSeries(0, 0)));
+    request.setPath(TestUtils.getTestSeries(0, 0));
     request.setDataTypeOrdinal(TSDataType.DOUBLE.ordinal());
     request.setRequester(TestUtils.getNode(10));
     request.setQueryId(0);
@@ -991,8 +991,7 @@ public class DataGroupMemberTest extends BaseMember {
     new DataAsyncService(dataGroupMember)
         .getAllPaths(
             TestUtils.getRaftNode(0, raftId), Collections.singletonList(path), false, handler);
-    List<String> result = new ArrayList<>();
-    pathResult.get().paths.forEach(p -> result.add(p.get(0)));
+    List<String> result = new ArrayList<>(pathResult.get().paths);
     assertEquals(20, result.size());
     for (int i = 0; i < 10; i++) {
       assertTrue(result.contains(TestUtils.getTestSeries(0, i)));
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/MetaGroupMemberTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/MetaGroupMemberTest.java
index 184d65d..172b200 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/MetaGroupMemberTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/MetaGroupMemberTest.java
@@ -90,8 +90,9 @@ import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.template.TemplateManager;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
@@ -596,7 +597,7 @@ public class MetaGroupMemberTest extends BaseMember {
     // the operation is accepted
     dummyResponse.set(Response.RESPONSE_AGREE);
     InsertRowPlan insertPlan = new InsertRowPlan();
-    insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(0)));
+    insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(0)));
     insertPlan.setNeedInferType(true);
     insertPlan.setMeasurements(new String[] {TestUtils.getTestMeasurement(0)});
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
@@ -950,7 +951,7 @@ public class MetaGroupMemberTest extends BaseMember {
     insertPlan.setMeasurements(new String[] {TestUtils.getTestMeasurement(0)});
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
     for (int i = 0; i < 10; i++) {
-      insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(i)));
+      insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(i)));
       IMeasurementSchema schema = TestUtils.getTestMeasurementSchema(0);
       try {
         IoTDB.metaManager.createTimeseries(
@@ -986,7 +987,7 @@ public class MetaGroupMemberTest extends BaseMember {
       for (int i = 0; i < 10; i++) {
         IReaderByTimestamp readerByTimestamp =
             readerFactory.getReaderByTimestamp(
-                new PartialPath(TestUtils.getTestSeries(i, 0)),
+                new MeasurementPath(TestUtils.getTestSeries(i, 0), TSDataType.DOUBLE),
                 deviceMeasurements,
                 TSDataType.DOUBLE,
                 context,
@@ -1016,7 +1017,7 @@ public class MetaGroupMemberTest extends BaseMember {
     ClusterConstant.setReadOperationTimeoutMS(1000);
 
     for (int i = 0; i < 10; i++) {
-      insertPlan.setPrefixPath(new PartialPath(TestUtils.getTestSg(i)));
+      insertPlan.setDeviceId(new PartialPath(TestUtils.getTestSg(i)));
       IMeasurementSchema schema = TestUtils.getTestMeasurementSchema(0);
       try {
         IoTDB.metaManager.createTimeseries(
@@ -1048,7 +1049,7 @@ public class MetaGroupMemberTest extends BaseMember {
       for (int i = 0; i < 10; i++) {
         ManagedSeriesReader reader =
             readerFactory.getSeriesReader(
-                new PartialPath(TestUtils.getTestSeries(i, 0)),
+                new MeasurementPath(TestUtils.getTestSeries(i, 0), TSDataType.DOUBLE),
                 deviceMeasurements,
                 TSDataType.DOUBLE,
                 TimeFilter.gtEq(5),
@@ -1074,7 +1075,7 @@ public class MetaGroupMemberTest extends BaseMember {
   @Test
   public void testGetMatchedPaths() throws MetadataException {
     System.out.println("Start testGetMatchedPaths()");
-    List<PartialPath> matchedPaths =
+    List<MeasurementPath> matchedPaths =
         ((CMManager) IoTDB.metaManager)
             .getMatchedPaths(new PartialPath(TestUtils.getTestSg(0) + ".*"));
     assertEquals(20, matchedPaths.size());
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/utils/SerializeUtilTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/utils/SerializeUtilTest.java
index 98b58d5..9c758bf 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/utils/SerializeUtilTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/utils/SerializeUtilTest.java
@@ -27,7 +27,7 @@ import org.apache.iotdb.cluster.log.logtypes.PhysicalPlanLog;
 import org.apache.iotdb.cluster.partition.slot.SlotPartitionTable;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateMultiTimeSeriesPlan;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
diff --git a/docs/UserGuide/Advanced-Features/Triggers.md b/docs/UserGuide/Advanced-Features/Triggers.md
index 0dcd98a..42af7ad 100644
--- a/docs/UserGuide/Advanced-Features/Triggers.md
+++ b/docs/UserGuide/Advanced-Features/Triggers.md
@@ -698,7 +698,7 @@ package org.apache.iotdb.trigger;
 
 import org.apache.iotdb.db.engine.trigger.api.Trigger;
 import org.apache.iotdb.db.engine.trigger.api.TriggerAttributes;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTConfiguration;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTEvent;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTHandler;
diff --git a/docs/zh/UserGuide/Advanced-Features/Triggers.md b/docs/zh/UserGuide/Advanced-Features/Triggers.md
index f3df705..b4074dd 100644
--- a/docs/zh/UserGuide/Advanced-Features/Triggers.md
+++ b/docs/zh/UserGuide/Advanced-Features/Triggers.md
@@ -632,7 +632,7 @@ package org.apache.iotdb.trigger;
 
 import org.apache.iotdb.db.engine.trigger.api.Trigger;
 import org.apache.iotdb.db.engine.trigger.api.TriggerAttributes;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTConfiguration;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTEvent;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTHandler;
diff --git a/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TSMRWriteExample.java b/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TSMRWriteExample.java
index 2339b04..d67c604 100644
--- a/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TSMRWriteExample.java
+++ b/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TSMRWriteExample.java
@@ -59,16 +59,14 @@ public class TSMRWriteExample {
     // add measurements into file schema (all with INT64 data type)
     for (int i = 0; i < 2; i++) {
       schema.registerTimeseries(
-          new org.apache.iotdb.tsfile.read.common.Path(
-              Constant.DEVICE_1, Constant.SENSOR_PREFIX + (i + 1)),
+          new org.apache.iotdb.tsfile.read.common.Path(Constant.DEVICE_1),
           new UnaryMeasurementSchema(
               Constant.SENSOR_PREFIX + (i + 1), TSDataType.INT64, TSEncoding.TS_2DIFF));
     }
 
     for (int i = 2; i < sensorNum; i++) {
       schema.registerTimeseries(
-          new org.apache.iotdb.tsfile.read.common.Path(
-              Constant.DEVICE_1, Constant.SENSOR_PREFIX + (i + 1)),
+          new org.apache.iotdb.tsfile.read.common.Path(Constant.DEVICE_1),
           new UnaryMeasurementSchema(
               Constant.SENSOR_PREFIX + (i + 1), TSDataType.DOUBLE, TSEncoding.TS_2DIFF));
     }
diff --git a/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TsFileHelper.java b/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TsFileHelper.java
index 832aa3b..95f5aaa 100644
--- a/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TsFileHelper.java
+++ b/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TsFileHelper.java
@@ -68,17 +68,15 @@ public class TsFileHelper {
         UnaryMeasurementSchema measurementSchema =
             new UnaryMeasurementSchema(
                 Constant.SENSOR_PREFIX + (i + 1), TSDataType.INT64, TSEncoding.TS_2DIFF);
-        schema.registerTimeseries(
-            new Path(Constant.DEVICE_1, Constant.SENSOR_PREFIX + (i + 1)), measurementSchema);
+        schema.registerTimeseries(new Path(Constant.DEVICE_1), measurementSchema);
         schemaList.add(measurementSchema);
       }
 
       for (int i = 2; i < sensorNum; i++) {
-        IMeasurementSchema measurementSchema =
+        UnaryMeasurementSchema measurementSchema =
             new UnaryMeasurementSchema(
                 Constant.SENSOR_PREFIX + (i + 1), TSDataType.DOUBLE, TSEncoding.TS_2DIFF);
-        schema.registerTimeseries(
-            new Path(Constant.DEVICE_1, Constant.SENSOR_PREFIX + (i + 1)), measurementSchema);
+        schema.registerTimeseries(new Path(Constant.DEVICE_1), measurementSchema);
         schemaList.add(measurementSchema);
       }
 
diff --git a/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TsFileWriteToHDFS.java b/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TsFileWriteToHDFS.java
index 19da583..140bbca 100644
--- a/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TsFileWriteToHDFS.java
+++ b/example/hadoop/src/main/java/org/apache/iotdb/hadoop/tsfile/TsFileWriteToHDFS.java
@@ -49,13 +49,13 @@ public class TsFileWriteToHDFS {
     File f = FSFactoryProducer.getFSFactory().getFile(path);
     try (TsFileWriter tsFileWriter = new TsFileWriter(f)) {
       tsFileWriter.registerTimeseries(
-          new Path(Constant.DEVICE_1, Constant.SENSOR_1),
+          new Path(Constant.DEVICE_1),
           new UnaryMeasurementSchema(Constant.SENSOR_1, TSDataType.INT64, TSEncoding.RLE));
       tsFileWriter.registerTimeseries(
-          new Path(Constant.DEVICE_1, Constant.SENSOR_2),
+          new Path(Constant.DEVICE_1),
           new UnaryMeasurementSchema(Constant.SENSOR_2, TSDataType.INT64, TSEncoding.RLE));
       tsFileWriter.registerTimeseries(
-          new Path(Constant.DEVICE_1, Constant.SENSOR_3),
+          new Path(Constant.DEVICE_1),
           new UnaryMeasurementSchema(Constant.SENSOR_3, TSDataType.INT64, TSEncoding.RLE));
 
       // construct TSRecord
diff --git a/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java b/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
index 7d20f8d..2c6d035 100644
--- a/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
+++ b/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
@@ -29,7 +29,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.utils.BitMap;
 import org.apache.iotdb.tsfile.write.record.Tablet;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
 
 import java.security.SecureRandom;
 import java.util.ArrayList;
@@ -42,7 +42,7 @@ import java.util.Map;
 public class AlignedTimeseriesSessionExample {
 
   private static Session session;
-  private static final String ROOT_SG1_D1_VECTOR1 = "root.sg_1.d1.vector";
+  private static final String ROOT_SG1_D1 = "root.sg_1.d1";
   private static final String ROOT_SG1_D1_VECTOR2 = "root.sg_1.d1.vector2";
   private static final String ROOT_SG1_D1_VECTOR3 = "root.sg_1.d1.vector3";
   private static final String ROOT_SG2_D1_VECTOR4 = "root.sg_2.d1.vector4";
@@ -59,42 +59,65 @@ public class AlignedTimeseriesSessionExample {
     // set session fetchSize
     session.setFetchSize(10000);
 
-    createTemplate();
+    //    createTemplate();
     createAlignedTimeseries();
 
     insertAlignedRecord();
-    insertAlignedRecords();
-    insertAlignedRecordsOfOneDevices();
+    //    insertAlignedRecords();
+    //    insertAlignedRecordsOfOneDevices();
 
-    insertAlignedStringRecord();
-    insertAlignedStringRecords();
+    //    insertAlignedStringRecord();
+    //    insertAlignedStringRecords();
 
-    insertTabletWithAlignedTimeseriesMethod1();
-    insertTabletWithAlignedTimeseriesMethod2();
-    insertNullableTabletWithAlignedTimeseries();
-    insertTabletsWithAlignedTimeseries();
+    //    insertTabletWithAlignedTimeseriesMethod1();
+    //    insertTabletWithAlignedTimeseriesMethod2();
+    //    insertNullableTabletWithAlignedTimeseries();
+    //    insertTabletsWithAlignedTimeseries();
+    session.executeNonQueryStatement("flush");
+    selectTest();
+    selectWithValueFilterTest();
+    selectWithLastTest();
+    selectWithLastTestWithoutValueFilter();
+    session.executeNonQueryStatement("delete from root.sg_1.d1.s1 where time <= 5");
+    System.out.println("execute sql delete from root.sg_1.d1.s1 where time <= 5");
+    selectTest();
+    selectWithValueFilterTest();
+    selectWithLastTest();
+    selectWithLastTestWithoutValueFilter();
+    session.executeNonQueryStatement("delete from root.sg_1.d1.s2 where time <= 3");
+    System.out.println("execute sql delete from root.sg_1.d1.s2 where time <= 3");
 
     selectTest();
     selectWithValueFilterTest();
-    selectWithGroupByTest();
     selectWithLastTest();
+    selectWithLastTestWithoutValueFilter();
+    session.executeNonQueryStatement("delete from root.sg_1.d1.s1 where time <= 10");
+    System.out.println("execute sql delete from root.sg_1.d1.s1 where time <= 10");
+    selectTest();
+    selectWithValueFilterTest();
+    selectWithLastTest();
+    selectWithLastTestWithoutValueFilter();
+
+    //    selectWithValueFilterTest();
+    //    selectWithGroupByTest();
+    //    selectWithLastTest();
 
-    selectWithAggregationTest();
+    //    selectWithAggregationTest();
 
-    selectWithAlignByDeviceTest();
+    //    selectWithAlignByDeviceTest();
 
     session.close();
   }
 
   private static void selectTest() throws StatementExecutionException, IoTDBConnectionException {
-    SessionDataSet dataSet = session.executeQueryStatement("select s1 from root.sg_1.d1.vector");
+    SessionDataSet dataSet = session.executeQueryStatement("select s1 from root.sg_1.d1");
     System.out.println(dataSet.getColumnNames());
     while (dataSet.hasNext()) {
       System.out.println(dataSet.next());
     }
 
     dataSet.closeOperationHandle();
-    dataSet = session.executeQueryStatement("select * from root.sg_1.d1.vector");
+    dataSet = session.executeQueryStatement("select * from root.sg_1.d1");
     System.out.println(dataSet.getColumnNames());
     while (dataSet.hasNext()) {
       System.out.println(dataSet.next());
@@ -118,7 +141,8 @@ public class AlignedTimeseriesSessionExample {
   private static void selectWithValueFilterTest()
       throws StatementExecutionException, IoTDBConnectionException {
     SessionDataSet dataSet =
-        session.executeQueryStatement("select s1 from root.sg_1.d1.vector where s1 > 0");
+        session.executeQueryStatement("select s1 from root.sg_1.d1 where s1 > 3 and time < 9");
+    System.out.println(dataSet.getColumnNames());
     while (dataSet.hasNext()) {
       System.out.println(dataSet.next());
     }
@@ -126,7 +150,7 @@ public class AlignedTimeseriesSessionExample {
     dataSet.closeOperationHandle();
     dataSet =
         session.executeQueryStatement(
-            "select * from root.sg_1.d1.vector where time > 50 and s1 > 0 and s2 > 10000");
+            "select * from root.sg_1.d1 where time < 8 and s1 > 3 and s2 > 5");
     System.out.println(dataSet.getColumnNames());
     while (dataSet.hasNext()) {
       System.out.println(dataSet.next());
@@ -137,15 +161,14 @@ public class AlignedTimeseriesSessionExample {
 
   private static void selectWithAggregationTest()
       throws StatementExecutionException, IoTDBConnectionException {
-    SessionDataSet dataSet =
-        session.executeQueryStatement("select count(s1) from root.sg_1.d1.vector");
+    SessionDataSet dataSet = session.executeQueryStatement("select count(s1) from root.sg_1.d1");
     System.out.println(dataSet.getColumnNames());
     while (dataSet.hasNext()) {
       System.out.println(dataSet.next());
     }
 
     dataSet.closeOperationHandle();
-    dataSet = session.executeQueryStatement("select count(*) from root.sg_1.d1.vector");
+    dataSet = session.executeQueryStatement("select count(*) from root.sg_1.d1");
     System.out.println(dataSet.getColumnNames());
     while (dataSet.hasNext()) {
       System.out.println(dataSet.next());
@@ -188,20 +211,45 @@ public class AlignedTimeseriesSessionExample {
 
   private static void selectWithLastTest()
       throws StatementExecutionException, IoTDBConnectionException {
+    SessionDataSet dataSet = session.executeQueryStatement("select last s1 from root.sg_1.d1");
+    System.out.println(dataSet.getColumnNames());
+    while (dataSet.hasNext()) {
+      System.out.println(dataSet.next());
+    }
+
+    dataSet.closeOperationHandle();
+    dataSet = session.executeQueryStatement("select last * from root.sg_1.d1");
+    System.out.println(dataSet.getColumnNames());
+    while (dataSet.hasNext()) {
+      System.out.println(dataSet.next());
+    }
+
+    dataSet.closeOperationHandle();
+  }
+
+  private static void selectWithLastTestWithoutValueFilter()
+      throws StatementExecutionException, IoTDBConnectionException {
     SessionDataSet dataSet =
-        session.executeQueryStatement("select last s1 from root.sg_1.d1.vector");
+        session.executeQueryStatement("select last s1 from root.sg_1.d1 where time >= 5");
     System.out.println(dataSet.getColumnNames());
     while (dataSet.hasNext()) {
       System.out.println(dataSet.next());
     }
 
     dataSet.closeOperationHandle();
-    dataSet = session.executeQueryStatement("select last * from root.sg_1.d1.vector");
+
+    dataSet = session.executeQueryStatement("select last * from root.sg_1.d1 where time >= 5");
     System.out.println(dataSet.getColumnNames());
     while (dataSet.hasNext()) {
       System.out.println(dataSet.next());
     }
+    dataSet.closeOperationHandle();
 
+    dataSet = session.executeQueryStatement("select last * from root.sg_1.d1 where time >= 20");
+    System.out.println(dataSet.getColumnNames());
+    while (dataSet.hasNext()) {
+      System.out.println(dataSet.next());
+    }
     dataSet.closeOperationHandle();
   }
 
@@ -219,7 +267,7 @@ public class AlignedTimeseriesSessionExample {
       encodings.add(TSEncoding.RLE);
     }
     session.createAlignedTimeseries(
-        ROOT_SG1_D1_VECTOR2,
+        ROOT_SG1_D1,
         multiMeasurementComponents,
         dataTypes,
         encodings,
@@ -271,13 +319,10 @@ public class AlignedTimeseriesSessionExample {
     // The schema of measurements of one device
     // only measurementId and data type in MeasurementSchema take effects in Tablet
     List<IMeasurementSchema> schemaList = new ArrayList<>();
-    schemaList.add(
-        new VectorMeasurementSchema(
-            "vector",
-            new String[] {"s1", "s2"},
-            new TSDataType[] {TSDataType.INT64, TSDataType.INT32}));
+    schemaList.add(new UnaryMeasurementSchema("s1", TSDataType.INT64));
+    schemaList.add(new UnaryMeasurementSchema("s2", TSDataType.INT32));
 
-    Tablet tablet = new Tablet(ROOT_SG1_D1_VECTOR1, schemaList);
+    Tablet tablet = new Tablet(ROOT_SG1_D1, schemaList);
     tablet.setAligned(true);
     long timestamp = 1;
 
@@ -285,13 +330,8 @@ public class AlignedTimeseriesSessionExample {
       int rowIndex = tablet.rowSize++;
       tablet.addTimestamp(rowIndex, timestamp);
       tablet.addValue(
-          schemaList.get(0).getSubMeasurementsList().get(0),
-          rowIndex,
-          new SecureRandom().nextLong());
-      tablet.addValue(
-          schemaList.get(0).getSubMeasurementsList().get(1),
-          rowIndex,
-          new SecureRandom().nextInt());
+          schemaList.get(0).getMeasurementId(), rowIndex, new SecureRandom().nextLong());
+      tablet.addValue(schemaList.get(1).getMeasurementId(), rowIndex, new SecureRandom().nextInt());
 
       if (tablet.rowSize == tablet.getMaxRowNumber()) {
         session.insertTablet(tablet, true);
@@ -301,7 +341,7 @@ public class AlignedTimeseriesSessionExample {
     }
 
     if (tablet.rowSize != 0) {
-      session.insertTablet(tablet);
+      session.insertAlignedTablet(tablet);
       tablet.reset();
     }
 
@@ -314,11 +354,8 @@ public class AlignedTimeseriesSessionExample {
     // The schema of measurements of one device
     // only measurementId and data type in MeasurementSchema take effects in Tablet
     List<IMeasurementSchema> schemaList = new ArrayList<>();
-    schemaList.add(
-        new VectorMeasurementSchema(
-            "vector2",
-            new String[] {"s1", "s2"},
-            new TSDataType[] {TSDataType.INT64, TSDataType.INT32}));
+    schemaList.add(new UnaryMeasurementSchema("s1", TSDataType.INT64));
+    schemaList.add(new UnaryMeasurementSchema("s2", TSDataType.INT32));
 
     Tablet tablet = new Tablet(ROOT_SG1_D1_VECTOR2, schemaList);
     tablet.setAligned(true);
@@ -354,11 +391,8 @@ public class AlignedTimeseriesSessionExample {
     // The schema of measurements of one device
     // only measurementId and data type in MeasurementSchema take effects in Tablet
     List<IMeasurementSchema> schemaList = new ArrayList<>();
-    schemaList.add(
-        new VectorMeasurementSchema(
-            "vector3",
-            new String[] {"s1", "s2"},
-            new TSDataType[] {TSDataType.INT64, TSDataType.INT32}));
+    schemaList.add(new UnaryMeasurementSchema("s1", TSDataType.INT64));
+    schemaList.add(new UnaryMeasurementSchema("s2", TSDataType.INT32));
 
     Tablet tablet = new Tablet(ROOT_SG1_D1_VECTOR3, schemaList);
     tablet.setAligned(true);
@@ -402,6 +436,7 @@ public class AlignedTimeseriesSessionExample {
 
   private static void insertAlignedRecord()
       throws IoTDBConnectionException, StatementExecutionException {
+    // first file we have both sensots' data
     List<String> multiMeasurementComponents = new ArrayList<>();
     List<TSDataType> types = new ArrayList<>();
     multiMeasurementComponents.add("s1");
@@ -409,12 +444,22 @@ public class AlignedTimeseriesSessionExample {
     types.add(TSDataType.INT64);
     types.add(TSDataType.INT32);
 
-    for (long time = 0; time < 1; time++) {
+    for (long time = 0; time < 10; time++) {
       List<Object> values = new ArrayList<>();
-      values.add(1L);
-      values.add(2);
-      session.insertAlignedRecord(
-          ROOT_SG2_D1_VECTOR4, time, multiMeasurementComponents, types, values);
+      values.add(time);
+      values.add((int) time);
+      session.insertAlignedRecord(ROOT_SG1_D1, time, multiMeasurementComponents, types, values);
+    }
+    session.executeNonQueryStatement("flush");
+    // second file we only have s1's data
+    multiMeasurementComponents.clear();
+    types.clear();
+    multiMeasurementComponents.add("s1");
+    types.add(TSDataType.INT64);
+    for (long time = 10; time < 20; time++) {
+      List<Object> values = new ArrayList<>();
+      values.add(time);
+      session.insertAlignedRecord(ROOT_SG1_D1, time, multiMeasurementComponents, types, values);
     }
   }
 
@@ -520,23 +565,16 @@ public class AlignedTimeseriesSessionExample {
       throws IoTDBConnectionException, StatementExecutionException {
 
     List<IMeasurementSchema> schemaList1 = new ArrayList<>();
-    schemaList1.add(
-        new VectorMeasurementSchema(
-            "vector6",
-            new String[] {"s1", "s2"},
-            new TSDataType[] {TSDataType.INT64, TSDataType.INT64}));
+    schemaList1.add(new UnaryMeasurementSchema("s1", TSDataType.INT64));
+    schemaList1.add(new UnaryMeasurementSchema("s2", TSDataType.INT64));
+
     List<IMeasurementSchema> schemaList2 = new ArrayList<>();
-    schemaList2.add(
-        new VectorMeasurementSchema(
-            "vector7",
-            new String[] {"s1", "s2"},
-            new TSDataType[] {TSDataType.INT64, TSDataType.INT64}));
+    schemaList1.add(new UnaryMeasurementSchema("s1", TSDataType.INT64));
+    schemaList1.add(new UnaryMeasurementSchema("s2", TSDataType.INT64));
+
     List<IMeasurementSchema> schemaList3 = new ArrayList<>();
-    schemaList3.add(
-        new VectorMeasurementSchema(
-            "vector8",
-            new String[] {"s1", "s2"},
-            new TSDataType[] {TSDataType.INT64, TSDataType.INT64}));
+    schemaList1.add(new UnaryMeasurementSchema("s1", TSDataType.INT64));
+    schemaList1.add(new UnaryMeasurementSchema("s2", TSDataType.INT64));
 
     Tablet tablet1 = new Tablet(ROOT_SG2_D1_VECTOR6, schemaList1, 100);
     Tablet tablet2 = new Tablet(ROOT_SG2_D1_VECTOR7, schemaList2, 100);
diff --git a/example/session/src/main/java/org/apache/iotdb/HybridTimeseriesSessionExample.java b/example/session/src/main/java/org/apache/iotdb/HybridTimeseriesSessionExample.java
index c2a9ed9..7c13681 100644
--- a/example/session/src/main/java/org/apache/iotdb/HybridTimeseriesSessionExample.java
+++ b/example/session/src/main/java/org/apache/iotdb/HybridTimeseriesSessionExample.java
@@ -25,7 +25,7 @@ import org.apache.iotdb.session.SessionDataSet;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.write.record.Tablet;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -73,11 +73,8 @@ public class HybridTimeseriesSessionExample {
     // The schema of measurements of one device
     // only measurementId and data type in MeasurementSchema take effects in Tablet
     List<IMeasurementSchema> schemaList = new ArrayList<>();
-    schemaList.add(
-        new VectorMeasurementSchema(
-            "vector",
-            new String[] {"s1", "s2"},
-            new TSDataType[] {TSDataType.INT64, TSDataType.INT32}));
+    schemaList.add(new UnaryMeasurementSchema("s1", TSDataType.INT64));
+    schemaList.add(new UnaryMeasurementSchema("s2", TSDataType.INT32));
 
     Tablet tablet = new Tablet(ROOT_SG1_D1_VECTOR1, schemaList);
     tablet.setAligned(true);
@@ -98,7 +95,7 @@ public class HybridTimeseriesSessionExample {
     }
 
     if (tablet.rowSize != 0) {
-      session.insertTablet(tablet);
+      session.insertAlignedTablet(tablet);
       tablet.reset();
     }
   }
diff --git a/example/trigger/src/main/java/org/apache/iotdb/trigger/TriggerExample.java b/example/trigger/src/main/java/org/apache/iotdb/trigger/TriggerExample.java
index 0632724..6e3ae52 100644
--- a/example/trigger/src/main/java/org/apache/iotdb/trigger/TriggerExample.java
+++ b/example/trigger/src/main/java/org/apache/iotdb/trigger/TriggerExample.java
@@ -27,7 +27,7 @@ import org.apache.iotdb.db.engine.trigger.sink.local.LocalIoTDBHandler;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTConfiguration;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTEvent;
 import org.apache.iotdb.db.engine.trigger.sink.mqtt.MQTTHandler;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.utils.windowing.configuration.SlidingSizeWindowConfiguration;
 import org.apache.iotdb.db.utils.windowing.handler.SlidingSizeWindowEvaluationHandler;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
diff --git a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileForceAppendWrite.java b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileForceAppendWrite.java
index f10b59b..6fd454b 100644
--- a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileForceAppendWrite.java
+++ b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileForceAppendWrite.java
@@ -51,13 +51,13 @@ public class TsFileForceAppendWrite {
       // add measurements into file schema
       for (int i = 0; i < 4; i++) {
         tsFileWriter.registerTimeseries(
-            new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_1),
+            new Path(Constant.DEVICE_PREFIX + i),
             new UnaryMeasurementSchema(Constant.SENSOR_1, TSDataType.INT64, TSEncoding.RLE));
         tsFileWriter.registerTimeseries(
-            new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_2),
+            new Path(Constant.DEVICE_PREFIX + i),
             new UnaryMeasurementSchema(Constant.SENSOR_2, TSDataType.INT64, TSEncoding.RLE));
         tsFileWriter.registerTimeseries(
-            new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_3),
+            new Path(Constant.DEVICE_PREFIX + i),
             new UnaryMeasurementSchema(Constant.SENSOR_3, TSDataType.INT64, TSEncoding.RLE));
       }
 
@@ -85,13 +85,13 @@ public class TsFileForceAppendWrite {
       // add measurements into file schema
       for (int i = 0; i < 4; i++) {
         tsFileWriter1.registerTimeseries(
-            new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_1),
+            new Path(Constant.DEVICE_PREFIX + i),
             new UnaryMeasurementSchema(Constant.SENSOR_1, TSDataType.INT64, TSEncoding.RLE));
         tsFileWriter1.registerTimeseries(
-            new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_2),
+            new Path(Constant.DEVICE_PREFIX + i),
             new UnaryMeasurementSchema(Constant.SENSOR_2, TSDataType.INT64, TSEncoding.RLE));
         tsFileWriter1.registerTimeseries(
-            new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_3),
+            new Path(Constant.DEVICE_PREFIX + i),
             new UnaryMeasurementSchema(Constant.SENSOR_3, TSDataType.INT64, TSEncoding.RLE));
       }
       // construct TSRecord
diff --git a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileSequenceRead.java b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileSequenceRead.java
index a51953b..512bd0c 100644
--- a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileSequenceRead.java
+++ b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileSequenceRead.java
@@ -33,13 +33,20 @@ import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
 import org.apache.iotdb.tsfile.read.TsFileSequenceReader;
 import org.apache.iotdb.tsfile.read.common.BatchData;
 import org.apache.iotdb.tsfile.read.reader.page.PageReader;
+import org.apache.iotdb.tsfile.read.reader.page.TimePageReader;
+import org.apache.iotdb.tsfile.read.reader.page.ValuePageReader;
+import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+/** This tool is used to read TsFile sequentially, including nonAligned or aligned timeseries. */
 public class TsFileSequenceRead {
+  // if you wanna print detailed datas in pages, then turn it true.
+  private static boolean printDetail = false;
 
   @SuppressWarnings({
     "squid:S3776",
@@ -64,6 +71,8 @@ public class TsFileSequenceRead {
       reader.position((long) TSFileConfig.MAGIC_STRING.getBytes().length + 1);
       System.out.println("[Chunk Group]");
       System.out.println("position: " + reader.position());
+      List<long[]> timeBatch = new ArrayList<>();
+      int pageIndex = 0;
       byte marker;
       while ((marker = reader.readMarker()) != MetaMarker.SEPARATOR) {
         switch (marker) {
@@ -85,33 +94,73 @@ public class TsFileSequenceRead {
             Decoder valueDecoder =
                 Decoder.getDecoderByType(header.getEncodingType(), header.getDataType());
             int dataSize = header.getDataSize();
+            pageIndex = 0;
+            if (header.getDataType() == TSDataType.VECTOR) {
+              timeBatch.clear();
+            }
             while (dataSize > 0) {
               valueDecoder.reset();
-              System.out.println("\t\t[Page]\n \t\tPage head position: " + reader.position());
+              System.out.println(
+                  "\t\t[Page" + pageIndex + "]\n \t\tPage head position: " + reader.position());
               PageHeader pageHeader =
                   reader.readPageHeader(
-                      header.getDataType(), header.getChunkType() == MetaMarker.CHUNK_HEADER);
+                      header.getDataType(),
+                      (header.getChunkType() & 0x3F) == MetaMarker.CHUNK_HEADER);
               System.out.println("\t\tPage data position: " + reader.position());
               ByteBuffer pageData = reader.readPage(pageHeader, header.getCompressionType());
               System.out.println(
                   "\t\tUncompressed page data size: " + pageHeader.getUncompressedSize());
-              PageReader reader1 =
-                  new PageReader(
-                      pageData, header.getDataType(), valueDecoder, defaultTimeDecoder, null);
-              BatchData batchData = reader1.getAllSatisfiedPageData();
-              if (header.getChunkType() == MetaMarker.CHUNK_HEADER) {
-                System.out.println("\t\tpoints in the page: " + pageHeader.getNumOfValues());
-              } else {
-                System.out.println("\t\tpoints in the page: " + batchData.length());
-              }
-              while (batchData.hasCurrent()) {
-                System.out.println(
-                    "\t\t\ttime, value: "
-                        + batchData.currentTime()
-                        + ", "
-                        + batchData.currentValue());
-                batchData.next();
+              System.out.println(
+                  "\t\tCompressed page data size: " + pageHeader.getCompressedSize());
+              if ((header.getChunkType() & (byte) TsFileConstant.TIME_COLUMN_MASK)
+                  == (byte) TsFileConstant.TIME_COLUMN_MASK) { // Time Chunk
+                TimePageReader timePageReader =
+                    new TimePageReader(pageHeader, pageData, defaultTimeDecoder);
+                timeBatch.add(timePageReader.getNextTimeBatch());
+                System.out.println("\t\tpoints in the page: " + timeBatch.get(pageIndex).length);
+                if (printDetail) {
+                  for (int i = 0; i < timeBatch.get(pageIndex).length; i++) {
+                    System.out.println("\t\t\ttime: " + timeBatch.get(pageIndex)[i]);
+                  }
+                }
+              } else if ((header.getChunkType() & (byte) TsFileConstant.VALUE_COLUMN_MASK)
+                  == (byte) TsFileConstant.VALUE_COLUMN_MASK) { // Value Chunk
+                ValuePageReader valuePageReader =
+                    new ValuePageReader(pageHeader, pageData, header.getDataType(), valueDecoder);
+                TsPrimitiveType[] valueBatch =
+                    valuePageReader.nextValueBatch(timeBatch.get(pageIndex));
+                if (valueBatch.length == 0) {
+                  System.out.println("\t\t-- Empty Page ");
+                } else {
+                  System.out.println("\t\tpoints in the page: " + valueBatch.length);
+                }
+                if (printDetail) {
+                  for (int i = 0; i < valueBatch.length; i++) {
+                    System.out.println("\t\t\tvalue: " + valueBatch[i]);
+                  }
+                }
+              } else { // NonAligned Chunk
+                PageReader pageReader =
+                    new PageReader(
+                        pageData, header.getDataType(), valueDecoder, defaultTimeDecoder, null);
+                BatchData batchData = pageReader.getAllSatisfiedPageData();
+                if (header.getChunkType() == MetaMarker.CHUNK_HEADER) {
+                  System.out.println("\t\tpoints in the page: " + pageHeader.getNumOfValues());
+                } else {
+                  System.out.println("\t\tpoints in the page: " + batchData.length());
+                }
+                if (printDetail) {
+                  while (batchData.hasCurrent()) {
+                    System.out.println(
+                        "\t\t\ttime, value: "
+                            + batchData.currentTime()
+                            + ", "
+                            + batchData.currentValue());
+                    batchData.next();
+                  }
+                }
               }
+              pageIndex++;
               dataSize -= pageHeader.getSerializedPageSize();
             }
             break;
diff --git a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteAlignedWithTSRecord.java b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteAlignedWithTSRecord.java
new file mode 100644
index 0000000..c4d8b56
--- /dev/null
+++ b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteAlignedWithTSRecord.java
@@ -0,0 +1,89 @@
+/*
+ * 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.iotdb.tsfile;
+
+import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
+import org.apache.iotdb.tsfile.read.common.Path;
+import org.apache.iotdb.tsfile.write.TsFileWriter;
+import org.apache.iotdb.tsfile.write.record.TSRecord;
+import org.apache.iotdb.tsfile.write.record.datapoint.DataPoint;
+import org.apache.iotdb.tsfile.write.record.datapoint.LongDataPoint;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TsFileWriteAlignedWithTSRecord {
+  private static final Logger logger =
+      LoggerFactory.getLogger(TsFileWriteAlignedWithTSRecord.class);
+
+  public static void main(String[] args) throws IOException {
+    File f = FSFactoryProducer.getFSFactory().getFile("alignedRecord.tsfile");
+    if (f.exists() && !f.delete()) {
+      throw new RuntimeException("can not delete " + f.getAbsolutePath());
+    }
+    try (TsFileWriter tsFileWriter = new TsFileWriter(f)) {
+      List<UnaryMeasurementSchema> measurementSchemas = new ArrayList<>();
+      measurementSchemas.add(new UnaryMeasurementSchema("s1", TSDataType.INT64, TSEncoding.RLE));
+      measurementSchemas.add(new UnaryMeasurementSchema("s2", TSDataType.INT64, TSEncoding.RLE));
+      measurementSchemas.add(new UnaryMeasurementSchema("s3", TSDataType.INT64, TSEncoding.RLE));
+
+      // register timeseries
+      tsFileWriter.registerAlignedTimeseries(new Path("root.sg.d1"), measurementSchemas);
+
+      List<IMeasurementSchema> writeMeasurementScheams = new ArrayList<>();
+      // example1
+      writeMeasurementScheams.add(measurementSchemas.get(0));
+      writeMeasurementScheams.add(measurementSchemas.get(1));
+      writeMeasurementScheams.add(measurementSchemas.get(2));
+      writeAligned(tsFileWriter, "root.sg.d1", writeMeasurementScheams, 1000000, 0, 0);
+    } catch (WriteProcessException e) {
+      logger.error("write TSRecord failed", e);
+    }
+  }
+
+  private static void writeAligned(
+      TsFileWriter tsFileWriter,
+      String deviceId,
+      List<IMeasurementSchema> schemas,
+      long rowSize,
+      long startTime,
+      long startValue)
+      throws IOException, WriteProcessException {
+    for (long time = startTime; time < rowSize + startTime; time++) {
+      // construct TsRecord
+      TSRecord tsRecord = new TSRecord(time, deviceId);
+      for (IMeasurementSchema schema : schemas) {
+        DataPoint dPoint = new LongDataPoint(schema.getMeasurementId(), startValue++);
+        tsRecord.addTuple(dPoint);
+      }
+      // write
+      tsFileWriter.writeAligned(tsRecord);
+    }
+  }
+}
diff --git a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteAlignedWithTablet.java b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteAlignedWithTablet.java
new file mode 100644
index 0000000..e1dd6f7
--- /dev/null
+++ b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteAlignedWithTablet.java
@@ -0,0 +1,141 @@
+/*
+ * 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.iotdb.tsfile;
+
+import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
+import org.apache.iotdb.tsfile.read.common.Path;
+import org.apache.iotdb.tsfile.utils.Binary;
+import org.apache.iotdb.tsfile.write.TsFileWriter;
+import org.apache.iotdb.tsfile.write.record.Tablet;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TsFileWriteAlignedWithTablet {
+  private static final Logger logger = LoggerFactory.getLogger(TsFileWriteAlignedWithTablet.class);
+  private static final String deviceId = "root.sg.d1";
+
+  public static void main(String[] args) throws IOException {
+    File f = FSFactoryProducer.getFSFactory().getFile("alignedTablet.tsfile");
+    if (f.exists() && !f.delete()) {
+      throw new RuntimeException("can not delete " + f.getAbsolutePath());
+    }
+    try (TsFileWriter tsFileWriter = new TsFileWriter(f)) {
+      List<UnaryMeasurementSchema> measurementSchemas = new ArrayList<>();
+      measurementSchemas.add(new UnaryMeasurementSchema("s1", TSDataType.TEXT, TSEncoding.PLAIN));
+      measurementSchemas.add(new UnaryMeasurementSchema("s2", TSDataType.TEXT, TSEncoding.PLAIN));
+      measurementSchemas.add(new UnaryMeasurementSchema("s3", TSDataType.TEXT, TSEncoding.PLAIN));
+
+      // register align timeseries
+      tsFileWriter.registerAlignedTimeseries(new Path(deviceId), measurementSchemas);
+
+      List<IMeasurementSchema> writeMeasurementScheams = new ArrayList<>();
+      // example 1
+      writeMeasurementScheams.add(measurementSchemas.get(0));
+      writeMeasurementScheams.add(measurementSchemas.get(1));
+      writeMeasurementScheams.add(measurementSchemas.get(2));
+      writeAlignedWithTablet(tsFileWriter, deviceId, writeMeasurementScheams, 200000, 0, 0);
+
+      writeNonAlignedWithTablet(tsFileWriter); // write nonAligned timeseries
+    } catch (WriteProcessException e) {
+      logger.error("write Tablet failed", e);
+    }
+  }
+
+  private static void writeAlignedWithTablet(
+      TsFileWriter tsFileWriter,
+      String deviceId,
+      List<IMeasurementSchema> schemas,
+      long rowNum,
+      long startTime,
+      long startValue)
+      throws IOException, WriteProcessException {
+    Tablet tablet = new Tablet(deviceId, schemas);
+    long[] timestamps = tablet.timestamps;
+    Object[] values = tablet.values;
+    long sensorNum = schemas.size();
+
+    for (long r = 0; r < rowNum; r++, startValue++) {
+      int row = tablet.rowSize++;
+      timestamps[row] = startTime++;
+      for (int i = 0; i < sensorNum; i++) {
+        Binary[] textSensor = (Binary[]) values[i];
+        textSensor[row] = new Binary("testString.........");
+      }
+      // write
+      if (tablet.rowSize == tablet.getMaxRowNumber()) {
+        tsFileWriter.writeAligned(tablet);
+        tablet.reset();
+      }
+    }
+    // write
+    if (tablet.rowSize != 0) {
+      tsFileWriter.writeAligned(tablet);
+      tablet.reset();
+    }
+  }
+
+  private static void writeNonAlignedWithTablet(TsFileWriter tsFileWriter)
+      throws WriteProcessException, IOException {
+    // register nonAlign timeseries
+    tsFileWriter.registerTimeseries(
+        new Path("root.sg.d2"), new UnaryMeasurementSchema("s1", TSDataType.INT64, TSEncoding.RLE));
+    tsFileWriter.registerTimeseries(
+        new Path("root.sg.d2"), new UnaryMeasurementSchema("s2", TSDataType.INT64, TSEncoding.RLE));
+    // construct Tablet
+    List<IMeasurementSchema> measurementSchemas = new ArrayList<>();
+    measurementSchemas.add(new UnaryMeasurementSchema("s1", TSDataType.INT64, TSEncoding.RLE));
+    measurementSchemas.add(new UnaryMeasurementSchema("s2", TSDataType.INT64, TSEncoding.RLE));
+    Tablet tablet = new Tablet("root.sg.d2", measurementSchemas);
+    long[] timestamps = tablet.timestamps;
+    Object[] values = tablet.values;
+    int rowNum = 100;
+    int sensorNum = measurementSchemas.size();
+    long timestamp = 1;
+    long value = 1000000L;
+    for (int r = 0; r < rowNum; r++, value++) {
+      int row = tablet.rowSize++;
+      timestamps[row] = timestamp++;
+      for (int i = 0; i < sensorNum; i++) {
+        long[] sensor = (long[]) values[i];
+        sensor[row] = value;
+      }
+      // write
+      if (tablet.rowSize == tablet.getMaxRowNumber()) {
+        tsFileWriter.write(tablet);
+        tablet.reset();
+      }
+    }
+    // write
+    if (tablet.rowSize != 0) {
+      tsFileWriter.write(tablet);
+      tablet.reset();
+    }
+  }
+}
diff --git a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteVectorWithTablet.java b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteVectorWithTablet.java
deleted file mode 100644
index 5f3e9ba..0000000
--- a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteVectorWithTablet.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.iotdb.tsfile;
-
-import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
-import org.apache.iotdb.tsfile.read.common.Path;
-import org.apache.iotdb.tsfile.write.TsFileWriter;
-import org.apache.iotdb.tsfile.write.record.Tablet;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.Schema;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/** An example of writing vector type timeseries with tablet */
-public class TsFileWriteVectorWithTablet {
-
-  private static final Logger logger = LoggerFactory.getLogger(TsFileWriteVectorWithTablet.class);
-
-  public static void main(String[] args) throws IOException {
-    try {
-      String path = "test.tsfile";
-      File f = FSFactoryProducer.getFSFactory().getFile(path);
-      if (f.exists() && !f.delete()) {
-        throw new RuntimeException("can not delete " + f.getAbsolutePath());
-      }
-      TSFileDescriptor.getInstance().getConfig().setMaxDegreeOfIndexNode(3);
-
-      Schema schema = new Schema();
-
-      String device = Constant.DEVICE_PREFIX + 1;
-      String sensorPrefix = "sensor_";
-      String vectorName = "vector1";
-      // the number of rows to include in the tablet
-      int rowNum = 10000;
-      // the number of vector values to include in the tablet
-      int multiSensorNum = 10;
-
-      String[] measurementNames = new String[multiSensorNum];
-      TSDataType[] dataTypes = new TSDataType[multiSensorNum];
-
-      List<IMeasurementSchema> measurementSchemas = new ArrayList<>();
-      // add measurements into file schema (all with INT64 data type)
-      for (int i = 0; i < multiSensorNum; i++) {
-        measurementNames[i] = sensorPrefix + (i + 1);
-        dataTypes[i] = TSDataType.INT64;
-      }
-      // vector schema
-      IMeasurementSchema vectorMeasurementSchema =
-          new VectorMeasurementSchema(vectorName, measurementNames, dataTypes);
-      measurementSchemas.add(vectorMeasurementSchema);
-      schema.registerTimeseries(new Path(device, vectorName), vectorMeasurementSchema);
-      // add measurements into TSFileWriter
-      try (TsFileWriter tsFileWriter = new TsFileWriter(f, schema)) {
-
-        // construct the tablet
-        Tablet tablet = new Tablet(device, measurementSchemas);
-
-        long[] timestamps = tablet.timestamps;
-        Object[] values = tablet.values;
-
-        long timestamp = 1;
-        long value = 1000000L;
-
-        for (int r = 0; r < rowNum; r++, value++) {
-          int row = tablet.rowSize++;
-          timestamps[row] = timestamp++;
-          for (int i = 0; i < measurementSchemas.size(); i++) {
-            IMeasurementSchema measurementSchema = measurementSchemas.get(i);
-            if (measurementSchema instanceof VectorMeasurementSchema) {
-              for (String valueName : measurementSchema.getSubMeasurementsList()) {
-                tablet.addValue(valueName, row, value);
-              }
-            }
-          }
-          // write Tablet to TsFile
-          if (tablet.rowSize == tablet.getMaxRowNumber()) {
-            tsFileWriter.write(tablet);
-            tablet.reset();
-          }
-        }
-        // write Tablet to TsFile
-        if (tablet.rowSize != 0) {
-          tsFileWriter.write(tablet);
-          tablet.reset();
-        }
-      }
-
-    } catch (Exception e) {
-      logger.error("meet error in TsFileWrite with tablet", e);
-    }
-  }
-}
diff --git a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteWithTSRecord.java b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteWithTSRecord.java
index b097daa..2a1ee19 100644
--- a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteWithTSRecord.java
+++ b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteWithTSRecord.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.tsfile;
 
+import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
@@ -27,55 +28,68 @@ import org.apache.iotdb.tsfile.write.TsFileWriter;
 import org.apache.iotdb.tsfile.write.record.TSRecord;
 import org.apache.iotdb.tsfile.write.record.datapoint.DataPoint;
 import org.apache.iotdb.tsfile.write.record.datapoint.LongDataPoint;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
 
 import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * An example of writing data with TSRecord to TsFile It uses the interface: public void
  * addMeasurement(MeasurementSchema measurementSchema) throws WriteProcessException
  */
 public class TsFileWriteWithTSRecord {
+  private static String deviceId = "root.sg.d1";
 
   public static void main(String[] args) {
     try {
-      String path = "test.tsfile";
+      String path = "Record.tsfile";
       File f = FSFactoryProducer.getFSFactory().getFile(path);
       if (f.exists()) {
         f.delete();
       }
 
       try (TsFileWriter tsFileWriter = new TsFileWriter(f)) {
-        // add measurements into file schema
-        for (int i = 0; i < 4; i++) {
-          // add measurements into file schema
-          tsFileWriter.registerTimeseries(
-              new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_1),
-              new UnaryMeasurementSchema(Constant.SENSOR_1, TSDataType.INT64, TSEncoding.RLE));
-          tsFileWriter.registerTimeseries(
-              new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_2),
-              new UnaryMeasurementSchema(Constant.SENSOR_2, TSDataType.INT64, TSEncoding.RLE));
-          tsFileWriter.registerTimeseries(
-              new Path(Constant.DEVICE_PREFIX + i, Constant.SENSOR_3),
-              new UnaryMeasurementSchema(Constant.SENSOR_3, TSDataType.INT64, TSEncoding.RLE));
-        }
+        List<UnaryMeasurementSchema> schemas = new ArrayList<>();
+        schemas.add(new UnaryMeasurementSchema("s1", TSDataType.INT64, TSEncoding.RLE));
+        schemas.add(new UnaryMeasurementSchema("s2", TSDataType.INT64, TSEncoding.RLE));
+        schemas.add(new UnaryMeasurementSchema("s3", TSDataType.INT64, TSEncoding.RLE));
 
-        // construct TSRecord
-        for (int i = 0; i < 100; i++) {
-          TSRecord tsRecord = new TSRecord(i, Constant.DEVICE_PREFIX + (i % 4));
-          DataPoint dPoint1 = new LongDataPoint(Constant.SENSOR_1, i);
-          DataPoint dPoint2 = new LongDataPoint(Constant.SENSOR_2, i);
-          DataPoint dPoint3 = new LongDataPoint(Constant.SENSOR_3, i);
-          tsRecord.addTuple(dPoint1);
-          tsRecord.addTuple(dPoint2);
-          tsRecord.addTuple(dPoint3);
-          // write TSRecord
-          tsFileWriter.write(tsRecord);
-        }
+        // register timeseries
+        tsFileWriter.registerTimeseries(new Path(deviceId), schemas);
+
+        List<IMeasurementSchema> writeMeasurementScheams = new ArrayList<>();
+        // example1
+        writeMeasurementScheams.add(schemas.get(0));
+        writeMeasurementScheams.add(schemas.get(1));
+        writeMeasurementScheams.add(schemas.get(2));
+        write(tsFileWriter, deviceId, writeMeasurementScheams, 10000, 0, 0);
       }
     } catch (Throwable e) {
       e.printStackTrace();
       System.out.println(e.getMessage());
     }
   }
+
+  private static void write(
+      TsFileWriter tsFileWriter,
+      String deviceId,
+      List<IMeasurementSchema> schemas,
+      long rowSize,
+      long startTime,
+      long startValue)
+      throws IOException, WriteProcessException {
+    for (long time = startTime; time < rowSize + startTime; time++) {
+      // construct TsRecord
+      TSRecord tsRecord = new TSRecord(time, deviceId);
+      for (IMeasurementSchema schema : schemas) {
+        DataPoint dPoint = new LongDataPoint(schema.getMeasurementId(), startValue++);
+        tsRecord.addTuple(dPoint);
+      }
+      // write
+      tsFileWriter.write(tsRecord);
+    }
+  }
 }
diff --git a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteWithTablet.java b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteWithTablet.java
index 1b1922f..97de571 100644
--- a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteWithTablet.java
+++ b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteWithTablet.java
@@ -19,20 +19,22 @@
 
 package org.apache.iotdb.tsfile;
 
+import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
 import org.apache.iotdb.tsfile.read.common.Path;
+import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.write.TsFileWriter;
 import org.apache.iotdb.tsfile.write.record.Tablet;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.Schema;
 import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -43,68 +45,62 @@ public class TsFileWriteWithTablet {
 
   public static void main(String[] args) {
     try {
-      String path = "test.tsfile";
+      String path = "Tablet.tsfile";
       File f = FSFactoryProducer.getFSFactory().getFile(path);
       if (f.exists() && !f.delete()) {
         throw new RuntimeException("can not delete " + f.getAbsolutePath());
       }
+      try (TsFileWriter tsFileWriter = new TsFileWriter(f)) {
+        List<UnaryMeasurementSchema> measurementSchemas = new ArrayList<>();
+        measurementSchemas.add(new UnaryMeasurementSchema("s1", TSDataType.TEXT, TSEncoding.PLAIN));
+        measurementSchemas.add(new UnaryMeasurementSchema("s2", TSDataType.TEXT, TSEncoding.PLAIN));
+        measurementSchemas.add(new UnaryMeasurementSchema("s3", TSDataType.TEXT, TSEncoding.PLAIN));
+
+        // register nonAlign timeseries
+        tsFileWriter.registerTimeseries(new Path("root.sg.d1"), measurementSchemas);
+
+        List<IMeasurementSchema> writeMeasurementScheams = new ArrayList<>();
+        // example 1
+        writeMeasurementScheams.add(measurementSchemas.get(0));
+        writeMeasurementScheams.add(measurementSchemas.get(1));
+        writeMeasurementScheams.add(measurementSchemas.get(2));
+        writeWithTablet(tsFileWriter, "root.sg.d1", writeMeasurementScheams, 10000, 0, 0);
+      }
+    } catch (Exception e) {
+      logger.error("meet error in TsFileWrite with tablet", e);
+    }
+  }
 
-      Schema schema = new Schema();
-
-      String device = Constant.DEVICE_PREFIX + 1;
-      String sensorPrefix = "sensor_";
-      // the number of rows to include in the tablet
-      int rowNum = 1000000;
-      // the number of values to include in the tablet
-      int sensorNum = 10;
-
-      List<IMeasurementSchema> measurementSchemas = new ArrayList<>();
-      // add measurements into file schema (all with INT64 data type)
+  private static void writeWithTablet(
+      TsFileWriter tsFileWriter,
+      String deviceId,
+      List<IMeasurementSchema> schemas,
+      long rowNum,
+      long startTime,
+      long startValue)
+      throws IOException, WriteProcessException {
+    Tablet tablet = new Tablet(deviceId, schemas);
+    long[] timestamps = tablet.timestamps;
+    Object[] values = tablet.values;
+    long sensorNum = schemas.size();
+
+    for (long r = 0; r < rowNum; r++, startValue++) {
+      int row = tablet.rowSize++;
+      timestamps[row] = startTime++;
       for (int i = 0; i < sensorNum; i++) {
-        IMeasurementSchema measurementSchema =
-            new UnaryMeasurementSchema(
-                sensorPrefix + (i + 1), TSDataType.INT64, TSEncoding.TS_2DIFF);
-        measurementSchemas.add(measurementSchema);
-        schema.registerTimeseries(
-            new Path(device, sensorPrefix + (i + 1)),
-            new UnaryMeasurementSchema(
-                sensorPrefix + (i + 1), TSDataType.INT64, TSEncoding.TS_2DIFF));
+        Binary[] textSensor = (Binary[]) values[i];
+        textSensor[row] = new Binary("testString.........");
       }
-
-      // add measurements into TSFileWriter
-      try (TsFileWriter tsFileWriter = new TsFileWriter(f, schema)) {
-
-        // construct the tablet
-        Tablet tablet = new Tablet(device, measurementSchemas);
-
-        long[] timestamps = tablet.timestamps;
-        Object[] values = tablet.values;
-
-        long timestamp = 1;
-        long value = 1000000L;
-
-        for (int r = 0; r < rowNum; r++, value++) {
-          int row = tablet.rowSize++;
-          timestamps[row] = timestamp++;
-          for (int i = 0; i < sensorNum; i++) {
-            long[] sensor = (long[]) values[i];
-            sensor[row] = value;
-          }
-          // write Tablet to TsFile
-          if (tablet.rowSize == tablet.getMaxRowNumber()) {
-            tsFileWriter.write(tablet);
-            tablet.reset();
-          }
-        }
-        // write Tablet to TsFile
-        if (tablet.rowSize != 0) {
-          tsFileWriter.write(tablet);
-          tablet.reset();
-        }
+      // write
+      if (tablet.rowSize == tablet.getMaxRowNumber()) {
+        tsFileWriter.write(tablet);
+        tablet.reset();
       }
-
-    } catch (Exception e) {
-      logger.error("meet error in TsFileWrite with tablet", e);
+    }
+    // write
+    if (tablet.rowSize != 0) {
+      tsFileWriter.write(tablet);
+      tablet.reset();
     }
   }
 }
diff --git a/hadoop/src/test/java/org/apache/iotdb/hadoop/tsfile/TsFileTestHelper.java b/hadoop/src/test/java/org/apache/iotdb/hadoop/tsfile/TsFileTestHelper.java
index bfe7371..08c7393 100644
--- a/hadoop/src/test/java/org/apache/iotdb/hadoop/tsfile/TsFileTestHelper.java
+++ b/hadoop/src/test/java/org/apache/iotdb/hadoop/tsfile/TsFileTestHelper.java
@@ -66,7 +66,7 @@ public class TsFileTestHelper {
       for (int i = 0; i < sensorNum; i++) {
         UnaryMeasurementSchema measurementSchema =
             new UnaryMeasurementSchema("sensor_" + (i + 1), TSDataType.INT64, TSEncoding.TS_2DIFF);
-        schema.registerTimeseries(new Path("device_1", "sensor_" + (i + 1)), measurementSchema);
+        schema.registerTimeseries(new Path("device_1"), measurementSchema);
         schemaList.add(measurementSchema);
       }
 
diff --git a/hive-connector/src/test/java/org/apache/iotdb/hive/TsFileTestHelper.java b/hive-connector/src/test/java/org/apache/iotdb/hive/TsFileTestHelper.java
index ea4835f..7463369 100644
--- a/hive-connector/src/test/java/org/apache/iotdb/hive/TsFileTestHelper.java
+++ b/hive-connector/src/test/java/org/apache/iotdb/hive/TsFileTestHelper.java
@@ -71,7 +71,7 @@ public class TsFileTestHelper {
                 TSDataType.INT64,
                 TSEncoding.TS_2DIFF,
                 CompressionType.UNCOMPRESSED);
-        schema.registerTimeseries(new Path("device_1", "sensor_" + (i + 1)), measurementSchema);
+        schema.registerTimeseries(new Path("device_1"), measurementSchema);
         schemaList.add(measurementSchema);
       }
 
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
index feefd07..6f0def1 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
@@ -519,8 +519,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
   public static TSQueryDataSet convertQueryDataSetByFetchSize(
       QueryDataSet queryDataSet, int fetchSize, WatermarkEncoder watermarkEncoder)
       throws IOException {
-    List<TSDataType> dataTypes = queryDataSet.getDataTypes();
-    int columnNum = dataTypes.size();
+    int columnNum = queryDataSet.getColumnNum();
     TSQueryDataSet tsQueryDataSet = new TSQueryDataSet();
     // one time column and each value column has a actual value buffer and a bitmap value to
     // indicate whether it is a null
diff --git a/server/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java b/server/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
index 33dc743..9f64526 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.db.auth.authorizer.IAuthorizer;
 import org.apache.iotdb.db.auth.entity.PrivilegeType;
 import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.logical.Operator;
 
 import org.slf4j.Logger;
@@ -49,7 +49,10 @@ public class AuthorityChecker {
    * @throws AuthException Authentication Exception
    */
   public static boolean check(
-      String username, List<PartialPath> paths, Operator.OperatorType type, String targetUser)
+      String username,
+      List<? extends PartialPath> paths,
+      Operator.OperatorType type,
+      String targetUser)
       throws AuthException {
     if (SUPER_USER.equals(username)) {
       return true;
diff --git a/server/src/main/java/org/apache/iotdb/db/cq/ContinuousQueryTask.java b/server/src/main/java/org/apache/iotdb/db/cq/ContinuousQueryTask.java
index 0962dfc..154c284 100644
--- a/server/src/main/java/org/apache/iotdb/db/cq/ContinuousQueryTask.java
+++ b/server/src/main/java/org/apache/iotdb/db/cq/ContinuousQueryTask.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.Planner;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.logical.crud.GroupByClauseComponent;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java b/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
index 36137ec..d3497ee 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
@@ -39,8 +39,8 @@ import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.exception.runtime.StorageEngineFailureException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.monitor.StatMonitor;
 import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
@@ -57,7 +57,7 @@ import org.apache.iotdb.db.utils.UpgradeUtils;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.service.rpc.thrift.TSStatus;
-import org.apache.iotdb.tsfile.read.expression.impl.SingleSeriesExpression;
+import org.apache.iotdb.tsfile.read.filter.basic.Filter;
 import org.apache.iotdb.tsfile.utils.FilePathUtils;
 import org.apache.iotdb.tsfile.utils.Pair;
 
@@ -578,7 +578,7 @@ public class StorageEngine implements IService {
         throw new StorageEngineException(e);
       }
     }
-    StorageGroupProcessor storageGroupProcessor = getProcessor(insertRowPlan.getPrefixPath());
+    StorageGroupProcessor storageGroupProcessor = getProcessor(insertRowPlan.getDeviceId());
 
     try {
       storageGroupProcessor.insert(insertRowPlan);
@@ -586,7 +586,7 @@ public class StorageEngine implements IService {
         try {
           updateMonitorStatistics(
               processorMap.get(
-                  IoTDB.metaManager.getBelongedStorageGroup(insertRowPlan.getPrefixPath())),
+                  IoTDB.metaManager.getBelongedStorageGroup(insertRowPlan.getDeviceId())),
               insertRowPlan);
         } catch (MetadataException e) {
           logger.error("failed to record status", e);
@@ -607,7 +607,7 @@ public class StorageEngine implements IService {
       }
     }
     StorageGroupProcessor storageGroupProcessor =
-        getProcessor(insertRowsOfOneDevicePlan.getPrefixPath());
+        getProcessor(insertRowsOfOneDevicePlan.getDeviceId());
 
     // TODO monitor: update statistics
     try {
@@ -631,12 +631,11 @@ public class StorageEngine implements IService {
     }
     StorageGroupProcessor storageGroupProcessor;
     try {
-      storageGroupProcessor = getProcessor(insertTabletPlan.getPrefixPath());
+      storageGroupProcessor = getProcessor(insertTabletPlan.getDeviceId());
     } catch (StorageEngineException e) {
       throw new StorageEngineException(
           String.format(
-              "Get StorageGroupProcessor of device %s " + "failed",
-              insertTabletPlan.getPrefixPath()),
+              "Get StorageGroupProcessor of device %s " + "failed", insertTabletPlan.getDeviceId()),
           e);
     }
 
@@ -646,7 +645,7 @@ public class StorageEngine implements IService {
       try {
         updateMonitorStatistics(
             processorMap.get(
-                IoTDB.metaManager.getBelongedStorageGroup(insertTabletPlan.getPrefixPath())),
+                IoTDB.metaManager.getBelongedStorageGroup(insertTabletPlan.getDeviceId())),
             insertTabletPlan);
       } catch (MetadataException e) {
         logger.error("failed to record status", e);
@@ -757,15 +756,11 @@ public class StorageEngine implements IService {
 
   /** query data. */
   public QueryDataSource query(
-      SingleSeriesExpression seriesExpression,
-      QueryContext context,
-      QueryFileManager filePathsManager)
+      PartialPath fullPath, Filter filter, QueryContext context, QueryFileManager filePathsManager)
       throws StorageEngineException, QueryProcessException {
-    PartialPath fullPath = (PartialPath) seriesExpression.getSeriesPath();
     PartialPath deviceId = fullPath.getDevicePath();
     StorageGroupProcessor storageGroupProcessor = getProcessor(deviceId);
-    return storageGroupProcessor.query(
-        fullPath, context, filePathsManager, seriesExpression.getFilter());
+    return storageGroupProcessor.query(fullPath, context, filePathsManager, filter);
   }
 
   /**
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java b/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
index a13fe93..ed269a8 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
@@ -24,10 +24,8 @@ import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.query.control.FileReaderManager;
 import org.apache.iotdb.db.utils.TestOnly;
-import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
 import org.apache.iotdb.tsfile.file.metadata.TimeseriesMetadata;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.TsFileSequenceReader;
 import org.apache.iotdb.tsfile.read.common.Path;
 import org.apache.iotdb.tsfile.utils.BloomFilter;
@@ -43,15 +41,11 @@ import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-import java.util.TreeSet;
 import java.util.WeakHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -187,187 +181,6 @@ public class TimeSeriesMetadataCache {
     }
   }
 
-  /**
-   * Support for vector. allSensors > subSensors
-   *
-   * @param key vector's own fullPath, e.g. root.sg1.d1.vector
-   * @param subSensorList all subSensors of this vector in query, e.g. [vector.s1, vector.s2,
-   *     vector.s3]
-   * @param allSensors all sensors belonging to this device that appear in query. For vector, this
-   *     should contain both vector name and subSensors' name, e.g. [vector, vector.s1, vector.s2,
-   *     vector.s3]
-   */
-  // Suppress synchronize warning
-  // Suppress high Cognitive Complexity warning
-  @SuppressWarnings({"squid:S1860", "squid:S3776"})
-  public List<TimeseriesMetadata> get(
-      TimeSeriesMetadataCacheKey key,
-      List<String> subSensorList,
-      Set<String> allSensors,
-      boolean debug)
-      throws IOException {
-    // put all sub sensors into allSensors
-    for (int i = 0; i < subSensorList.size(); i++) {
-      subSensorList.set(i, key.measurement + TsFileConstant.PATH_SEPARATOR + subSensorList.get(i));
-    }
-    allSensors.addAll(subSensorList);
-    if (!CACHE_ENABLE) {
-      // bloom filter part
-      TsFileSequenceReader reader = FileReaderManager.getInstance().get(key.filePath, true);
-      BloomFilter bloomFilter = reader.readBloomFilter();
-      if (bloomFilter != null
-          && !bloomFilter.contains(key.device + IoTDBConstant.PATH_SEPARATOR + key.measurement)) {
-        return Collections.emptyList();
-      }
-      // for the condition that cache is disabled, we only get what we need
-      Set<String> allSensorSet = new HashSet<>(subSensorList);
-      allSensorSet.add(key.measurement);
-      return readTimeseriesMetadataForVector(reader, key, subSensorList, allSensorSet);
-    }
-
-    List<TimeseriesMetadata> res = new ArrayList<>();
-    getVectorTimeSeriesMetadataListFromCache(key, subSensorList, res);
-
-    if (res.isEmpty()) {
-      if (debug) {
-        DEBUG_LOGGER.info(
-            "Cache miss: {}.{} in file: {}", key.device, key.measurement, key.filePath);
-        DEBUG_LOGGER.info("Device: {}, all sensors: {}", key.device, allSensors);
-      }
-      // allow for the parallelism of different devices
-      synchronized (
-          devices.computeIfAbsent(key.device + SEPARATOR + key.filePath, WeakReference::new)) {
-        // double check
-        getVectorTimeSeriesMetadataListFromCache(key, subSensorList, res);
-        if (res.isEmpty()) {
-          Path path = new Path(key.device, key.measurement);
-          // bloom filter part
-          TsFileSequenceReader reader = FileReaderManager.getInstance().get(key.filePath, true);
-          BloomFilter bloomFilter =
-              BloomFilterCache.getInstance()
-                  .get(new BloomFilterCache.BloomFilterCacheKey(key.filePath), debug);
-          if (bloomFilter != null && !bloomFilter.contains(path.getFullPath())) {
-            if (debug) {
-              DEBUG_LOGGER.info("TimeSeries meta data {} is filter by bloomFilter!", key);
-            }
-            allSensors.removeAll(subSensorList);
-            return Collections.emptyList();
-          }
-          res = readTimeseriesMetadataForVector(reader, key, subSensorList, allSensors);
-          Iterator<TimeseriesMetadata> iterator = res.iterator();
-          Set<String> subSensorSet = new HashSet<>(subSensorList);
-          subSensorSet.add(key.measurement);
-          // Note: allSensors > subSensors
-          // Put TimeSeriesMetadata of all sensors used in this query into cache
-          // Remove redundant TimeSeriesMetadata that do not belong to subSensors
-          while (iterator.hasNext()) {
-            TimeseriesMetadata metadata = iterator.next();
-            TimeSeriesMetadataCacheKey k =
-                new TimeSeriesMetadataCacheKey(
-                    key.filePath, key.device, metadata.getMeasurementId());
-            lruCache.put(k, metadata);
-            if (!subSensorSet.contains(metadata.getMeasurementId())) {
-              iterator.remove();
-            }
-          }
-        }
-      }
-    }
-    if (debug) {
-      if (res.isEmpty()) {
-        DEBUG_LOGGER.info("The file doesn't have this time series {}.", key);
-      } else {
-        DEBUG_LOGGER.info(
-            "Get timeseries: {}.{}  metadata in file: {}  from cache: {}.",
-            key.device,
-            key.measurement,
-            key.filePath,
-            res);
-      }
-    }
-
-    allSensors.removeAll(subSensorList);
-    return res;
-  }
-
-  /**
-   * Support for vector, extraction of common function of `get`
-   *
-   * @param key vector's own fullPath, e.g. root.sg1.d1.vector
-   * @param subSensorList all subSensors of this vector in one query, e.g. [vector.s1, vector.s2,
-   *     vector.s3]
-   * @param allSensors all sensors of the device in one device, to vector, this should contain both
-   *     vector name and subSensors' name, e.g. [vector, vector.s1, vector.s2, vector.s3]
-   * @param reader TsFileSequenceReader created by file
-   */
-  private List<TimeseriesMetadata> readTimeseriesMetadataForVector(
-      TsFileSequenceReader reader,
-      TimeSeriesMetadataCacheKey key,
-      List<String> subSensorList,
-      Set<String> allSensors)
-      throws IOException {
-    Path path = new Path(key.device, key.measurement);
-    List<TimeseriesMetadata> timeSeriesMetadataList =
-        reader.readTimeseriesMetadata(path, allSensors);
-    // for new implementation of index tree, subSensor may not all stored in one leaf
-    // for this case, it's necessary to make sure all subSensor's timeseries add to list
-    TreeSet<String> subSensorsSet = new TreeSet<>(subSensorList);
-    for (int i = 0; i < timeSeriesMetadataList.size(); i++) {
-      TimeseriesMetadata tsMetadata = timeSeriesMetadataList.get(i);
-      if (tsMetadata.getTSDataType().equals(TSDataType.VECTOR)
-          && tsMetadata.getMeasurementId().equals(key.measurement)) {
-        for (int j = i + 1; j < timeSeriesMetadataList.size(); j++) {
-          tsMetadata = timeSeriesMetadataList.get(j);
-          if (!subSensorsSet.isEmpty() && subSensorsSet.contains(tsMetadata.getMeasurementId())) {
-            subSensorsSet.remove(tsMetadata.getMeasurementId());
-          }
-        }
-        break;
-      }
-    }
-    while (!subSensorsSet.isEmpty()) {
-      Path subPath = new Path(key.device, subSensorsSet.first());
-      List<TimeseriesMetadata> subTsMetaDataList =
-          reader.readTimeseriesMetadata(subPath, allSensors);
-      for (TimeseriesMetadata tsMetadata : subTsMetaDataList) {
-        if (!subSensorsSet.isEmpty() && subSensorsSet.contains(tsMetadata.getMeasurementId())) {
-          subSensorsSet.remove(tsMetadata.getMeasurementId());
-        }
-      }
-      timeSeriesMetadataList.addAll(subTsMetaDataList);
-    }
-    return timeSeriesMetadataList;
-  }
-
-  /**
-   * !!!Attention!!!
-   *
-   * <p>For a vector, e.g. root.sg1.d1.vector1(s1, s2) TimeSeriesMetadataCacheKey for vector1 should
-   * be {filePath: ""./data/data/seq/......., device: root.sg1.d1, measurement: vector1}, vector1
-   * will be in both device and measurement TimeSeriesMetadataCacheKey for vector1.s1 should be
-   * {filePath: ""./data/data/seq/......., device: root.sg1.d1, measurement: vector.s1}
-   * TimeSeriesMetadataCacheKey for vector1.s2 should be {filePath: ""./data/data/seq/.......,
-   * device: root.sg1.d1, measurement: vector.s2}
-   */
-  private void getVectorTimeSeriesMetadataListFromCache(
-      TimeSeriesMetadataCacheKey key, List<String> subSensorList, List<TimeseriesMetadata> res) {
-    TimeseriesMetadata timeseriesMetadata = lruCache.getIfPresent(key);
-    if (timeseriesMetadata != null) {
-      res.add(timeseriesMetadata);
-      for (String subSensor : subSensorList) {
-        timeseriesMetadata =
-            lruCache.getIfPresent(
-                new TimeSeriesMetadataCacheKey(key.filePath, key.device, subSensor));
-        if (timeseriesMetadata != null) {
-          res.add(timeseriesMetadata);
-        } else {
-          res.clear();
-          break;
-        }
-      }
-    }
-  }
-
   public double calculateTimeSeriesMetadataHitRatio() {
     return lruCache.stats().hitRate();
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/manage/CrossSpaceMergeContext.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/manage/CrossSpaceMergeContext.java
index c7b30b4..721c54b 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/manage/CrossSpaceMergeContext.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/manage/CrossSpaceMergeContext.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.engine.compaction.cross.inplace.manage;
 
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 import java.util.HashMap;
 import java.util.List;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/manage/CrossSpaceMergeResource.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/manage/CrossSpaceMergeResource.java
index e466150..8c4548f 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/manage/CrossSpaceMergeResource.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/manage/CrossSpaceMergeResource.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.engine.compaction.cross.inplace.manage;
 
 import org.apache.iotdb.db.engine.modification.Modification;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.reader.resource.CachedUnseqResourceMergeReader;
 import org.apache.iotdb.db.utils.MergeUtils;
 import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
@@ -32,7 +32,6 @@ import org.apache.iotdb.tsfile.read.common.Chunk;
 import org.apache.iotdb.tsfile.read.reader.IPointReader;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.write.chunk.ChunkWriterImpl;
-import org.apache.iotdb.tsfile.write.chunk.IChunkWriter;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
 
@@ -67,7 +66,7 @@ public class CrossSpaceMergeResource {
       new HashMap<>(); // pair<startTime, endTime>
   private Map<PartialPath, IMeasurementSchema> measurementSchemaMap =
       new HashMap<>(); // is this too waste?
-  private Map<IMeasurementSchema, IChunkWriter> chunkWriterCache = new ConcurrentHashMap<>();
+  private Map<IMeasurementSchema, ChunkWriterImpl> chunkWriterCache = new ConcurrentHashMap<>();
 
   private long ttlLowerBound = Long.MIN_VALUE;
 
@@ -176,7 +175,7 @@ public class CrossSpaceMergeResource {
    * Construct the a new or get an existing ChunkWriter of a measurement. Different timeseries of
    * the same measurement and data type shares the same instance.
    */
-  public IChunkWriter getChunkWriter(IMeasurementSchema measurementSchema) {
+  public ChunkWriterImpl getChunkWriter(IMeasurementSchema measurementSchema) {
     return chunkWriterCache.computeIfAbsent(measurementSchema, ChunkWriterImpl::new);
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/recover/LogAnalyzer.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/recover/LogAnalyzer.java
index 25ec908..2b427d1 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/recover/LogAnalyzer.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/recover/LogAnalyzer.java
@@ -25,7 +25,8 @@ import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 
 import org.slf4j.Logger;
@@ -102,8 +103,8 @@ public class LogAnalyzer {
 
         analyzeUnseqFiles(bufferedReader);
 
-        List<PartialPath> storageGroupPaths =
-            IoTDB.metaManager.getFlatMeasurementPaths(new PartialPath(storageGroupName + ".*"));
+        List<MeasurementPath> storageGroupPaths =
+            IoTDB.metaManager.getMeasurementPaths(new PartialPath(storageGroupName + ".*"));
         unmergedPaths = new ArrayList<>();
         unmergedPaths.addAll(storageGroupPaths);
 
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/recover/MergeLogger.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/recover/MergeLogger.java
index 7f30c17..63b4f06 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/recover/MergeLogger.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/recover/MergeLogger.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.engine.compaction.cross.inplace.recover;
 
 import org.apache.iotdb.db.engine.compaction.cross.inplace.manage.CrossSpaceMergeResource;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 import java.io.BufferedWriter;
 import java.io.File;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/selector/IMergePathSelector.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/selector/IMergePathSelector.java
index faab6ae..e0e19f7 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/selector/IMergePathSelector.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/selector/IMergePathSelector.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.engine.compaction.cross.inplace.selector;
 
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 import java.util.Iterator;
 import java.util.List;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/selector/NaivePathSelector.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/selector/NaivePathSelector.java
index e7a0ee7..75793c7 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/selector/NaivePathSelector.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/selector/NaivePathSelector.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.engine.compaction.cross.inplace.selector;
 
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 import java.util.List;
 import java.util.NoSuchElementException;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/CrossSpaceMergeTask.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/CrossSpaceMergeTask.java
index 4f0701b..23dddbf 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/CrossSpaceMergeTask.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/CrossSpaceMergeTask.java
@@ -24,7 +24,7 @@ import org.apache.iotdb.db.engine.compaction.cross.inplace.manage.CrossSpaceMerg
 import org.apache.iotdb.db.engine.compaction.cross.inplace.recover.MergeLogger;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.MergeUtils;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/MergeFileTask.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/MergeFileTask.java
index 02453ad..85a3192 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/MergeFileTask.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/MergeFileTask.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.db.engine.compaction.cross.inplace.manage.CrossSpaceMerg
 import org.apache.iotdb.db.engine.compaction.cross.inplace.manage.CrossSpaceMergeResource;
 import org.apache.iotdb.db.engine.compaction.cross.inplace.recover.MergeLogger;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.control.FileReaderManager;
 import org.apache.iotdb.tsfile.exception.write.TsFileNotCompleteException;
 import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/MergeMultiChunkTask.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/MergeMultiChunkTask.java
index 4a3b5e5..c6dfac9 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/MergeMultiChunkTask.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/MergeMultiChunkTask.java
@@ -29,7 +29,7 @@ import org.apache.iotdb.db.engine.compaction.cross.inplace.selector.NaivePathSel
 import org.apache.iotdb.db.engine.modification.Modification;
 import org.apache.iotdb.db.engine.storagegroup.TsFileManager;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.utils.MergeUtils;
 import org.apache.iotdb.db.utils.MergeUtils.MetaListEntry;
 import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
@@ -39,7 +39,7 @@ import org.apache.iotdb.tsfile.read.common.BatchData;
 import org.apache.iotdb.tsfile.read.common.Chunk;
 import org.apache.iotdb.tsfile.read.reader.IPointReader;
 import org.apache.iotdb.tsfile.read.reader.chunk.ChunkReader;
-import org.apache.iotdb.tsfile.write.chunk.IChunkWriter;
+import org.apache.iotdb.tsfile.write.chunk.ChunkWriterImpl;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
 import org.apache.iotdb.tsfile.write.writer.TsFileIOWriter;
@@ -459,7 +459,7 @@ public class MergeMultiChunkTask {
       int pathIdx,
       TsFileIOWriter mergeFileWriter,
       IPointReader unseqReader,
-      IChunkWriter chunkWriter,
+      ChunkWriterImpl chunkWriter,
       TsFileResource currFile)
       throws IOException {
     int unclosedChunkPoint = lastUnclosedChunkPoint;
@@ -521,7 +521,7 @@ public class MergeMultiChunkTask {
   }
 
   private int writeRemainingUnseq(
-      IChunkWriter chunkWriter, IPointReader unseqReader, long timeLimit, int pathIdx)
+      ChunkWriterImpl chunkWriter, IPointReader unseqReader, long timeLimit, int pathIdx)
       throws IOException {
     int ptWritten = 0;
     while (currTimeValuePairs[pathIdx] != null
@@ -537,7 +537,7 @@ public class MergeMultiChunkTask {
 
   private int writeChunkWithUnseq(
       Chunk chunk,
-      IChunkWriter chunkWriter,
+      ChunkWriterImpl chunkWriter,
       IPointReader unseqReader,
       long chunkLimitTime,
       int pathIdx)
@@ -553,7 +553,7 @@ public class MergeMultiChunkTask {
   }
 
   private int mergeWriteBatch(
-      BatchData batchData, IChunkWriter chunkWriter, IPointReader unseqReader, int pathIdx)
+      BatchData batchData, ChunkWriterImpl chunkWriter, IPointReader unseqReader, int pathIdx)
       throws IOException {
     int cnt = 0;
     for (int i = 0; i < batchData.length(); i++) {
@@ -630,7 +630,7 @@ public class MergeMultiChunkTask {
         PartialPath path = currMergingPaths.get(pathIdx);
         IMeasurementSchema measurementSchema = resource.getSchema(path);
         // chunkWriter will keep the data in memory
-        IChunkWriter chunkWriter = resource.getChunkWriter(measurementSchema);
+        ChunkWriterImpl chunkWriter = resource.getChunkWriter(measurementSchema);
         if (Thread.interrupted()) {
           Thread.currentThread().interrupt();
           return;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/RecoverCrossMergeTask.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/RecoverCrossMergeTask.java
index 16e047e..062fd80 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/RecoverCrossMergeTask.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/inplace/task/RecoverCrossMergeTask.java
@@ -26,7 +26,7 @@ import org.apache.iotdb.db.engine.compaction.cross.inplace.recover.MergeLogger;
 import org.apache.iotdb.db.engine.compaction.cross.inplace.selector.MaxSeriesMergeFileSelector;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.utils.MergeUtils;
 import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
 import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/compaction/inner/utils/InnerSpaceCompactionUtils.java b/server/src/main/java/org/apache/iotdb/db/engine/compaction/inner/utils/InnerSpaceCompactionUtils.java
index 0c92ff2..38732a4 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/compaction/inner/utils/InnerSpaceCompactionUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/compaction/inner/utils/InnerSpaceCompactionUtils.java
@@ -32,7 +32,7 @@ import org.apache.iotdb.db.engine.storagegroup.TsFileManager;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.control.FileReaderManager;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
@@ -44,7 +44,6 @@ import org.apache.iotdb.tsfile.read.reader.IPointReader;
 import org.apache.iotdb.tsfile.read.reader.chunk.ChunkReaderByTimestamp;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.write.chunk.ChunkWriterImpl;
-import org.apache.iotdb.tsfile.write.chunk.IChunkWriter;
 import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
 
 import com.google.common.util.concurrent.RateLimiter;
@@ -200,11 +199,11 @@ public class InnerSpaceCompactionUtils {
     if (isChunkMetadataEmpty) {
       return;
     }
-    IChunkWriter chunkWriter;
+    ChunkWriterImpl chunkWriter;
     try {
       chunkWriter =
           new ChunkWriterImpl(
-              IoTDB.metaManager.getSeriesSchema(new PartialPath(device), entry.getKey()), true);
+              IoTDB.metaManager.getSeriesSchema(new PartialPath(device, entry.getKey())), true);
     } catch (MetadataException e) {
       // this may caused in IT by restart
       logger.error("{} get schema {} error, skip this sensor", device, entry.getKey(), e);
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/flush/MemTableFlushTask.java b/server/src/main/java/org/apache/iotdb/db/engine/flush/MemTableFlushTask.java
index 7962da4..957d03e 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/flush/MemTableFlushTask.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/flush/MemTableFlushTask.java
@@ -25,22 +25,13 @@ import org.apache.iotdb.db.engine.memtable.IMemTable;
 import org.apache.iotdb.db.engine.memtable.IWritableMemChunk;
 import org.apache.iotdb.db.exception.runtime.FlushRunTimeException;
 import org.apache.iotdb.db.rescon.SystemInfo;
-import org.apache.iotdb.db.utils.datastructure.TVList;
-import org.apache.iotdb.db.utils.datastructure.VectorTVList;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.utils.Pair;
-import org.apache.iotdb.tsfile.write.chunk.ChunkWriterImpl;
 import org.apache.iotdb.tsfile.write.chunk.IChunkWriter;
-import org.apache.iotdb.tsfile.write.chunk.VectorChunkWriterImpl;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -118,13 +109,12 @@ public class MemTableFlushTask {
       for (Map.Entry<String, IWritableMemChunk> iWritableMemChunkEntry : value.entrySet()) {
         long startTime = System.currentTimeMillis();
         IWritableMemChunk series = iWritableMemChunkEntry.getValue();
-        IMeasurementSchema desc = series.getSchema();
         /*
          * sort task (first task of flush pipeline)
          */
-        TVList tvList = series.getSortedTvListForFlush();
+        series.sortTvListForFlush();
         sortTime += System.currentTimeMillis() - startTime;
-        encodingTaskQueue.put(new Pair<>(tvList, desc));
+        encodingTaskQueue.put(series);
       }
 
       encodingTaskQueue.put(new EndChunkGroupIoTask());
@@ -168,118 +158,6 @@ public class MemTableFlushTask {
   /** encoding task (second task of pipeline) */
   private Runnable encodingTask =
       new Runnable() {
-        private void writeOneSeries(
-            TVList tvPairs, IChunkWriter seriesWriterImpl, TSDataType dataType) {
-          List<Integer> timeDuplicatedVectorRowIndexList = null;
-          for (int sortedRowIndex = 0; sortedRowIndex < tvPairs.size(); sortedRowIndex++) {
-            long time = tvPairs.getTime(sortedRowIndex);
-
-            // skip duplicated data
-            if ((sortedRowIndex + 1 < tvPairs.size()
-                && (time == tvPairs.getTime(sortedRowIndex + 1)))) {
-              // record the time duplicated row index list for vector type
-              if (dataType == TSDataType.VECTOR) {
-                if (timeDuplicatedVectorRowIndexList == null) {
-                  timeDuplicatedVectorRowIndexList = new ArrayList<>();
-                  timeDuplicatedVectorRowIndexList.add(tvPairs.getValueIndex(sortedRowIndex));
-                }
-                timeDuplicatedVectorRowIndexList.add(tvPairs.getValueIndex(sortedRowIndex + 1));
-              }
-              continue;
-            }
-
-            // store last point for SDT
-            if (dataType != TSDataType.VECTOR && sortedRowIndex + 1 == tvPairs.size()) {
-              ((ChunkWriterImpl) seriesWriterImpl).setLastPoint(true);
-            }
-
-            switch (dataType) {
-              case BOOLEAN:
-                seriesWriterImpl.write(time, tvPairs.getBoolean(sortedRowIndex), false);
-                break;
-              case INT32:
-                seriesWriterImpl.write(time, tvPairs.getInt(sortedRowIndex), false);
-                break;
-              case INT64:
-                seriesWriterImpl.write(time, tvPairs.getLong(sortedRowIndex), false);
-                break;
-              case FLOAT:
-                seriesWriterImpl.write(time, tvPairs.getFloat(sortedRowIndex), false);
-                break;
-              case DOUBLE:
-                seriesWriterImpl.write(time, tvPairs.getDouble(sortedRowIndex), false);
-                break;
-              case TEXT:
-                seriesWriterImpl.write(time, tvPairs.getBinary(sortedRowIndex), false);
-                break;
-              case VECTOR:
-                VectorTVList vectorTvPairs = (VectorTVList) tvPairs;
-                List<TSDataType> dataTypes = vectorTvPairs.getTsDataTypes();
-                int originRowIndex = vectorTvPairs.getValueIndex(sortedRowIndex);
-                for (int columnIndex = 0; columnIndex < dataTypes.size(); columnIndex++) {
-                  // write the time duplicated rows
-                  if (timeDuplicatedVectorRowIndexList != null
-                      && !timeDuplicatedVectorRowIndexList.isEmpty()) {
-                    originRowIndex =
-                        vectorTvPairs.getValidRowIndexForTimeDuplicatedRows(
-                            timeDuplicatedVectorRowIndexList, columnIndex);
-                  }
-                  boolean isNull = vectorTvPairs.isValueMarked(originRowIndex, columnIndex);
-                  switch (dataTypes.get(columnIndex)) {
-                    case BOOLEAN:
-                      seriesWriterImpl.write(
-                          time,
-                          vectorTvPairs.getBooleanByValueIndex(originRowIndex, columnIndex),
-                          isNull);
-                      break;
-                    case INT32:
-                      seriesWriterImpl.write(
-                          time,
-                          vectorTvPairs.getIntByValueIndex(originRowIndex, columnIndex),
-                          isNull);
-                      break;
-                    case INT64:
-                      seriesWriterImpl.write(
-                          time,
-                          vectorTvPairs.getLongByValueIndex(originRowIndex, columnIndex),
-                          isNull);
-                      break;
-                    case FLOAT:
-                      seriesWriterImpl.write(
-                          time,
-                          vectorTvPairs.getFloatByValueIndex(originRowIndex, columnIndex),
-                          isNull);
-                      break;
-                    case DOUBLE:
-                      seriesWriterImpl.write(
-                          time,
-                          vectorTvPairs.getDoubleByValueIndex(originRowIndex, columnIndex),
-                          isNull);
-                      break;
-                    case TEXT:
-                      seriesWriterImpl.write(
-                          time,
-                          vectorTvPairs.getBinaryByValueIndex(originRowIndex, columnIndex),
-                          isNull);
-                      break;
-                    default:
-                      LOGGER.error(
-                          "Storage group {} does not support data type: {}",
-                          storageGroup,
-                          dataTypes.get(columnIndex));
-                      break;
-                  }
-                }
-                seriesWriterImpl.write(time);
-                timeDuplicatedVectorRowIndexList = null;
-                break;
-              default:
-                LOGGER.error(
-                    "Storage group {} does not support data type: {}", storageGroup, dataType);
-                break;
-            }
-          }
-        }
 
         @SuppressWarnings("squid:S135")
         @Override
@@ -290,7 +168,7 @@ public class MemTableFlushTask {
               writer.getFile().getName());
           while (true) {
 
-            Object task = null;
+            Object task;
             try {
               task = encodingTaskQueue.take();
             } catch (InterruptedException e1) {
@@ -316,15 +194,9 @@ public class MemTableFlushTask {
               break;
             } else {
               long starTime = System.currentTimeMillis();
-              Pair<TVList, IMeasurementSchema> encodingMessage =
-                  (Pair<TVList, IMeasurementSchema>) task;
-              IChunkWriter seriesWriter;
-              if (encodingMessage.left.getDataType() == TSDataType.VECTOR) {
-                seriesWriter = new VectorChunkWriterImpl(encodingMessage.right);
-              } else {
-                seriesWriter = new ChunkWriterImpl(encodingMessage.right);
-              }
-              writeOneSeries(encodingMessage.left, seriesWriter, encodingMessage.right.getType());
+              IWritableMemChunk writableMemChunk = (IWritableMemChunk) task;
+              IChunkWriter seriesWriter = writableMemChunk.createIChunkWriter();
+              writableMemChunk.encode(seriesWriter);
               seriesWriter.sealCurrentPage();
               seriesWriter.clearPageWriter();
               try {
@@ -374,16 +246,12 @@ public class MemTableFlushTask {
               this.writer.startChunkGroup(((StartFlushGroupIOTask) ioMessage).deviceId);
             } else if (ioMessage instanceof TaskEnd) {
               break;
-            } else if (ioMessage instanceof ChunkWriterImpl) {
-              ChunkWriterImpl chunkWriter = (ChunkWriterImpl) ioMessage;
-              chunkWriter.writeToFileWriter(this.writer);
-            } else if (ioMessage instanceof VectorChunkWriterImpl) {
-              VectorChunkWriterImpl chunkWriter = (VectorChunkWriterImpl) ioMessage;
-              chunkWriter.writeToFileWriter(this.writer);
-            } else {
+            } else if (ioMessage instanceof EndChunkGroupIoTask) {
               this.writer.setMinPlanIndex(memTable.getMinPlanIndex());
               this.writer.setMaxPlanIndex(memTable.getMaxPlanIndex());
               this.writer.endChunkGroup();
+            } else {
+              ((IChunkWriter) ioMessage).writeToFileWriter(this.writer);
             }
           } catch (IOException e) {
             LOGGER.error(
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/flush/NotifyFlushMemTable.java b/server/src/main/java/org/apache/iotdb/db/engine/flush/NotifyFlushMemTable.java
index 4aeb66c..169c22f 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/flush/NotifyFlushMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/flush/NotifyFlushMemTable.java
@@ -35,6 +35,11 @@ public class NotifyFlushMemTable extends AbstractMemTable {
   }
 
   @Override
+  protected IWritableMemChunk genAlignedMemSeries(IMeasurementSchema schema) {
+    return null;
+  }
+
+  @Override
   public IMemTable copy() {
     return null;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
index cbbf421..72c9b72 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
@@ -22,16 +22,18 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.querycontext.ReadOnlyMemChunk;
 import org.apache.iotdb.db.exception.WriteProcessException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.db.rescon.TVListAllocator;
 import org.apache.iotdb.db.utils.MemUtils;
 import org.apache.iotdb.db.utils.datastructure.TVList;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.read.common.TimeRange;
-import org.apache.iotdb.tsfile.utils.BitMap;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 
@@ -88,22 +90,14 @@ public abstract class AbstractMemTable implements IMemTable {
   }
 
   /**
-   * check whether the given seriesPath is within this memtable.
-   *
-   * @return true if seriesPath is within this memtable
-   */
-  private boolean checkPath(String deviceId, String measurement) {
-    return memTableMap.containsKey(deviceId) && memTableMap.get(deviceId).containsKey(measurement);
-  }
-
-  /**
-   * create this memtable if it's not exist
+   * create this MemChunk if it's not exist
    *
    * @param deviceId device id
    * @param schema measurement schema
-   * @return this memtable
+   * @return this MemChunk
    */
-  private IWritableMemChunk createIfNotExistAndGet(String deviceId, IMeasurementSchema schema) {
+  private IWritableMemChunk createMemChunkIfNotExistAndGet(
+      String deviceId, IMeasurementSchema schema) {
     Map<String, IWritableMemChunk> memSeries =
         memTableMap.computeIfAbsent(deviceId, k -> new HashMap<>());
 
@@ -111,61 +105,89 @@ public abstract class AbstractMemTable implements IMemTable {
         schema.getMeasurementId(),
         k -> {
           seriesNumber++;
-          totalPointsNumThreshold +=
-              ((long) avgSeriesPointNumThreshold * schema.getSubMeasurementsCount());
+          totalPointsNumThreshold += avgSeriesPointNumThreshold;
           return genMemSeries(schema);
         });
   }
 
+  private IWritableMemChunk createAlignedMemChunkIfNotExistAndGet(
+      String deviceId, IMeasurementSchema schema) {
+    Map<String, IWritableMemChunk> memSeries =
+        memTableMap.computeIfAbsent(deviceId, k -> new HashMap<>());
+
+    VectorMeasurementSchema vectorSchema = (VectorMeasurementSchema) schema;
+    return memSeries.computeIfAbsent(
+        vectorSchema.getMeasurementId(),
+        k -> {
+          seriesNumber++;
+          totalPointsNumThreshold +=
+              avgSeriesPointNumThreshold * vectorSchema.getSubMeasurementsCount();
+          return genAlignedMemSeries(vectorSchema);
+        });
+  }
+
   protected abstract IWritableMemChunk genMemSeries(IMeasurementSchema schema);
 
+  protected abstract IWritableMemChunk genAlignedMemSeries(IMeasurementSchema schema);
+
   @Override
   public void insert(InsertRowPlan insertRowPlan) {
     updatePlanIndexes(insertRowPlan.getIndex());
     Object[] values = insertRowPlan.getValues();
 
     IMeasurementMNode[] measurementMNodes = insertRowPlan.getMeasurementMNodes();
-    int columnIndex = 0;
-    if (insertRowPlan.isAligned()) {
-      IMeasurementMNode measurementMNode = measurementMNodes[0];
-      if (measurementMNode != null) {
-        // write vector
-        Object[] vectorValue =
-            new Object[measurementMNode.getSchema().getSubMeasurementsTSDataTypeList().size()];
-        for (int j = 0; j < vectorValue.length; j++) {
-          vectorValue[j] = values[columnIndex];
-          columnIndex++;
-        }
-        memSize +=
-            MemUtils.getVectorRecordSize(
-                measurementMNode.getSchema().getSubMeasurementsTSDataTypeList(),
-                vectorValue,
-                disableMemControl);
-        write(
-            insertRowPlan.getPrefixPath().getFullPath(),
-            measurementMNode.getSchema(),
-            insertRowPlan.getTime(),
-            vectorValue);
-      }
-    } else {
-      for (IMeasurementMNode measurementMNode : measurementMNodes) {
-        if (values[columnIndex] == null) {
-          columnIndex++;
-          continue;
-        }
-        memSize +=
-            MemUtils.getRecordSize(
-                measurementMNode.getSchema().getType(), values[columnIndex], disableMemControl);
-
-        write(
-            insertRowPlan.getPrefixPath().getFullPath(),
-            measurementMNode.getSchema(),
-            insertRowPlan.getTime(),
-            values[columnIndex]);
-        columnIndex++;
+    for (int i = 0; i < measurementMNodes.length; i++) {
+      if (values[i] == null) {
+        continue;
       }
+      memSize +=
+          MemUtils.getRecordSize(
+              measurementMNodes[i].getSchema().getType(), values[i], disableMemControl);
+
+      write(
+          insertRowPlan.getDeviceId().getFullPath(),
+          measurementMNodes[i].getSchema(),
+          insertRowPlan.getTime(),
+          values[i]);
     }
+    totalPointsNum +=
+        insertRowPlan.getMeasurements().length - insertRowPlan.getFailedMeasurementNumber();
+  }
 
+  @Override
+  public void insertAlignedRow(InsertRowPlan insertRowPlan) {
+    updatePlanIndexes(insertRowPlan.getIndex());
+    // write vector
+    List<String> measurements = new ArrayList<>();
+    List<TSDataType> types = new ArrayList<>();
+    List<TSEncoding> encodings = new ArrayList<>();
+    CompressionType compressionType = null;
+    for (int i = 0; i < insertRowPlan.getMeasurements().length; i++) {
+      if (insertRowPlan.getMeasurements()[i] == null) {
+        continue;
+      }
+      IMeasurementSchema schema = insertRowPlan.getMeasurementMNodes()[i].getSchema();
+      measurements.add(schema.getMeasurementId());
+      types.add(schema.getType());
+      encodings.add(schema.getEncodingType());
+      compressionType = schema.getCompressor();
+    }
+    if (measurements.isEmpty()) {
+      return;
+    }
+    VectorMeasurementSchema vectorSchema =
+        new VectorMeasurementSchema(
+            AlignedPath.VECTOR_PLACEHOLDER,
+            measurements.toArray(new String[measurements.size()]),
+            types.toArray(new TSDataType[measurements.size()]),
+            encodings.toArray(new TSEncoding[measurements.size()]),
+            compressionType);
+    memSize += MemUtils.getAlignedRecordSize(types, insertRowPlan.getValues(), disableMemControl);
+    writeAlignedRow(
+        insertRowPlan.getDeviceId().getFullPath(),
+        vectorSchema,
+        insertRowPlan.getTime(),
+        insertRowPlan.getValues());
     totalPointsNum +=
         insertRowPlan.getMeasurements().length - insertRowPlan.getFailedMeasurementNumber();
   }
@@ -186,54 +208,92 @@ public abstract class AbstractMemTable implements IMemTable {
   }
 
   @Override
+  public void insertAlignedTablet(InsertTabletPlan insertTabletPlan, int start, int end)
+      throws WriteProcessException {
+    updatePlanIndexes(insertTabletPlan.getIndex());
+    try {
+      writeAlignedTablet(insertTabletPlan, start, end);
+      memSize += MemUtils.getAlignedRecordSize(insertTabletPlan, start, end, disableMemControl);
+      totalPointsNum +=
+          (insertTabletPlan.getDataTypes().length - insertTabletPlan.getFailedMeasurementNumber())
+              * (end - start);
+    } catch (RuntimeException e) {
+      throw new WriteProcessException(e);
+    }
+  }
+
+  @Override
   public void write(
       String deviceId, IMeasurementSchema schema, long insertTime, Object objectValue) {
-    IWritableMemChunk memSeries = createIfNotExistAndGet(deviceId, schema);
+    IWritableMemChunk memSeries = createMemChunkIfNotExistAndGet(deviceId, schema);
     memSeries.write(insertTime, objectValue);
   }
 
+  @Override
+  public void writeAlignedRow(
+      String deviceId, IMeasurementSchema schema, long insertTime, Object[] objectValue) {
+    IWritableMemChunk memSeries = createAlignedMemChunkIfNotExistAndGet(deviceId, schema);
+    memSeries.writeAlignedValue(insertTime, objectValue, schema);
+  }
+
   @SuppressWarnings("squid:S3776") // high Cognitive Complexity
   @Override
   public void write(InsertTabletPlan insertTabletPlan, int start, int end) {
-    int columnIndex = 0;
     updatePlanIndexes(insertTabletPlan.getIndex());
     for (int i = 0; i < insertTabletPlan.getMeasurements().length; i++) {
-      if (insertTabletPlan.getColumns()[columnIndex] == null) {
-        columnIndex++;
+      if (insertTabletPlan.getColumns()[i] == null) {
         continue;
       }
       IWritableMemChunk memSeries =
-          createIfNotExistAndGet(
-              insertTabletPlan.getPrefixPath().getFullPath(),
+          createMemChunkIfNotExistAndGet(
+              insertTabletPlan.getDeviceId().getFullPath(),
               insertTabletPlan.getMeasurementMNodes()[i].getSchema());
-      if (insertTabletPlan.isAligned()) {
-        VectorMeasurementSchema vectorSchema =
-            (VectorMeasurementSchema) insertTabletPlan.getMeasurementMNodes()[i].getSchema();
-        Object[] columns = new Object[vectorSchema.getSubMeasurementsList().size()];
-        BitMap[] bitMaps = new BitMap[vectorSchema.getSubMeasurementsList().size()];
-        for (int j = 0; j < vectorSchema.getSubMeasurementsList().size(); j++) {
-          columns[j] = insertTabletPlan.getColumns()[columnIndex];
-          if (insertTabletPlan.getBitMaps() != null) {
-            bitMaps[j] = insertTabletPlan.getBitMaps()[columnIndex];
-          }
-          columnIndex++;
-        }
-        memSeries.write(
-            insertTabletPlan.getTimes(), columns, bitMaps, TSDataType.VECTOR, start, end);
-        break;
-      } else {
-        memSeries.write(
-            insertTabletPlan.getTimes(),
-            insertTabletPlan.getColumns()[columnIndex],
-            insertTabletPlan.getBitMaps() != null
-                ? insertTabletPlan.getBitMaps()[columnIndex]
-                : null,
-            insertTabletPlan.getDataTypes()[columnIndex],
-            start,
-            end);
-        columnIndex++;
+      memSeries.write(
+          insertTabletPlan.getTimes(),
+          insertTabletPlan.getColumns()[i],
+          insertTabletPlan.getBitMaps() != null ? insertTabletPlan.getBitMaps()[i] : null,
+          insertTabletPlan.getDataTypes()[i],
+          start,
+          end);
+    }
+  }
+
+  public void writeAlignedTablet(InsertTabletPlan insertTabletPlan, int start, int end) {
+    updatePlanIndexes(insertTabletPlan.getIndex());
+    List<String> measurements = new ArrayList<>();
+    List<TSDataType> types = new ArrayList<>();
+    List<TSEncoding> encodings = new ArrayList<>();
+    CompressionType compressionType = null;
+    for (int i = 0; i < insertTabletPlan.getMeasurements().length; i++) {
+      if (insertTabletPlan.getColumns()[i] == null) {
+        continue;
       }
+      IMeasurementSchema schema = insertTabletPlan.getMeasurementMNodes()[i].getSchema();
+      measurements.add(schema.getMeasurementId());
+      types.add(schema.getType());
+      encodings.add(schema.getEncodingType());
+      compressionType = schema.getCompressor();
+    }
+    if (measurements.isEmpty()) {
+      return;
     }
+    VectorMeasurementSchema vectorSchema =
+        new VectorMeasurementSchema(
+            AlignedPath.VECTOR_PLACEHOLDER,
+            measurements.toArray(new String[measurements.size()]),
+            types.toArray(new TSDataType[measurements.size()]),
+            encodings.toArray(new TSEncoding[measurements.size()]),
+            compressionType);
+    IWritableMemChunk memSeries =
+        createAlignedMemChunkIfNotExistAndGet(
+            insertTabletPlan.getDeviceId().getFullPath(), vectorSchema);
+    memSeries.writeAlignedValues(
+        insertTabletPlan.getTimes(),
+        insertTabletPlan.getColumns(),
+        insertTabletPlan.getBitMaps(),
+        vectorSchema,
+        start,
+        end);
   }
 
   @Override
@@ -242,7 +302,6 @@ public abstract class AbstractMemTable implements IMemTable {
     if (null == memSeries) {
       return true;
     }
-
     return !memSeries.containsKey(measurement);
   }
 
@@ -250,7 +309,7 @@ public abstract class AbstractMemTable implements IMemTable {
   public int getCurrentChunkPointNum(String deviceId, String measurement) {
     Map<String, IWritableMemChunk> memSeries = memTableMap.get(deviceId);
     IWritableMemChunk memChunk = memSeries.get(measurement);
-    return memChunk.getTVList().size();
+    return (int) memChunk.count();
   }
 
   @Override
@@ -305,50 +364,9 @@ public abstract class AbstractMemTable implements IMemTable {
 
   @Override
   public ReadOnlyMemChunk query(
-      String deviceId,
-      String measurement,
-      IMeasurementSchema partialVectorSchema,
-      long ttlLowerBound,
-      List<TimeRange> deletionList)
+      PartialPath fullPath, long ttlLowerBound, List<TimeRange> deletionList)
       throws IOException, QueryProcessException {
-    if (partialVectorSchema.getType() == TSDataType.VECTOR) {
-      if (!memTableMap.containsKey(deviceId)) {
-        return null;
-      }
-      IWritableMemChunk vectorMemChunk =
-          memTableMap.get(deviceId).get(partialVectorSchema.getMeasurementId());
-      if (vectorMemChunk == null) {
-        return null;
-      }
-
-      List<String> measurementIdList = partialVectorSchema.getSubMeasurementsList();
-      List<Integer> columns = new ArrayList<>();
-      IMeasurementSchema vectorSchema = vectorMemChunk.getSchema();
-      for (String queryingMeasurement : measurementIdList) {
-        columns.add(vectorSchema.getSubMeasurementsList().indexOf(queryingMeasurement));
-      }
-      // get sorted tv list is synchronized so different query can get right sorted list reference
-      TVList vectorTvListCopy = vectorMemChunk.getSortedTvListForQuery(columns);
-      int curSize = vectorTvListCopy.size();
-      return new ReadOnlyMemChunk(partialVectorSchema, vectorTvListCopy, curSize, deletionList);
-    } else {
-      if (!checkPath(deviceId, measurement)) {
-        return null;
-      }
-      IWritableMemChunk memChunk =
-          memTableMap.get(deviceId).get(partialVectorSchema.getMeasurementId());
-      // get sorted tv list is synchronized so different query can get right sorted list reference
-      TVList chunkCopy = memChunk.getSortedTvListForQuery();
-      int curSize = chunkCopy.size();
-      return new ReadOnlyMemChunk(
-          measurement,
-          partialVectorSchema.getType(),
-          partialVectorSchema.getEncodingType(),
-          chunkCopy,
-          partialVectorSchema.getProps(),
-          curSize,
-          deletionList);
-    }
+    return fullPath.getReadOnlyMemChunkFromMemTable(memTableMap, deletionList);
   }
 
   @SuppressWarnings("squid:S3776") // high Cognitive Complexity
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AlignedWritableMemChunk.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AlignedWritableMemChunk.java
new file mode 100644
index 0000000..cd7184b
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AlignedWritableMemChunk.java
@@ -0,0 +1,313 @@
+/*
+ * 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.iotdb.db.engine.memtable;
+
+import org.apache.iotdb.db.rescon.TVListAllocator;
+import org.apache.iotdb.db.utils.datastructure.AlignedTVList;
+import org.apache.iotdb.db.utils.datastructure.TVList;
+import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.utils.Binary;
+import org.apache.iotdb.tsfile.utils.BitMap;
+import org.apache.iotdb.tsfile.write.chunk.AlignedChunkWriterImpl;
+import org.apache.iotdb.tsfile.write.chunk.IChunkWriter;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AlignedWritableMemChunk implements IWritableMemChunk {
+
+  private final VectorMeasurementSchema schema;
+  private AlignedTVList list;
+  private static final String UNSUPPORTED_TYPE = "Unsupported data type:";
+  private static final Logger LOGGER = LoggerFactory.getLogger(AlignedWritableMemChunk.class);
+
+  public AlignedWritableMemChunk(VectorMeasurementSchema schema) {
+    this.schema = schema;
+    this.list = TVListAllocator.getInstance().allocate(schema.getSubMeasurementsTSDataTypeList());
+  }
+
+  public boolean containsMeasurement(String measurementId) {
+    return schema.containsSubMeasurement(measurementId);
+  }
+
+  @Override
+  public void putLong(long t, long v) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putInt(long t, int v) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putFloat(long t, float v) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putDouble(long t, double v) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putBinary(long t, Binary v) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putBoolean(long t, boolean v) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putAlignedValue(long t, Object[] v, int[] columnIndexArray) {
+    list.putAlignedValue(t, v, columnIndexArray);
+  }
+
+  @Override
+  public void putLongs(long[] t, long[] v, BitMap bitMap, int start, int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putInts(long[] t, int[] v, BitMap bitMap, int start, int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putFloats(long[] t, float[] v, BitMap bitMap, int start, int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putDoubles(long[] t, double[] v, BitMap bitMap, int start, int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putBinaries(long[] t, Binary[] v, BitMap bitMap, int start, int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putBooleans(long[] t, boolean[] v, BitMap bitMap, int start, int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void putAlignedValues(
+      long[] t, Object[] v, BitMap[] bitMaps, int[] columnIndexArray, int start, int end) {
+    list.putAlignedValues(t, v, bitMaps, columnIndexArray, start, end);
+  }
+
+  @Override
+  public void write(long insertTime, Object objectValue) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void writeAlignedValue(long insertTime, Object[] objectValue, IMeasurementSchema schema) {
+    int[] columnIndexArray = checkColumnsInInsertPlan(schema);
+    putAlignedValue(insertTime, objectValue, columnIndexArray);
+  }
+
+  @Override
+  public void write(
+      long[] times, Object valueList, BitMap bitMap, TSDataType dataType, int start, int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public void writeAlignedValues(
+      long[] times,
+      Object[] valueList,
+      BitMap[] bitMaps,
+      IMeasurementSchema schema,
+      int start,
+      int end) {
+    int[] columnIndexArray = checkColumnsInInsertPlan(schema);
+    putAlignedValues(times, valueList, bitMaps, columnIndexArray, start, end);
+  }
+
+  private int[] checkColumnsInInsertPlan(IMeasurementSchema schema) {
+    VectorMeasurementSchema vectorSchema = (VectorMeasurementSchema) schema;
+    List<String> measurementIdsInInsertPlan = vectorSchema.getSubMeasurementsList();
+    List<TSDataType> dataTypesInInsertPlan = vectorSchema.getSubMeasurementsTSDataTypeList();
+    List<TSEncoding> encodingsInInsertPlan = vectorSchema.getSubMeasurementsTSEncodingList();
+    for (int i = 0; i < measurementIdsInInsertPlan.size(); i++) {
+      if (!containsMeasurement(measurementIdsInInsertPlan.get(i))) {
+        this.schema.addMeasurement(
+            measurementIdsInInsertPlan.get(i),
+            dataTypesInInsertPlan.get(i),
+            encodingsInInsertPlan.get(i));
+        this.list.extendColumn(dataTypesInInsertPlan.get(i));
+      }
+    }
+    List<String> measurementIdsInTVList = this.schema.getSubMeasurementsList();
+    int[] columnIndexArray = new int[measurementIdsInTVList.size()];
+    for (int i = 0; i < columnIndexArray.length; i++) {
+      columnIndexArray[i] = measurementIdsInInsertPlan.indexOf(measurementIdsInTVList.get(i));
+    }
+    return columnIndexArray;
+  }
+
+  @Override
+  public TVList getTVList() {
+    return list;
+  }
+
+  @Override
+  public long count() {
+    return (long) list.size() * schema.getSubMeasurementsCount();
+  }
+
+  public long alignedListSize() {
+    return list.size();
+  }
+
+  @Override
+  public IMeasurementSchema getSchema() {
+    return schema;
+  }
+
+  @Override
+  public TVList getSortedTvListForQuery() {
+    sortTVList();
+    // increase reference count
+    list.increaseReferenceCount();
+    return list;
+  }
+
+  @Override
+  public TVList getSortedTvListForQuery(List<IMeasurementSchema> schemaList) {
+    sortTVList();
+    // increase reference count
+    list.increaseReferenceCount();
+    List<Integer> columnIndexList = new ArrayList<>();
+    for (IMeasurementSchema measurementSchema : schemaList) {
+      columnIndexList.add(schema.getSubMeasurementIndex(measurementSchema.getMeasurementId()));
+    }
+    return list.getTvListByColumnIndex(columnIndexList);
+  }
+
+  private void sortTVList() {
+    // check reference count
+    if ((list.getReferenceCount() > 0 && !list.isSorted())) {
+      list = list.clone();
+    }
+
+    if (!list.isSorted()) {
+      list.sort();
+    }
+  }
+
+  @Override
+  public void sortTvListForFlush() {
+    sortTVList();
+  }
+
+  @Override
+  public int delete(long lowerBound, long upperBound) {
+    return list.delete(lowerBound, upperBound);
+  }
+
+  @Override
+  // TODO: THIS METHOLD IS FOR DELETING ONE COLUMN OF A VECTOR
+  public int delete(long lowerBound, long upperBound, String measurementId) {
+    return 0;
+  }
+
+  @Override
+  public IChunkWriter createIChunkWriter() {
+    return new AlignedChunkWriterImpl(schema);
+  }
+
+  @Override
+  public void encode(IChunkWriter chunkWriter) {
+    AlignedChunkWriterImpl alignedChunkWriter = (AlignedChunkWriterImpl) chunkWriter;
+    List<Integer> timeDuplicateAlignedRowIndexList = null;
+    for (int sortedRowIndex = 0; sortedRowIndex < list.size(); sortedRowIndex++) {
+      long time = list.getTime(sortedRowIndex);
+
+      // skip duplicated data
+      if ((sortedRowIndex + 1 < list.size() && (time == list.getTime(sortedRowIndex + 1)))) {
+        // record the time duplicated row index list for vector type
+        if (timeDuplicateAlignedRowIndexList == null) {
+          timeDuplicateAlignedRowIndexList = new ArrayList<>();
+          timeDuplicateAlignedRowIndexList.add(list.getValueIndex(sortedRowIndex));
+        }
+        timeDuplicateAlignedRowIndexList.add(list.getValueIndex(sortedRowIndex + 1));
+        continue;
+      }
+      List<TSDataType> dataTypes = list.getTsDataTypes();
+      int originRowIndex = list.getValueIndex(sortedRowIndex);
+      for (int columnIndex = 0; columnIndex < dataTypes.size(); columnIndex++) {
+        // write the time duplicated rows
+        if (timeDuplicateAlignedRowIndexList != null
+            && !timeDuplicateAlignedRowIndexList.isEmpty()) {
+          originRowIndex =
+              list.getValidRowIndexForTimeDuplicatedRows(
+                  timeDuplicateAlignedRowIndexList, columnIndex);
+        }
+        boolean isNull = list.isValueMarked(originRowIndex, columnIndex);
+        switch (dataTypes.get(columnIndex)) {
+          case BOOLEAN:
+            alignedChunkWriter.write(
+                time, list.getBooleanByValueIndex(originRowIndex, columnIndex), isNull);
+            break;
+          case INT32:
+            alignedChunkWriter.write(
+                time, list.getIntByValueIndex(originRowIndex, columnIndex), isNull);
+            break;
+          case INT64:
+            alignedChunkWriter.write(
+                time, list.getLongByValueIndex(originRowIndex, columnIndex), isNull);
+            break;
+          case FLOAT:
+            alignedChunkWriter.write(
+                time, list.getFloatByValueIndex(originRowIndex, columnIndex), isNull);
+            break;
+          case DOUBLE:
+            alignedChunkWriter.write(
+                time, list.getDoubleByValueIndex(originRowIndex, columnIndex), isNull);
+            break;
+          case TEXT:
+            alignedChunkWriter.write(
+                time, list.getBinaryByValueIndex(originRowIndex, columnIndex), isNull);
+            break;
+          default:
+            LOGGER.error(
+                "AlignedWritableMemChunk does not support data type: {}",
+                dataTypes.get(columnIndex));
+            break;
+        }
+      }
+      alignedChunkWriter.write(time);
+      timeDuplicateAlignedRowIndexList = null;
+    }
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
index e86fc96..1dc2446 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
@@ -22,7 +22,7 @@ import org.apache.iotdb.db.engine.querycontext.ReadOnlyMemChunk;
 import org.apache.iotdb.db.exception.WriteProcessException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.tsfile.read.common.TimeRange;
@@ -46,12 +46,16 @@ public interface IMemTable {
 
   void write(String deviceId, IMeasurementSchema schema, long insertTime, Object objectValue);
 
+  void writeAlignedRow(
+      String deviceId, IMeasurementSchema schema, long insertTime, Object[] objectValue);
   /**
    * write data in the range [start, end). Null value in each column values will be replaced by the
    * subsequent non-null value, e.g., {1, null, 3, null, 5} will be {1, 3, 5, null, 5}
    */
   void write(InsertTabletPlan insertTabletPlan, int start, int end);
 
+  void writeAlignedTablet(InsertTabletPlan insertTabletPlan, int start, int end);
+
   /** @return the number of points */
   long size();
 
@@ -85,6 +89,8 @@ public interface IMemTable {
    */
   void insert(InsertRowPlan insertRowPlan);
 
+  void insertAlignedRow(InsertRowPlan insertRowPlan);
+
   /**
    * insert tablet into this memtable. The rows to be inserted are in the range [start, end). Null
    * value in each column values will be replaced by the subsequent non-null value, e.g., {1, null,
@@ -97,12 +103,10 @@ public interface IMemTable {
   void insertTablet(InsertTabletPlan insertTabletPlan, int start, int end)
       throws WriteProcessException;
 
-  ReadOnlyMemChunk query(
-      String deviceId,
-      String measurement,
-      IMeasurementSchema schema,
-      long ttlLowerBound,
-      List<TimeRange> deletionList)
+  void insertAlignedTablet(InsertTabletPlan insertTabletPlan, int start, int end)
+      throws WriteProcessException;
+
+  ReadOnlyMemChunk query(PartialPath fullPath, long ttlLowerBound, List<TimeRange> deletionList)
       throws IOException, QueryProcessException, MetadataException;
 
   /** putBack all the memory resources. */
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IWritableMemChunk.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IWritableMemChunk.java
index b58f3b7..ee10ea1 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IWritableMemChunk.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IWritableMemChunk.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.db.utils.datastructure.TVList;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.BitMap;
+import org.apache.iotdb.tsfile.write.chunk.IChunkWriter;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 
 import java.util.List;
@@ -40,7 +41,7 @@ public interface IWritableMemChunk {
 
   void putBoolean(long t, boolean v);
 
-  void putVector(long t, Object[] v);
+  void putAlignedValue(long t, Object[] v, int[] columnIndexArray);
 
   void putLongs(long[] t, long[] v, BitMap bitMap, int start, int end);
 
@@ -54,16 +55,27 @@ public interface IWritableMemChunk {
 
   void putBooleans(long[] t, boolean[] v, BitMap bitMap, int start, int end);
 
-  void putVectors(long[] t, Object[] v, BitMap[] bitMaps, int start, int end);
+  void putAlignedValues(
+      long[] t, Object[] v, BitMap[] bitMaps, int[] columnIndexArray, int start, int end);
 
   void write(long insertTime, Object objectValue);
 
+  void writeAlignedValue(long insertTime, Object[] objectValue, IMeasurementSchema schema);
+
   /**
    * write data in the range [start, end). Null value in the valueList will be replaced by the
    * subsequent non-null value, e.g., {1, null, 3, null, 5} will be {1, 3, 5, null, 5}
    */
   void write(
-      long[] times, Object valueList, Object bitMaps, TSDataType dataType, int start, int end);
+      long[] times, Object valueList, BitMap bitMap, TSDataType dataType, int start, int end);
+
+  void writeAlignedValues(
+      long[] times,
+      Object[] valueList,
+      BitMap[] bitMaps,
+      IMeasurementSchema schema,
+      int start,
+      int end);
 
   long count();
 
@@ -90,18 +102,15 @@ public interface IWritableMemChunk {
    *
    * <p>the mechanism is just like copy on write
    *
-   * @param columnIndexList indices of queried columns in the full VectorTVList
    * @return sorted tv list
    */
-  TVList getSortedTvListForQuery(List<Integer> columnIndexList);
+  TVList getSortedTvListForQuery(List<IMeasurementSchema> schemaList);
 
   /**
    * served for flush requests. The logic is just same as getSortedTVListForQuery, but without add
    * reference count
-   *
-   * @return sorted tv list
    */
-  TVList getSortedTvListForFlush();
+  void sortTvListForFlush();
 
   default TVList getTVList() {
     return null;
@@ -115,5 +124,9 @@ public interface IWritableMemChunk {
   int delete(long lowerBound, long upperBound);
 
   // For delete one column in the vector
-  int delete(long lowerBound, long upperBound, int columnIndex);
+  int delete(long lowerBound, long upperBound, String measurementId);
+
+  IChunkWriter createIChunkWriter();
+
+  void encode(IChunkWriter chunkWriter);
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTable.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTable.java
index 922cb12..6915967 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTable.java
@@ -19,9 +19,8 @@
 
 package org.apache.iotdb.db.engine.memtable;
 
-import org.apache.iotdb.db.rescon.TVListAllocator;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -40,12 +39,12 @@ public class PrimitiveMemTable extends AbstractMemTable {
 
   @Override
   protected IWritableMemChunk genMemSeries(IMeasurementSchema schema) {
-    if (schema.getType() == TSDataType.VECTOR) {
-      return new WritableMemChunk(
-          schema,
-          TVListAllocator.getInstance().allocate(schema.getSubMeasurementsTSDataTypeList()));
-    }
-    return new WritableMemChunk(schema, TVListAllocator.getInstance().allocate(schema.getType()));
+    return new WritableMemChunk(schema);
+  }
+
+  @Override
+  protected IWritableMemChunk genAlignedMemSeries(IMeasurementSchema schema) {
+    return new AlignedWritableMemChunk((VectorMeasurementSchema) schema);
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/WritableMemChunk.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/WritableMemChunk.java
index feaf8ef..3b096ad 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/WritableMemChunk.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/WritableMemChunk.java
@@ -18,13 +18,19 @@
  */
 package org.apache.iotdb.db.engine.memtable;
 
+import org.apache.iotdb.db.rescon.TVListAllocator;
 import org.apache.iotdb.db.utils.datastructure.TVList;
 import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.BitMap;
+import org.apache.iotdb.tsfile.write.chunk.ChunkWriterImpl;
+import org.apache.iotdb.tsfile.write.chunk.IChunkWriter;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.util.List;
 
 public class WritableMemChunk implements IWritableMemChunk {
@@ -32,10 +38,11 @@ public class WritableMemChunk implements IWritableMemChunk {
   private IMeasurementSchema schema;
   private TVList list;
   private static final String UNSUPPORTED_TYPE = "Unsupported data type:";
+  private static final Logger LOGGER = LoggerFactory.getLogger(WritableMemChunk.class);
 
-  public WritableMemChunk(IMeasurementSchema schema, TVList list) {
+  public WritableMemChunk(IMeasurementSchema schema) {
     this.schema = schema;
-    this.list = list;
+    this.list = TVListAllocator.getInstance().allocate(schema.getType());
   }
 
   @Override
@@ -59,45 +66,43 @@ public class WritableMemChunk implements IWritableMemChunk {
       case TEXT:
         putBinary(insertTime, (Binary) objectValue);
         break;
-      case VECTOR:
-        putVector(insertTime, (Object[]) objectValue);
-        break;
       default:
         throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
     }
   }
 
   @Override
+  public void writeAlignedValue(long insertTime, Object[] objectValue, IMeasurementSchema schema) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + list.getDataType());
+  }
+
+  @Override
   public void write(
-      long[] times, Object valueList, Object bitMap, TSDataType dataType, int start, int end) {
+      long[] times, Object valueList, BitMap bitMap, TSDataType dataType, int start, int end) {
     switch (dataType) {
       case BOOLEAN:
         boolean[] boolValues = (boolean[]) valueList;
-        putBooleans(times, boolValues, (BitMap) bitMap, start, end);
+        putBooleans(times, boolValues, bitMap, start, end);
         break;
       case INT32:
         int[] intValues = (int[]) valueList;
-        putInts(times, intValues, (BitMap) bitMap, start, end);
+        putInts(times, intValues, bitMap, start, end);
         break;
       case INT64:
         long[] longValues = (long[]) valueList;
-        putLongs(times, longValues, (BitMap) bitMap, start, end);
+        putLongs(times, longValues, bitMap, start, end);
         break;
       case FLOAT:
         float[] floatValues = (float[]) valueList;
-        putFloats(times, floatValues, (BitMap) bitMap, start, end);
+        putFloats(times, floatValues, bitMap, start, end);
         break;
       case DOUBLE:
         double[] doubleValues = (double[]) valueList;
-        putDoubles(times, doubleValues, (BitMap) bitMap, start, end);
+        putDoubles(times, doubleValues, bitMap, start, end);
         break;
       case TEXT:
         Binary[] binaryValues = (Binary[]) valueList;
-        putBinaries(times, binaryValues, (BitMap) bitMap, start, end);
-        break;
-      case VECTOR:
-        Object[] vectorValues = (Object[]) valueList;
-        putVectors(times, vectorValues, (BitMap[]) bitMap, start, end);
+        putBinaries(times, binaryValues, bitMap, start, end);
         break;
       default:
         throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + dataType);
@@ -105,6 +110,17 @@ public class WritableMemChunk implements IWritableMemChunk {
   }
 
   @Override
+  public void writeAlignedValues(
+      long[] times,
+      Object[] valueList,
+      BitMap[] bitMaps,
+      IMeasurementSchema schema,
+      int start,
+      int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + list.getDataType());
+  }
+
+  @Override
   public void putLong(long t, long v) {
     list.putLong(t, v);
   }
@@ -135,8 +151,8 @@ public class WritableMemChunk implements IWritableMemChunk {
   }
 
   @Override
-  public void putVector(long t, Object[] v) {
-    list.putVector(t, v);
+  public void putAlignedValue(long t, Object[] v, int[] columnOrder) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
   }
 
   @Override
@@ -170,8 +186,9 @@ public class WritableMemChunk implements IWritableMemChunk {
   }
 
   @Override
-  public void putVectors(long[] t, Object[] v, BitMap[] bitMaps, int start, int end) {
-    list.putVectors(t, v, bitMaps, start, end);
+  public void putAlignedValues(
+      long[] t, Object[] v, BitMap[] bitMaps, int[] columnOrder, int start, int end) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
   }
 
   @Override
@@ -183,14 +200,8 @@ public class WritableMemChunk implements IWritableMemChunk {
   }
 
   @Override
-  public synchronized TVList getSortedTvListForQuery(List<Integer> columnIndexList) {
-    if (list.getDataType() != TSDataType.VECTOR) {
-      throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + list.getDataType());
-    }
-    sortTVList();
-    // increase reference count
-    list.increaseReferenceCount();
-    return list.getTvListByColumnIndex(columnIndexList);
+  public synchronized TVList getSortedTvListForQuery(List<IMeasurementSchema> measurementSchema) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + list.getDataType());
   }
 
   private void sortTVList() {
@@ -205,9 +216,8 @@ public class WritableMemChunk implements IWritableMemChunk {
   }
 
   @Override
-  public synchronized TVList getSortedTvListForFlush() {
+  public synchronized void sortTvListForFlush() {
     sortTVList();
-    return list;
   }
 
   @Override
@@ -251,10 +261,14 @@ public class WritableMemChunk implements IWritableMemChunk {
     return list.delete(lowerBound, upperBound);
   }
 
-  // TODO: THIS METHOLD IS FOR DELETING ONE COLUMN OF A VECTOR
   @Override
-  public int delete(long lowerBound, long upperBound, int columnIndex) {
-    return list.delete(lowerBound, upperBound, columnIndex);
+  public int delete(long lowerBound, long upperBound, String measurementId) {
+    throw new UnSupportedDataTypeException(UNSUPPORTED_TYPE + schema.getType());
+  }
+
+  @Override
+  public IChunkWriter createIChunkWriter() {
+    return new ChunkWriterImpl(schema);
   }
 
   @Override
@@ -288,4 +302,48 @@ public class WritableMemChunk implements IWritableMemChunk {
     }
     return out.toString();
   }
+
+  @Override
+  public void encode(IChunkWriter chunkWriter) {
+
+    ChunkWriterImpl chunkWriterImpl = (ChunkWriterImpl) chunkWriter;
+
+    for (int sortedRowIndex = 0; sortedRowIndex < list.size(); sortedRowIndex++) {
+      long time = list.getTime(sortedRowIndex);
+
+      // skip duplicated data
+      if ((sortedRowIndex + 1 < list.size() && (time == list.getTime(sortedRowIndex + 1)))) {
+        continue;
+      }
+
+      // store last point for SDT
+      if (sortedRowIndex + 1 == list.size()) {
+        ((ChunkWriterImpl) chunkWriterImpl).setLastPoint(true);
+      }
+
+      switch (schema.getType()) {
+        case BOOLEAN:
+          chunkWriterImpl.write(time, list.getBoolean(sortedRowIndex));
+          break;
+        case INT32:
+          chunkWriterImpl.write(time, list.getInt(sortedRowIndex));
+          break;
+        case INT64:
+          chunkWriterImpl.write(time, list.getLong(sortedRowIndex));
+          break;
+        case FLOAT:
+          chunkWriterImpl.write(time, list.getFloat(sortedRowIndex));
+          break;
+        case DOUBLE:
+          chunkWriterImpl.write(time, list.getDouble(sortedRowIndex));
+          break;
+        case TEXT:
+          chunkWriterImpl.write(time, list.getBinary(sortedRowIndex));
+          break;
+        default:
+          LOGGER.error("WritableMemChunk does not support data type: {}", schema.getType());
+          break;
+      }
+    }
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/modification/Deletion.java b/server/src/main/java/org/apache/iotdb/db/engine/modification/Deletion.java
index 5d41dbe..edbc767 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/modification/Deletion.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/modification/Deletion.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.engine.modification;
 
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 import java.util.Objects;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/modification/Modification.java b/server/src/main/java/org/apache/iotdb/db/engine/modification/Modification.java
index e72fb7c..3b113ef 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/modification/Modification.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/modification/Modification.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.engine.modification;
 
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 import java.util.Objects;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/modification/io/LocalTextModificationAccessor.java b/server/src/main/java/org/apache/iotdb/db/engine/modification/io/LocalTextModificationAccessor.java
index 0e07e1c..27cf34b 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/modification/io/LocalTextModificationAccessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/modification/io/LocalTextModificationAccessor.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.db.engine.modification.Deletion;
 import org.apache.iotdb.db.engine.modification.Modification;
 import org.apache.iotdb.db.engine.modification.utils.TracedBufferedReader;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
 
 import org.slf4j.Logger;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/querycontext/AlignedReadOnlyMemChunk.java b/server/src/main/java/org/apache/iotdb/db/engine/querycontext/AlignedReadOnlyMemChunk.java
new file mode 100644
index 0000000..ddc1cc7
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/engine/querycontext/AlignedReadOnlyMemChunk.java
@@ -0,0 +1,165 @@
+/*
+ * 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.iotdb.db.engine.querycontext;
+
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.query.reader.chunk.MemChunkLoader;
+import org.apache.iotdb.db.utils.datastructure.AlignedTVList;
+import org.apache.iotdb.db.utils.datastructure.TVList;
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.file.metadata.AlignedChunkMetadata;
+import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
+import org.apache.iotdb.tsfile.file.metadata.IChunkMetadata;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
+import org.apache.iotdb.tsfile.read.common.TimeRange;
+import org.apache.iotdb.tsfile.read.reader.IPointReader;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class AlignedReadOnlyMemChunk extends ReadOnlyMemChunk {
+
+  // deletion list for this chunk
+  private final List<TimeRange> deletionList;
+
+  private String measurementUid;
+  private TSDataType dataType;
+  private List<TSEncoding> encodingList;
+
+  private static final Logger logger = LoggerFactory.getLogger(AlignedReadOnlyMemChunk.class);
+
+  private int floatPrecision = TSFileDescriptor.getInstance().getConfig().getFloatPrecision();
+
+  private AlignedTVList chunkData;
+
+  private int chunkDataSize;
+
+  /**
+   * The constructor for Aligned type.
+   *
+   * @param schema VectorMeasurementSchema
+   * @param tvList VectorTvList
+   * @param size The Number of Chunk data points
+   * @param deletionList The timeRange of deletionList
+   */
+  public AlignedReadOnlyMemChunk(
+      IMeasurementSchema schema, TVList tvList, int size, List<TimeRange> deletionList)
+      throws IOException, QueryProcessException {
+    super();
+    this.measurementUid = schema.getMeasurementId();
+    this.dataType = schema.getType();
+
+    this.encodingList = ((VectorMeasurementSchema) schema).getSubMeasurementsTSEncodingList();
+    this.chunkData = (AlignedTVList) tvList;
+    this.chunkDataSize = size;
+    this.deletionList = deletionList;
+
+    this.chunkPointReader =
+        (chunkData).getAlignedIterator(floatPrecision, encodingList, chunkDataSize, deletionList);
+    initAlignedChunkMeta((VectorMeasurementSchema) schema);
+  }
+
+  private void initAlignedChunkMeta(VectorMeasurementSchema schema)
+      throws IOException, QueryProcessException {
+    AlignedTVList alignedChunkData = (AlignedTVList) chunkData;
+    List<String> measurementList = schema.getSubMeasurementsList();
+    List<TSDataType> dataTypeList = schema.getSubMeasurementsTSDataTypeList();
+    // time chunk
+    Statistics timeStatistics = Statistics.getStatsByType(TSDataType.VECTOR);
+    IChunkMetadata timeChunkMetadata =
+        new ChunkMetadata(measurementUid, TSDataType.VECTOR, 0, timeStatistics);
+    List<IChunkMetadata> valueChunkMetadataList = new ArrayList<>();
+    // update time chunk
+    for (int row = 0; row < alignedChunkData.size(); row++) {
+      timeStatistics.update(alignedChunkData.getTime(row));
+    }
+    timeStatistics.setEmpty(false);
+    // update value chunk
+    for (int column = 0; column < measurementList.size(); column++) {
+      Statistics valueStatistics = Statistics.getStatsByType(dataTypeList.get(column));
+      IChunkMetadata valueChunkMetadata =
+          new ChunkMetadata(
+              measurementList.get(column), dataTypeList.get(column), 0, valueStatistics);
+      valueChunkMetadataList.add(valueChunkMetadata);
+      if (alignedChunkData.getValues().get(column) == null) {
+        valueStatistics.setEmpty(true);
+        continue;
+      } else {
+        valueStatistics.setEmpty(false);
+      }
+      for (int row = 0; row < alignedChunkData.size(); row++) {
+        long time = alignedChunkData.getTime(row);
+        int originRowIndex = alignedChunkData.getValueIndex(row);
+        boolean isNull = alignedChunkData.isValueMarked(originRowIndex, column);
+        if (isNull) {
+          continue;
+        }
+        switch (dataTypeList.get(column)) {
+          case BOOLEAN:
+            valueStatistics.update(
+                time, alignedChunkData.getBooleanByValueIndex(originRowIndex, column));
+            break;
+          case TEXT:
+            valueStatistics.update(
+                time, alignedChunkData.getBinaryByValueIndex(originRowIndex, column));
+            break;
+          case FLOAT:
+            valueStatistics.update(
+                time, alignedChunkData.getFloatByValueIndex(originRowIndex, column));
+            break;
+          case INT32:
+            valueStatistics.update(
+                time, alignedChunkData.getIntByValueIndex(originRowIndex, column));
+            break;
+          case INT64:
+            valueStatistics.update(
+                time, alignedChunkData.getLongByValueIndex(originRowIndex, column));
+            break;
+          case DOUBLE:
+            valueStatistics.update(
+                time, alignedChunkData.getDoubleByValueIndex(originRowIndex, column));
+            break;
+          default:
+            throw new QueryProcessException("Unsupported data type:" + dataType);
+        }
+      }
+    }
+    IChunkMetadata vectorChunkMetadata =
+        new AlignedChunkMetadata(timeChunkMetadata, valueChunkMetadataList);
+    vectorChunkMetadata.setChunkLoader(new MemChunkLoader(this));
+    vectorChunkMetadata.setVersion(Long.MAX_VALUE);
+    cachedMetaData = vectorChunkMetadata;
+  }
+
+  @Override
+  public IPointReader getPointReader() {
+    chunkPointReader =
+        chunkData.getAlignedIterator(floatPrecision, encodingList, chunkDataSize, deletionList);
+    return chunkPointReader;
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/querycontext/ReadOnlyMemChunk.java b/server/src/main/java/org/apache/iotdb/db/engine/querycontext/ReadOnlyMemChunk.java
index bdd9e3b..b24313f 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/querycontext/ReadOnlyMemChunk.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/querycontext/ReadOnlyMemChunk.java
@@ -25,20 +25,17 @@ import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
 import org.apache.iotdb.tsfile.encoding.encoder.Encoder;
 import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
 import org.apache.iotdb.tsfile.file.metadata.IChunkMetadata;
-import org.apache.iotdb.tsfile.file.metadata.VectorChunkMetadata;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.read.common.TimeRange;
 import org.apache.iotdb.tsfile.read.reader.IPointReader;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -59,14 +56,18 @@ public class ReadOnlyMemChunk {
 
   private int floatPrecision = TSFileDescriptor.getInstance().getConfig().getFloatPrecision();
 
-  private IChunkMetadata cachedMetaData;
+  protected IChunkMetadata cachedMetaData;
 
   private TVList chunkData;
 
-  private IPointReader chunkPointReader;
+  protected IPointReader chunkPointReader;
 
   private int chunkDataSize;
 
+  public ReadOnlyMemChunk() {
+    this.deletionList = null;
+  }
+
   public ReadOnlyMemChunk(
       String measurementUid,
       TSDataType dataType,
@@ -143,142 +144,6 @@ public class ReadOnlyMemChunk {
     cachedMetaData = metaData;
   }
 
-  /**
-   * The constructor for VECTOR type.
-   *
-   * @param schema VectorMeasurementSchema
-   * @param tvList VectorTvList
-   * @param size The Number of Chunk data points
-   * @param deletionList The timeRange of deletionList
-   */
-  public ReadOnlyMemChunk(
-      IMeasurementSchema schema, TVList tvList, int size, List<TimeRange> deletionList)
-      throws IOException, QueryProcessException {
-    this.measurementUid = schema.getMeasurementId();
-    this.dataType = schema.getType();
-
-    this.chunkData = tvList;
-    this.chunkDataSize = size;
-    this.deletionList = deletionList;
-
-    this.chunkPointReader =
-        tvList.getIterator(floatPrecision, encoding, chunkDataSize, deletionList);
-    initVectorChunkMeta(schema);
-  }
-
-  @SuppressWarnings("squid:S3776") // high Cognitive Complexity
-  private void initVectorChunkMeta(IMeasurementSchema schema)
-      throws IOException, QueryProcessException {
-    Statistics timeStatistics = Statistics.getStatsByType(TSDataType.VECTOR);
-    IChunkMetadata timeChunkMetadata =
-        new ChunkMetadata(measurementUid, TSDataType.VECTOR, 0, timeStatistics);
-    List<IChunkMetadata> valueChunkMetadataList = new ArrayList<>();
-    Statistics[] valueStatistics = new Statistics[schema.getSubMeasurementsTSDataTypeList().size()];
-    for (int i = 0; i < schema.getSubMeasurementsTSDataTypeList().size(); i++) {
-      valueStatistics[i] =
-          Statistics.getStatsByType(schema.getSubMeasurementsTSDataTypeList().get(i));
-      IChunkMetadata valueChunkMetadata =
-          new ChunkMetadata(
-              schema.getSubMeasurementsList().get(i),
-              schema.getSubMeasurementsTSDataTypeList().get(i),
-              0,
-              valueStatistics[i]);
-      valueChunkMetadataList.add(valueChunkMetadata);
-    }
-    if (!isEmpty()) {
-      IPointReader iterator =
-          chunkData.getIterator(floatPrecision, encoding, chunkDataSize, deletionList);
-      while (iterator.hasNextTimeValuePair()) {
-        TimeValuePair timeValuePair = iterator.nextTimeValuePair();
-        timeStatistics.update(timeValuePair.getTimestamp());
-        if (schema.getSubMeasurementsTSDataTypeList().size() == 1) {
-          updateValueStatisticsForSingleColumn(schema, valueStatistics, timeValuePair);
-        } else {
-          updateValueStatistics(schema, valueStatistics, timeValuePair);
-        }
-      }
-    }
-    timeStatistics.setEmpty(isEmpty());
-    for (Statistics valueStatistic : valueStatistics) {
-      valueStatistic.setEmpty(isEmpty());
-    }
-    IChunkMetadata vectorChunkMetadata =
-        new VectorChunkMetadata(timeChunkMetadata, valueChunkMetadataList);
-    vectorChunkMetadata.setChunkLoader(new MemChunkLoader(this));
-    vectorChunkMetadata.setVersion(Long.MAX_VALUE);
-    cachedMetaData = vectorChunkMetadata;
-  }
-
-  // When query one measurement in a Vector, the timeValuePair is not a vector type
-  private void updateValueStatisticsForSingleColumn(
-      IMeasurementSchema schema, Statistics[] valueStatistics, TimeValuePair timeValuePair)
-      throws QueryProcessException {
-    switch (schema.getSubMeasurementsTSDataTypeList().get(0)) {
-      case BOOLEAN:
-        valueStatistics[0].update(
-            timeValuePair.getTimestamp(), timeValuePair.getValue().getBoolean());
-        break;
-      case TEXT:
-        valueStatistics[0].update(
-            timeValuePair.getTimestamp(), timeValuePair.getValue().getBinary());
-        break;
-      case FLOAT:
-        valueStatistics[0].update(
-            timeValuePair.getTimestamp(), timeValuePair.getValue().getFloat());
-        break;
-      case INT32:
-        valueStatistics[0].update(timeValuePair.getTimestamp(), timeValuePair.getValue().getInt());
-        break;
-      case INT64:
-        valueStatistics[0].update(timeValuePair.getTimestamp(), timeValuePair.getValue().getLong());
-        break;
-      case DOUBLE:
-        valueStatistics[0].update(
-            timeValuePair.getTimestamp(), timeValuePair.getValue().getDouble());
-        break;
-      default:
-        throw new QueryProcessException("Unsupported data type:" + dataType);
-    }
-  }
-
-  private void updateValueStatistics(
-      IMeasurementSchema schema, Statistics[] valueStatistics, TimeValuePair timeValuePair)
-      throws QueryProcessException {
-    for (int i = 0; i < schema.getSubMeasurementsTSDataTypeList().size(); i++) {
-      if (timeValuePair.getValue().getVector()[i] == null) {
-        continue;
-      }
-      switch (schema.getSubMeasurementsTSDataTypeList().get(i)) {
-        case BOOLEAN:
-          valueStatistics[i].update(
-              timeValuePair.getTimestamp(), timeValuePair.getValue().getVector()[i].getBoolean());
-          break;
-        case TEXT:
-          valueStatistics[i].update(
-              timeValuePair.getTimestamp(), timeValuePair.getValue().getVector()[i].getBinary());
-          break;
-        case FLOAT:
-          valueStatistics[i].update(
-              timeValuePair.getTimestamp(), timeValuePair.getValue().getVector()[i].getFloat());
-          break;
-        case INT32:
-          valueStatistics[i].update(
-              timeValuePair.getTimestamp(), timeValuePair.getValue().getVector()[i].getInt());
-          break;
-        case INT64:
-          valueStatistics[i].update(
-              timeValuePair.getTimestamp(), timeValuePair.getValue().getVector()[i].getLong());
-          break;
-        case DOUBLE:
-          valueStatistics[i].update(
-              timeValuePair.getTimestamp(), timeValuePair.getValue().getVector()[i].getDouble());
-          break;
-        default:
-          throw new QueryProcessException("Unsupported data type:" + dataType);
-      }
-    }
-  }
-
   public TSDataType getDataType() {
     return dataType;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/selectinto/InsertTabletPlanGenerator.java b/server/src/main/java/org/apache/iotdb/db/engine/selectinto/InsertTabletPlanGenerator.java
index f0e594e..b0c83b5 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/selectinto/InsertTabletPlanGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/selectinto/InsertTabletPlanGenerator.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.engine.selectinto;
 
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/selectinto/InsertTabletPlansIterator.java b/server/src/main/java/org/apache/iotdb/db/engine/selectinto/InsertTabletPlansIterator.java
index 95051ff..20ba4a0 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/selectinto/InsertTabletPlansIterator.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/selectinto/InsertTabletPlansIterator.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.engine.selectinto;
 
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.db.qp.physical.crud.QueryPlan;
 import org.apache.iotdb.db.query.expression.ResultColumn;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
index b4cebdb..04604c9 100755
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
@@ -56,9 +56,8 @@ import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.OutOfTTLException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.VectorPartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowsOfOneDevicePlan;
@@ -83,7 +82,6 @@ import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
 import org.apache.iotdb.tsfile.fileSystem.fsFactory.FSFactory;
 import org.apache.iotdb.tsfile.read.filter.basic.Filter;
 import org.apache.iotdb.tsfile.utils.Pair;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
 
 import org.apache.commons.io.FileUtils;
@@ -908,7 +906,7 @@ public class StorageGroupProcessor {
           insertRowPlan.getTime()
               > partitionLatestFlushedTimeForEachDevice
                   .get(timePartitionId)
-                  .getOrDefault(insertRowPlan.getPrefixPath().getFullPath(), Long.MIN_VALUE);
+                  .getOrDefault(insertRowPlan.getDeviceId().getFullPath(), Long.MIN_VALUE);
 
       // is unsequence and user set config to discard out of order data
       if (!isSequence
@@ -980,8 +978,7 @@ public class StorageGroupProcessor {
       long lastFlushTime =
           partitionLatestFlushedTimeForEachDevice
               .computeIfAbsent(beforeTimePartition, id -> new HashMap<>())
-              .computeIfAbsent(
-                  insertTabletPlan.getPrefixPath().getFullPath(), id -> Long.MIN_VALUE);
+              .computeIfAbsent(insertTabletPlan.getDeviceId().getFullPath(), id -> Long.MIN_VALUE);
       // if is sequence
       boolean isSequence = false;
       while (loc < insertTabletPlan.getRowCount()) {
@@ -1004,7 +1001,7 @@ public class StorageGroupProcessor {
               partitionLatestFlushedTimeForEachDevice
                   .computeIfAbsent(beforeTimePartition, id -> new HashMap<>())
                   .computeIfAbsent(
-                      insertTabletPlan.getPrefixPath().getFullPath(), id -> Long.MIN_VALUE);
+                      insertTabletPlan.getDeviceId().getFullPath(), id -> Long.MIN_VALUE);
           isSequence = false;
         }
         // still in this partition
@@ -1036,7 +1033,7 @@ public class StorageGroupProcessor {
       }
       long globalLatestFlushedTime =
           globalLatestFlushedTimeForEachDevice.getOrDefault(
-              insertTabletPlan.getPrefixPath().getFullPath(), Long.MIN_VALUE);
+              insertTabletPlan.getDeviceId().getFullPath(), Long.MIN_VALUE);
       tryToUpdateBatchInsertLastCache(insertTabletPlan, globalLatestFlushedTime);
 
       if (!noFailure) {
@@ -1106,12 +1103,11 @@ public class StorageGroupProcessor {
     if (sequence
         && latestTimeForEachDevice
                 .get(timePartitionId)
-                .getOrDefault(insertTabletPlan.getPrefixPath().getFullPath(), Long.MIN_VALUE)
+                .getOrDefault(insertTabletPlan.getDeviceId().getFullPath(), Long.MIN_VALUE)
             < insertTabletPlan.getTimes()[end - 1]) {
       latestTimeForEachDevice
           .get(timePartitionId)
-          .put(
-              insertTabletPlan.getPrefixPath().getFullPath(), insertTabletPlan.getTimes()[end - 1]);
+          .put(insertTabletPlan.getDeviceId().getFullPath(), insertTabletPlan.getTimes()[end - 1]);
     }
 
     // check memtable size and may async try to flush the work memtable
@@ -1132,38 +1128,16 @@ public class StorageGroupProcessor {
       }
       // Update cached last value with high priority
       if (mNodes[i] == null) {
-        if (plan.isAligned()) {
-          IoTDB.metaManager.updateLastCache(
-              new VectorPartialPath(plan.getPrefixPath(), plan.getMeasurements()[i]),
-              plan.composeLastTimeValuePair(i),
-              true,
-              latestFlushedTime);
-        } else {
-          IoTDB.metaManager.updateLastCache(
-              plan.getPrefixPath().concatNode(plan.getMeasurements()[i]),
-              plan.composeLastTimeValuePair(i),
-              true,
-              latestFlushedTime);
-        }
+        IoTDB.metaManager.updateLastCache(
+            plan.getDeviceId().concatNode(plan.getMeasurements()[i]),
+            plan.composeLastTimeValuePair(i),
+            true,
+            latestFlushedTime);
       } else {
-        if (plan.isAligned()) {
-          // vector lastCache update need subMeasurement
-          IoTDB.metaManager.updateLastCache(
-              mNodes[i].getAsMultiMeasurementMNode(),
-              plan.getMeasurements()[i],
-              plan.composeLastTimeValuePair(i),
-              true,
-              latestFlushedTime);
-
-        } else {
-          // in stand alone version, the seriesPath is not needed, just use measurementMNodes[i] to
-          // update last cache
-          IoTDB.metaManager.updateLastCache(
-              mNodes[i].getAsUnaryMeasurementMNode(),
-              plan.composeLastTimeValuePair(i),
-              true,
-              latestFlushedTime);
-        }
+        // in stand alone version, the seriesPath is not needed, just use measurementMNodes[i] to
+        // update last cache
+        IoTDB.metaManager.updateLastCache(
+            mNodes[i], plan.composeLastTimeValuePair(i), true, latestFlushedTime);
       }
     }
   }
@@ -1181,16 +1155,16 @@ public class StorageGroupProcessor {
     // try to update the latest time of the device of this tsRecord
     if (latestTimeForEachDevice
             .get(timePartitionId)
-            .getOrDefault(insertRowPlan.getPrefixPath().getFullPath(), Long.MIN_VALUE)
+            .getOrDefault(insertRowPlan.getDeviceId().getFullPath(), Long.MIN_VALUE)
         < insertRowPlan.getTime()) {
       latestTimeForEachDevice
           .get(timePartitionId)
-          .put(insertRowPlan.getPrefixPath().getFullPath(), insertRowPlan.getTime());
+          .put(insertRowPlan.getDeviceId().getFullPath(), insertRowPlan.getTime());
     }
 
     long globalLatestFlushTime =
         globalLatestFlushedTimeForEachDevice.getOrDefault(
-            insertRowPlan.getPrefixPath().getFullPath(), Long.MIN_VALUE);
+            insertRowPlan.getDeviceId().getFullPath(), Long.MIN_VALUE);
 
     tryToUpdateInsertLastCache(insertRowPlan, globalLatestFlushTime);
 
@@ -1211,37 +1185,16 @@ public class StorageGroupProcessor {
       }
       // Update cached last value with high priority
       if (mNodes[i] == null) {
-        if (plan.isAligned()) {
-          IoTDB.metaManager.updateLastCache(
-              new VectorPartialPath(plan.getPrefixPath(), plan.getMeasurements()[i]),
-              plan.composeTimeValuePair(i),
-              true,
-              latestFlushedTime);
-        } else {
-          IoTDB.metaManager.updateLastCache(
-              plan.getPrefixPath().concatNode(plan.getMeasurements()[i]),
-              plan.composeTimeValuePair(i),
-              true,
-              latestFlushedTime);
-        }
+        IoTDB.metaManager.updateLastCache(
+            plan.getDeviceId().concatNode(plan.getMeasurements()[i]),
+            plan.composeTimeValuePair(i),
+            true,
+            latestFlushedTime);
       } else {
-        if (plan.isAligned()) {
-          // vector lastCache update need subSensor path
-          IoTDB.metaManager.updateLastCache(
-              mNodes[i].getAsMultiMeasurementMNode(),
-              plan.getMeasurements()[i],
-              plan.composeTimeValuePair(i),
-              true,
-              latestFlushedTime);
-        } else {
-          // in stand alone version, the seriesPath is not needed, just use measurementMNodes[i] to
-          // update last cache
-          IoTDB.metaManager.updateLastCache(
-              mNodes[i].getAsUnaryMeasurementMNode(),
-              plan.composeTimeValuePair(i),
-              true,
-              latestFlushedTime);
-        }
+        // in stand alone version, the seriesPath is not needed, just use measurementMNodes[i] to
+        // update last cache
+        IoTDB.metaManager.updateLastCache(
+            mNodes[i], plan.composeTimeValuePair(i), true, latestFlushedTime);
       }
     }
   }
@@ -1860,8 +1813,6 @@ public class StorageGroupProcessor {
           (timeFilter == null ? "null" : timeFilter));
     }
 
-    IMeasurementSchema schema = IoTDB.metaManager.getSeriesSchema(fullPath);
-
     List<TsFileResource> tsfileResourcesForQuery = new ArrayList<>();
     long ttlLowerBound =
         dataTTL != Long.MAX_VALUE ? System.currentTimeMillis() - dataTTL : Long.MIN_VALUE;
@@ -1892,7 +1843,7 @@ public class StorageGroupProcessor {
         } else {
           tsFileResource
               .getUnsealedFileProcessor()
-              .query(deviceId, fullPath.getMeasurement(), schema, context, tsfileResourcesForQuery);
+              .query(fullPath, context, tsfileResourcesForQuery);
         }
       } catch (IOException e) {
         throw new MetadataException(e);
@@ -3216,7 +3167,7 @@ public class StorageGroupProcessor {
               plan.getTime()
                   > partitionLatestFlushedTimeForEachDevice
                       .get(timePartitionId)
-                      .getOrDefault(plan.getPrefixPath().getFullPath(), Long.MIN_VALUE);
+                      .getOrDefault(plan.getDeviceId().getFullPath(), Long.MIN_VALUE);
         }
         // is unsequence and user set config to discard out of order data
         if (!isSequence
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
index 4318a5b..93d020f 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
@@ -19,7 +19,6 @@
 package org.apache.iotdb.db.engine.storagegroup;
 
 import org.apache.iotdb.db.conf.IoTDBConfig;
-import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.conf.adapter.CompressionRatio;
 import org.apache.iotdb.db.engine.StorageEngine;
@@ -28,11 +27,11 @@ import org.apache.iotdb.db.engine.flush.FlushListener;
 import org.apache.iotdb.db.engine.flush.FlushManager;
 import org.apache.iotdb.db.engine.flush.MemTableFlushTask;
 import org.apache.iotdb.db.engine.flush.NotifyFlushMemTable;
+import org.apache.iotdb.db.engine.memtable.AlignedWritableMemChunk;
 import org.apache.iotdb.db.engine.memtable.IMemTable;
 import org.apache.iotdb.db.engine.memtable.PrimitiveMemTable;
 import org.apache.iotdb.db.engine.modification.Deletion;
 import org.apache.iotdb.db.engine.modification.Modification;
-import org.apache.iotdb.db.engine.modification.ModificationFile;
 import org.apache.iotdb.db.engine.querycontext.ReadOnlyMemChunk;
 import org.apache.iotdb.db.engine.storagegroup.StorageGroupProcessor.UpdateEndTimeCallBack;
 import org.apache.iotdb.db.exception.TsFileProcessorException;
@@ -40,7 +39,8 @@ import org.apache.iotdb.db.exception.WriteProcessException;
 import org.apache.iotdb.db.exception.WriteProcessRejectException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -48,7 +48,7 @@ import org.apache.iotdb.db.rescon.MemTableManager;
 import org.apache.iotdb.db.rescon.PrimitiveArrayManager;
 import org.apache.iotdb.db.rescon.SystemInfo;
 import org.apache.iotdb.db.utils.MemUtils;
-import org.apache.iotdb.db.utils.QueryUtils;
+import org.apache.iotdb.db.utils.datastructure.AlignedTVList;
 import org.apache.iotdb.db.utils.datastructure.TVList;
 import org.apache.iotdb.db.writelog.WALFlushListener;
 import org.apache.iotdb.db.writelog.manager.MultiFileLogNodeManager;
@@ -58,13 +58,10 @@ import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.service.rpc.thrift.TSStatus;
 import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
 import org.apache.iotdb.tsfile.file.metadata.IChunkMetadata;
-import org.apache.iotdb.tsfile.file.metadata.VectorChunkMetadata;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.common.TimeRange;
 import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.Pair;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
 
 import org.slf4j.Logger;
@@ -214,7 +211,11 @@ public class TsFileProcessor {
 
     long[] memIncrements = null;
     if (enableMemControl) {
-      memIncrements = checkMemCostAndAddToTspInfo(insertRowPlan);
+      if (insertRowPlan.isAligned()) {
+        memIncrements = checkAlignedMemCostAndAddToTspInfo(insertRowPlan);
+      } else {
+        memIncrements = checkMemCostAndAddToTspInfo(insertRowPlan);
+      }
     }
 
     if (IoTDBDescriptor.getInstance().getConfig().isEnableWal()) {
@@ -232,16 +233,20 @@ public class TsFileProcessor {
       }
     }
 
-    workMemTable.insert(insertRowPlan);
+    if (insertRowPlan.isAligned()) {
+      workMemTable.insertAlignedRow(insertRowPlan);
+    } else {
+      workMemTable.insert(insertRowPlan);
+    }
 
     // update start time of this memtable
     tsFileResource.updateStartTime(
-        insertRowPlan.getPrefixPath().getFullPath(), insertRowPlan.getTime());
+        insertRowPlan.getDeviceId().getFullPath(), insertRowPlan.getTime());
     // for sequence tsfile, we update the endTime only when the file is prepared to be closed.
     // for unsequence tsfile, we have to update the endTime for each insertion.
     if (!sequence) {
       tsFileResource.updateEndTime(
-          insertRowPlan.getPrefixPath().getFullPath(), insertRowPlan.getTime());
+          insertRowPlan.getDeviceId().getFullPath(), insertRowPlan.getTime());
     }
     tsFileResource.updatePlanIndexes(insertRowPlan.getIndex());
   }
@@ -272,7 +277,11 @@ public class TsFileProcessor {
     long[] memIncrements = null;
     try {
       if (enableMemControl) {
-        memIncrements = checkMemCostAndAddToTspInfo(insertTabletPlan, start, end);
+        if (insertTabletPlan.isAligned()) {
+          memIncrements = checkAlignedMemCostAndAddToTsp(insertTabletPlan, start, end);
+        } else {
+          memIncrements = checkMemCostAndAddToTspInfo(insertTabletPlan, start, end);
+        }
       }
     } catch (WriteProcessException e) {
       for (int i = start; i < end; i++) {
@@ -298,7 +307,11 @@ public class TsFileProcessor {
     }
 
     try {
-      workMemTable.insertTablet(insertTabletPlan, start, end);
+      if (insertTabletPlan.isAligned()) {
+        workMemTable.insertAlignedTablet(insertTabletPlan, start, end);
+      } else {
+        workMemTable.insertTablet(insertTabletPlan, start, end);
+      }
     } catch (WriteProcessException e) {
       for (int i = start; i < end; i++) {
         results[i] = RpcUtils.getStatus(TSStatusCode.INTERNAL_SERVER_ERROR, e.getMessage());
@@ -310,13 +323,13 @@ public class TsFileProcessor {
       results[i] = RpcUtils.SUCCESS_STATUS;
     }
     tsFileResource.updateStartTime(
-        insertTabletPlan.getPrefixPath().getFullPath(), insertTabletPlan.getTimes()[start]);
+        insertTabletPlan.getDeviceId().getFullPath(), insertTabletPlan.getTimes()[start]);
 
     // for sequence tsfile, we update the endTime only when the file is prepared to be closed.
     // for unsequence tsfile, we have to update the endTime for each insertion.
     if (!sequence) {
       tsFileResource.updateEndTime(
-          insertTabletPlan.getPrefixPath().getFullPath(), insertTabletPlan.getTimes()[end - 1]);
+          insertTabletPlan.getDeviceId().getFullPath(), insertTabletPlan.getTimes()[end - 1]);
     }
     tsFileResource.updatePlanIndexes(insertTabletPlan.getIndex());
   }
@@ -328,45 +341,78 @@ public class TsFileProcessor {
     long memTableIncrement = 0L;
     long textDataIncrement = 0L;
     long chunkMetadataIncrement = 0L;
-    String deviceId = insertRowPlan.getPrefixPath().getFullPath();
-    int columnIndex = 0;
-    for (int i = 0; i < insertRowPlan.getMeasurementMNodes().length; i++) {
+    String deviceId = insertRowPlan.getDeviceId().getFullPath();
+    for (int i = 0; i < insertRowPlan.getDataTypes().length; i++) {
       // skip failed Measurements
-      if (insertRowPlan.getDataTypes()[columnIndex] == null
-          || insertRowPlan.getMeasurements()[i] == null) {
-        columnIndex++;
+      if (insertRowPlan.getDataTypes()[i] == null || insertRowPlan.getMeasurements()[i] == null) {
         continue;
       }
       if (workMemTable.checkIfChunkDoesNotExist(deviceId, insertRowPlan.getMeasurements()[i])) {
         // ChunkMetadataIncrement
-        IMeasurementSchema schema = insertRowPlan.getMeasurementMNodes()[i].getSchema();
-        if (insertRowPlan.isAligned()) {
-          chunkMetadataIncrement +=
-              schema.getSubMeasurementsTSDataTypeList().size()
-                  * ChunkMetadata.calculateRamSize(
-                      schema.getSubMeasurementsList().get(0),
-                      schema.getSubMeasurementsTSDataTypeList().get(0));
-          memTableIncrement +=
-              TVList.vectorTvListArrayMemSize(schema.getSubMeasurementsTSDataTypeList());
-        } else {
-          chunkMetadataIncrement +=
-              ChunkMetadata.calculateRamSize(
-                  insertRowPlan.getMeasurements()[i], insertRowPlan.getDataTypes()[columnIndex]);
-          memTableIncrement += TVList.tvListArrayMemSize(insertRowPlan.getDataTypes()[columnIndex]);
-        }
+        chunkMetadataIncrement +=
+            ChunkMetadata.calculateRamSize(
+                insertRowPlan.getMeasurements()[i], insertRowPlan.getDataTypes()[i]);
+        memTableIncrement += TVList.tvListArrayMemSize(insertRowPlan.getDataTypes()[i]);
       } else {
         // here currentChunkPointNum >= 1
         int currentChunkPointNum =
             workMemTable.getCurrentChunkPointNum(deviceId, insertRowPlan.getMeasurements()[i]);
         memTableIncrement +=
             (currentChunkPointNum % PrimitiveArrayManager.ARRAY_SIZE) == 0
-                ? TVList.tvListArrayMemSize(insertRowPlan.getDataTypes()[columnIndex])
+                ? TVList.tvListArrayMemSize(insertRowPlan.getDataTypes()[i])
                 : 0;
       }
       // TEXT data mem size
-      if (insertRowPlan.getDataTypes()[columnIndex] == TSDataType.TEXT) {
-        textDataIncrement +=
-            MemUtils.getBinarySize((Binary) insertRowPlan.getValues()[columnIndex]);
+      if (insertRowPlan.getDataTypes()[i] == TSDataType.TEXT) {
+        textDataIncrement += MemUtils.getBinarySize((Binary) insertRowPlan.getValues()[i]);
+      }
+    }
+    updateMemoryInfo(memTableIncrement, chunkMetadataIncrement, textDataIncrement);
+    return new long[] {memTableIncrement, textDataIncrement, chunkMetadataIncrement};
+  }
+
+  @SuppressWarnings("squid:S3776") // high Cognitive Complexity
+  private long[] checkAlignedMemCostAndAddToTspInfo(InsertRowPlan insertRowPlan)
+      throws WriteProcessException {
+    // memory of increased PrimitiveArray and TEXT values, e.g., add a long[128], add 128*8
+    long memTableIncrement = 0L;
+    long textDataIncrement = 0L;
+    long chunkMetadataIncrement = 0L;
+    AlignedWritableMemChunk vectorMemChunk = null;
+    String deviceId = insertRowPlan.getDeviceId().getFullPath();
+    if (workMemTable.checkIfChunkDoesNotExist(deviceId, AlignedPath.VECTOR_PLACEHOLDER)) {
+      // ChunkMetadataIncrement
+      chunkMetadataIncrement +=
+          ChunkMetadata.calculateRamSize(AlignedPath.VECTOR_PLACEHOLDER, TSDataType.VECTOR)
+              * insertRowPlan.getDataTypes().length;
+      memTableIncrement += AlignedTVList.alignedTvListArrayMemSize(insertRowPlan.getDataTypes());
+    } else {
+      // here currentChunkPointNum >= 1
+      int currentChunkPointNum =
+          workMemTable.getCurrentChunkPointNum(deviceId, AlignedPath.VECTOR_PLACEHOLDER);
+      memTableIncrement +=
+          (currentChunkPointNum % PrimitiveArrayManager.ARRAY_SIZE) == 0
+              ? AlignedTVList.alignedTvListArrayMemSize(insertRowPlan.getDataTypes())
+              : 0;
+      vectorMemChunk =
+          ((AlignedWritableMemChunk)
+              workMemTable.getMemTableMap().get(deviceId).get(AlignedPath.VECTOR_PLACEHOLDER));
+    }
+    for (int i = 0; i < insertRowPlan.getDataTypes().length; i++) {
+      // skip failed Measurements
+      if (insertRowPlan.getDataTypes()[i] == null || insertRowPlan.getMeasurements()[i] == null) {
+        continue;
+      }
+      // extending the column of aligned mem chunk
+      if (vectorMemChunk != null
+          && !vectorMemChunk.containsMeasurement(insertRowPlan.getMeasurements()[i])) {
+        memTableIncrement +=
+            (vectorMemChunk.alignedListSize() / PrimitiveArrayManager.ARRAY_SIZE + 1)
+                * insertRowPlan.getDataTypes()[i].getDataTypeSize();
+      }
+      // TEXT data mem size
+      if (insertRowPlan.getDataTypes()[i] == TSDataType.TEXT) {
+        textDataIncrement += MemUtils.getBinarySize((Binary) insertRowPlan.getValues()[i]);
       }
     }
     updateMemoryInfo(memTableIncrement, chunkMetadataIncrement, textDataIncrement);
@@ -380,36 +426,17 @@ public class TsFileProcessor {
     }
     long[] memIncrements = new long[3]; // memTable, text, chunk metadata
 
-    String deviceId = insertTabletPlan.getPrefixPath().getFullPath();
+    String deviceId = insertTabletPlan.getDeviceId().getFullPath();
 
-    int columnIndex = 0;
-    for (int i = 0; i < insertTabletPlan.getMeasurementMNodes().length; i++) {
-      // for aligned timeseries
-      if (insertTabletPlan.isAligned()) {
-        if (insertTabletPlan.getMeasurementMNodes()[i] == null) {
-          continue;
-        }
-        VectorMeasurementSchema vectorSchema =
-            (VectorMeasurementSchema) insertTabletPlan.getMeasurementMNodes()[i].getSchema();
-        Object[] columns = new Object[vectorSchema.getSubMeasurementsList().size()];
-        for (int j = 0; j < vectorSchema.getSubMeasurementsList().size(); j++) {
-          columns[j] = insertTabletPlan.getColumns()[columnIndex++];
-        }
-        updateVectorMemCost(vectorSchema, deviceId, start, end, memIncrements, columns);
-        break;
-      }
-      // for non aligned
-      else {
-        // skip failed Measurements
-        TSDataType dataType = insertTabletPlan.getDataTypes()[columnIndex];
-        String measurement = insertTabletPlan.getMeasurements()[i];
-        Object column = insertTabletPlan.getColumns()[columnIndex];
-        columnIndex++;
-        if (dataType == null || column == null || measurement == null) {
-          continue;
-        }
-        updateMemCost(dataType, measurement, deviceId, start, end, memIncrements, column);
+    for (int i = 0; i < insertTabletPlan.getDataTypes().length; i++) {
+      // skip failed Measurements
+      TSDataType dataType = insertTabletPlan.getDataTypes()[i];
+      String measurement = insertTabletPlan.getMeasurements()[i];
+      Object column = insertTabletPlan.getColumns()[i];
+      if (dataType == null || column == null || measurement == null) {
+        continue;
       }
+      updateMemCost(dataType, measurement, deviceId, start, end, memIncrements, column);
     }
     long memTableIncrement = memIncrements[0];
     long textDataIncrement = memIncrements[1];
@@ -418,6 +445,30 @@ public class TsFileProcessor {
     return memIncrements;
   }
 
+  private long[] checkAlignedMemCostAndAddToTsp(
+      InsertTabletPlan insertTabletPlan, int start, int end) throws WriteProcessException {
+    if (start >= end) {
+      return new long[] {0, 0, 0};
+    }
+    long[] memIncrements = new long[3]; // memTable, text, chunk metadata
+
+    String deviceId = insertTabletPlan.getDeviceId().getFullPath();
+
+    updateAlignedMemCost(
+        insertTabletPlan.getDataTypes(),
+        deviceId,
+        insertTabletPlan.getMeasurements(),
+        start,
+        end,
+        memIncrements,
+        insertTabletPlan.getColumns());
+    long memTableIncrement = memIncrements[0];
+    long textDataIncrement = memIncrements[1];
+    long chunkMetadataIncrement = memIncrements[2];
+    updateMemoryInfo(memTableIncrement, chunkMetadataIncrement, textDataIncrement);
+    return memIncrements;
+  }
+
   private void updateMemCost(
       TSDataType dataType,
       String measurement,
@@ -455,43 +506,59 @@ public class TsFileProcessor {
     }
   }
 
-  private void updateVectorMemCost(
-      VectorMeasurementSchema vectorSchema,
+  private void updateAlignedMemCost(
+      TSDataType[] dataTypes,
       String deviceId,
+      String[] measurementIds,
       int start,
       int end,
       long[] memIncrements,
       Object[] columns) {
+    AlignedWritableMemChunk vectorMemChunk = null;
     // memIncrements = [memTable, text, chunk metadata] respectively
-
-    List<String> measurementIds = vectorSchema.getSubMeasurementsList();
-    List<TSDataType> dataTypes = vectorSchema.getSubMeasurementsTSDataTypeList();
-    if (workMemTable.checkIfChunkDoesNotExist(deviceId, vectorSchema.getMeasurementId())) {
+    if (workMemTable.checkIfChunkDoesNotExist(deviceId, AlignedPath.VECTOR_PLACEHOLDER)) {
       // ChunkMetadataIncrement
       memIncrements[2] +=
-          dataTypes.size()
-              * ChunkMetadata.calculateRamSize(measurementIds.get(0), dataTypes.get(0));
+          dataTypes.length
+              * ChunkMetadata.calculateRamSize(AlignedPath.VECTOR_PLACEHOLDER, TSDataType.VECTOR);
       memIncrements[0] +=
           ((end - start) / PrimitiveArrayManager.ARRAY_SIZE + 1)
-              * TVList.vectorTvListArrayMemSize(dataTypes);
+              * AlignedTVList.alignedTvListArrayMemSize(dataTypes);
     } else {
       int currentChunkPointNum =
-          workMemTable.getCurrentChunkPointNum(deviceId, vectorSchema.getMeasurementId());
+          workMemTable.getCurrentChunkPointNum(deviceId, AlignedPath.VECTOR_PLACEHOLDER);
       if (currentChunkPointNum % PrimitiveArrayManager.ARRAY_SIZE == 0) {
         memIncrements[0] +=
             ((end - start) / PrimitiveArrayManager.ARRAY_SIZE + 1)
-                * TVList.vectorTvListArrayMemSize(dataTypes);
+                * AlignedTVList.alignedTvListArrayMemSize(dataTypes);
       } else {
         int acquireArray =
             (end - start - 1 + (currentChunkPointNum % PrimitiveArrayManager.ARRAY_SIZE))
                 / PrimitiveArrayManager.ARRAY_SIZE;
         memIncrements[0] +=
-            acquireArray == 0 ? 0 : acquireArray * TVList.vectorTvListArrayMemSize(dataTypes);
+            acquireArray == 0
+                ? 0
+                : acquireArray * AlignedTVList.alignedTvListArrayMemSize(dataTypes);
       }
+      vectorMemChunk =
+          ((AlignedWritableMemChunk)
+              workMemTable.getMemTableMap().get(deviceId).get(AlignedPath.VECTOR_PLACEHOLDER));
     }
-    // TEXT data size
-    for (int i = 0; i < dataTypes.size(); i++) {
-      if (dataTypes.get(i) == TSDataType.TEXT) {
+    for (int i = 0; i < dataTypes.length; i++) {
+      TSDataType dataType = dataTypes[i];
+      String measurement = measurementIds[i];
+      Object column = columns[i];
+      if (dataType == null || column == null || measurement == null) {
+        continue;
+      }
+      // extending the column of aligned mem chunk
+      if (vectorMemChunk != null && !vectorMemChunk.containsMeasurement(measurementIds[i])) {
+        memIncrements[0] +=
+            (vectorMemChunk.alignedListSize() / PrimitiveArrayManager.ARRAY_SIZE + 1)
+                * dataType.getDataTypeSize();
+      }
+      // TEXT data size
+      if (dataType == TSDataType.TEXT) {
         Binary[] binColumn = (Binary[]) columns[i];
         memIncrements[1] += MemUtils.getBinaryColumnSize(binColumn, start, end);
       }
@@ -1176,20 +1243,16 @@ public class TsFileProcessor {
    * construct a deletion list from a memtable
    *
    * @param memTable memtable
-   * @param deviceId device id
-   * @param measurement measurement name
    * @param timeLowerBound time water mark
    */
   private List<TimeRange> constructDeletionList(
-      IMemTable memTable, String deviceId, String measurement, long timeLowerBound)
-      throws MetadataException {
+      IMemTable memTable, PartialPath fullPath, long timeLowerBound) {
     List<TimeRange> deletionList = new ArrayList<>();
     deletionList.add(new TimeRange(Long.MIN_VALUE, timeLowerBound));
     for (Modification modification : getModificationsForMemtable(memTable)) {
       if (modification instanceof Deletion) {
         Deletion deletion = (Deletion) modification;
-        if (deletion.getPath().matchFullPath(new PartialPath(deviceId, measurement))
-            && deletion.getEndTime() > timeLowerBound) {
+        if (deletion.getPath().matchFullPath(fullPath) && deletion.getEndTime() > timeLowerBound) {
           long lowerBound = Math.max(deletion.getStartTime(), timeLowerBound);
           deletionList.add(new TimeRange(lowerBound, deletion.getEndTime()));
         }
@@ -1202,17 +1265,10 @@ public class TsFileProcessor {
    * get the chunk(s) in the memtable (one from work memtable and the other ones in flushing
    * memtables and then compact them into one TimeValuePairSorter). Then get the related
    * ChunkMetadata of data on disk.
-   *
-   * @param deviceId device id
-   * @param measurementId measurements id
    */
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
   public void query(
-      String deviceId,
-      String measurementId,
-      IMeasurementSchema schema,
-      QueryContext context,
-      List<TsFileResource> tsfileResourcesForQuery)
+      PartialPath fullPath, QueryContext context, List<TsFileResource> tsfileResourcesForQuery)
       throws IOException, MetadataException {
     if (logger.isDebugEnabled()) {
       logger.debug(
@@ -1228,64 +1284,28 @@ public class TsFileProcessor {
           continue;
         }
         List<TimeRange> deletionList =
-            constructDeletionList(
-                flushingMemTable, deviceId, measurementId, context.getQueryTimeLowerBound());
+            constructDeletionList(flushingMemTable, fullPath, context.getQueryTimeLowerBound());
         ReadOnlyMemChunk memChunk =
-            flushingMemTable.query(
-                deviceId, measurementId, schema, context.getQueryTimeLowerBound(), deletionList);
+            flushingMemTable.query(fullPath, context.getQueryTimeLowerBound(), deletionList);
         if (memChunk != null) {
           readOnlyMemChunks.add(memChunk);
         }
       }
       if (workMemTable != null) {
         ReadOnlyMemChunk memChunk =
-            workMemTable.query(
-                deviceId, measurementId, schema, context.getQueryTimeLowerBound(), null);
+            workMemTable.query(fullPath, context.getQueryTimeLowerBound(), null);
         if (memChunk != null) {
           readOnlyMemChunks.add(memChunk);
         }
       }
 
-      ModificationFile modificationFile = tsFileResource.getModFile();
-      List<Modification> modifications =
-          context.getPathModifications(
-              modificationFile,
-              new PartialPath(deviceId + IoTDBConstant.PATH_SEPARATOR + measurementId));
-
-      List<IChunkMetadata> chunkMetadataList = new ArrayList<>();
-      if (schema instanceof VectorMeasurementSchema) {
-        List<ChunkMetadata> timeChunkMetadataList =
-            writer.getVisibleMetadataList(deviceId, measurementId, schema.getType());
-        List<List<ChunkMetadata>> valueChunkMetadataList = new ArrayList<>();
-        List<String> valueMeasurementIdList = schema.getSubMeasurementsList();
-        List<TSDataType> valueDataTypeList = schema.getSubMeasurementsTSDataTypeList();
-        for (int i = 0; i < valueMeasurementIdList.size(); i++) {
-          valueChunkMetadataList.add(
-              writer.getVisibleMetadataList(
-                  deviceId, valueMeasurementIdList.get(i), valueDataTypeList.get(i)));
-        }
-
-        for (int i = 0; i < timeChunkMetadataList.size(); i++) {
-          List<IChunkMetadata> valueChunkMetadata = new ArrayList<>();
-          for (List<ChunkMetadata> chunkMetadata : valueChunkMetadataList) {
-            valueChunkMetadata.add(chunkMetadata.get(i));
-          }
-          chunkMetadataList.add(
-              new VectorChunkMetadata(timeChunkMetadataList.get(i), valueChunkMetadata));
-        }
-      } else {
-        chunkMetadataList =
-            new ArrayList<>(
-                writer.getVisibleMetadataList(deviceId, measurementId, schema.getType()));
-      }
-
-      QueryUtils.modifyChunkMetaData(chunkMetadataList, modifications);
-      chunkMetadataList.removeIf(context::chunkNotSatisfy);
+      List<IChunkMetadata> chunkMetadataList =
+          fullPath.getVisibleMetadataListFromWriter(writer, tsFileResource, context);
 
       // get in memory data
       if (!readOnlyMemChunks.isEmpty() || !chunkMetadataList.isEmpty()) {
         tsfileResourcesForQuery.add(
-            new TsFileResource(readOnlyMemChunks, chunkMetadataList, tsFileResource));
+            fullPath.createTsFileResource(readOnlyMemChunks, chunkMetadataList, tsFileResource));
       }
     } catch (QueryProcessException e) {
       logger.error(
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileResource.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileResource.java
index b715803..081a67e 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileResource.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileResource.java
@@ -36,11 +36,6 @@ import org.apache.iotdb.db.utils.TestOnly;
 import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.file.metadata.IChunkMetadata;
 import org.apache.iotdb.tsfile.file.metadata.ITimeSeriesMetadata;
-import org.apache.iotdb.tsfile.file.metadata.TimeseriesMetadata;
-import org.apache.iotdb.tsfile.file.metadata.VectorChunkMetadata;
-import org.apache.iotdb.tsfile.file.metadata.VectorTimeSeriesMetadata;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
 import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
 import org.apache.iotdb.tsfile.fileSystem.fsFactory.FSFactory;
 import org.apache.iotdb.tsfile.read.filter.basic.Filter;
@@ -54,7 +49,6 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.Serializable;
 import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -112,12 +106,10 @@ public class TsFileResource {
 
   private TsFileLock tsFileLock = new TsFileLock();
 
-  private Random random = new Random();
+  private final Random random = new Random();
 
   private boolean isSeq;
 
-  private Map<String, Integer> holderMap = new HashMap<>();
-
   /**
    * Chunk metadata list of unsealed tsfile. Only be set in a temporal TsFileResource in a query
    * process.
@@ -173,7 +165,6 @@ public class TsFileResource {
     this.isMerging = other.isMerging;
     this.chunkMetadataList = other.chunkMetadataList;
     this.readOnlyMemChunk = other.readOnlyMemChunk;
-    generateTimeSeriesMetadata();
     this.tsFileLock = other.tsFileLock;
     this.fsFactory = other.fsFactory;
     this.maxPlanIndex = other.maxPlanIndex;
@@ -211,7 +202,6 @@ public class TsFileResource {
     this.readOnlyMemChunk = readOnlyMemChunk;
     this.originTsFileResource = originTsFileResource;
     this.version = originTsFileResource.version;
-    generateTimeSeriesMetadata();
   }
 
   @TestOnly
@@ -222,113 +212,6 @@ public class TsFileResource {
     this.timeIndexType = 1;
   }
 
-  /**
-   * Because the unclosed tsfile don't have TimeSeriesMetadata and memtables in the memory don't
-   * have chunkMetadata, but query will use these, so we need to generate it for them.
-   */
-  @SuppressWarnings("squid:S3776") // high Cognitive Complexity
-  private void generateTimeSeriesMetadata() throws IOException {
-    TimeseriesMetadata timeTimeSeriesMetadata = new TimeseriesMetadata();
-    timeTimeSeriesMetadata.setOffsetOfChunkMetaDataList(-1);
-    timeTimeSeriesMetadata.setDataSizeOfChunkMetaDataList(-1);
-
-    if (!(chunkMetadataList == null || chunkMetadataList.isEmpty())) {
-      timeTimeSeriesMetadata.setMeasurementId(chunkMetadataList.get(0).getMeasurementUid());
-      TSDataType dataType = chunkMetadataList.get(0).getDataType();
-      timeTimeSeriesMetadata.setTSDataType(dataType);
-    } else if (!(readOnlyMemChunk == null || readOnlyMemChunk.isEmpty())) {
-      timeTimeSeriesMetadata.setMeasurementId(readOnlyMemChunk.get(0).getMeasurementUid());
-      TSDataType dataType = readOnlyMemChunk.get(0).getDataType();
-      timeTimeSeriesMetadata.setTSDataType(dataType);
-    }
-    if (timeTimeSeriesMetadata.getTSDataType() != null) {
-      if (timeTimeSeriesMetadata.getTSDataType() == TSDataType.VECTOR) {
-        Statistics<? extends Serializable> timeStatistics =
-            Statistics.getStatsByType(timeTimeSeriesMetadata.getTSDataType());
-
-        List<TimeseriesMetadata> valueTimeSeriesMetadataList = new ArrayList<>();
-
-        if (!(chunkMetadataList == null || chunkMetadataList.isEmpty())) {
-          VectorChunkMetadata vectorChunkMetadata = (VectorChunkMetadata) chunkMetadataList.get(0);
-          for (IChunkMetadata valueChunkMetadata :
-              vectorChunkMetadata.getValueChunkMetadataList()) {
-            TimeseriesMetadata valueMetadata = new TimeseriesMetadata();
-            valueMetadata.setOffsetOfChunkMetaDataList(-1);
-            valueMetadata.setDataSizeOfChunkMetaDataList(-1);
-            valueMetadata.setMeasurementId(valueChunkMetadata.getMeasurementUid());
-            valueMetadata.setTSDataType(valueChunkMetadata.getDataType());
-            valueTimeSeriesMetadataList.add(valueMetadata);
-            valueMetadata.setStatistics(
-                Statistics.getStatsByType(valueChunkMetadata.getDataType()));
-          }
-        } else if (!(readOnlyMemChunk == null || readOnlyMemChunk.isEmpty())) {
-          VectorChunkMetadata vectorChunkMetadata =
-              (VectorChunkMetadata) readOnlyMemChunk.get(0).getChunkMetaData();
-          for (IChunkMetadata valueChunkMetadata :
-              vectorChunkMetadata.getValueChunkMetadataList()) {
-            TimeseriesMetadata valueMetadata = new TimeseriesMetadata();
-            valueMetadata.setOffsetOfChunkMetaDataList(-1);
-            valueMetadata.setDataSizeOfChunkMetaDataList(-1);
-            valueMetadata.setMeasurementId(valueChunkMetadata.getMeasurementUid());
-            valueMetadata.setTSDataType(valueChunkMetadata.getDataType());
-            valueTimeSeriesMetadataList.add(valueMetadata);
-            valueMetadata.setStatistics(
-                Statistics.getStatsByType(valueChunkMetadata.getDataType()));
-          }
-        }
-
-        for (IChunkMetadata chunkMetadata : chunkMetadataList) {
-          VectorChunkMetadata vectorChunkMetadata = (VectorChunkMetadata) chunkMetadata;
-          timeStatistics.mergeStatistics(
-              vectorChunkMetadata.getTimeChunkMetadata().getStatistics());
-          for (int i = 0; i < valueTimeSeriesMetadataList.size(); i++) {
-            valueTimeSeriesMetadataList
-                .get(i)
-                .getStatistics()
-                .mergeStatistics(
-                    vectorChunkMetadata.getValueChunkMetadataList().get(i).getStatistics());
-          }
-        }
-
-        for (ReadOnlyMemChunk memChunk : readOnlyMemChunk) {
-          if (!memChunk.isEmpty()) {
-            VectorChunkMetadata vectorChunkMetadata =
-                (VectorChunkMetadata) memChunk.getChunkMetaData();
-            timeStatistics.mergeStatistics(
-                vectorChunkMetadata.getTimeChunkMetadata().getStatistics());
-            for (int i = 0; i < valueTimeSeriesMetadataList.size(); i++) {
-              valueTimeSeriesMetadataList
-                  .get(i)
-                  .getStatistics()
-                  .mergeStatistics(
-                      vectorChunkMetadata.getValueChunkMetadataList().get(i).getStatistics());
-            }
-          }
-        }
-        timeTimeSeriesMetadata.setStatistics(timeStatistics);
-        timeSeriesMetadata =
-            new VectorTimeSeriesMetadata(timeTimeSeriesMetadata, valueTimeSeriesMetadataList);
-      } else {
-        Statistics<? extends Serializable> seriesStatistics =
-            Statistics.getStatsByType(timeTimeSeriesMetadata.getTSDataType());
-        // flush chunkMetadataList one by one
-        for (IChunkMetadata chunkMetadata : chunkMetadataList) {
-          seriesStatistics.mergeStatistics(chunkMetadata.getStatistics());
-        }
-
-        for (ReadOnlyMemChunk memChunk : readOnlyMemChunk) {
-          if (!memChunk.isEmpty()) {
-            seriesStatistics.mergeStatistics(memChunk.getChunkMetaData().getStatistics());
-          }
-        }
-        timeTimeSeriesMetadata.setStatistics(seriesStatistics);
-        this.timeSeriesMetadata = timeTimeSeriesMetadata;
-      }
-    } else {
-      this.timeSeriesMetadata = null;
-    }
-  }
-
   public synchronized void serialize() throws IOException {
     try (OutputStream outputStream =
         fsFactory.getBufferedOutputStream(file + RESOURCE_SUFFIX + TEMP_SUFFIX)) {
@@ -702,6 +585,10 @@ public class TsFileResource {
     return timeSeriesMetadata;
   }
 
+  public void setTimeSeriesMetadata(ITimeSeriesMetadata timeSeriesMetadata) {
+    this.timeSeriesMetadata = timeSeriesMetadata;
+  }
+
   public void setUpgradedResources(List<TsFileResource> upgradedResources) {
     this.upgradedResources = upgradedResources;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/HashVirtualPartitioner.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/HashVirtualPartitioner.java
index 829850b..14537e8 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/HashVirtualPartitioner.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/HashVirtualPartitioner.java
@@ -19,7 +19,7 @@
 package org.apache.iotdb.db.engine.storagegroup.virtualSg;
 
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 public class HashVirtualPartitioner implements VirtualPartitioner {
 
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualPartitioner.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualPartitioner.java
index 59711fc..ea6ab05 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualPartitioner.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualPartitioner.java
@@ -18,7 +18,7 @@
  */
 package org.apache.iotdb.db.engine.storagegroup.virtualSg;
 
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 public interface VirtualPartitioner {
 
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualStorageGroupManager.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualStorageGroupManager.java
index 63cea4d..d37aefc 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualStorageGroupManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualStorageGroupManager.java
@@ -27,8 +27,8 @@ import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.StorageGroupNotReadyException;
 import org.apache.iotdb.db.exception.StorageGroupProcessorException;
 import org.apache.iotdb.db.exception.TsFileProcessorException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.tsfile.utils.Pair;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationInformation.java b/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationInformation.java
index 12d0343..fb0c34b 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationInformation.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationInformation.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.engine.trigger.service;
 
 import org.apache.iotdb.db.engine.trigger.executor.TriggerEvent;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.sys.CreateTriggerPlan;
 
 import java.util.Map;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationService.java b/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationService.java
index 1a77088..7d2cf9c 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationService.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationService.java
@@ -27,8 +27,8 @@ import org.apache.iotdb.db.exception.StartupException;
 import org.apache.iotdb.db.exception.TriggerExecutionException;
 import org.apache.iotdb.db.exception.TriggerManagementException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTriggerPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropTriggerPlan;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/local/LocalIoTDBConfiguration.java b/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/local/LocalIoTDBConfiguration.java
index c4ebb8b..8018347 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/local/LocalIoTDBConfiguration.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/local/LocalIoTDBConfiguration.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.engine.trigger.sink.local;
 
 import org.apache.iotdb.db.engine.trigger.sink.api.Configuration;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 public class LocalIoTDBConfiguration implements Configuration {
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/local/LocalIoTDBHandler.java b/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/local/LocalIoTDBHandler.java
index 9b22dcb..d3d2ffd 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/local/LocalIoTDBHandler.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/local/LocalIoTDBHandler.java
@@ -26,7 +26,7 @@ import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.executor.IPlanExecutor;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
@@ -72,7 +72,7 @@ public class LocalIoTDBHandler implements Handler<LocalIoTDBConfiguration, Local
             TSFileDescriptor.getInstance().getConfig().getCompressor(),
             Collections.emptyMap());
       } else {
-        if (!IoTDB.metaManager.getSeriesSchema(device, measurement).getType().equals(dataType)) {
+        if (!IoTDB.metaManager.getSeriesType(path).equals(dataType)) {
           throw new SinkException(
               String.format("The data type of %s you provided was not correct.", path));
         }
@@ -85,7 +85,7 @@ public class LocalIoTDBHandler implements Handler<LocalIoTDBConfiguration, Local
       throws QueryProcessException, StorageEngineException, StorageGroupNotSetException {
     InsertRowPlan plan = new InsertRowPlan();
     plan.setNeedInferType(false);
-    plan.setPrefixPath(device);
+    plan.setDeviceId(device);
     plan.setMeasurements(measurements);
     plan.setDataTypes(dataTypes);
     plan.setTime(event.getTimestamp());
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/mqtt/MQTTConfiguration.java b/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/mqtt/MQTTConfiguration.java
index 154007e..b75689f 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/mqtt/MQTTConfiguration.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/trigger/sink/mqtt/MQTTConfiguration.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.engine.trigger.sink.mqtt;
 
 import org.apache.iotdb.db.engine.trigger.sink.api.Configuration;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 
 public class MQTTConfiguration implements Configuration {
 
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index 91c81da..6900b6d 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -45,9 +45,9 @@ import org.apache.iotdb.db.metadata.mnode.IMNode;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
-import org.apache.iotdb.db.metadata.mnode.MultiMeasurementMNode;
-import org.apache.iotdb.db.metadata.mnode.UnaryMeasurementMNode;
 import org.apache.iotdb.db.metadata.mtree.MTree;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.tag.TagManager;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.template.TemplateManager;
@@ -87,7 +87,6 @@ import org.apache.iotdb.db.utils.SchemaUtils;
 import org.apache.iotdb.db.utils.TestOnly;
 import org.apache.iotdb.db.utils.TypeInferenceUtils;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
-import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.exception.cache.CacheException;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -96,8 +95,6 @@ import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.schema.TimeseriesSchema;
-import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -110,7 +107,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -591,7 +587,7 @@ public class MManager {
           prefixPath, measurements, plan.getDataTypes(), plan.getEncodings(), plan.getCompressor());
 
       // the cached mNode may be replaced by new entityMNode in mtree
-      mNodeCache.removeObject(prefixPath.getDevicePath());
+      mNodeCache.removeObject(prefixPath);
 
       // update statistics and schemaDataTypeNumMap
       totalSeriesNumber.addAndGet(measurements.size());
@@ -628,18 +624,14 @@ public class MManager {
   }
 
   /**
-   * Delete all timeseries matching the given path pattern, may cross different storage group The
-   * given pathPattern only match measurement but not flat measurement. For example, given MTree:
-   * root.sg.d.vector(s1, s2), root.sg.d.s2; give pathPattern root.**.s2 and then only root.sg.d.s2
-   * will be deleted; give pathPattern like root.sg.d.* or root.sg.d.vector and then the deletion
-   * will work on root.sg.d.vector(s1, s2)
+   * Delete all timeseries matching the given path pattern, may cross different storage group
    *
    * @param pathPattern path to be deleted
    * @return deletion failed Timeseries
    */
   public String deleteTimeseries(PartialPath pathPattern) throws MetadataException {
     try {
-      List<PartialPath> allTimeseries = mtree.getMeasurementPaths(pathPattern);
+      List<MeasurementPath> allTimeseries = mtree.getMeasurementPaths(pathPattern);
       if (allTimeseries.isEmpty()) {
         throw new MetadataException(
             String.format(
@@ -689,13 +681,7 @@ public class MManager {
         mtree.deleteTimeseriesAndReturnEmptyStorageGroup(path);
     // if one of the aligned timeseries is deleted, pair.right could be null
     IMeasurementMNode measurementMNode = pair.right;
-    int timeseriesNum = 0;
-    if (measurementMNode.isUnaryMeasurement()) {
-      removeFromTagInvertedIndex(measurementMNode);
-      timeseriesNum = 1;
-    } else if (measurementMNode.isMultiMeasurement()) {
-      timeseriesNum += measurementMNode.getSchema().getSubMeasurementsTSDataTypeList().size();
-    }
+    removeFromTagInvertedIndex(measurementMNode);
     PartialPath storageGroupPath = pair.left;
 
     // drop trigger with no exceptions
@@ -712,7 +698,7 @@ public class MManager {
       mNodeCache.removeObject(node.getPartialPath());
       node = node.getParent();
     }
-    totalSeriesNumber.addAndGet(-timeseriesNum);
+    totalSeriesNumber.addAndGet(-1);
     if (!allowToCreateNewSeries
         && totalSeriesNumber.get() * ESTIMATED_SERIES_SIZE < MTREE_SIZE_THRESHOLD) {
       logger.info("Current series number {} come back to normal level", totalSeriesNumber);
@@ -888,14 +874,6 @@ public class MManager {
     return mtree.getAllTimeseriesCount(pathPattern);
   }
 
-  /**
-   * To calculate the count of timeseries component matching given path. The path could be a pattern
-   * of a full path, may contain wildcard.
-   */
-  public int getAllTimeseriesFlatCount(PartialPath pathPattern) throws MetadataException {
-    return mtree.getAllTimeseriesFlatCount(pathPattern);
-  }
-
   /** To calculate the count of devices for given path pattern. */
   public int getDevicesNum(PartialPath pathPattern) throws MetadataException {
     return mtree.getDevicesNum(pathPattern);
@@ -1087,53 +1065,24 @@ public class MManager {
   // region Interfaces for timeseries, measurement and schema info Query
 
   /**
-   * PartialPath of aligned time series will be organized to one VectorPartialPath. BEFORE this
-   * method, all the aligned time series is NOT united. For example, given root.sg.d1.vector1[s1]
-   * and root.sg.d1.vector1[s2], they will be organized to root.sg.d1.vector1 [s1,s2]
-   *
-   * @param fullPaths full path list without uniting the sub measurement under the same aligned time
-   *     series.
-   * @return Size of partial path list could NOT equal to the input list size. For example, the
-   *     VectorMeasurementSchema (s1,s2) would be returned once.
-   */
-  public List<PartialPath> groupVectorPaths(List<PartialPath> fullPaths) throws MetadataException {
-    Map<IMNode, PartialPath> nodeToPartialPath = new LinkedHashMap<>();
-    for (PartialPath path : fullPaths) {
-      IMeasurementMNode node = getMeasurementMNode(path);
-      if (!nodeToPartialPath.containsKey(node)) {
-        nodeToPartialPath.put(node, path.copy());
-      } else {
-        // if nodeToPartialPath contains node
-        PartialPath existPath = nodeToPartialPath.get(node);
-        if (!existPath.equals(path)) {
-          // could be VectorPartialPath
-          ((VectorPartialPath) existPath)
-              .addSubSensor(((VectorPartialPath) path).getSubSensorsList());
-        }
-      }
-    }
-    return new ArrayList<>(nodeToPartialPath.values());
-  }
-
-  /**
-   * Return all flat measurement paths for given path if the path is abstract. Or return the path
-   * itself. Regular expression in this method is formed by the amalgamation of seriesPath and the
-   * character '*'.
+   * Return all measurement paths for given path if the path is abstract. Or return the path itself.
+   * Regular expression in this method is formed by the amalgamation of seriesPath and the character
+   * '*'.
    *
    * @param pathPattern can be a pattern or a full path of timeseries.
    */
-  public List<PartialPath> getFlatMeasurementPaths(PartialPath pathPattern)
+  public List<MeasurementPath> getMeasurementPaths(PartialPath pathPattern)
       throws MetadataException {
-    return mtree.getFlatMeasurementPaths(pathPattern);
+    return mtree.getMeasurementPaths(pathPattern);
   }
 
   /**
-   * Similar to method getAllTimeseriesPath(), but return Path with alias and filter the result by
+   * Similar to method getMeasurementPaths(), but return Path with alias and filter the result by
    * limit and offset.
    */
-  public Pair<List<PartialPath>, Integer> getFlatMeasurementPathsWithAlias(
+  public Pair<List<MeasurementPath>, Integer> getMeasurementPathsWithAlias(
       PartialPath pathPattern, int limit, int offset) throws MetadataException {
-    return mtree.getFlatMeasurementPathsWithAlias(pathPattern, limit, offset);
+    return mtree.getMeasurementPathsWithAlias(pathPattern, limit, offset);
   }
 
   public List<ShowTimeSeriesResult> showTimeseries(ShowTimeSeriesPlan plan, QueryContext context)
@@ -1201,9 +1150,9 @@ public class MManager {
       ShowTimeSeriesPlan plan, QueryContext context) throws MetadataException {
     List<Pair<PartialPath, String[]>> ans;
     if (plan.isOrderByHeat()) {
-      ans = mtree.getAllFlatMeasurementSchemaByHeatOrder(plan, context);
+      ans = mtree.getAllMeasurementSchemaByHeatOrder(plan, context);
     } else {
-      ans = mtree.getAllFlatMeasurementSchema(plan);
+      ans = mtree.getAllMeasurementSchema(plan);
     }
     List<ShowTimeSeriesResult> res = new LinkedList<>();
     for (Pair<PartialPath, String[]> ansString : ans) {
@@ -1216,7 +1165,7 @@ public class MManager {
         }
         res.add(
             new ShowTimeSeriesResult(
-                ansString.left.getExactFullPath(),
+                ansString.left.getFullPath(),
                 ansString.right[0],
                 ansString.right[1],
                 TSDataType.valueOf(ansString.right[2]),
@@ -1242,95 +1191,43 @@ public class MManager {
     if (fullPath.equals(SQLConstant.TIME_PATH)) {
       return TSDataType.INT64;
     }
-
-    IMeasurementSchema schema = mtree.getSchema(fullPath);
-    if (schema instanceof UnaryMeasurementSchema) {
-      return schema.getType();
-    } else {
-      if (((VectorPartialPath) fullPath).getSubSensorsList().size() != 1) {
-        return TSDataType.VECTOR;
-      } else {
-        String subSensor = ((VectorPartialPath) fullPath).getSubSensor(0);
-        List<String> measurements = schema.getSubMeasurementsList();
-        return schema.getSubMeasurementsTSDataTypeList().get(measurements.indexOf(subSensor));
-      }
-    }
-  }
-
-  /**
-   * get MeasurementSchema or VectorMeasurementSchema which contains the measurement
-   *
-   * @param device device path
-   * @param measurement measurement name, could be vector name
-   * @return MeasurementSchema or VectorMeasurementSchema
-   */
-  public IMeasurementSchema getSeriesSchema(PartialPath device, String measurement)
-      throws MetadataException {
-    IMNode deviceIMNode = getDeviceNode(device);
-    IMeasurementMNode measurementMNode = deviceIMNode.getChild(measurement).getAsMeasurementMNode();
-    if (measurementMNode == null) {
-      // Just for the initial adaptation of the template functionality and merge functionality
-      // The getSeriesSchema interface needs to be cleaned up later
-      return getSeriesSchema(device.concatNode(measurement));
-    }
-    return measurementMNode.getSchema();
+    return getSeriesSchema(fullPath).getType();
   }
 
   /**
    * Get schema of paritialPath
    *
-   * @param fullPath (may be ParitialPath or VectorPartialPath)
-   * @return MeasurementSchema or VectorMeasurementSchema
+   * @param fullPath (may be ParitialPath or AlignedPath)
+   * @return MeasurementSchema
    */
   public IMeasurementSchema getSeriesSchema(PartialPath fullPath) throws MetadataException {
-    IMeasurementMNode leaf = getMeasurementMNode(fullPath);
-    return getSeriesSchema(fullPath, leaf);
-  }
-
-  protected IMeasurementSchema getSeriesSchema(PartialPath fullPath, IMeasurementMNode leaf) {
-    IMeasurementSchema schema = leaf.getSchema();
-
-    if (!(fullPath instanceof VectorPartialPath)
-        || schema == null
-        || schema.getType() != TSDataType.VECTOR) {
-      return schema;
-    }
-    List<String> measurementsInLeaf = schema.getSubMeasurementsList();
-    List<String> subMeasurements = ((VectorPartialPath) fullPath).getSubSensorsList();
-    TSDataType[] types = new TSDataType[subMeasurements.size()];
-    TSEncoding[] encodings = new TSEncoding[subMeasurements.size()];
-
-    for (int i = 0; i < subMeasurements.size(); i++) {
-      int index = measurementsInLeaf.indexOf(subMeasurements.get(i));
-      types[i] = schema.getSubMeasurementsTSDataTypeList().get(index);
-      encodings[i] = schema.getSubMeasurementsTSEncodingList().get(index);
-    }
-    String[] array = new String[subMeasurements.size()];
-    for (int i = 0; i < array.length; i++) {
-      array[i] = subMeasurements.get(i);
-    }
-    return new VectorMeasurementSchema(
-        schema.getMeasurementId(), array, types, encodings, schema.getCompressor());
+    return getMeasurementMNode(fullPath).getSchema();
   }
 
   // attention: this path must be a device node
-  public List<IMeasurementSchema> getAllMeasurementByDevicePath(PartialPath devicePath)
+  public List<MeasurementPath> getAllMeasurementByDevicePath(PartialPath devicePath)
       throws PathNotExistException {
-    Set<IMeasurementSchema> res = new HashSet<>();
+    List<MeasurementPath> res = new LinkedList<>();
     try {
       IMNode node = mNodeCache.get(devicePath);
-      Template template = node.getUpperTemplate();
 
       for (IMNode child : node.getChildren().values()) {
         if (child.isMeasurement()) {
           IMeasurementMNode measurementMNode = child.getAsMeasurementMNode();
-          res.add(measurementMNode.getSchema());
+          res.add(measurementMNode.getMeasurementPath());
         }
       }
 
       // template
+      Template template = node.getUpperTemplate();
       if (node.isUseTemplate() && template != null) {
-        res.addAll(template.getSchemaMap().values());
+        MeasurementPath measurementPath;
+        for (IMeasurementSchema schema : template.getSchemaMap().values()) {
+          measurementPath =
+              new MeasurementPath(devicePath.concatNode(schema.getMeasurementId()), schema);
+          measurementPath.setUnderAlignedEntity(node.getAsEntityMNode().isAligned());
+          res.add(measurementPath);
+        }
       }
     } catch (CacheException e) {
       throw new PathNotExistException(devicePath.getFullPath());
@@ -1692,8 +1589,7 @@ public class MManager {
    * <p>Invoking scenario: (1) after executing insertPlan (2) after reading last value from file
    * during last Query
    *
-   * @param seriesPath the PartialPath of full path from root to UnaryMeasurement or the
-   *     VectorPartialPath contains target subMeasurement
+   * @param seriesPath the PartialPath of full path from root to Measurement
    * @param timeValuePair the latest point value
    * @param highPriorityUpdate the last value from insertPlan is high priority
    * @param latestFlushedTime latest flushed time
@@ -1711,55 +1607,26 @@ public class MManager {
       return;
     }
 
-    LastCacheManager.updateLastCache(
-        seriesPath, timeValuePair, highPriorityUpdate, latestFlushedTime, node);
+    LastCacheManager.updateLastCache(node, timeValuePair, highPriorityUpdate, latestFlushedTime);
   }
 
   /**
-   * Update the last cache value in given unary MeasurementMNode. Vector lastCache operation won't
-   * work.
-   *
-   * <p>Invoking scenario: (1) after executing insertPlan (2) after reading last value from file
-   * during last Query
-   *
-   * @param node the measurementMNode holding the lastCache, must be unary measurement
-   * @param timeValuePair the latest point value
-   * @param highPriorityUpdate the last value from insertPlan is high priority
-   * @param latestFlushedTime latest flushed time
-   */
-  public void updateLastCache(
-      UnaryMeasurementMNode node,
-      TimeValuePair timeValuePair,
-      boolean highPriorityUpdate,
-      Long latestFlushedTime) {
-    LastCacheManager.updateLastCache(
-        node.getPartialPath(), timeValuePair, highPriorityUpdate, latestFlushedTime, node);
-  }
-
-  /**
-   * Update the last cache value of subMeasurement given Vector MeasurementMNode.
+   * Update the last cache value in given MeasurementMNode. work.
    *
    * <p>Invoking scenario: (1) after executing insertPlan (2) after reading last value from file
    * during last Query
    *
    * @param node the measurementMNode holding the lastCache
-   * @param subMeasurement the subMeasurement of aligned timeseries
    * @param timeValuePair the latest point value
    * @param highPriorityUpdate the last value from insertPlan is high priority
    * @param latestFlushedTime latest flushed time
    */
   public void updateLastCache(
-      MultiMeasurementMNode node,
-      String subMeasurement,
+      IMeasurementMNode node,
       TimeValuePair timeValuePair,
       boolean highPriorityUpdate,
       Long latestFlushedTime) {
-    LastCacheManager.updateLastCache(
-        new VectorPartialPath(node.getPartialPath(), subMeasurement),
-        timeValuePair,
-        highPriorityUpdate,
-        latestFlushedTime,
-        node);
+    LastCacheManager.updateLastCache(node, timeValuePair, highPriorityUpdate, latestFlushedTime);
   }
 
   /**
@@ -1768,8 +1635,7 @@ public class MManager {
    *
    * <p>Invoking scenario: last cache read during last Query
    *
-   * @param seriesPath the PartialPath of full path from root to UnaryMeasurement or the
-   *     VectorPartialPath contains target subMeasurement
+   * @param seriesPath the PartialPath of full path from root to Measurement
    * @return the last cache value
    */
   public TimeValuePair getLastCache(PartialPath seriesPath) {
@@ -1781,42 +1647,26 @@ public class MManager {
       return null;
     }
 
-    return LastCacheManager.getLastCache(seriesPath, node);
+    return LastCacheManager.getLastCache(node);
   }
 
   /**
-   * Get the last cache value in given unary MeasurementMNode. Vector case won't work.
-   *
-   * <p>Invoking scenario: last cache read during last Query
-   *
-   * @param node the measurementMNode holding the lastCache, must be unary measurement
-   * @return the last cache value
-   */
-  public TimeValuePair getLastCache(UnaryMeasurementMNode node) {
-    return LastCacheManager.getLastCache(node.getPartialPath(), node);
-  }
-
-  /**
-   * Get the last cache value of given subMeasurement of given MeasurementMNode. Must be Vector
-   * case.
+   * Get the last cache value in given MeasurementMNode.
    *
    * <p>Invoking scenario: last cache read during last Query
    *
    * @param node the measurementMNode holding the lastCache
-   * @param subMeasurement the subMeasurement of aligned timeseries
    * @return the last cache value
    */
-  public TimeValuePair getLastCache(MultiMeasurementMNode node, String subMeasurement) {
-    return LastCacheManager.getLastCache(
-        new VectorPartialPath(node.getPartialPath(), subMeasurement), node);
+  public TimeValuePair getLastCache(IMeasurementMNode node) {
+    return LastCacheManager.getLastCache(node);
   }
 
   /**
    * Reset the last cache value of time series of given seriesPath. MManager will use the seriesPath
    * to search the node.
    *
-   * @param seriesPath the PartialPath of full path from root to UnaryMeasurement or the
-   *     VectorPartialPath contains target subMeasurement
+   * @param seriesPath the PartialPath of full path from root to Measurement
    */
   public void resetLastCache(PartialPath seriesPath) {
     IMeasurementMNode node;
@@ -1827,7 +1677,7 @@ public class MManager {
       return;
     }
 
-    LastCacheManager.resetLastCache(seriesPath, node);
+    LastCacheManager.resetLastCache(node);
   }
 
   /**
@@ -1871,98 +1721,40 @@ public class MManager {
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
   public IMNode getSeriesSchemasAndReadLockDevice(InsertPlan plan)
       throws MetadataException, IOException {
-    PartialPath prefixPath = plan.getPrefixPath();
-    PartialPath deviceId = prefixPath;
-    String vectorId = null;
-    if (plan.isAligned()) {
-      deviceId = prefixPath.getDevicePath();
-      vectorId = prefixPath.getMeasurement();
-    }
+    PartialPath devicePath = plan.getDeviceId();
     String[] measurementList = plan.getMeasurements();
     IMeasurementMNode[] measurementMNodes = plan.getMeasurementMNodes();
 
     // 1. get device node
-    IMNode deviceMNode = getDeviceNodeWithAutoCreate(deviceId);
+    IMNode deviceMNode = getDeviceNodeWithAutoCreate(devicePath);
 
     // check insert non-aligned InsertPlan for aligned timeseries
-    if (deviceMNode.isMeasurement()
-        && deviceMNode.getAsMeasurementMNode().getSchema() instanceof VectorMeasurementSchema
-        && !plan.isAligned()) {
-      throw new MetadataException(
-          String.format(
-              "Path [%s] is an aligned timeseries, please set InsertPlan.isAligned() = true",
-              prefixPath));
-    }
-    // check insert aligned InsertPlan for non-aligned timeseries
-    else if (plan.isAligned()
-        && deviceMNode.getChild(vectorId) != null
-        && !(deviceMNode.getChild(vectorId).isMeasurement())) {
+    if (plan.isAligned() && deviceMNode.isEntity() && !deviceMNode.getAsEntityMNode().isAligned()) {
       throw new MetadataException(
           String.format(
-              "Path [%s] is not an aligned timeseries, please set InsertPlan.isAligned() = false",
-              prefixPath));
+              "Timeseries under path [%s] is not aligned , please set InsertPlan.isAligned() = false",
+              plan.getDeviceId()));
     }
 
     // 2. get schema of each measurement
-    // if do not have measurement
     IMeasurementMNode measurementMNode;
     for (int i = 0; i < measurementList.length; i++) {
       try {
-        String measurement = measurementList[i];
-        measurementMNode =
-            getMeasurementMNode(deviceMNode, plan.isAligned() ? vectorId : measurement);
-        if (measurementMNode == null) {
-          measurementMNode = findTemplate(deviceMNode, measurement, vectorId);
-        }
-        if (measurementMNode == null) {
-          if (!config.isAutoCreateSchemaEnabled()) {
-            throw new PathNotExistException(deviceId + PATH_SEPARATOR + measurement);
-          } else {
-            if (plan instanceof InsertRowPlan || plan instanceof InsertTabletPlan) {
-              if (!plan.isAligned()) {
-                internalCreateTimeseries(
-                    prefixPath.concatNode(measurement), plan.getDataTypes()[i]);
-                // after creating timeseries, the deviceMNode has been replaced by a new entityMNode
-                deviceMNode = mtree.getNodeByPath(deviceId);
-                measurementMNode = deviceMNode.getChild(measurement).getAsMeasurementMNode();
-              } else {
-                internalAlignedCreateTimeseries(
-                    prefixPath, Arrays.asList(measurementList), Arrays.asList(plan.getDataTypes()));
-                // after creating timeseries, the deviceMNode has been replaced by a new entityMNode
-                deviceMNode = mtree.getNodeByPath(deviceId);
-                measurementMNode = deviceMNode.getChild(vectorId).getAsMeasurementMNode();
-              }
-            } else {
-              throw new MetadataException(
-                  String.format(
-                      "Only support insertRow and insertTablet, plan is [%s]",
-                      plan.getOperatorType()));
-            }
-          }
-        }
+        // get MeasurementMNode, auto create if absent
+        Pair<IMNode, IMeasurementMNode> pair =
+            getMeasurementMNodeForInsertPlan(plan, i, deviceMNode);
+        deviceMNode = pair.left;
+        measurementMNode = pair.right;
 
         // check type is match
-        TSDataType insertDataType;
         if (plan instanceof InsertRowPlan || plan instanceof InsertTabletPlan) {
-          if (plan.isAligned()) {
-            TSDataType dataTypeInNode =
-                measurementMNode.getSchema().getSubMeasurementsTSDataTypeList().get(i);
-            insertDataType = plan.getDataTypes()[i];
-            if (insertDataType == null) {
-              insertDataType = dataTypeInNode;
-            }
-            if (dataTypeInNode != insertDataType) {
-              logger.warn(
-                  "DataType mismatch, Insert measurement {} in {} type {}, metadata tree type {}",
-                  measurementMNode.getSchema().getSubMeasurementsList().get(i),
-                  measurementList[i],
-                  insertDataType,
-                  dataTypeInNode);
-              DataTypeMismatchException mismatchException =
-                  new DataTypeMismatchException(measurementList[i], insertDataType, dataTypeInNode);
-              if (!config.isEnablePartialInsert()) {
-                throw mismatchException;
-              } else {
+          try {
+            checkDataTypeMatch(plan, i, measurementMNode.getSchema().getType());
+          } catch (DataTypeMismatchException mismatchException) {
+            if (!config.isEnablePartialInsert()) {
+              throw mismatchException;
+            } else {
+              if (plan.isAligned()) {
                 // mark failed measurement
                 plan.markFailedMeasurementAlignedInsertion(mismatchException);
                 for (int j = 0; j < i; j++) {
@@ -1970,53 +1762,28 @@ public class MManager {
                   measurementMNodes[j] = null;
                 }
                 break;
-              }
-            }
-            measurementMNodes[i] = measurementMNode;
-          } else {
-            if (plan instanceof InsertRowPlan) {
-              if (!((InsertRowPlan) plan).isNeedInferType()) {
-                // only when InsertRowPlan's values is object[], we should check type
-                insertDataType = getTypeInLoc(plan, i);
-              } else {
-                insertDataType = measurementMNode.getSchema().getType();
-              }
-            } else {
-              insertDataType = getTypeInLoc(plan, i);
-            }
-            if (measurementMNode.getSchema().getType() != insertDataType) {
-              logger.warn(
-                  "DataType mismatch, Insert measurement {} type {}, metadata tree type {}",
-                  measurementList[i],
-                  insertDataType,
-                  measurementMNode.getSchema().getType());
-              DataTypeMismatchException mismatchException =
-                  new DataTypeMismatchException(
-                      measurementList[i], insertDataType, measurementMNode.getSchema().getType());
-              if (!config.isEnablePartialInsert()) {
-                throw mismatchException;
               } else {
                 // mark failed measurement
                 plan.markFailedMeasurementInsertion(i, mismatchException);
                 continue;
               }
             }
-            measurementMNodes[i] = measurementMNode;
-            // set measurementName instead of alias
-            measurementList[i] = measurementMNode.getName();
           }
+          measurementMNodes[i] = measurementMNode;
+          // set measurementName instead of alias
+          measurementList[i] = measurementMNode.getName();
         }
       } catch (MetadataException e) {
         if (IoTDB.isClusterMode()) {
           logger.debug(
               "meet error when check {}.{}, message: {}",
-              deviceId,
+              devicePath,
               measurementList[i],
               e.getMessage());
         } else {
           logger.warn(
               "meet error when check {}.{}, message: {}",
-              deviceId,
+              devicePath,
               measurementList[i],
               e.getMessage());
         }
@@ -2032,6 +1799,63 @@ public class MManager {
     return deviceMNode;
   }
 
+  private Pair<IMNode, IMeasurementMNode> getMeasurementMNodeForInsertPlan(
+      InsertPlan plan, int loc, IMNode deviceMNode) throws MetadataException {
+    PartialPath devicePath = plan.getDeviceId();
+    String[] measurementList = plan.getMeasurements();
+    String measurement = measurementList[loc];
+    IMeasurementMNode measurementMNode = getMeasurementMNode(deviceMNode, measurement);
+    if (measurementMNode == null) {
+      measurementMNode = findTemplate(deviceMNode, measurement);
+    }
+    if (measurementMNode == null) {
+      if (!config.isAutoCreateSchemaEnabled()) {
+        throw new PathNotExistException(devicePath + PATH_SEPARATOR + measurement);
+      } else {
+        if (plan instanceof InsertRowPlan || plan instanceof InsertTabletPlan) {
+          if (!plan.isAligned()) {
+            internalCreateTimeseries(devicePath.concatNode(measurement), plan.getDataTypes()[loc]);
+          } else {
+            internalAlignedCreateTimeseries(
+                devicePath, Arrays.asList(measurementList), Arrays.asList(plan.getDataTypes()));
+          }
+          // after creating timeseries, the deviceMNode has been replaced by a new entityMNode
+          deviceMNode = mtree.getNodeByPath(devicePath);
+          measurementMNode = deviceMNode.getChild(measurement).getAsMeasurementMNode();
+        } else {
+          throw new MetadataException(
+              String.format(
+                  "Only support insertRow and insertTablet, plan is [%s]", plan.getOperatorType()));
+        }
+      }
+    }
+    return new Pair<>(deviceMNode, measurementMNode);
+  }
+
+  private void checkDataTypeMatch(InsertPlan plan, int loc, TSDataType dataType)
+      throws MetadataException {
+    TSDataType insertDataType;
+    if (plan instanceof InsertRowPlan) {
+      if (!((InsertRowPlan) plan).isNeedInferType()) {
+        // only when InsertRowPlan's values is object[], we should check type
+        insertDataType = getTypeInLoc(plan, loc);
+      } else {
+        insertDataType = dataType;
+      }
+    } else {
+      insertDataType = getTypeInLoc(plan, loc);
+    }
+    if (dataType != insertDataType) {
+      String measurement = plan.getMeasurements()[loc];
+      logger.warn(
+          "DataType mismatch, Insert measurement {} type {}, metadata tree type {}",
+          measurement,
+          insertDataType,
+          dataType);
+      throw new DataTypeMismatchException(measurement, insertDataType, dataType);
+    }
+  }
+
   /** get dataType of plan, in loc measurements only support InsertRowPlan and InsertTabletPlan */
   private TSDataType getTypeInLoc(InsertPlan plan, int loc) throws MetadataException {
     TSDataType dataType;
@@ -2049,28 +1873,18 @@ public class MManager {
     return dataType;
   }
 
-  private IMeasurementMNode findTemplate(IMNode deviceMNode, String measurement, String vectorId)
+  private IMeasurementMNode findTemplate(IMNode deviceMNode, String measurement)
       throws MetadataException {
     Template curTemplate = deviceMNode.getUpperTemplate();
     if (curTemplate != null) {
-      Map<String, IMeasurementSchema> curTemplateMap = curTemplate.getSchemaMap();
-
-      // Modified for tree structure template, need refactor after new_vector
-      String schemaName =
-          vectorId != null ? vectorId + TsFileConstant.PATH_SEPARATOR + measurement : measurement;
-      IMeasurementSchema schema = curTemplateMap.get(schemaName);
+      IMeasurementSchema schema = curTemplate.getSchema(measurement);
       if (!deviceMNode.isUseTemplate()) {
         deviceMNode = setUsingSchemaTemplate(deviceMNode);
       }
 
       if (schema != null) {
-        if (schema instanceof UnaryMeasurementSchema) {
-          return MeasurementMNode.getMeasurementMNode(
-              deviceMNode.getAsEntityMNode(), measurement, schema, null);
-        } else if (schema instanceof VectorMeasurementSchema) {
-          return MeasurementMNode.getMeasurementMNode(
-              deviceMNode.getAsEntityMNode(), vectorId, schema, null);
-        }
+        return MeasurementMNode.getMeasurementMNode(
+            deviceMNode.getAsEntityMNode(), measurement, schema, null);
       }
       return null;
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/VectorPartialPath.java b/server/src/main/java/org/apache/iotdb/db/metadata/VectorPartialPath.java
deleted file mode 100644
index 82b81a1..0000000
--- a/server/src/main/java/org/apache/iotdb/db/metadata/VectorPartialPath.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.iotdb.db.metadata;
-
-import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * VectorPartialPath represents a vector's fullPath. It not only contains the full path of vector's
- * own name, but also has subSensorsList which contain all the fullPath of vector's sub sensors.
- * e.g. VectorPartialPath1(root.sg1.d1.vector1, [root.sg1.d1.vector1.s1, root.sg1.d1.vector1.s2])
- * VectorPartialPath2(root.sg1.d1.vector2, [root.sg1.d1.vector2.s1, root.sg1.d1.vector2.s2])
- */
-public class VectorPartialPath extends PartialPath {
-
-  private List<String> subSensorsList;
-
-  public VectorPartialPath() {}
-
-  public VectorPartialPath(String vectorPath, List<String> subSensorsList)
-      throws IllegalPathException {
-    super(vectorPath);
-    this.subSensorsList = subSensorsList;
-  }
-
-  public VectorPartialPath(String vectorPath, String subSensor) throws IllegalPathException {
-    super(vectorPath);
-    subSensorsList = new ArrayList<>();
-    subSensorsList.add(subSensor);
-  }
-
-  public VectorPartialPath(PartialPath vectorPath, String subSensor) {
-    super(vectorPath.getNodes());
-    subSensorsList = new ArrayList<>();
-    subSensorsList.add(subSensor);
-  }
-
-  public List<String> getSubSensorsList() {
-    return subSensorsList;
-  }
-
-  public String getSubSensor(int index) {
-    return subSensorsList.get(index);
-  }
-
-  public PartialPath getPathWithSubSensor(int index) {
-    return new PartialPath(nodes).concatNode(subSensorsList.get(index));
-  }
-
-  public void setSubSensorsList(List<String> subSensorsList) {
-    this.subSensorsList = subSensorsList;
-  }
-
-  public void addSubSensor(String subSensor) {
-    this.subSensorsList.add(subSensor);
-  }
-
-  public void addSubSensor(List<String> subSensors) {
-    this.subSensorsList.addAll(subSensors);
-  }
-
-  @Override
-  public PartialPath copy() {
-    VectorPartialPath result = new VectorPartialPath();
-    result.nodes = nodes;
-    result.fullPath = fullPath;
-    result.device = device;
-    result.measurementAlias = measurementAlias;
-    result.subSensorsList = new ArrayList<>(subSensorsList);
-    return result;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    if (!super.equals(o)) {
-      return false;
-    }
-    VectorPartialPath that = (VectorPartialPath) o;
-    return Objects.equals(subSensorsList, that.subSensorsList);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(super.hashCode(), subSensorsList);
-  }
-
-  @Override
-  public String getExactFullPath() {
-    fullPath = getFullPath();
-    if (subSensorsList.size() == 1) {
-      return fullPath + TsFileConstant.PATH_SEPARATOR + subSensorsList.get(0);
-    }
-    return fullPath;
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/LastCacheManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/LastCacheManager.java
index 8af8a7b..17ec217 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/LastCacheManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/LastCacheManager.java
@@ -21,20 +21,15 @@ package org.apache.iotdb.db.metadata.lastCache;
 
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.VectorPartialPath;
 import org.apache.iotdb.db.metadata.lastCache.container.ILastCacheContainer;
 import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
-import org.apache.iotdb.db.metadata.template.Template;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
 import org.apache.iotdb.db.query.executor.fill.LastPointReader;
-import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -54,12 +49,11 @@ public class LastCacheManager {
   /**
    * get the last cache value of time series of given seriesPath
    *
-   * @param seriesPath the path of timeseries or subMeasurement of aligned timeseries
    * @param node the measurementMNode holding the lastCache When invoker only has the target
    *     seriesPath, the node could be null and MManager will search the node
    * @return the last cache value
    */
-  public static TimeValuePair getLastCache(PartialPath seriesPath, IMeasurementMNode node) {
+  public static TimeValuePair getLastCache(IMeasurementMNode node) {
     if (node == null) {
       return null;
     }
@@ -67,38 +61,23 @@ public class LastCacheManager {
     checkIsTemplateLastCacheAndSetIfAbsent(node);
 
     ILastCacheContainer lastCacheContainer = node.getLastCacheContainer();
-    if (seriesPath == null) {
-      return lastCacheContainer.getCachedLast();
-    } else if (seriesPath instanceof VectorPartialPath) {
-      IMeasurementSchema schema = node.getSchema();
-      if (schema instanceof VectorMeasurementSchema) {
-        return lastCacheContainer.getCachedLast(
-            node.getSchema()
-                .getSubMeasurementIndex(
-                    ((VectorPartialPath) seriesPath).getSubSensorsList().get(0)));
-      }
-      return null;
-    } else {
-      return lastCacheContainer.getCachedLast();
-    }
+    return lastCacheContainer.getCachedLast();
   }
 
   /**
    * update the last cache value of time series of given seriesPath
    *
-   * @param seriesPath the path of timeseries or subMeasurement of aligned timeseries
+   * @param node the measurementMNode holding the lastCache When invoker only has the target
+   *     seriesPath, the node could be null and MManager will search the node
    * @param timeValuePair the latest point value
    * @param highPriorityUpdate the last value from insertPlan is high priority
    * @param latestFlushedTime latest flushed time
-   * @param node the measurementMNode holding the lastCache When invoker only has the target
-   *     seriesPath, the node could be null and MManager will search the node
    */
   public static void updateLastCache(
-      PartialPath seriesPath,
+      IMeasurementMNode node,
       TimeValuePair timeValuePair,
       boolean highPriorityUpdate,
-      Long latestFlushedTime,
-      IMeasurementMNode node) {
+      Long latestFlushedTime) {
     if (node == null) {
       return;
     }
@@ -106,44 +85,16 @@ public class LastCacheManager {
     checkIsTemplateLastCacheAndSetIfAbsent(node);
 
     ILastCacheContainer lastCacheContainer = node.getLastCacheContainer();
-    if (seriesPath == null) {
-      lastCacheContainer.updateCachedLast(timeValuePair, highPriorityUpdate, latestFlushedTime);
-    } else if (seriesPath instanceof VectorPartialPath) {
-      IMeasurementSchema schema = node.getSchema();
-      if (schema instanceof VectorMeasurementSchema) {
-        if (lastCacheContainer.isEmpty()) {
-          lastCacheContainer.init(schema.getSubMeasurementsCount());
-        }
-        // #TODO: Quick patch for tree template, need refactor after new_vector
-        if (!schema.getMeasurementId().contains(TsFileConstant.PATH_SEPARATOR)) {
-          lastCacheContainer.updateCachedLast(
-              schema.getSubMeasurementIndex(
-                  ((VectorPartialPath) seriesPath).getSubSensorsList().get(0)),
-              timeValuePair,
-              highPriorityUpdate,
-              latestFlushedTime);
-        } else {
-          // vector in tree template
-          lastCacheContainer.updateCachedLast(
-              schema.getSubMeasurementIndex(schema.getMeasurementId()),
-              timeValuePair,
-              highPriorityUpdate,
-              latestFlushedTime);
-        }
-      }
-    } else {
-      lastCacheContainer.updateCachedLast(timeValuePair, highPriorityUpdate, latestFlushedTime);
-    }
+    lastCacheContainer.updateCachedLast(timeValuePair, highPriorityUpdate, latestFlushedTime);
   }
 
   /**
    * reset the last cache value of time series of given seriesPath
    *
-   * @param seriesPath the path of timeseries or subMeasurement of aligned timeseries
    * @param node the measurementMNode holding the lastCache When invoker only has the target
    *     seriesPath, the node could be null and MManager will search the node
    */
-  public static void resetLastCache(PartialPath seriesPath, IMeasurementMNode node) {
+  public static void resetLastCache(IMeasurementMNode node) {
     if (node == null) {
       return;
     }
@@ -151,21 +102,7 @@ public class LastCacheManager {
     checkIsTemplateLastCacheAndSetIfAbsent(node);
 
     ILastCacheContainer lastCacheContainer = node.getLastCacheContainer();
-    if (seriesPath == null) {
-      lastCacheContainer.resetLastCache();
-    } else if (seriesPath instanceof VectorPartialPath) {
-      IMeasurementSchema schema = node.getSchema();
-      if (schema instanceof VectorMeasurementSchema) {
-        if (lastCacheContainer.isEmpty()) {
-          lastCacheContainer.init(schema.getSubMeasurementsCount());
-        }
-        lastCacheContainer.resetLastCache(
-            schema.getSubMeasurementIndex(
-                ((VectorPartialPath) seriesPath).getSubSensorsList().get(0)));
-      }
-    } else {
-      lastCacheContainer.resetLastCache();
-    }
+    lastCacheContainer.resetLastCache();
   }
 
   private static void checkIsTemplateLastCacheAndSetIfAbsent(IMeasurementMNode node) {
@@ -179,10 +116,6 @@ public class LastCacheManager {
     // if entityMNode doesn't have this child, the child is derived from template
     if (!entityMNode.hasChild(measurement)) {
       ILastCacheContainer lastCacheContainer = entityMNode.getLastCacheContainer(measurement);
-      IMeasurementSchema schema = node.getSchema();
-      if (lastCacheContainer.isEmpty() && (schema instanceof VectorMeasurementSchema)) {
-        lastCacheContainer.init(schema.getSubMeasurementsCount());
-      }
       node.setLastCacheContainer(lastCacheContainer);
     }
   }
@@ -227,7 +160,6 @@ public class LastCacheManager {
   public static void deleteLastCacheByDevice(
       IEntityMNode node, PartialPath originalPath, long startTime, long endTime) {
     PartialPath path;
-    IMeasurementSchema schema;
     ILastCacheContainer lastCacheContainer;
 
     // process lastCache of timeseries represented by measurementNode
@@ -243,13 +175,11 @@ public class LastCacheManager {
         if (lastCacheContainer == null) {
           continue;
         }
-        schema = measurementMNode.getSchema();
-        deleteLastCache(path, schema, lastCacheContainer, startTime, endTime);
+        deleteLastCache(path, lastCacheContainer, startTime, endTime);
       }
     }
 
     // process lastCache of timeseries represented by template
-    Template template = node.getUpperTemplate();
     for (Map.Entry<String, ILastCacheContainer> entry : node.getTemplateLastCaches().entrySet()) {
       path = node.getPartialPath().concatNode(entry.getKey());
       if (originalPath.matchFullPath(path)) {
@@ -257,45 +187,21 @@ public class LastCacheManager {
         if (lastCacheContainer == null) {
           continue;
         }
-        schema = template.getSchemaMap().get(entry.getKey());
-        deleteLastCache(path, schema, lastCacheContainer, startTime, endTime);
+        deleteLastCache(path, lastCacheContainer, startTime, endTime);
       }
     }
   }
 
   private static void deleteLastCache(
-      PartialPath path,
-      IMeasurementSchema schema,
-      ILastCacheContainer lastCacheContainer,
-      long startTime,
-      long endTime) {
-    TimeValuePair lastPair;
-    if (schema instanceof VectorMeasurementSchema) {
-      int index;
-      for (String measurement : schema.getSubMeasurementsList()) {
-        index = schema.getSubMeasurementIndex(measurement);
-        lastPair = lastCacheContainer.getCachedLast(index);
-        if (lastPair != null
-            && startTime <= lastPair.getTimestamp()
-            && lastPair.getTimestamp() <= endTime) {
-          lastCacheContainer.resetLastCache(index);
-          if (logger.isDebugEnabled()) {
-            logger.debug(
-                "[tryToDeleteLastCache] Last cache for path: {} is set to null",
-                path.concatNode(measurement).getFullPath());
-          }
-        }
-      }
-    } else {
-      lastPair = lastCacheContainer.getCachedLast();
-      if (lastPair != null
-          && startTime <= lastPair.getTimestamp()
-          && lastPair.getTimestamp() <= endTime) {
-        lastCacheContainer.resetLastCache();
-        if (logger.isDebugEnabled()) {
-          logger.debug(
-              "[tryToDeleteLastCache] Last cache for path: {} is set to null", path.getFullPath());
-        }
+      PartialPath path, ILastCacheContainer lastCacheContainer, long startTime, long endTime) {
+    TimeValuePair lastPair = lastCacheContainer.getCachedLast();
+    if (lastPair != null
+        && startTime <= lastPair.getTimestamp()
+        && lastPair.getTimestamp() <= endTime) {
+      lastCacheContainer.resetLastCache();
+      if (logger.isDebugEnabled()) {
+        logger.debug(
+            "[tryToDeleteLastCache] Last cache for path: {} is set to null", path.getFullPath());
       }
     }
   }
@@ -309,9 +215,9 @@ public class LastCacheManager {
    * @return the last value
    */
   public static long getLastTimeStamp(IMeasurementMNode node, QueryContext queryContext) {
-    TimeValuePair last = getLastCache(null, node);
+    TimeValuePair last = getLastCache(node);
     if (last != null) {
-      return getLastCache(null, node).getTimestamp();
+      return getLastCache(node).getTimestamp();
     } else {
       try {
         QueryDataSource dataSource =
@@ -330,7 +236,7 @@ public class LastCacheManager {
                 null);
         last = lastReader.readLastPoint();
         if (CACHE_ENABLED && last != null && last.getValue() != null) {
-          updateLastCache(node.getPartialPath(), last, false, Long.MIN_VALUE, node);
+          updateLastCache(node, last, false, Long.MIN_VALUE);
         }
         return (last != null ? last.getTimestamp() : Long.MIN_VALUE);
       } catch (Exception e) {
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/ILastCacheContainer.java b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/ILastCacheContainer.java
index 3767b51..831d930 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/ILastCacheContainer.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/ILastCacheContainer.java
@@ -24,15 +24,9 @@ import org.apache.iotdb.tsfile.read.TimeValuePair;
 /** this interface declares the operations of LastCache data */
 public interface ILastCacheContainer {
 
-  // if vector, entry need schema size to init LastCache Value list
-  void init(int size);
-
   // get lastCache of monad timseries
   TimeValuePair getCachedLast();
 
-  // get lastCache of vector timseries
-  TimeValuePair getCachedLast(int index);
-
   /**
    * update last point cache
    *
@@ -43,16 +37,9 @@ public interface ILastCacheContainer {
   void updateCachedLast(
       TimeValuePair timeValuePair, boolean highPriorityUpdate, Long latestFlushedTime);
 
-  // update lastCache for vector timseries
-  void updateCachedLast(
-      int index, TimeValuePair timeValuePair, boolean highPriorityUpdate, Long latestFlushedTime);
-
   // reset all lastCache data of one timeseries(monad or vector)
   void resetLastCache();
 
-  // reset lastCache of vector's subsensor
-  void resetLastCache(int index);
-
   // whether the entry contains lastCache Value.
   boolean isEmpty();
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/LastCacheContainer.java b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/LastCacheContainer.java
index 8ba9a99..57ce10e 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/LastCacheContainer.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/LastCacheContainer.java
@@ -20,8 +20,7 @@
 package org.apache.iotdb.db.metadata.lastCache.container;
 
 import org.apache.iotdb.db.metadata.lastCache.container.value.ILastCacheValue;
-import org.apache.iotdb.db.metadata.lastCache.container.value.UnaryLastCacheValue;
-import org.apache.iotdb.db.metadata.lastCache.container.value.VectorLastCacheValue;
+import org.apache.iotdb.db.metadata.lastCache.container.value.LastCacheValue;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 
 /**
@@ -35,23 +34,11 @@ public class LastCacheContainer implements ILastCacheContainer {
   ILastCacheValue lastCacheValue;
 
   @Override
-  public void init(int size) {
-    if (size > 1) {
-      lastCacheValue = new VectorLastCacheValue(size);
-    }
-  }
-
-  @Override
   public TimeValuePair getCachedLast() {
     return lastCacheValue == null ? null : lastCacheValue.getTimeValuePair();
   }
 
   @Override
-  public TimeValuePair getCachedLast(int index) {
-    return lastCacheValue == null ? null : lastCacheValue.getTimeValuePair(index);
-  }
-
-  @Override
   public synchronized void updateCachedLast(
       TimeValuePair timeValuePair, boolean highPriorityUpdate, Long latestFlushedTime) {
     if (timeValuePair == null || timeValuePair.getValue() == null) {
@@ -62,8 +49,7 @@ public class LastCacheContainer implements ILastCacheContainer {
       // If no cached last, (1) a last query (2) an unseq insertion or (3) a seq insertion will
       // update cache.
       if (!highPriorityUpdate || latestFlushedTime <= timeValuePair.getTimestamp()) {
-        lastCacheValue =
-            new UnaryLastCacheValue(timeValuePair.getTimestamp(), timeValuePair.getValue());
+        lastCacheValue = new LastCacheValue(timeValuePair.getTimestamp(), timeValuePair.getValue());
       }
     } else if (timeValuePair.getTimestamp() > lastCacheValue.getTimestamp()
         || (timeValuePair.getTimestamp() == lastCacheValue.getTimestamp() && highPriorityUpdate)) {
@@ -73,45 +59,11 @@ public class LastCacheContainer implements ILastCacheContainer {
   }
 
   @Override
-  public synchronized void updateCachedLast(
-      int index, TimeValuePair timeValuePair, boolean highPriorityUpdate, Long latestFlushedTime) {
-    if (timeValuePair == null || timeValuePair.getValue() == null) {
-      return;
-    }
-
-    if (lastCacheValue.getTimeValuePair(index) == null) {
-      // If no cached last, (1) a last query (2) an unseq insertion or (3) a seq insertion will
-      // update cache.
-      if (!highPriorityUpdate || latestFlushedTime <= timeValuePair.getTimestamp()) {
-        lastCacheValue.setTimestamp(index, timeValuePair.getTimestamp());
-        lastCacheValue.setValue(index, timeValuePair.getValue());
-      }
-    } else if (timeValuePair.getTimestamp() > lastCacheValue.getTimestamp(index)) {
-      lastCacheValue.setTimestamp(index, timeValuePair.getTimestamp());
-      lastCacheValue.setValue(index, timeValuePair.getValue());
-    } else if (timeValuePair.getTimestamp() == lastCacheValue.getTimestamp(index)) {
-      if (highPriorityUpdate || lastCacheValue.getValue(index) == null) {
-        lastCacheValue.setTimestamp(index, timeValuePair.getTimestamp());
-        lastCacheValue.setValue(index, timeValuePair.getValue());
-      }
-    }
-  }
-
-  @Override
   public synchronized void resetLastCache() {
     lastCacheValue = null;
   }
 
   @Override
-  public void resetLastCache(int index) {
-    if (lastCacheValue instanceof VectorLastCacheValue) {
-      lastCacheValue.setValue(index, null);
-    } else {
-      lastCacheValue = null;
-    }
-  }
-
-  @Override
   public boolean isEmpty() {
     return lastCacheValue == null;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/ILastCacheValue.java b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/ILastCacheValue.java
index e4fc716..2a0c3d0 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/ILastCacheValue.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/ILastCacheValue.java
@@ -32,16 +32,4 @@ public interface ILastCacheValue {
   void setValue(TsPrimitiveType value);
 
   TimeValuePair getTimeValuePair();
-
-  int getSize();
-
-  long getTimestamp(int index);
-
-  void setTimestamp(int index, long timestamp);
-
-  TsPrimitiveType getValue(int index);
-
-  void setValue(int index, TsPrimitiveType value);
-
-  TimeValuePair getTimeValuePair(int index);
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/ILastCacheValue.java b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/LastCacheValue.java
similarity index 62%
copy from server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/ILastCacheValue.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/LastCacheValue.java
index e4fc716..d9fd930 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/ILastCacheValue.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/LastCacheValue.java
@@ -22,26 +22,34 @@ package org.apache.iotdb.db.metadata.lastCache.container.value;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
 
-// this interface declares the simplest storage operation of lastCacheValue
-public interface ILastCacheValue {
+public class LastCacheValue implements ILastCacheValue {
 
-  long getTimestamp();
+  private long timestamp;
 
-  void setTimestamp(long timestamp);
+  private TsPrimitiveType value;
 
-  void setValue(TsPrimitiveType value);
+  public LastCacheValue(long timestamp, TsPrimitiveType value) {
+    this.timestamp = timestamp;
+    this.value = value;
+  }
 
-  TimeValuePair getTimeValuePair();
+  @Override
+  public long getTimestamp() {
+    return timestamp;
+  }
 
-  int getSize();
+  @Override
+  public void setTimestamp(long timestamp) {
+    this.timestamp = timestamp;
+  }
 
-  long getTimestamp(int index);
+  @Override
+  public void setValue(TsPrimitiveType value) {
+    this.value = value;
+  }
 
-  void setTimestamp(int index, long timestamp);
-
-  TsPrimitiveType getValue(int index);
-
-  void setValue(int index, TsPrimitiveType value);
-
-  TimeValuePair getTimeValuePair(int index);
+  @Override
+  public TimeValuePair getTimeValuePair() {
+    return new TimeValuePair(timestamp, value);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/UnaryLastCacheValue.java b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/UnaryLastCacheValue.java
deleted file mode 100644
index b8f21ce..0000000
--- a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/UnaryLastCacheValue.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.iotdb.db.metadata.lastCache.container.value;
-
-import org.apache.iotdb.tsfile.read.TimeValuePair;
-import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
-
-public class UnaryLastCacheValue implements ILastCacheValue {
-
-  private static final String INDEX_OPERATION_ON_MONAD_EXCEPTION =
-      "Cannot operate data on any index but 0 on MonadLastCacheValue";
-
-  private long timestamp;
-
-  private TsPrimitiveType value;
-
-  public UnaryLastCacheValue(long timestamp, TsPrimitiveType value) {
-    this.timestamp = timestamp;
-    this.value = value;
-  }
-
-  @Override
-  public long getTimestamp() {
-    return timestamp;
-  }
-
-  @Override
-  public void setTimestamp(long timestamp) {
-    this.timestamp = timestamp;
-  }
-
-  @Override
-  public void setValue(TsPrimitiveType value) {
-    this.value = value;
-  }
-
-  @Override
-  public TimeValuePair getTimeValuePair() {
-    return new TimeValuePair(timestamp, value);
-  }
-
-  @Override
-  public int getSize() {
-    return 1;
-  }
-
-  @Override
-  public long getTimestamp(int index) {
-    if (index == 0) {
-      return timestamp;
-    }
-    throw new RuntimeException(INDEX_OPERATION_ON_MONAD_EXCEPTION);
-  }
-
-  @Override
-  public void setTimestamp(int index, long timestamp) {
-    if (index == 0) {
-      this.timestamp = timestamp;
-    }
-    throw new RuntimeException(INDEX_OPERATION_ON_MONAD_EXCEPTION);
-  }
-
-  @Override
-  public TsPrimitiveType getValue(int index) {
-    if (index == 0) {
-      return value;
-    }
-    throw new RuntimeException(INDEX_OPERATION_ON_MONAD_EXCEPTION);
-  }
-
-  @Override
-  public void setValue(int index, TsPrimitiveType value) {
-    if (index == 0) {
-      this.value = value;
-    }
-    throw new RuntimeException(INDEX_OPERATION_ON_MONAD_EXCEPTION);
-  }
-
-  @Override
-  public TimeValuePair getTimeValuePair(int index) {
-    if (index != 0) {
-      throw new RuntimeException(INDEX_OPERATION_ON_MONAD_EXCEPTION);
-    } else if (value == null) {
-      return null;
-    } else {
-      return new TimeValuePair(timestamp, value);
-    }
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/VectorLastCacheValue.java b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/VectorLastCacheValue.java
deleted file mode 100644
index d5a3ada..0000000
--- a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/container/value/VectorLastCacheValue.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.iotdb.db.metadata.lastCache.container.value;
-
-import org.apache.iotdb.tsfile.read.TimeValuePair;
-import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
-
-// this class defines the storage of vector lastCache data
-public class VectorLastCacheValue implements ILastCacheValue {
-
-  // the last point data of different subSensors may vary from each other on timestamp
-  private long[] timestamps;
-
-  private TsPrimitiveType[] values;
-
-  public VectorLastCacheValue(int size) {
-    timestamps = new long[size];
-    values = new TsPrimitiveType[size];
-  }
-
-  @Override
-  public int getSize() {
-    return values.length;
-  }
-
-  @Override
-  public long getTimestamp(int index) {
-    return timestamps[index];
-  }
-
-  @Override
-  public void setTimestamp(int index, long timestamp) {
-    timestamps[index] = timestamp;
-  }
-
-  @Override
-  public TsPrimitiveType getValue(int index) {
-    return values == null ? null : values[index];
-  }
-
-  @Override
-  public void setValue(int index, TsPrimitiveType value) {
-    values[index] = value;
-  }
-
-  @Override
-  public TimeValuePair getTimeValuePair(int index) {
-    if (values == null || index < 0 || index >= values.length || values[index] == null) {
-      return null;
-    }
-    return new TimeValuePair(timestamps[index], values[index]);
-  }
-
-  @Override
-  public long getTimestamp() {
-    return 0;
-  }
-
-  @Override
-  public void setTimestamp(long timestamp) {}
-
-  @Override
-  public void setValue(TsPrimitiveType value) {}
-
-  @Override
-  public TimeValuePair getTimeValuePair() {
-    return null;
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogUpgrader.java b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogUpgrader.java
index 32f6718..8c32dfd 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogUpgrader.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogUpgrader.java
@@ -22,7 +22,7 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.MetadataConstant;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.tag.TagLogFile;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.*;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
index b920c75..c19a58e 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
@@ -20,10 +20,10 @@ package org.apache.iotdb.db.metadata.logfile;
 
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.AppendTemplatePlan;
 import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/EntityMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/EntityMNode.java
index ad8d3d5..e6884c0 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/EntityMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/EntityMNode.java
@@ -37,6 +37,8 @@ public class EntityMNode extends InternalMNode implements IEntityMNode {
 
   private volatile boolean useTemplate = false;
 
+  private volatile boolean isAligned = false;
+
   private volatile Map<String, ILastCacheContainer> lastCacheMap = null;
 
   /**
@@ -116,6 +118,15 @@ public class EntityMNode extends InternalMNode implements IEntityMNode {
   }
 
   @Override
+  public boolean isAligned() {
+    return isAligned;
+  }
+
+  @Override
+  public void setAligned(boolean isAligned) {
+    this.isAligned = isAligned;
+  }
+
   public ILastCacheContainer getLastCacheContainer(String measurementId) {
     checkLastCacheMap();
     return lastCacheMap.computeIfAbsent(measurementId, k -> new LastCacheContainer());
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IEntityMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IEntityMNode.java
index fadc368..a6780cb 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IEntityMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IEntityMNode.java
@@ -37,6 +37,10 @@ public interface IEntityMNode extends IMNode {
 
   void setUseTemplate(boolean useTemplate);
 
+  boolean isAligned();
+
+  void setAligned(boolean isAligned);
+
   ILastCacheContainer getLastCacheContainer(String measurementId);
 
   Map<String, ILastCacheContainer> getTemplateLastCaches();
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMNode.java
index dbbd02a..3c6638e 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMNode.java
@@ -18,8 +18,8 @@
  */
 package org.apache.iotdb.db.metadata.mnode;
 
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.logfile.MLogWriter;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.template.Template;
 
 import java.io.IOException;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java
index e99116b..fca21a9 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.db.metadata.mnode;
 
 import org.apache.iotdb.db.engine.trigger.executor.TriggerExecutor;
 import org.apache.iotdb.db.metadata.lastCache.container.ILastCacheContainer;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 
@@ -29,12 +30,12 @@ public interface IMeasurementMNode extends IMNode {
   @Override
   IEntityMNode getParent();
 
+  MeasurementPath getMeasurementPath();
+
   IMeasurementSchema getSchema();
 
   TSDataType getDataType(String measurementId);
 
-  int getMeasurementCount();
-
   String getAlias();
 
   void setAlias(String alias);
@@ -50,12 +51,4 @@ public interface IMeasurementMNode extends IMNode {
   ILastCacheContainer getLastCacheContainer();
 
   void setLastCacheContainer(ILastCacheContainer lastCacheContainer);
-
-  boolean isUnaryMeasurement();
-
-  boolean isMultiMeasurement();
-
-  UnaryMeasurementMNode getAsUnaryMeasurementMNode();
-
-  MultiMeasurementMNode getAsMultiMeasurementMNode();
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MNode.java
index 9f6e075..839e4e2 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MNode.java
@@ -20,7 +20,7 @@ package org.apache.iotdb.db.metadata.mnode;
 
 import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.rescon.CachedStringPool;
 
 import java.util.ArrayList;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
index e094a34..90c7635 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
@@ -22,12 +22,11 @@ import org.apache.iotdb.db.engine.trigger.executor.TriggerExecutor;
 import org.apache.iotdb.db.metadata.lastCache.container.ILastCacheContainer;
 import org.apache.iotdb.db.metadata.lastCache.container.LastCacheContainer;
 import org.apache.iotdb.db.metadata.logfile.MLogWriter;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.qp.physical.sys.MeasurementMNodePlan;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -36,7 +35,7 @@ import java.io.IOException;
 import java.util.Collections;
 import java.util.Map;
 
-public abstract class MeasurementMNode extends MNode implements IMeasurementMNode {
+public class MeasurementMNode extends MNode implements IMeasurementMNode {
 
   private static final Logger logger = LoggerFactory.getLogger(MeasurementMNode.class);
 
@@ -44,6 +43,8 @@ public abstract class MeasurementMNode extends MNode implements IMeasurementMNod
   protected String alias;
   /** tag/attribute's start offset in tag file */
   private long offset = -1;
+  /** measurement's Schema for one timeseries represented by current leaf node */
+  private IMeasurementSchema schema;
   /** last value cache */
   private volatile ILastCacheContainer lastCacheContainer = null;
   /** registered trigger */
@@ -56,22 +57,13 @@ public abstract class MeasurementMNode extends MNode implements IMeasurementMNod
    */
   public static IMeasurementMNode getMeasurementMNode(
       IEntityMNode parent, String measurementName, IMeasurementSchema schema, String alias) {
-    if (schema == null) {
-      return new UnaryMeasurementMNode(parent, measurementName, null, alias);
-    } else if (schema instanceof UnaryMeasurementSchema) {
-      return new UnaryMeasurementMNode(
-          parent, measurementName, (UnaryMeasurementSchema) schema, alias);
-    } else if (schema instanceof VectorMeasurementSchema) {
-      return new MultiMeasurementMNode(
-          parent, measurementName, (VectorMeasurementSchema) schema, alias);
-    } else {
-      throw new RuntimeException("Undefined schema type.");
-    }
+    return new MeasurementMNode(parent, measurementName, schema, alias);
   }
 
   /** @param alias alias of measurementName */
-  MeasurementMNode(IMNode parent, String name, String alias) {
+  MeasurementMNode(IMNode parent, String name, IMeasurementSchema schema, String alias) {
     super(parent, name);
+    this.schema = schema;
     this.alias = alias;
   }
 
@@ -83,11 +75,22 @@ public abstract class MeasurementMNode extends MNode implements IMeasurementMNod
     return parent.getAsEntityMNode();
   }
 
+  /**
+   * get MeasurementPath of this node
+   *
+   * @return MeasurementPath
+   */
   @Override
-  public abstract IMeasurementSchema getSchema();
+  public MeasurementPath getMeasurementPath() {
+    MeasurementPath result = new MeasurementPath(super.getPartialPath(), schema);
+    result.setUnderAlignedEntity(getParent().isAligned());
+    return result;
+  }
 
   @Override
-  public abstract int getMeasurementCount();
+  public IMeasurementSchema getSchema() {
+    return schema;
+  }
 
   /**
    * get data type
@@ -96,7 +99,9 @@ public abstract class MeasurementMNode extends MNode implements IMeasurementMNod
    * @return measurement data type
    */
   @Override
-  public abstract TSDataType getDataType(String measurementId);
+  public TSDataType getDataType(String measurementId) {
+    return schema.getType();
+  }
 
   @Override
   public long getOffset() {
@@ -160,34 +165,6 @@ public abstract class MeasurementMNode extends MNode implements IMeasurementMNod
   }
 
   @Override
-  public boolean isUnaryMeasurement() {
-    return false;
-  }
-
-  @Override
-  public boolean isMultiMeasurement() {
-    return false;
-  }
-
-  @Override
-  public UnaryMeasurementMNode getAsUnaryMeasurementMNode() {
-    if (isUnaryMeasurement()) {
-      return (UnaryMeasurementMNode) this;
-    } else {
-      throw new UnsupportedOperationException("This is not an UnaryMeasurementMNode");
-    }
-  }
-
-  @Override
-  public MultiMeasurementMNode getAsMultiMeasurementMNode() {
-    if (isMultiMeasurement()) {
-      return (MultiMeasurementMNode) this;
-    } else {
-      throw new UnsupportedOperationException("This is not an MultiMeasurementMNode");
-    }
-  }
-
-  @Override
   public String getFullPath() {
     if (fullPath != null) {
       return fullPath;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MultiMeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MultiMeasurementMNode.java
deleted file mode 100644
index 2c5bb5d..0000000
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MultiMeasurementMNode.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.iotdb.db.metadata.mnode;
-
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
-
-import java.util.List;
-
-public class MultiMeasurementMNode extends MeasurementMNode {
-
-  /** measurement's Schema for one aligned timeseries represented by current leaf node */
-  private VectorMeasurementSchema schema;
-
-  MultiMeasurementMNode(
-      IEntityMNode parent, String measurementName, VectorMeasurementSchema schema, String alias) {
-    super(parent, measurementName, alias);
-    this.schema = schema;
-  }
-
-  @Override
-  public VectorMeasurementSchema getSchema() {
-    return schema;
-  }
-
-  public void setSchema(VectorMeasurementSchema schema) {
-    this.schema = schema;
-  }
-
-  @Override
-  public int getMeasurementCount() {
-    return schema.getSubMeasurementsCount();
-  }
-
-  @Override
-  public TSDataType getDataType(String measurementId) {
-    int index = schema.getSubMeasurementIndex(measurementId);
-    return schema.getSubMeasurementsTSDataTypeList().get(index);
-  }
-
-  public List<String> getSubMeasurementList() {
-    return schema.getSubMeasurementsList();
-  }
-
-  @Override
-  public boolean isMultiMeasurement() {
-    return true;
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/UnaryMeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/UnaryMeasurementMNode.java
deleted file mode 100644
index 82417c9..0000000
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/UnaryMeasurementMNode.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.iotdb.db.metadata.mnode;
-
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
-
-/** Represents an MNode which has a Measurement or Sensor attached to it. */
-public class UnaryMeasurementMNode extends MeasurementMNode {
-
-  /** measurement's Schema for one timeseries represented by current leaf node */
-  private UnaryMeasurementSchema schema;
-
-  UnaryMeasurementMNode(
-      IEntityMNode parent, String measurementName, UnaryMeasurementSchema schema, String alias) {
-    super(parent, measurementName, alias);
-    this.schema = schema;
-  }
-
-  @Override
-  public UnaryMeasurementSchema getSchema() {
-    return schema;
-  }
-
-  public void setSchema(UnaryMeasurementSchema schema) {
-    this.schema = schema;
-  }
-
-  @Override
-  public int getMeasurementCount() {
-    return 1;
-  }
-
-  @Override
-  public TSDataType getDataType(String measurementId) {
-    if (name.equals(measurementId)) {
-      return schema.getType();
-    } else {
-      throw new RuntimeException("MeasurementId mismatch in UnaryMeasurementMNode");
-    }
-  }
-
-  @Override
-  public boolean isUnaryMeasurement() {
-    return true;
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java
index 77b8e47..b8f83cd 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
 import org.apache.iotdb.db.exception.metadata.AliasAlreadyExistException;
+import org.apache.iotdb.db.exception.metadata.AlignedTimeseriesException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MNodeTypeMismatchException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
@@ -32,24 +33,27 @@ import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.metadata.TemplateIsInUseException;
 import org.apache.iotdb.db.metadata.MManager.StorageGroupFilter;
 import org.apache.iotdb.db.metadata.MetadataConstant;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.logfile.MLogReader;
 import org.apache.iotdb.db.metadata.logfile.MLogWriter;
-import org.apache.iotdb.db.metadata.mnode.*;
-import org.apache.iotdb.db.metadata.mtree.traverser.PathGrouperByStorageGroup;
-import org.apache.iotdb.db.metadata.mtree.traverser.collector.BelongedEntityPathCollector;
-import org.apache.iotdb.db.metadata.mtree.traverser.collector.EntityPathCollector;
-import org.apache.iotdb.db.metadata.mtree.traverser.collector.FlatMeasurementPathCollector;
-import org.apache.iotdb.db.metadata.mtree.traverser.collector.FlatMeasurementSchemaCollector;
+import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
+import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.InternalMNode;
+import org.apache.iotdb.db.metadata.mnode.MNodeUtils;
+import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mtree.traverser.collector.EntityCollector;
 import org.apache.iotdb.db.metadata.mtree.traverser.collector.MNodeCollector;
 import org.apache.iotdb.db.metadata.mtree.traverser.collector.MeasurementCollector;
-import org.apache.iotdb.db.metadata.mtree.traverser.collector.StorageGroupPathCollector;
+import org.apache.iotdb.db.metadata.mtree.traverser.collector.StorageGroupCollector;
 import org.apache.iotdb.db.metadata.mtree.traverser.counter.CounterTraverser;
 import org.apache.iotdb.db.metadata.mtree.traverser.counter.EntityCounter;
-import org.apache.iotdb.db.metadata.mtree.traverser.counter.FlatMeasurementCounter;
 import org.apache.iotdb.db.metadata.mtree.traverser.counter.MNodeLevelCounter;
 import org.apache.iotdb.db.metadata.mtree.traverser.counter.MeasurementCounter;
 import org.apache.iotdb.db.metadata.mtree.traverser.counter.StorageGroupCounter;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.utils.MetaFormatUtils;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
@@ -69,7 +73,6 @@ import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.schema.TimeseriesSchema;
 import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -101,6 +104,7 @@ import java.util.stream.Stream;
 
 import static java.util.stream.Collectors.toList;
 import static org.apache.iotdb.db.conf.IoTDBConstant.ONE_LEVEL_PATH_WILDCARD;
+import static org.apache.iotdb.db.metadata.lastCache.LastCacheManager.getLastTimeStamp;
 
 /**
  * The hierarchical struct of the Metadata Tree is implemented in this class.
@@ -383,7 +387,7 @@ public class MTree implements Serializable {
 
     MetaFormatUtils.checkTimeseriesProps(path.getFullPath(), props);
 
-    String leafName = nodeNames[nodeNames.length - 1];
+    String leafName = path.getMeasurement();
 
     // synchronize check and add, we need addChild and add Alias become atomic operation
     // only write on mtree will be synchronized
@@ -396,6 +400,12 @@ public class MTree implements Serializable {
         throw new AliasAlreadyExistException(path.getFullPath(), alias);
       }
 
+      if (upperTemplate != null
+          && (upperTemplate.hasSchema(leafName) || upperTemplate.hasSchema(alias))) {
+        throw new PathAlreadyExistException(
+            path.getFullPath() + " ( which is incompatible with template )");
+      }
+
       IEntityMNode entityMNode = MNodeUtils.setToEntity(cur);
 
       IMeasurementMNode measurementMNode =
@@ -430,63 +440,91 @@ public class MTree implements Serializable {
       List<TSEncoding> encodings,
       CompressionType compressor)
       throws MetadataException {
-    String[] deviceNodeNames = devicePath.getNodes();
-    if (deviceNodeNames.length <= 1 || !deviceNodeNames[0].equals(root.getName())) {
+    MetaFormatUtils.checkSchemaMeasurementNames(measurements);
+    Pair<IMNode, Template> pair = checkAndAutoCreateInternalPath(devicePath);
+    IMNode cur = pair.left;
+    Template upperTemplate = pair.right;
+
+    // synchronize check and add, we need addChild and add Alias become atomic operation
+    // only write on mtree will be synchronized
+    synchronized (this) {
+      for (String measurement : measurements) {
+        if (cur.hasChild(measurement)) {
+          throw new PathAlreadyExistException(devicePath.getFullPath() + "." + measurement);
+        }
+      }
+
+      if (upperTemplate != null) {
+        for (String measurement : measurements) {
+          if (upperTemplate.hasSchema(measurement)) {
+            throw new PathAlreadyExistException(
+                devicePath.concatNode(measurement).getFullPath()
+                    + " ( which is incompatible with template )");
+          }
+        }
+      }
+
+      if (cur.isEntity()
+          && !cur.getAsEntityMNode().isAligned()
+          && (!cur.getChildren().isEmpty() || cur.isUseTemplate())) {
+        throw new AlignedTimeseriesException(
+            "Aligned timeseries cannot be created under this entity", devicePath.getFullPath());
+      }
+
+      IEntityMNode entityMNode = MNodeUtils.setToEntity(cur);
+
+      for (int i = 0; i < measurements.size(); i++) {
+        IMeasurementMNode measurementMNode =
+            MeasurementMNode.getMeasurementMNode(
+                entityMNode,
+                measurements.get(i),
+                new UnaryMeasurementSchema(
+                    measurements.get(i), dataTypes.get(i), encodings.get(i), compressor),
+                null);
+        entityMNode.addChild(measurements.get(i), measurementMNode);
+      }
+      entityMNode.setAligned(true);
+    }
+  }
+
+  private Pair<IMNode, Template> checkAndAutoCreateInternalPath(PartialPath devicePath)
+      throws MetadataException {
+    String[] nodeNames = devicePath.getNodes();
+    if (nodeNames.length < 2 || !nodeNames[0].equals(root.getName())) {
       throw new IllegalPathException(devicePath.getFullPath());
     }
     MetaFormatUtils.checkTimeseries(devicePath);
-    MetaFormatUtils.checkSchemaMeasurementNames(measurements);
     IMNode cur = root;
     boolean hasSetStorageGroup = false;
-    // e.g, devicePath = root.sg.d1, create internal nodes and set cur to d1 node
-    for (int i = 1; i < deviceNodeNames.length - 1; i++) {
+    Template upperTemplate = cur.getSchemaTemplate();
+    // e.g, path = root.sg.d1.s1,  create internal nodes and set cur to d1 node
+    for (int i = 1; i < nodeNames.length; i++) {
+      String childName = nodeNames[i];
+      if (!cur.hasChild(childName)) {
+        if (!hasSetStorageGroup) {
+          throw new StorageGroupNotSetException("Storage group should be created first");
+        }
+        if (upperTemplate != null && upperTemplate.hasSchema(childName)) {
+          throw new PathAlreadyExistException(
+              cur.getPartialPath().concatNode(childName).getFullPath()
+                  + " ( which is incompatible with template )");
+        }
+        cur.addChild(childName, new InternalMNode(cur, childName));
+      }
+      cur = cur.getChild(childName);
+
       if (cur.isMeasurement()) {
         throw new PathAlreadyExistException(cur.getFullPath());
       }
       if (cur.isStorageGroup()) {
         hasSetStorageGroup = true;
       }
-      String nodeName = deviceNodeNames[i];
-      if (!cur.hasChild(nodeName)) {
-        if (!hasSetStorageGroup) {
-          throw new StorageGroupNotSetException("Storage group should be created first");
-        }
-        cur.addChild(nodeName, new InternalMNode(cur, nodeName));
-      }
-      cur = cur.getChild(nodeName);
-    }
-
-    if (cur.isMeasurement()) {
-      throw new PathAlreadyExistException(cur.getFullPath());
-    }
-
-    String leafName = deviceNodeNames[deviceNodeNames.length - 1];
 
-    // synchronize check and add, we need addChild and add Alias become atomic operation
-    // only write on mtree will be synchronized
-    synchronized (this) {
-      if (cur.hasChild(leafName)) {
-        throw new PathAlreadyExistException(devicePath.getFullPath() + "." + leafName);
+      if (cur.getSchemaTemplate() != null) {
+        upperTemplate = cur.getSchemaTemplate();
       }
-
-      IEntityMNode entityMNode = MNodeUtils.setToEntity(cur);
-
-      int measurementsSize = measurements.size();
-
-      // this measurementMNode could be a leaf or not.
-      IMeasurementMNode measurementMNode =
-          MeasurementMNode.getMeasurementMNode(
-              entityMNode,
-              leafName,
-              new VectorMeasurementSchema(
-                  leafName,
-                  measurements.toArray(new String[measurementsSize]),
-                  dataTypes.toArray(new TSDataType[measurementsSize]),
-                  encodings.toArray(new TSEncoding[measurementsSize]),
-                  compressor),
-              null);
-      entityMNode.addChild(leafName, measurementMNode);
     }
+    return new Pair<>(cur, upperTemplate);
   }
 
   /**
@@ -694,15 +732,7 @@ public class MTree implements Serializable {
       }
       cur = cur.getChild(nodeNames[i]);
       if (cur.isMeasurement()) {
-        if (i == nodeNames.length - 1) {
-          return true;
-        }
-        IMeasurementSchema schema = cur.getAsMeasurementMNode().getSchema();
-        if (schema instanceof VectorMeasurementSchema) {
-          return i == nodeNames.length - 2 && schema.containsSubMeasurement(nodeNames[i + 1]);
-        } else {
-          return false;
... 20064 lines suppressed ...