【问题标题】:How do I get table and columns information from Redshift?如何从 Redshift 获取表和列信息?
【发布时间】:2014-02-11 22:49:07
【问题描述】:

pg_tables 提供了一个表列表。是否有 pg_columns 或其等效项来提供列列表?

在 DB2 中,我会查询 sysibm.systables/columns 以获取此类信息。红移中的等价物是什么?

【问题讨论】:

    标签: amazon-redshift


    【解决方案1】:

    使用PG_TABLE_DEF 表获取该信息:

    看起来像这样:

    select * from pg_table_def where tablename = 't2';
    
    模式名|表名|列|类型 |编码 | distkey |排序键|非空 ----------+---------+------+---------+---------+- --------+-------+--------- 公共 | t2 | c1 |大整数 |没有 |吨 | 0 | F 公共 | t2 | c2 |整数 |大部分16 | f | 0 | F 公共 | t2 | c3 |整数 |没有 | f | 1 |吨 公共 | t2 | c4 |整数 |没有 | f | 2 | F (4 行)

    【讨论】:

    • 是按列顺序返回的吗??
    • 仅当用户有权访问表时才有效。不列出数据库中的所有表
    • 确保您要查找的架构在您的搜索路径中。
    • 如果我有一个表的模式怎么办?如果提供了架构则不起作用。
    【解决方案2】:

    来自http://www.postgresonline.com/journal/archives/20-The-Anatomy-of-PostgreSQL-Part-2-Database-Objects.html

    information_schema 是一个非常重要的模式,是 ANSI 标准的一部分,但不是很标准。如果所有关系数据库都支持它会很好,但它们并不都支持 - MySQL 5、SQL Server (2000+) 和 PostgreSQL (7.4+) 都支持它们。 Oracle 和 DB2 显然还没有,但还是有希望的。对于支持 information_schema 的 DBMS,有不同的级别,但总而言之,您可以放心找到具有相同命名字段的表、视图、列,其中包含数据库中所有表的完整列表、视图列表和查看定义 DDL 和所有列、列的大小和数据类型。

    pg_catalog 模式是标准的 PostgreSQL 元数据和核心模式。您将在此处找到预定义的全局 postgres 函数以及有关数据库的有用元数据,这些元数据非常特定于 postgres。这是 postgres 用来在内部管理事物的模式。很多信息与 information_schema 中的信息重叠,但对于 information_schema 中存在的数据,information_schema 更容易查询,并且需要更少或不需要连接来获得基本信息。

    所以对于基本查询,您最好使用information_schema

    此页面 (http://www.alberton.info/postgresql_meta_info.html) 显示了一个漂亮的查询列表,用于获取有关您的架构的信息。以下是与此问题相关的内容:

    SELECT a.attname
      FROM pg_class c, pg_attribute a, pg_type t
     WHERE c.relname = 'test2'
       AND a.attnum > 0
       AND a.attrelid = c.oid
      AND a.atttypid = t.oid
    
    -- with INFORMATION_SCHEMA:
    
    SELECT column_name
      FROM information_schema.columns
     WHERE table_name = 'test2';
    

    详细信息,有:

    SELECT a.attnum AS ordinal_position,
             a.attname AS column_name,
             t.typname AS data_type,
             a.attlen AS character_maximum_length,
             a.atttypmod AS modifier,
             a.attnotnull AS notnull,
             a.atthasdef AS hasdefault
        FROM pg_class c,
             pg_attribute a,
             pg_type t
       WHERE c.relname = 'test2'
         AND a.attnum > 0
         AND a.attrelid = c.oid
         AND a.atttypid = t.oid
    ORDER BY a.attnum;
    
    -- with INFORMATION_SCHEMA:
    
      SELECT ordinal_position,
             column_name,
             data_type,
             column_default,
             is_nullable,
             character_maximum_length,
             numeric_precision
        FROM information_schema.columns
       WHERE table_name = 'test2'
    ORDER BY ordinal_position;
    

    【讨论】:

    • 如果您的用例是创建新表或在表列元数据和另一个表之间使用 SET 操作,则必须使用 pg_class、pg_attribute 和 pg_type。否则,当您尝试对 information_schema 或 pg_table_def 表执行这些操作时,您将得到Invalid operation: Specified types or functions (one per INFO message) not supported on Redshift tables.
    【解决方案3】:

    Pg_table_def 可以提供一些有用的信息,但它不会告诉您列顺序、默认值或字符字段大小。这是一个可以向您展示所有内容的查询(请注意,自原始帖子以来我已经更新了此查询,它现在包括列编码、diststyle/distkey、sortkey 和主键以及打印出显示表所有者的语句):

    select pk.pkey, tm.schemaname||'.'||tm.tablename, 'create table '||tm.schemaname||'.'||tm.tablename
      ||' ('
      ||cp.coldef
      -- primary key
      ||decode(pk.pkey,null,'',pk.pkey)
      -- diststyle and dist key
      ||decode(d.distkey,null,') diststyle '||dist_style||' ',d.distkey)
      --sort key 
      || (select decode(skey,null,'',skey) from  (select 
        ' sortkey(' ||substr(array_to_string(
                         array( select ','||cast(column_name as varchar(100))  as str from
                               (select column_name from information_schema.columns col where  col.table_schema= tm.schemaname and col.table_name=tm.tablename) c2
                                join 
                                (-- gives sort cols
                                  select attrelid as tableid, attname as colname, attsortkeyord as sort_col_order from pg_attribute pa where 
                                  pa.attnum > 0  AND NOT pa.attisdropped AND pa.attsortkeyord > 0
                                ) st on tm.tableid=st.tableid and c2.column_name=st.colname   order by sort_col_order
                              )
                        ,'')
                      ,2,10000) || ')' as skey
       ))
      ||';'
      -- additional alter table queries here to set owner
      || 'alter table '||tm.schemaname||'.'||tm.tablename||' owner to "'||tm.owner||'";'   
       from 
    -- t  master table list
    (
    SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid ,use2.usename as owner, decode(c.reldiststyle,0,'EVEN',1,'KEY',8,'ALL') as dist_style
    FROM pg_namespace n, pg_class c,  pg_user use2 
    WHERE n.oid = c.relnamespace 
      AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
      AND c.relname <> 'temp_staging_tables_1'
      and c.relowner = use2.usesysid
    ) tm 
    -- cp  creates the col params for the create string
    join
    (select 
      substr(str,(charindex('QQQ',str)+3),(charindex('ZZZ',str))-(charindex('QQQ',str)+3)) as tableid
      ,substr(replace(replace(str,'ZZZ',''),'QQQ'||substr(str,(charindex('QQQ',str)+3),(charindex('ZZZ',str))-(charindex('QQQ',str)+3)),''),2,10000) as coldef
     from
     ( select array_to_string(array(
      SELECT  'QQQ'||cast(t.tableid as varchar(10))||'ZZZ'|| ','||column_name||' '|| decode(udt_name,'bpchar','char',udt_name) || decode(character_maximum_length,null,'', '('||cast(character_maximum_length as varchar(9))||')'   )
      -- default
      || decode(substr(column_default,2,8),'identity','',null,'',' default '||column_default||' ')
      -- nullable
      || decode(is_nullable,'YES',' NULL ','NO',' NOT NULL ') 
      -- identity 
      || decode(substr(column_default,2,8),'identity',' identity('||substr(column_default,(charindex('''',column_default)+1), (length(column_default)-charindex('''',reverse(column_default))-charindex('''',column_default)   ) )  ||') ', '')
      -- encoding
      || decode(enc,'none','',' encode '||enc)
       as str 
       from  
      -- ci  all the col info
      (
        select cast(t.tableid as int), cast(table_schema as varchar(100)), cast(table_name as varchar(100)), cast(column_name as varchar(100)), 
        cast(ordinal_position as int), cast(column_default as varchar(100)), cast(is_nullable as varchar(20)) , cast(udt_name as varchar(50))  ,cast(character_maximum_length as int),
         sort_col_order  , decode(d.colname,null,0,1) dist_key , e.enc
        from 
        (select * from information_schema.columns c where  c.table_schema= t.schemaname and c.table_name=t.tablename) c
        left join 
        (-- gives sort cols
        select attrelid as tableid, attname as colname, attsortkeyord as sort_col_order from pg_attribute a where 
         a.attnum > 0  AND NOT a.attisdropped AND a.attsortkeyord > 0
        ) s on t.tableid=s.tableid and c.column_name=s.colname
        left join 
        (-- gives encoding
        select attrelid as tableid, attname as colname, format_encoding(a.attencodingtype::integer) AS enc from pg_attribute a where 
         a.attnum > 0  AND NOT a.attisdropped 
        ) e on t.tableid=e.tableid and c.column_name=e.colname
        left join 
        -- gives dist col
        (select attrelid as tableid, attname as colname from pg_attribute a where
         a.attnum > 0 AND NOT a.attisdropped  AND a.attisdistkey = 't'
        ) d on t.tableid=d.tableid and c.column_name=d.colname
        order by ordinal_position
      ) ci 
      -- for the working array funct
      ), '') as str
     from 
     (-- need tableid
     SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid 
     FROM pg_namespace n, pg_class c
     WHERE n.oid = c.relnamespace 
       AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
     ) t 
    )) cp on tm.tableid=cp.tableid
    -- primary key query here
    left join 
     (select c.oid as tableid, ', primary key '|| substring(pg_get_indexdef(indexrelid),charindex('(',pg_get_indexdef(indexrelid))-1 ,60) as pkey
      from pg_index i , pg_namespace n, pg_class c 
      where i.indisprimary=true 
      and i.indrelid =c.oid
      and n.oid = c.relnamespace
     )  pk on tm.tableid=pk.tableid
    -- dist key
    left join
    (  select 
      -- close off the col defs after the primary key 
      ')' ||
      ' distkey('|| cast(column_name as varchar(100)) ||')'  as distkey, t.tableid
      from information_schema.columns c
      join 
      (-- need tableid
      SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid 
      FROM pg_namespace n, pg_class c
      WHERE n.oid = c.relnamespace 
        AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
      ) t on c.table_schema= t.schemaname and c.table_name=t.tablename
      join 
      -- gives dist col
      (select attrelid as tableid, attname as colname from pg_attribute a where
       a.attnum > 0 AND NOT a.attisdropped  AND a.attisdistkey = 't'
      ) d on t.tableid=d.tableid and c.column_name=d.colname
    
    ) d on tm.tableid=d.tableid 
    where tm.schemaname||'.'||tm.tablename='myschema.mytable'
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多