如何限制Amazon Redshift外部Schema中外部表的可见性?多外部Schema表互见问题排查与解决
这种情况的核心原因是你创建的两个外部Schema(schA和schB)关联了同一个底层外部数据目录(比如AWS Glue Data Catalog或Redshift External Data Catalog)中的同一个数据库。
Redshift的外部Schema本质上是一个「映射层」,它把Redshift内部的Schema指向外部数据目录中的一个数据库。当你用同一个IAM角色创建两个外部Schema,但没有指定不同的外部数据库时,这两个Redshift Schema其实都指向了外部数据目录里的同一个数据库——自然就能看到该数据库下的所有外部表,不管你用哪个Redshift Schema访问。
IAM角色确实不是问题根源:它的作用是让Redshift有权限读取S3和访问外部数据目录,和Schema之间的表隔离没有直接关系。
要实现两个外部Schema的表隔离,你需要从外部数据目录的层级做区分,具体步骤如下:
1. 先在外部数据目录中创建独立的数据库
以AWS Glue为例,你需要在Glue控制台中创建两个不同的数据库(比如glue_db_a和glue_db_b),分别对应Redshift的schA和schB。
如果用SQL命令(Redshift或Glue Data Catalog)创建的话,可以用:
-- 在Glue中创建新数据库(如果用Redshift执行,需要确保IAM角色有Glue创建数据库的权限) CREATE EXTERNAL DATABASE glue_db_b FROM DATA CATALOG IAM_ROLE 'arn:aws:iam::123456789012:role/YourRedshiftRole' REGION 'us-east-1';
2. 创建Redshift外部Schema时关联不同的外部数据库
创建schB时,明确指定关联到新的外部数据库:
CREATE EXTERNAL SCHEMA sch_b FROM DATA CATALOG DATABASE 'glue_db_b' -- 这里指定新的Glue数据库 IAM_ROLE 'arn:aws:iam::123456789012:role/YourRedshiftRole' REGION 'us-east-1';
这样一来,schA关联glue_db_a,schB关联glue_db_b,两个Schema就会各自对应外部数据目录中独立的数据库,彼此看不到对方的表。
3. (可选)如果需要在同一个外部数据库中做更细粒度的隔离
如果你不想创建多个外部数据库,也可以通过S3路径前缀+Glue表的路径过滤来实现,但这种方式不如独立数据库直观:
- 给schA的表放在S3的
s3://your-bucket/data/a/路径下,schB的表放在s3://your-bucket/data/b/ - 在创建外部表时分别指定对应的路径,同时确保IAM角色能访问这两个路径
- 注意:这种方式下,如果你在同一个Glue数据库中创建表,还是会在两个Redshift Schema中看到所有表,所以更推荐用独立数据库的方式。
创建完成后,你可以分别执行以下命令验证:
-- 查看schA的表 SELECT * FROM sch_a.information_schema.tables; -- 查看schB的表 SELECT * FROM sch_b.information_schema.tables;
此时两个Schema的表列表应该是完全独立的,不会互相看到对方的外部表。
内容的提问来源于stack exchange,提问作者rajat saha

