如何从Redshift获取表和列信息?

时间:2014-01-22 03:09:53

标签: amazon-redshift

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

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

3 个答案:

答案 0 :(得分:18)

使用PG_TABLE_DEF表获取该信息:

看起来像这样:

select * from pg_table_def where tablename = 't2';
schemaname|tablename|column|  type   | encoding | distkey |sortkey| notnull 
----------+---------+------+---------+----------+---------+-------+---------
public    | t2      | c1   | bigint  | none     | t       |     0 | f
public    | t2      | c2   | integer | mostly16 | f       |     0 | f
public    | t2      | c3   | integer | none     | f       |     1 | t
public    | t2      | c4   | integer | none     | f       |     2 | f
(4 rows)

答案 1 :(得分:8)

来自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;

答案 2 :(得分:4)

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'