如何将系统表或信息架构表与 Redshift 中的用户定义表连接起来

Posted

技术标签:

【中文标题】如何将系统表或信息架构表与 Redshift 中的用户定义表连接起来【英文标题】:How to join System tables or Information Schema tables with User defined tables in Redshift 【发布时间】:2021-04-06 02:39:35 【问题描述】:

我有一个要求,我需要将 Redshift Information schema 表与 User defined 表一起加入。我尝试了以下查询并收到了提到的错误。

select *
from pg_table_def a join user_defined_table b
on 1 = 1 -- condition just to give an example
where tablename = 'table1'; 

SQL Error [500310] [0A000]: [Amazon](500310) Invalid operation: Specified types or functions (one per INFO message) not supported on Redshift tables.;

select *
from information_schema.columns  a join user_defined_table b
on 1 =1 -- condition just to give an example
where a.table_name = 'table1';

SQL Error [500310] [0A000]: [Amazon](500310) Invalid operation: Specified types or functions (one per INFO message) not supported on Redshift tables.;

可能是我缺少一些基础知识,请提出建议。

【问题讨论】:

【参考方案1】:

当您发现位于领导节点上的目录表与普通表完全不同。将这些表中的数据与普通表一起使用的方法是将这些目录表中的数据保存为普通表。然后可以根据您的尝试组合数据。

如果不从目录中选择(据我所知),没有从这些表直接到普通表的路径。因此,您可以从 redshift 中选择此数据,然后将其作为带有脚本或程序的普通表放回。或者,您可以通过选择光标并将光标读入普通表格来执行几乎等效的操作。这种从游标读取的操作可以通过存储过程来完成。我们先来看看这条路。

下面的代码创建一个存储过程,生成普通表“fred”,选择pg_table_def数据放入fred,然后执行存储过程,最后选择fred中存储的内容。

CREATE OR REPLACE procedure rewrite_data()
AS
$$
DECLARE 
  row record;
BEGIN
  drop table if exists fred;
  create table fred (schemaname varchar(256),tablename varchar(256),"column"varchar(256), "type"varchar(256));
  for row in select "schemaname"::text, "tablename"::text, "column"::text, "type"::text from pg_table_def where "schemaname" <> 'pg_catalog' LOOP
    INSERT INTO fred(schemaname,tablename,"column","type") VALUES (row.schemaname,row.tablename,row."column",row."type");
  END LOOP;
END;
$$ LANGUAGE plpgsql;
call rewrite_data();
select * from fred;

此过程运行良好,但一次循环遍历游标一行很慢,在我们进行时将一行插入到 fred 上。这个过程适用于小事情,但有些目录表相当大。这个过程的好处在于,fred 的更新可以在需要时作为 SQL 调用来完成。这个过程非常适合需要由其他 SQL 发起的小更新。

在大量行上循环的速度是游标/存储过程方法的坏处。在 1000 行游标上循环 10 秒。因此,如果您需要将大量仅限领导节点的目录数据复制到普通表中,您将需要看起来更像 ETL 过程的东西。读取目录表,将其写入 S3,然后将其复制到您的表中。这很容易做到,而且速度相当快,但不能由 SQL 命令启动,因此这些表在使用时会过期一段时间(这些表在上次更新时是正确的)。

因此,没有完美的解决方案,只有几个可行的解决方案,具体取决于您的需求。

【讨论】:

以上是关于如何将系统表或信息架构表与 Redshift 中的用户定义表连接起来的主要内容,如果未能解决你的问题,请参考以下文章

在 Redshift 中更新整个表的正确方法,删除表 + 创建表与截断 + 插入表

Redshift - 如何显示 CASCADE 将删除的依赖项?

数据仓库分层架构

将Redshift架构隐藏到特定用户或仅显示特定架构

如何使用无服务器架构将数据从 S3 加载到 Redshift?

如何将 SQL 中的 2 个表与 1 个公共列组合在一起,而其他列中没有关系?