本文介绍如何在外网或VPC网络环境下基于RDS数据源创建外部表并写入数据。
功能介绍
RDS(Relational Database Service)是阿里云的关系型数据库服务,通常使用内网域名访问。通过MaxCompute可以将数据加载至RDS表,并执行数据读写操作。
适用范围
地域限制:目前支持地域包括华北2(北京)、华东2(上海)、华北3(张家口)、华北6(乌兰察布)、华东1(杭州)、华南1(深圳)、中国香港、华东 2 金融云(可用区F)、日本(东京)、新加坡、马来西亚(吉隆坡)、印度尼西亚(雅加达)、德国(法兰克福)、美国(硅谷)、美国(弗吉尼亚)。
引擎限制:支持RDS MySQL 5.x和8.0版本,暂不支持其他RDS引擎。
暂不支持PrivateZone域名。
RDS外部表不支持cluster属性。
向RDS外部表写入大量数据时,采用并行多进程写入方式,会小概率出现某个写入进程数据重写情况,导致数据重复。
小数位数限制:MaxCompute中创建的RDS外部表,DECIMAL数据类型默认小数位为18位,不能修改,只能创建为
DECIMAL(38,18)。如果小数位数比较少,可以在MaxCompute中创建外部表时,数据类型选择String,使用该数据时再使用CAST函数强制转换。
注意事项
当RDS MySQL源表中的Schema与外表Schema不一致时:
列数不一致:如果RDS MySQL源表中的列数小于外表DDL的列数,则读取RDS数据时,系统会报错。例如
Unknown column 'xxx' in 'field list'。当RDS MySQL源表中的列数大于外表DDL的列数时,系统会丢弃超出的列数据。列类型不一致:MaxCompute不支持使用INT类型接收RDS源表中的STRING类型数据,支持使用STRING类型接收INT类型数据(不推荐)。
创建外部表
语法结构
建表时,表名和列名大小写不敏感。在查询表或列名时,无需区分大小写,且不支持强制转换大小写。
-- 开启Hive兼容模式。
SET odps.sql.hive.compatible = true;
CREATE EXTERNAL TABLE <table_name>(
<col_name1> <data_type>,
<col_name2> <data_type>,
......
)
STORED BY 'com.aliyun.odps.jdbc.JdbcStorageHandler' -- 处理JDBC连接类数据源的Handler。
location '<jdbc:mysql://<realm_name:port>/<rds_database_name>?useSSL=false&user=<user_name>&password=<password_value>&table=<rds_table_name>>'
TBLPROPERTIES(
['odps.federation.jdbc.colmapping'='<col_name1:rdstable_colname1|select_alias1>,[<col_name2:rdstable_colname2|select_alias2>,...]',]
'mcfed.mapreduce.jdbc.input.query'='<select_sentence>',
'networklink'='<networklink_name>');参数说明
table_name:必填。待创建外部表的名称。
col_name:必填。外部表的列名称。
data_type:必填。列的数据类型。
jdbc:mysql://realm_name:port/rds_database_name?useSSL=false&user=user_name&password=password_value&table=rds_table_name:必填。连接RDS数据源表的连接字符串。
连接字符串中如果包含特殊字符需要转换为URL编码,转换URL编码请参见URL_ENCODE。
realm_name:port:RDS数据连接内网地址及内网端口。
登录RDS 控制台。
在左侧导航栏,选择实例列表,在左上角选择地域。
在实例列表页面,单击目标实例ID/名称,进入实例详情页。
在左侧导航栏,单击数据库连接。
查看数据库内网地址、外网地址及内网端口。
rds_database_name:RDS数据库名称。
user_name:RDS数据库的账号。
password_value:RDS数据库的密码。
rds_table_name:RDS源表名称。
TBLPROPERTIES:
odps.federation.jdbc.colmapping:可选。
MaxCompute外部表与RDS数据源表列的映射关系,此处的映射列数需要与MaxCompute外部表定义的列数保持一致。
其中:rdstable_colname为RDS源表的列名(全部列映射),select_alias为给查询结果定义的列别名(指定列映射)。
若未配置该参数,则会使用MaxCompute外部表中定义的列名映射RDS同名列访问。
若配置该参数,但是只指定MaxCompute外部表部分列的映射关系,则按照源表字段名映射至RDS外部表的对应列。其他未指定的列,如果列名或类型不匹配会报错。
mcfed.mapreduce.jdbc.input.query:可选。
读取RDS数据源表数据。外部表的列、列名与直接查询的RDS数据源表的列、列名及数据类型保持一致。如果使用了别名,则与别名保持一致。
select_sentence格式为SELECT xxx FROM <rds_database_name>.<rds_table_name>。networklink:必填。RDS实例所在VPC的MaxCompute网络连接名称。
登录MaxCompute控制台,在左上角选择地域。
在左侧导航栏,选择 。
在网络连接页面获取RDS所在VPC对应的网络连接名称。
RDS的网络连接查看位置在登录RDS 控制台并选择实例后,单击左侧导航栏的数据库连接,查看该数据库所在VPC网络。
使用RDS数据源创建MaxCompute的外部表并加载数据
使用RDS数据源创建MaxCompute外部表的步骤如下:
已开通MaxCompute和云数据库RDS间的网络连接,详情请参见访问公网方案。
网络打通时,MaxCompute侧仅打通到所填VPC ID的网络连接,如需跨Region访问或者访问该Region的其他VPC,请根据云上VPC现有打通方案,打通专线直连方案所填写的VPC和其他VPC之间的网络。
登录RDS数据库,执行建表语句并插入数据。操作详情请参见通过DMS登录RDS数据库。
登录RDS 控制台。
在左侧导航栏,选择实例列表,在左上角选择地域。
若没有实例,则在实例列表页面,单击创建实例;若已有实例,则在实例列表页面,单击目标实例ID/名称,进入实例详情页。
创建实例时,RDS引擎选择RDS MySQL 5.x和8.0版本,暂不支持其他RDS引擎。
在左侧导航栏,单击数据库管理。
单击新建数据库。配置如下参数:
参数
是否必填
说明
示例
数据库(DB)名称
必填
长度为2~64个字符。
以字母开头,以字母或数字结尾。
由小写字母、数字、下划线或中划线组成。
数据库名称在实例内必须是唯一的。
数据库名称中如果包含
-,创建出的数据库的文件夹的名字中的-会变成@002d。
rds_mc_test支持字符集
必填
请按需选择字符集。
utf8授权账号
选填
选中需要访问本数据库的账号。本参数可以留空,创建数据库后再绑定账号。
此处仅会显示普通账号。高权限账号拥有所有数据库的所有权限,无需授权。
默认备注说明
选填
用于备注该数据库的相关信息,便于后续数据库管理,最多支持256个字符。
RDS外部表测试数据库单击登录数据库,在左侧导航栏选择数据库实例,双击选中已创建的数据库,在右侧SQLConsole页面执行下列语句,创建测试表并写入测试数据。
如果实例存在,但实例展开后未找到目标数据库,可能是:
登录账号无目标数据库的访问权限:可前往RDS实例详情页的账号管理页面手动修改账号权限或更换登录的数据库账号
元数据未同步导致目录无法显示:请将鼠标悬浮在目标数据库所属实例上,单击实例名右侧的
按钮,即可刷新数据库列表,显示目标数据库。
建表示例如下:
CREATE TABLE `rds_mc_external` ( `id` int(11) DEFAULT NULL, `name` varchar(32) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `rds_mc_external`(`id` ,`name` ) VALUES(1,"Alice"); INSERT INTO `rds_mc_external`(`id` ,`name` ) VALUES(1,"Bob");
在MaxCompute客户端创建映射RDS数据源的外部表
方式一:全部列映射
在MaxCompute客户端创建外部表,表列名与RDS中表的列名完全对应。命令示例如下:
SET odps.sql.hive.compatible = true; CREATE EXTERNAL TABLE mc_vpc_rds_external ( id INT, name STRING) STORED BY 'com.aliyun.odps.jdbc.JdbcStorageHandler' location 'jdbc:mysql://rm-2ze01y92y1tzp****.mysql.rds.aliyuncs.com:3306/rds_mc_test?useSSL=false&user=<>&password=<>&table=rds_mc_external' TBLPROPERTIES( 'odps.federation.jdbc.colmapping'='key:id,value:name', 'mcfed.mapreduce.jdbc.input.query'='select * from rds_mc_test.rds_mc_external', 'networklink'='<your network name>');向新建的MaxCompute表中插入数据
INSERT INTO TABLE mc_vpc_rds_external VALUES(2,"Zoey");查询结果
-- 查询数据插入结果。 SELECT * FROM mc_vpc_rds_external; -- 返回结果: +------------+------------+ | id | name | +------------+------------+ | 1 | Alice | | 1 | Bob | | 2 | Zoey | +------------+------------+
方式二:指定列映射
在MaxCompute客户端创建外部表,表列名与RDS表中指定的列名映射。命令示例如下:
SET odps.sql.hive.compatible = true; CREATE EXTERNAL TABLE mc_vpc_rds_external_mapping ( id INT, name STRING ) STORED BY 'com.aliyun.odps.jdbc.JdbcStorageHandler' location 'jdbc:mysql://rm-2ze01y92y1tzp****.mysql.rds.aliyuncs.com:3306/rds_mc_test?useSSL=false&user=****&password=****&table=rds_mc_external' TBLPROPERTIES( 'mcfed.mapreduce.jdbc.input.query'='select * from rds_mc_test.rds_mc_external', 'networklink'='<your network name>');向新建的MaxCompute表中插入数据
INSERT INTO TABLE mc_vpc_rds_external_mapping VALUES(4,"Lisa");查询数据插入结果
SELECT * FROM mc_vpc_rds_external_mapping; -- 返回结果 +------------+------------+ | id | name | +------------+------------+ | 1 | Alice | | 1 | Bob | | 4 | Lisa | +------------+------------+