01-sql-writing.mdx 4.9 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
---
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

G
gccgdb1234 已提交
55 56
- 要提高写入效率,需要批量写入。一般来说一批写入的记录条数越多,插入效率就越高。但一条记录不能超过 48K,一条 SQL 语句总长度不能超过 1M 。
- TDengine 支持多线程同时写入,要进一步提高写入速度,一个客户端需要打开多个同时写。但线程数达到一定数量后,无法再提高,甚至还会下降,因为线程频繁切换,会带来额外开销,合适的线程数量与服务端的处理能力,服务端的具体配置,数据库的参数,数据定义的 Schema,写入数据的 Batch Size 等很多因素相关。一般来说,服务端和客户端处理能力越强,所能支持的并发写入的线程可以越多;数据库配置时的 vgroups 越多(但仍然要在服务端的处理能力以内)则所能支持的并发写入越多;数据定义的 Schema 越简单,所能支持的并发写入越多。
57 58 59 60 61

:::

:::warning

G
gccgdb1234 已提交
62 63
- 对同一张表,如果新插入记录的时间戳已经存在,则指定了新值的列会用新值覆盖旧值,而没有指定新值的列则不受影响。
- 写入的数据的时间戳必须大于当前时间减去配置参数 keep 的时间。如果 keep 配置为 3650 天,那么无法写入比 3650 天还早的数据。写入数据的时间戳也不能大于当前时间加配置参数 duration。如果 duration 为 2,那么无法写入比当前时间还晚 2 天的数据。
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

:::

## 示例程序

### 普通 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`指定表名。

:::

### 参数绑定写入

G
gccgdb1234 已提交
107
TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 类似,这些 API 目前也仅支持用问号 `?` 来代表待绑定的参数。在通过参数绑定接口写入数据时,就避免了 SQL 语法解析的资源消耗,从而在绝大多数情况下显著提升写入性能。
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

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

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