<!--

    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.

-->

## 自动创建元数据

自动创建元数据指的是根据写入数据的特征自动创建出用户未定义的时间序列，
这既能解决海量序列场景下设备及测点难以提前预测与建模的难题，又能为用户提供开箱即用的写入体验。

### 自动创建存储组的元数据

* enable\_auto\_create\_schema

| 名字 | enable\_auto\_create\_schema |
|:---:|:---|
| 描述 | 是否开启自动创建元数据功能 |
| 类型 | boolean |
| 默认值 | true |
| 改后生效方式 | 重启服务生效 |

* default\_storage\_group\_level

| 名字 | default\_storage\_group\_level |
|:---:|:---|
| 描述 | 指定存储组在时间序列所处的层级，默认为第 1 层（root为第 0 层） |
| 类型 | int |
| 默认值 | 1 |
| 改后生效方式 | 仅允许在第一次启动服务前修改 |

以下图为例：

* 当 default_storage_group_level=1 时，将使用 root.turbine1 和 root.turbine2 作为存储组。

* 当 default_storage_group_level=2 时，将使用 root.turbine1.d1、root.turbine1.d2、root.turbine2.d1 和 root.turbine2.d2 作为存储组。

<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto; margin-right:auto; display:block;" src="https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/Data%20Concept/Auto-Create-MetaData/auto_create_sg_example.png?raw=true" alt="auto create storage group example">

### 自动创建序列的元数据（前端指定数据类型）

* 用户在写入时精确指定数据类型：

    * Session中的insertTablet接口。
    * Session中带有TSDataType的insert接口。
      ```
      public void insertRecord(String deviceId, long time, List<String> measurements, List<TSDataType> types, Object... values);
      public void insertRecords(List<String> deviceIds, List<Long> times, List<List<String>> measurementsList, List<List<TSDataType>> typesList, List<List<Object>> valuesList);
      ```
    * ......

* 插入数据的同时自动创建序列，效率较高。

### 自动创建序列的元数据（类型推断）

* 在写入时直接传入字符串，数据库推断数据类型：
  
    * CLI的insert命令。
    * Session中不带有TSDataType的insert接口。
      ```
      public void insertRecord(String deviceId, long time, List<String> measurements, List<TSDataType> types, List<Object> values);
      public void insertRecords(List<String> deviceIds, List<Long> times, List<List<String>> measurementsList, List<List<String>> valuesList);
      ```
    * ......

* 由于类型推断会增加写入时间，所以通过类型推断自动创建序列元数据的效率要低于通过前端指定数据类型自动创建序列元数据，建议用户在可行时先选用前端指定数据类型的方式自动创建序列的元数据。

#### 类型推断

| 数据(String) | 字符串格式 | iotdb-engine.properties配置项 | 默认值 |
|:---:|:---|:---|:---|
| true | boolean | boolean\_string\_infer\_type | BOOLEAN |
| 1 | integer | integer\_string\_infer\_type | FLOAT |
| 17000000（大于 2^24 的整数） | integer | long\_string\_infer\_type | DOUBLE |
| 1.2 | floating | floating\_string\_infer\_type | FLOAT |
| NaN | nan | nan\_string\_infer\_type | DOUBLE |
| 'I am text' | text | 无 | 无 |

* 可配置的数据类型包括：BOOLEAN, INT32, INT64, FLOAT, DOUBLE, TEXT

* long_string_infer_type 配置项的目的是防止使用 FLOAT 推断 integer_string_infer_type 而造成精度缺失。

#### 编码方式

| 数据类型 | iotdb-engine.properties配置项 | 默认值 |
|:---|:---|:---|
| BOOLEAN | default\_boolean\_encoding | RLE |
| INT32 | default\_int32\_encoding | RLE |
| INT64 | default\_int64\_encoding | RLE |
| FLOAT | default\_float\_encoding | GORILLA |
| DOUBLE | default\_double\_encoding | GORILLA |
| TEXT | default\_text\_encoding | PLAIN |

* 可配置的编码方式包括：PLAIN, RLE, TS_2DIFF, GORILLA, DICTIONARY

* 数据类型与编码方式的对应关系详见 [编码方式](../Data-Concept/Encoding.md)。