本文介绍StarRocks集群的基本使用说明。
StarRocks兼容MySQL协议,可使用MySQL Client直接连接FE进行相关SQL操作。
mysql -h 127.0.0.1 -P9030 -u root -p
EMR StarRocks完全兼容开源StarRocks语法,以下对基本的库表操作做一个示例
本文以MySQL Client方式为例, 进行样例SQL执行
通过下面的命令创建一个普通用户:
CREATE USER 'test_user' IDENTIFIED BY 'test_user_passwd';
后续登录时即可通过如下连接命令登录:
mysql -h 127.0.0.1 -P9030 -u test_user -ptest_user_passwd
新创建的普通用户默认没有任何权限。
初始可通过 root用户创建数据库,命令如下:
CREATE DATABASE example_db;
数据库创建完成后,可以通过 SHOW DATABASES;
查看数据库信息。
MySQL> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | example_db | | information_schema | | _statistics_ | +--------------------+ 2 rows in set (0.00 sec)
information_schema
是为了兼容 MySQL 协议而存在,实际中信息可能不是很准确,所以关于具体数据库的信息建议通过直接查询相应数据库而获得
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;
此处及以后用test_user
账号登录StarRocks
使用 CREATE TABLE 命令建立一个表(Table) ,更多详细参数访问官网文档查看详细信息。
切换数据库命令如下:
USE example_db;
StarRocks 支持单分区和复合分区两种建表方式。
下面以聚合模型为例,分别演示两种分区的建表语句。
建立一个名字为 table1 的逻辑表。分桶列为 siteid,桶数为 10。
这个表的 schema 如下:
siteid:类型是INT(4字节), 默认值为10
citycode:类型是 SMALLINT(2字节)
username:类型是 VARCHAR, 最大长度为32, 默认值为空字符串
pv:类型是 BIGINT(8字节), 默认值是0; 这是一个指标列, StarRocks 内部会对指标列做聚合操作, 这个列的聚合方法是求和(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;
建立一个名字为 table2 的逻辑表。
这个表的 schema 如下:
event_day:类型是DATE,无默认值
siteid:类型是 INT(4字节), 默认值为10
citycode:类型是 SMALLINT(2字节)
username:类型是 VARCHAR, 最大长度为32, 默认值为空字符串
pv:类型是BIGINT(8字节), 默认值是0; 这是一个指标列, StarRocks 内部会对指标列做聚合操作, 这个列的聚合方法是求和(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)
关于 Insert 使用的更多详细语法及最佳实践,请参阅 Insert 手册。
Insert Into 语句的使用方式和 MySQL 等数据库中 Insert Into 语句的使用方式类似。但在 StarRocks 中,所有的数据写入都是一个独立的导入作业。所以这里将 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 LABEL
和 column 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:
如果 status
为 committed
,表示数据还不可见。需要通过 show transaction
语句查看状态直到 visible
如果 status
为 visible
,表示数据导入成功。
如果 warnings
大于 0,表示有数据被过滤,可以通过 show load
语句获取 url 查看被过滤的行。
StarRocks 支持多种数据导入方式。具体可以参阅数据导入文档。这里我们使用流式导入 (Stream-Load) 和 Broker-Load 导入做示例。
关于 Stream-Load 使用的更多详细语法及最佳实践,请参阅 Stream-Load 手册。
流式导入通过 HTTP 协议向 StarRocks 传输数据,可以不依赖其他系统或组件直接导入本地数据。详细语法帮助可以参阅 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
注意
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";
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)
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)
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)