tencent cloud

文档反馈

创建数据表并导入数据

最后更新时间:2022-07-08 11:50:45

    创建数据库

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

    CREATE DATABASE example_db;
    

    所有命令都可以使用 HELP command; 查看到详细的语法帮助,例如 HELP CREATE DATABASE;

    如果不清楚命令的全名,可使用"help 命令某一字段"进行模糊查询。如键入 HELP CREATE,可以匹配到 CREATE DATABASECREATE TABLECREATE USER 等命令。

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

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

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

    账户授权

    example_db 创建完成后,可通过 root/admin 账户将 example_db 读写权限授权给普通账户,例如 test。授权后,即可通过 test 账户登录并操作 example_db 数据库。

    GRANT ALL ON example_db TO test;
    

    建表

    使用 CREATE TABLE 命令建立一个表(Table) ,更多详细参数可输入 HELP CREATE TABLE; 命令查看。

    切换数据库命令如下:

    USE example_db;
    

    Doris 支持单分区和复合分区两种建表方式。

    在复合分区中:

    • 第一级称为 Partition,即分区。用户可以指定某一维度列作为分区列(当前只支持整型和时间类型的列),并指定每个分区的取值范围。
    • 第二级称为 Distribution,即分桶。用户可以指定一个或多个维度列以及桶数对数据进行 HASH 分布。

    以下场景推荐使用复合分区:

    • 有时间维度或类似带有有序值的维度,可以这类维度列作为分区列。分区粒度可以根据导入频次、分区数据量等进行评估。
    • 历史数据删除需求:如有删除历史数据的需求(例如仅保留最近 N 天的数据)。使用复合分区,可通过删除历史分区来达到目的。也可以通过在指定分区内发送 DELETE 语句进行数据删除。
    • 解决数据倾斜问题:每个分区可以单独指定分桶数量。如按天分区,当每天的数据量差异很大时,可以通过指定分区的分桶数,合理划分不同分区的数据,分桶列建议选择区分度大的列。
    • 用户也可以不使用复合分区,即使用单分区。则数据只做 HASH 分布。

    下面以聚合模型为例,分别演示两种分区的建表语句。

    单分区

    建立一个名字为 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
    PROPERTIES("replication_num" = "1");
    

    复合分区

    建立一个名字为 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)
    

    注意事项

    说明:

    Doris 使用中更多语法说明,可参考 数据表的创建与数据导入。

    1. 上述表通过设置 replication_num 建的都是单副本的表,Doris 建议用户采用默认的3副本设置,以保证高可用。
    2. 可以对复合分区表动态的增删分区。
    3. 数据导入可以导入指定的 Partition。
    4. 可以动态修改表的 Schema。
    5. 可以对 Table 增加上卷表(Rollup)以提高查询性能。
    6. 表的列的 Null 属性默认为 true,会对查询性能有一定的影响。

    导入数据

    Doris 支持多种数据导入方式,下文以使用流式导入和 Broker 导入为例进行说明。

    流式导入

    流式导入通过 HTTP 协议向 Doris 传输数据,可以不依赖其他系统或组件直接导入本地数据。

    示例一

    以 "table1_20170707" 为 Label,使用本地文件 table1_data 导入 table1 表。

    curl --location-trusted -u test:test -H "label:table1_20170707" -H "column_separator:," -T table1_data http://FE_HOST:8030/api/example_db/table1/_stream_load
    
    1. FE_HOST 是任一 FE 所在节点 IP,8030 为 fe.conf 中的 http_port。
    2. 可以使用任一 BE 的 IP,以及 be.conf 中的 webserver_port 进行导入,例如 BE_HOST:8040。

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

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

    示例二

    以 "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. 流式导入是同步命令。命令返回成功则表示数据已经导入,返回失败表示这批数据没有导入。

    Broker 导入

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

    以 "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"
    )
    PROPERTIES
    (
            "timeout"="3600",
            "max_filter_ratio"="0.1"
    );
    

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

    SHOW LOAD WHERE LABEL = "table1_20170708";
    

    返回结果中,State 字段为 FINISHED 则表示导入成功。

    异步的导入任务在结束前可以取消,命令如下:

    CANCEL LOAD WHERE LABEL = "table1_20170708";
    
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持