一、背景
Redshift默认会创建名为dev
的数据库,在其中又包含名为public
的schema,然后用户在其中创建表和视图。如果希望在同一个Redshift集群内同时创建多个数据库,并且进行跨数据库访问,那么可参照本文的方法。
注:本功能仅支持RA3机型,老的dc2/ds2机型上不支持。
二、基础环境
以下操作用具有admin权限的默认用户awsuser完成。可通过AWS控制台上的Redshift Query Editor V2图形界面完成,也可以是使用管理员账户awsuser
连接到JDBC默认的dev
库后,运行如下命令。
1、创建db1和db2
CREATE DATABASE db1;
CREATE DATABASE db2;
2、创建对应的user1和user2
CREATE USER user1 PASSWORD 'Redshift01';
CREATE USER user2 PASSWORD 'Redshift02';
3、为两个用户分别赋予各自库的权限
GRANT ALL ON DATABASE db1 TO user1;
GRANT ALL ON DATABASE db2 TO user2;
准备完毕。
三、以user1身份创建测试数据和设置权限
本文使用SQL Workbench J作为JDBC客户端访问Redshift,使用的JDBC驱动版本是redshift-jdbc42-2.0.0.4.jar
。在登陆时候,设置JDBC字符串地址为:
jdbc:redshift://redshift-cluster-1.caochylzoc3i.cn-northwest-1.redshift.amazonaws.com.cn:5439/db1
以上信息可以看到,JDBC连接字符串的末尾已经替换为了db1
。
1、登陆、建表、注入数据
以user1身份执行本命令。
CREATE TABLE table1 (c1 int, c2 int, c3 int);
INSERT INTO table1 VALUES (1,2,3),(4,5,6),(7,8,9);
测试本数据库对应的user1数据访问正常。
select * from table1
可看到数据正常加载。
2、以user1身份登陆、将user1对应的db1内的表授权给user2可查询
执行如下命令:
GRANT SELECT ON TABLE table1 TO user2;
四、以user2身份登陆db2、并验证对db1的跨数据库访问
配置JDBC使用user2登陆,并声明连接数据库为db2
。
jdbc:redshift://redshift-cluster-1.caochylzoc3i.cn-northwest-1.redshift.amazonaws.com.cn:5439/db2
执行如下命令查询:
select * from db1.public.table1
可看到查询正常。
五、跨数据库创建视图(可选)
注意:注意:这一步是可选的,因为上一步测试跨数据库查询已经正常了。以下命令继续在db2内使用用户user02完成。
1、在db2内创建表
由于上文db1内已经有了table1
表,因此这里在db2内创建table2
表。执行如下命令:
CREATE TABLE table2 (a int, b int, c int);
INSERT INTO table2 VALUES (1,2,3), (4,5,6), (7,8,9);
确认db2内的table2
表数据正常:
select * from table2
返回结果正常。至此db1和db2都分别有了自己的数据表。
2、在db2内创建包含db1和db2的物化视图
在db2内创建物化视图total
,执行如下命令:
CREATE MATERIALIZED VIEW total
AS
SELECT t1.c1 AS c1,
t1.c2 AS c2,
t1.c3 AS c3,
t2.a AS a,
t2.b AS b,
t2.c AS c,
(t1.c1 + t1.c2 ++ t1.c3 + t2.a + t2.b + t2.c) AS SUM
FROM db1.public.table1 t1,
db2.public.table2 t2
WHERE t1.c1 = t2.a
返回信息如下:
Warnings:
An incrementally maintained materialized view could not be created, reason: External tables other than Elastic Views are unsupported. The materialized view created, total, will be recomputed from scratch for every REFRESH.
Materialized view total created
Execution time: 3.58s
这是正常的,因为存在跨数据库,因此Redshift在External tables上创建的物化视图不支持自动递增刷新,查询时候会触发整个视图的完整刷新。
3、在db2内查询包含db1数据的物化视图
select * from total
返回结果如下:
c1 | c2 | c3 | a | b | c | sum |
---|---|---|---|---|---|---|
1 | 2 | 3 | 1 | 2 | 3 | 12 |
4 | 5 | 6 | 4 | 5 | 6 | 30 |
7 | 8 | 9 | 7 | 8 | 9 | 48 |
这里看到,返回的查询结果,前三列来自db1的table1,后三列来自db2的table2,最后一列是所有字段的求和。这个视图的查询结果与预期结果相符。
六、其他辅助命令
列出所有数据库、Schema名为Public下的表:
select database_name, schema_name, table_name, table_type
from svv_redshift_tables
where schema_name in ('public');
七、参考文档
使用跨数据库查询的示例:
https://docs.aws.amazon.com/zh_cn/redshift/latest/dg/cross-database_example.html
GRANT命令赋予权限的使用说明:
https://docs.aws.amazon.com/zhcn/redshift/latest/dg/rGRANT-examples.html
刷新物化视图:
https://docs.aws.amazon.com/zh_cn/redshift/latest/dg/materialized-view-refresh.html