<!--

    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-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     | 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)。