You need to enable JavaScript to run this app.
导航

基础使用

最近更新时间2023.11.27 14:22:06

首次发布时间2022.10.10 15:20:28

本文将为您介绍 Doris 集群的基本使用说明。

1 前提条件

  • 已创建好 E-MapReduce(简称“EMR”)集群并安装有 Doris 服务,详见:创建集群

2 MySQL Client连接Doris集群

Doris 兼容 MySQL 协议,可使用 MySQL Client 直接连接 FE 进行相关 SQL 操作。

  1. 集群管理 > 集群列表 > 具体集群名称,进入集群详情 界面.

  2. 导航栏中点击 服务列表,点击 Doris 服务并进入。

  3. 点击 EMR 集群节点 (emr-master-1主机名称)的 ECS ID,跳转进入到云服务器的实例界面,点击右上角的 远程连接 按钮,输入集群创建时的 root 密码,进入远程终端。

    说明

    不同 EMR 版本中节点的域名命名方式可能不同,所以上方“emr-master-1主机名称”可参考 EMR 的域名规则做相应调整。

  4. Master 节点机器上已经安装了 MySQL 客户端, 可以通过如下命令连接 Doris 集群:

mysql -h 127.0.0.1 -P9030 -u root -p
  1. 初次登录时, 可以使用root用户和空字符串密码登录。初次登录后请尽快完成 root 账号密码修改,您可以通过以下命令修改 root 账号密码:
SET PASSWORD FOR 'root' = PASSWORD('my_root_password');

后续可以使用有权限的用户创建子用户, 详细用户权限参考 开源文档

3 Doris 支持的 SQL 语法说明

EMR Doris 完全兼容开源 Doris 语法,以下对基本的库表操作做一个示例,其他详细指南可以参考 开源Doris使用示例
下文以 MySQL Client 方式为例, 进行样例 SQL 执行。

3.1 创建用户

通过下面的命令创建一个普通用户:

CREATE USER 'test_user' IDENTIFIED BY 'test_user_passwd';

后续登录时即可通过如下连接命令登录:

mysql -h 127.0.0.1 -P9030 -u test_user -ptest_user_passwd

新创建的普通用户默认没有任何权限。

3.2 创建数据库

初始可通过 root用户创建数据库,命令如下:

CREATE DATABASE test_db;

数据库创建完成后,可以通过 SHOW DATABASES; 查看数据库信息。

MySQL> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| example_db         |
| information_schema |
+--------------------+
3 rows in set (0.00 sec)

information_schema 是为了兼容 MySQL 协议而存在,实际中信息可能不是很准确,所以关于具体数据库的信息建议通过直接查询相应数据库而获得。

3.3 账号授权

example_db 创建完成后,可通过 root 账户将 example_db 读写权限授权给之前创建的用户:test_user。授权后,即可通过 test_user 账户登录并操作 example_db 数据库。

-- 授权test_user在example_db的全部权限
GRANT ALL ON example_db TO test_user;
-- 只授权test_user在example_db的SELECT在\权限
GRANT SELECT_PRIV ON example_db TO test_user;

3.4 建表

此处及后面,您可以切换用户为:test_user账号来登录 Doris。
使用 CREATE TABLE 命令建立一个表(Table) ,更多详细参数访问 官网文档 查看详细信息。
切换数据库命令如下:

USE example_db;

Doris 支持单分区和复合分区两种建表方式。
下面以聚合模型为例,分别演示两种分区的建表语句。

3.4.1 非分区表

建立一个名字为 table1 的逻辑表。分桶列为 siteid,桶数为 10。
这个表的 schema 如下:

字段名说明
siteid类型是INT(4字节),默认值为10。
citycode类型是 SMALLINT(2字节)。
username类型是 VARCHAR,最大长度为32,默认值为空字符串。

pv

类型是 BIGINT(8字节),默认值是0;
这是一个指标列,Doris 内部会对指标列做聚合操作,这个列的聚合方法是求和(SUM)。

建表语句如下:

CREATE TABLE table1
(
    siteid INT DEFAULT '10',
    citycode SMALLINT,
    username VARCHAR(32) DEFAULT '',
    pv BIGINT SUM DEFAULT '0'
)
AGGREGATE KEY(siteid, citycode, username)
DISTRIBUTED BY HASH(siteid) BUCKETS 10

3.4.2 分区表

建立一个名字为 table2 的逻辑表。
这个表的 schema 如下:

字段名说明
event_day类型是DATE,无默认值。
siteid类型是 INT(4字节),默认值为10。
citycode类型是 SMALLINT(2字节)。
username类型是 VARCHAR,最大长度为32,默认值为空字符串。

pv

类型是BIGINT(8字节),默认值是0。
这是一个指标列,Doris 内部会对指标列做聚合操作,这个列的聚合方法是求和(SUM)。

另外我们使用 event_day 列作为分区列,建立3个分区: p201706, p201707, p201708:
注意区间为左闭右开。

  • p201706:范围为 [最小值, 2017-07-01)

  • p201707:范围为 [2017-07-01, 2017-08-01)

  • p201708:范围为 [2017-08-01, 2017-09-01)

