<!--

    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.

-->

## 自动创建元数据

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

### 自动创建 database

* enable\_auto\_create\_schema

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

* default\_storage\_group\_level

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

以下图为例：

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

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

<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 database 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-datanode.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-datanode.properties配置项 | 默认值 |
|:---|:-----------------------------|:---|
| BOOLEAN | default\_boolean\_encoding   | RLE |
| INT32 | default\_int32\_encoding     | TS_2DIFF |
| INT64 | default\_int64\_encoding     | TS_2DIFF |
| FLOAT | default\_float\_encoding     | GORILLA |
| DOUBLE | default\_double\_encoding    | GORILLA |
| TEXT | default\_text\_encoding      | PLAIN |

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

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