【问题标题】:Alter column data type in Amazon Redshift在 Amazon Redshift 中更改列数据类型
【发布时间】:2013-06-10 17:09:50
【问题描述】:

如何更改 Amazon Redshift 数据库中的列数据类型?

我无法更改 Redshift 中的列数据类型;有什么方法可以修改 Amazon Redshift 中的数据类型?

【问题讨论】:

  • "Create table as select..." 并使用更好的列类型设计新表。

标签: amazon-web-services amazon-redshift


【解决方案1】:

您可以使用以下语句:

ALTER TABLE <table name --etl_proj_atm.dim_card_type >
ALTER COLUMN <col name --card_type> type varchar(30)

【讨论】:

    【解决方案2】:

    UNLOADCOPY 使用表重命名策略应该是最有效的方法如果保留表结构(行顺序)很重要的话。

    这是添加到this 答案的示例。

    BEGIN TRANSACTION;
    
    ALTER TABLE <TABLE_NAME> RENAME TO <TABLE_NAME>_OLD;
    CREATE TABLE <TABLE_NAME> ( <NEW_COLUMN_DEFINITION> );
    UNLOAD ('select * from <TABLE_NAME>_OLD') TO 's3://bucket/key/unload_' manifest;
    COPY <TABLE_NAME> FROM 's3://bucket/key/unload_manifest'manifest;
    
    END TRANSACTION;
    

    【讨论】:

      【解决方案3】:

      ALTER TABLE documentation 中所述,您可以使用以下方法更改VARCHAR 列的长度

      ALTER TABLE table_name
      {
          ALTER COLUMN column_name TYPE new_data_type 
      }
      

      对于其他列类型,我能想到的只是添加一个具有正确数据类型的新列,然后将旧列中的所有数据插入新列,最后删除旧列。

      使用类似的代码:

      ALTER TABLE t1 ADD COLUMN new_column ___correct_column_type___;
      UPDATE t1 SET new_column = column;
      ALTER TABLE t1 DROP COLUMN column;
      ALTER TABLE t1 RENAME COLUMN new_column TO column;
      

      架构会发生变化 - 新添加的列将在表中的最后一个(这可能是 COPY 语句的问题,请记住这一点 - 您可以使用 COPY 定义列顺序)

      【讨论】:

      • ALTER 或就此而言,任何 DDL 语句都会立即提交,无论天气如何,它是否包含在事务中。
      • @RanienduSingh 一些数据库确实支持事务性 DDL 语句。我还没有找到权威列表,但 Redshift 中的大多数 DDL 语句似乎都可以在事务中工作。但是,我认为重新排序类似于此处描述的方法(重命名、添加、更新、删除)的操作可能更健壮:simple.com/engineering/safe-migrations-with-redshift
      • 值得注意的是,现在可以增加 varchar 列的大小——请参阅下面 user0000 的回答和文档链接 (docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html)
      • @Tomasz Tybulewicz 您能否更新您的答案,包括 user0000 的答案?你当时的回答是正确的,但我被误导了。幸运的是,我也阅读了 user0000 的回答
      • 我不知道为什么第一个子句格式在我的 SQL 客户端中不起作用,例如Postico 和 DataGrip,而 @shruti pawar 的答案有效。
      【解决方案4】:

      (最近更新)可以在 Redshift 中更改 varchar 列的类型。

      ALTER COLUMN column_name TYPE new_data_type
      

      例子:

      CREATE TABLE t1 (c1 varchar(100))
      
      ALTER TABLE t1 ALTER COLUMN c1 TYPE varchar(200)
      

      这里是文档link

      【讨论】:

      • 这非常有效。一个不错的内衬,它根本不会更改架构,但会更新数据类型。这应该是新的更新答案!
      【解决方案5】:

      此方法适用于将(大)int 列转换为 varchar

      -- Create a backup of the original table
      create table original_table_backup as select * from original_table;
      
      -- Drop the original table, and then recreate with new desired data types
      drop table original_table;
      
      create table original_table (
        col1 bigint,
        col2 varchar(20) -- changed from bigint
      );
      
      -- insert original entries back into the new table
      insert into original_table select * from original_table_backup;
      
      -- cleanup
      drop original_table_backup;
      

      【讨论】:

        【解决方案6】:

        对于更新 redshift 中的同一列,这可以正常工作

        UPDATE table_name 
        SET column_name = 'new_value' WHERE column_name = 'old_value'
        

        使用and可以在where中有多个子句,避免sql混淆

        干杯!!

        【讨论】:

          【解决方案7】:

          Redshift 是列式数据库,不允许您直接修改数据类型, 但是下面是一种方法,这将改变列顺序。

          步骤 -

          1.Alter table 向表中添加新列 2.用旧列值更新新列值 3.Alter table 删除oldcolumn 4.alter table 将column重命名为oldcolumn

          如果您不想更改列的顺序,那么解决方案是

          1.用新列名创建临时表

          1. 将数据从旧表复制到新表。

          2. 删除旧表

          3. 将新表重命名为旧表

          4. 使用like 命令创建新表而不是简单创建很重要。

          【讨论】:

            【解决方案8】:

            如果您不想更改列顺序,可以选择创建一个临时表,删除并创建具有所需大小的新表,然后再次批量处理数据。

            CREATE TEMP TABLE temp_table AS SELECT * FROM original_table;
            DROP TABLE original_table;
            CREATE TABLE original_table ...
            INSERT INTO original_table SELECT * FROM temp_table;
            

            重新创建表的唯一问题是您需要再次授予权限,如果表太大,则需要一些时间。

            【讨论】:

            • 这与 Wolli 的现有答案非常相似,即重命名然后将旧表数据复制到新模式中。两者都将保持列顺序,但是这个带有临时表的解决方案需要复制数据两次。一次复制到临时表中,另一次复制回新表。只需执行一份副本,重命名表应该会更快。
            【解决方案9】:

            为了避免 Tomasz 提到的架构更改:

            BEGIN TRANSACTION;
            
            ALTER TABLE <TABLE_NAME> RENAME TO <TABLE_NAME>_OLD;
            CREATE TABLE <TABLE_NAME> ( <NEW_COLUMN_DEFINITION> );
            INSERT INTO <TABLE_NAME> (<NEW_COLUMN_DEFINITION>)
            SELECT <COLUMNS>
            FROM <TABLE_NAME>_OLD;
            DROP TABLE <TABLE_NAME>_OLD;
            
            END TRANSACTION;
            

            【讨论】:

            • 这也是我们使用的方法,以避免复制语句错位。
            • 请记住,任何用于从旧表中选择的视图都继续指向旧表。 drop table 查询将显示可以但不应绕过的依赖错误。
            • 谢谢你,这真的很有帮助。我在一个有 3100 万行的表上使用它,使用 dc1.large 类型只花了 3 分钟。伟大的!我还使用了一个稍微简单的形式:INSERT INTO &lt;TABLE_NAME&gt; SELECT * FROM &lt;TABLE_NAME&gt;_OLD;
            • 用TRANSACTION封装很重要
            【解决方案10】:
            ALTER TABLE publisher_catalogs ADD COLUMN new_version integer;
            
            update publisher_catalogs set new_version = CAST(version AS integer);
            ALTER TABLE publisher_catalogs DROP COLUMN version RESTRICT;
            ALTER TABLE publisher_catalogs RENAME new_version to version;
            

            【讨论】:

              猜你喜欢
              • 2015-07-01
              • 2016-09-26
              • 1970-01-01
              • 2017-12-23
              • 2012-03-19
              • 1970-01-01
              • 1970-01-01
              • 2019-04-29
              相关资源
              最近更新 更多