如何更改Amazon Redshift中的列排序

时间:2015-04-23 10:18:53

标签: amazon-redshift

有没有办法在Amazon Redshift(或Postgres,因为它基于它)中更改列排序?或者可能在特定位置添加一列?

在mysql中你可以这样做:

ALTER TABLE MY_TABLE
ADD COLUMN {NEW_COL} AFTER {EXISTING_COL}

但这在Redshift中不起作用。有什么想法吗?

4 个答案:

答案 0 :(得分:7)

从您的评论中,您实际需要的是能够COPY从具有特定顺序列的文件中的表中进行查看。

根据Redshift documentation for the COPY command

  

(column1 [,column2,...])

     

指定可选列列表以将数据字段加载到特定列中。这些列可以在COPY语句中以任何顺序排列,但是当从平面文件(例如在Amazon S3存储桶中)加载时,它们的顺序必须与源数据的顺序匹配。   [...]   如果未指定列列表,则该命令的行为就像指定了完整的有序列列表一样。

因此,您只需在COPY语句中指定列,而不是重新排序表中的列,而不是some of the examples in the docs

copy venue_new(venueid, venuename, venuecity, venuestate) 
from 's3://mybucket/data/venue_noseats.txt' 
credentials 'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
delimiter '|';

答案 1 :(得分:4)

答案是否定的,redshift不(轻松)支持列重排,这很奇怪,因为我认为表存储为单独的列。没有卸载/加载或表复制就无法做到这一点。

据说卸载/加载是首选方法,因为它将利用您在表中配置的任何并行性。

因此,标准方法是必要的:

只有一个列(转储列,删除列,添加列,重新加载列)可能有“秘密方式”来执行此操作,但这听起来非常粗略,应该避免使用。

答案 2 :(得分:0)

Redshift根本不支持订购。 在我的情况下,我必须解决同样的问题,这就是我做到的。

最好的选择是卸载,逐个改变并重新创建。

1)卸载到S3

unload ('select (Column1,column2,Column3,...,Column_n) from orginal_table') to 's3://<your_bucket>/<your_file>' CREDENTIALS 'aws_access_key_id=<your_key>;aws_secret_access_key=<your_secret>' MANIFEST  DELIMITER '|'  GZIP   NULL AS 'null_string' ESCAPE ALLOWOVERWRITE;

2)删除和/或重新创建

Create duplicate_table(Column1,column2,Column3,...,Column_n);**with new sequence make sure your seq

3)重新加载。

copy duplicate_table(Column1,column2,Column3,...,Column_n) from  's3://<your_bucket>/<your_file>manifest' CREDENTIALS 'aws_access_key_id=<your_key>;aws_secret_access_key=<your_secret>' MANIFEST  DELIMITER '|'  GZIP   NULL AS 'null_string' ESCAPE ALLOWOVERWRITE;

答案 3 :(得分:0)

您只需按照所需的顺序在Redshift中创建一个新表

CREATE TABLE temp_table_name (column1 dtype1, column2 dtype2, column3 dtype 3 ...);

并按所需顺序从源表中插入数据。

INSERT INTO temp_table_name (SELECT column1, column2, column3 ... FROM table_name);

然后删除原始表

DROP TABLE table_name;

并将临时表重命名为原始表

ALTER TABLE temp_table_name RENAME TO table_name;