01-sql-writing.mdx 4.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
---
title: SQL 写入
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import JavaSQL from "./_java_sql.mdx";
import JavaStmt from "./_java_stmt.mdx";
import PySQL from "./_py_sql.mdx";
import PyStmt from "./_py_stmt.mdx";
import GoSQL from "./_go_sql.mdx";
import GoStmt from "./_go_stmt.mdx";
import RustSQL from "./_rust_sql.mdx";
import RustStmt from "./_rust_stmt.mdx";
import NodeSQL from "./_js_sql.mdx";
import NodeStmt from "./_js_stmt.mdx";
import CsSQL from "./_cs_sql.mdx";
import CsStmt from "./_cs_stmt.mdx";
import CSQL from "./_c_sql.mdx";
import CStmt from "./_c_stmt.mdx";
import PhpSQL from "./_php_sql.mdx";
import PhpStmt from "./_php_stmt.mdx";

## SQL 写入简介

应用通过连接器执行 INSERT 语句来插入数据,用户还可以通过 TAOS Shell,手动输入 INSERT 语句插入数据。

### 一次写入一条
下面这条 INSERT 就将一条记录写入到表 d1001 中:

```sql
INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31);
```

### 一次写入多条

TDengine 支持一次写入多条记录,比如下面这条命令就将两条记录写入到表 d1001 中:

```sql
INSERT INTO d1001 VALUES (1538548684000, 10.2, 220, 0.23) (1538548696650, 10.3, 218, 0.25);
```

### 一次写入多表

TDengine 也支持一次向多个表写入数据,比如下面这条命令就向 d1001 写入两条记录,向 d1002 写入一条记录:

```sql
INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, 218, 0.33) d1002 VALUES (1538548696800, 12.3, 221, 0.31);
```

详细的 SQL INSERT 语法规则参考 [TAOS SQL 的数据写入](/taos-sql/insert)。

:::info

- 要提高写入效率,需要批量写入。一批写入的记录条数越多,插入效率就越高。但一条记录不能超过 16K,一条 SQL 语句总长度不能超过 1M 。
- TDengine 支持多线程同时写入,要进一步提高写入速度,一个客户端需要打开 20 个以上的线程同时写。但线程数达到一定数量后,无法再提高,甚至还会下降,因为线程频繁切换,带来额外开销。

:::

:::warning

- 对同一张表,如果新插入记录的时间戳已经存在,默认情形下(UPDATE=0)新记录将被直接抛弃,也就是说,在一张表里,时间戳必须是唯一的。如果应用自动生成记录,很有可能生成的时间戳是一样的,这样,成功插入的记录条数会小于应用插入的记录条数。如果在创建数据库时使用了 UPDATE 1 选项,插入相同时间戳的新记录将覆盖原有记录。
- 写入的数据的时间戳必须大于当前时间减去配置参数 keep 的时间。如果 keep 配置为 3650 天,那么无法写入比 3650 天还早的数据。写入数据的时间戳也不能大于当前时间加配置参数 days。如果 days 为 2,那么无法写入比当前时间还晚 2 天的数据。

:::

## 示例程序

### 普通 SQL 写入

<Tabs defaultValue="java" groupId="lang">
  <TabItem label="Java" value="java">
    <JavaSQL />
  </TabItem>
  <TabItem label="Python" value="python">
    <PySQL />
  </TabItem>
  <TabItem label="Go" value="go">
    <GoSQL />
  </TabItem>
  <TabItem label="Rust" value="rust">
    <RustSQL />
  </TabItem>
  <TabItem label="Node.js" value="nodejs">
    <NodeSQL />
  </TabItem>
  <TabItem label="C#" value="csharp">
    <CsSQL />
  </TabItem>
  <TabItem label="C" value="c">
    <CSQL />
  </TabItem>
  <TabItem label="PHP" value="php">
    <PhpSQL />
  </TabItem>
</Tabs>

:::note

1. 无论 RESTful 方式建立连接还是本地驱动方式建立连接,以上示例代码都能正常工作。
2. 唯一需要注意的是:由于 RESTful 接口无状态, 不能使用 `use db` 语句来切换数据库, 所以在上面示例中使用了`dbName.tbName`指定表名。

:::

### 参数绑定写入

TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 类似,这些 API 目前也仅支持用问号 `?` 来代表待绑定的参数。从 2.1.1.0 和 2.1.2.0 版本开始,TDengine 大幅改进了参数绑定接口对数据写入(INSERT)场景的支持。这样在通过参数绑定接口写入数据时,就避免了 SQL 语法解析的资源消耗,从而在绝大多数情况下显著提升写入性能。

需要注意的是,只有使用原生连接的连接器,才能使用参数绑定功能。

<Tabs defaultValue="java" groupId="lang">
  <TabItem label="Java" value="java">
    <JavaStmt />
  </TabItem>
  <TabItem label="Python" value="python">
    <PyStmt />
  </TabItem>
  <TabItem label="Go" value="go">
    <GoStmt />
  </TabItem>
  <TabItem label="Rust" value="rust">
    <RustStmt />
  </TabItem>
  <TabItem label="Node.js" value="nodejs">
    <NodeStmt />
  </TabItem>
  <TabItem label="C#" value="csharp">
    <CsStmt />
  </TabItem>
  <TabItem label="C" value="c">
    <CStmt />
  </TabItem>
  <TabItem label="PHP" value="php">
    <PhpStmt />
  </TabItem>
</Tabs>