【问题标题】:How to change column ordering in Amazon Redshift如何更改 Amazon Redshift 中的列顺序
【发布时间】:2015-07-01 11:09:08
【问题描述】:

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

在mysql中你可以这样做:

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

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

【问题讨论】:

  • 纯粹主义者会争辩说您永远不需要这样做,因为列应该按名称而不是顺序来引用,但实际上 SQL 确实将列视为有序,因此它排序of 想要选择那个顺序是有道理的。 The ALTER TABLE docs 没有提及任何方法,但这并不能证明没有某种解决方法,尤其是在 Redshift 中,它使用“面向列”的存储模型。
  • 使用 COPY 命令导入数据时,需要表中的列顺序与 CSV 文件的列顺序匹配。
  • 可能更好的链接是the Redshift docs,因为它在一段时间前与 Postgres 不同。但是,现在你提到 COPY,我想我们这里可能有一个 X/Y Problem...
  • 请问 - 为什么需要更改列的顺序?我看它的方式,红移列顺序应该无关紧要。
  • 因为马丁说的。当您复制以从 s3 上传表格时,例如您需要 csv/parquet 的列与 redshift 表的顺序相同,否则它将不起作用

标签: amazon-redshift


【解决方案1】:

从您的 cmets 看来,您真正需要的是能够从具有特定顺序列的文件中将 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 '|';

【讨论】:

  • 更改复制命令比更改列顺序对我来说要困难得多。似乎有办法在 postgres 中做到这一点,我正在检查它是否可以在 Redshift 中工作:stackoverflow.com/questions/285733/… 但是,感谢您的努力
  • @MartinTaleski 好的,认为这是值得的建议。请注意,视图无助于写入表,其他选项需要手动删除并重新插入现有数据。
  • 不管他需要什么,标题是“如何在 Amazon Redshift 中更改列排序”。我实际上需要这样做,原因超出了这个问题的范围。 “做一些完全不同的事情”应该添加到实际答案中。
【解决方案2】:

答案是否定的,redshift 不(很容易)支持列混洗,这很奇怪,因为我相信表是作为单独的列存储的。如果没有卸载/加载或表复制,就无法做到这一点。

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

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

可能有一种“秘密方法”可以只使用有问题的一列(转储列、删除列、添加列、重新加载列),但这听起来非常粗略,应该避免。

【讨论】:

    【解决方案3】:

    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;
    

    【讨论】:

    • Redshift 确实支持alter table。有关详细信息,请参阅their docs。不过,他们似乎不支持通过它对列重新排序。
    • 是的,同意! Red-shift 确实支持更改,但这里我的意思是更改仅用于订购。我已经更正了我的陈述。
    【解决方案4】:

    您可以简单地在 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;
    

    【讨论】:

      【解决方案5】:

      给定 old_table (oldcolumn1 int, oldcolumn2 int),您可以执行以下操作:

      create table new_table (
        newcolumn0 int,
        oldcolumn1 int,
        oldcolumn2 int
      );
      alter table new_table append from old_table; --EMPTIES old_table and COMMITS!
      drop table old_table;
      alter table new_table rename to old_table;
      

      这种方法不适合胆小的人,请阅读 ALTER TABLE APPEND 上的文档。 https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE_APPEND.html

      如果没问题,优点是: ..不关心具有相同名称/类型的列的列顺序 ..不需要复制 ..应该比 insert..select 更快

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-10
        • 1970-01-01
        • 1970-01-01
        • 2019-10-27
        • 2011-04-15
        • 2021-01-26
        相关资源
        最近更新 更多