每个分区使用 siteid 进行哈希分桶,桶数为10
建表语句如下:

CREATE TABLE table2
(
    event_day DATE,
    siteid INT DEFAULT '10',
    citycode SMALLINT,
    username VARCHAR(32) DEFAULT '',
    pv BIGINT SUM DEFAULT '0'
)
AGGREGATE KEY(event_day, siteid, citycode, username)
PARTITION BY RANGE(event_day)
(
    PARTITION p201706 VALUES LESS THAN ('2017-07-01'),
    PARTITION p201707 VALUES LESS THAN ('2017-08-01'),
    PARTITION p201708 VALUES LESS THAN ('2017-09-01')
)
DISTRIBUTED BY HASH(siteid) BUCKETS 10
PROPERTIES("replication_num" = "1");

表建完之后,可以查看 example_db 中表的信息:

MySQL> SHOW TABLES;
+----------------------+
| Tables_in_example_db |
+----------------------+
| table1               |
| table2               |
+----------------------+
2 rows in set (0.01 sec)

MySQL> DESC table1;
+----------+-------------+------+-------+---------+-------+
| Field    | Type        | Null | Key   | Default | Extra |
+----------+-------------+------+-------+---------+-------+
| siteid   | int(11)     | Yes  | true  | 10      |       |
| citycode | smallint(6) | Yes  | true  | N/A     |       |
| username | varchar(32) | Yes  | true  |         |       |
| pv       | bigint(20)  | Yes  | false | 0       | SUM   |
+----------+-------------+------+-------+---------+-------+
4 rows in set (0.00 sec)

MySQL> DESC table2;
+-----------+-------------+------+-------+---------+-------+
| Field     | Type        | Null | Key   | Default | Extra |
+-----------+-------------+------+-------+---------+-------+
| event_day | date        | Yes  | true  | N/A     |       |
| siteid    | int(11)     | Yes  | true  | 10      |       |
| citycode  | smallint(6) | Yes  | true  | N/A     |       |
| username  | varchar(32) | Yes  | true  |         |       |
| pv        | bigint(20)  | Yes  | false | 0       | SUM   |
+-----------+-------------+------+-------+---------+-------+
5 rows in set (0.00 sec)

3.4.3 注意事项

  1. 上述表通过设置 replication_num 建的都是单副本的表,Doris 建议用户采用默认的 3 副本设置,以保证高可用。

  2. 可以对复合分区表动态的增删分区。详见:HELP ALTER TABLE 中 Partition 相关部分。

  3. 数据导入可以导入指定的 Partition。详见:HELP LOAD

  4. 可以动态修改表的 Schema。

  5. 可以对 Table 增加上卷表(Rollup)以提高查询性能,这部分可以参见高级使用指南关于 Rollup 的描述。

  6. 表的列的Null属性默认为true,会对查询性能有一定的影响。

3.5 插入数据

3.5.1 Insert Into 插入

说明

关于 Insert 使用的更多详细语法及最佳实践,请参阅 Insert 命令手册。

Insert Into 语句的使用方式和 MySQL 等数据库中 Insert Into 语句的使用方式类似。但在 Doris 中,所有的数据写入都是一个独立的导入作业。所以这里将 Insert Into 也作为一种导入方式介绍。
主要的 Insert Into 命令包含以下两种;

  • INSERT INTO tbl SELECT ...

  • INSERT INTO tbl (col1, col2, ...) VALUES (1, 2, ...), (1,3, ...);

Insert Into 命令需要通过 MySQL 协议提交,创建导入请求会同步返回导入结果。
语法参考:

INSERT INTO table_name [partition_info] [WITH LABEL label] [col_list] [query_stmt] [VALUES];

label 为用户指定的 label 或自动生成的 label。Label 是该 Insert Into 导入作业的标识。每个导入作业,都有一个在单 database 内部唯一的 Label。
示例:

INSERT INTO tbl2 WITH LABEL label1 SELECT * FROM tbl3;
INSERT INTO tbl1 VALUES ("qweasdzxcqweasdzxc"),("a");

注意:
当需要使用 CTE(Common Table Expressions) 作为 insert 操作中的查询部分时,必须指定 WITH LABELcolumn list 部分。示例

INSERT INTO tbl1 WITH LABEL label1
WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2)
SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1;


INSERT INTO tbl1 (k1)
WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2)
SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1;

Insert Into 本身就是一个 SQL 命令,其返回结果会根据执行结果的不同,分为以下几种:

  • 如果返回结果为 ERROR 1064 (HY000),则表示导入失败。

  • 如果返回结果为Query OK,则表示执行成功。

    • 如果 rows affected 为 0,表示结果集为空,没有数据被导入。

    • 如果rows affected大于 0:

      • 如果 statuscommitted,表示数据还不可见。需要通过 show transaction 语句查看状态直到 visible

      • 如果 statusvisible,表示数据导入成功。

    • 如果 warnings 大于 0,表示有数据被过滤,可以通过 show load 语句获取 url 查看被过滤的行。

更多详细说明,请参阅 Insert 命令手册。

3.5.2 批量导入

Doris 支持多种数据导入方式。这里我们使用流式导入 (Stream-Load) 和 Broker-Load 导入做示例。

1. Stream-Load

说明

关于 Stream-Load 使用的更多详细语法及最佳实践,请参阅 Stream-Load 命令手册。

流式导入通过 HTTP 协议向 Doris 传输数据,可以不依赖其他系统或组件直接导入本地数据。详细语法帮助可以参阅: HELP STREAM LOAD
示例1:
以 "table1_20170707" 为 Label,使用本地文件 table1_data 导入 table1 表。

curl --location-trusted -u test:test_passwd -H "label:table1_20170707" -H "column_separator:," -T table1_data http://FE_HOST:8030/api/example_db/table1/_stream_load

本地文件 table1_data, 作为数据之间的分隔,具体内容如下:

1,1,jim,2
2,1,grace,2
3,2,tom,2
4,3,bush,3
5,3,helen,3

示例2:
以 "table2_20170707" 为 Label,使用本地文件 table2_data 导入 table2 表。

curl --location-trusted -u test:test -H "label:table2_20170707" -H "column_separator:|" -T table2_data http://127.0.0.1:8030/api/example_db/table2/_stream_load

本地文件 table2_data| 作为数据之间的分隔,具体内容如下:

2017-07-03|1|1|jim|2
2017-07-05|2|1|grace|2
2017-07-12|3|2|tom|2
2017-07-15|4|3|bush|3
2017-07-12|5|3|helen|3

注意

  1. 采用流式导入建议文件大小限制在 10GB 以内,过大的文件会导致失败重试代价变大。
  2. 每一批导入数据都需要取一个 Label,Label 最好是一个和一批数据有关的字符串,方便阅读和管理。Doris 基于 Label 保证在一个Database 内,同一批数据只可导入成功一次。失败任务的 Label 可以重用。
  3. 流式导入是同步命令。命令返回成功则表示数据已经导入,返回失败表示这批数据没有导入。

2. Broker-Load

Broker 导入通过部署的 Broker 进程,读取外部存储上的数据进行导入。

注意

关于 Broker Load 使用的更多详细语法及最佳实践,请参阅 Broker Load 命令手册,你也可以在 MySql 客户端命令行下输入:HELP BROKER LOAD 获取更多帮助信息。

示例:
以 "table1_20170708" 为 Label,将 HDFS 上的文件导入 table1 表

LOAD LABEL table1_20170708
(
    DATA INFILE("hdfs://your.namenode.host:port/dir/table1_data")
    INTO TABLE table1
)
WITH BROKER hdfs 
(
    "username"="hdfs_user",
    "password"="hdfs_password"
);

Broker 导入是异步命令。以上命令执行成功只表示提交任务成功。导入是否成功需要通过 SHOW LOAD; 查看。如:

SHOW LOAD WHERE LABEL = "table1_20170708";

返回结果中,State 字段为 FINISHED 则表示导入成功。
关于 SHOW LOAD 的更多说明,可以参阅 HELP SHOW LOAD;
异步的导入任务在结束前可以取消:

CANCEL LOAD WHERE LABEL = "table1_20170708";

更详细信息可参与 社区文档

3.6 查询数据

3.6.1 简单查询

MySQL> SELECT * FROM table1 LIMIT 3;
+--------+----------+----------+------+
| siteid | citycode | username | pv   |
+--------+----------+----------+------+
|      2 |        1 | 'grace'  |    2 |
|      5 |        3 | 'helen'  |    3 |
|      3 |        2 | 'tom'    |    2 |
+--------+----------+----------+------+
3 rows in set (0.01 sec)
MySQL> SELECT * FROM table1 ORDER BY citycode;
+--------+----------+----------+------+
| siteid | citycode | username | pv   |
+--------+----------+----------+------+
|      2 |        1 | 'grace'  |    2 |
|      1 |        1 | 'jim'    |    2 |
|      3 |        2 | 'tom'    |    2 |
|      4 |        3 | 'bush'   |    3 |
|      5 |        3 | 'helen'  |    3 |
+--------+----------+----------+------+
5 rows in set (0.01 sec)

3.6.2 Join 查询

MySQL> SELECT SUM(table1.pv) FROM table1 JOIN table2 WHERE table1.siteid = table2.siteid;
+--------------------+
| sum(`table1`.`pv`) |
+--------------------+
|                 12 |
+--------------------+
1 row in set (0.20 sec)

3.6.3 子查询

MySQL> SELECT SUM(pv) FROM table2 WHERE siteid IN (SELECT siteid FROM table1 WHERE siteid > 2);
+-----------+
| sum(`pv`) |
+-----------+
|         8 |
+-----------+
1 row in set (0.13 sec)