【问题标题】:How to change table schema after created in Redshift?在 Redshift 中创建后如何更改表模式?
【发布时间】:2014-04-28 05:45:41
【问题描述】:

Postgre 支持如下操作:

ALTER TABLE name
    SET SCHEMA new_schema

该操作在 Redshift 中不起作用。有什么办法吗?

我尝试更新 pg_class 为表设置 relnamespace(schema id),这需要超级用户帐户,并且 usecatupd 在 pg_shadow 表中为 true。但是我得到了权限被拒绝的错误。唯一可以修改pg系统表的账号是rdsdb。

server=# select * from pg_user;
 usename   | usesysid | usecreatedb | usesuper | usecatupd |  passwd  | valuntil |            useconfig             
------------+----------+-------------+----------+-----------+----------+----------+----------------------------------
 rdsdb      |        1 | t           | t        | t         | ******** |          | 
 myuser     |      100 | t           | t        | f         | ******** |          | 

所以真的 redshift 不允许这样做吗?

【问题讨论】:

    标签: amazon-redshift


    【解决方案1】:

    最好的方法是创建一个具有所需架构的新表,然后使用旧表中的数据执行 INSERT .... SELECT。

    然后删除当前表并使用 ALTER TABLE 重命名新表。

    【讨论】:

    • 请注意,如果您使用create newschema.table1 (like table1); 创建新表,sortkey、distkey 和约束将被复制,但主键和外键不会(它们只是提供信息)。您也可以使用select * into newschema.table1 from table1; 复制表,而不必先创建新表,但这不会复制非空约束、主键和外键。
    • @DmitriiI。此查询是否还复制与旧表关联的授权?
    【解决方案2】:

    您可以使用

    创建一个新表

    CREATE TABLE schema1.tableName(LIKE schema2.tableName INCLUDING DEFAULTS);

    然后使用 INSERT INTO 语句将表的内容从一个模式复制到另一个模式

    后跟 DROP TABLE 删除表。

    【讨论】:

      【解决方案3】:

      现在最快的方法如下:

      CREATE TABLE my_new_schema.my_table (LIKE my_old_schema.my_table);
      ALTER TABLE my_new_schema.my_table APPEND FROM my_old_schema.my_table;
      DROP TABLE my_old_schema.my_table;
      

      在这种情况下,my_old_schema.my_table 的数据只是简单地重新映射为属于 my_new_schema.my_table。比INSERT INTO 快得多。

      重要提示:“数据成功追加到目标表后,源表为空”(来自AWS docs on ALTER TABLE APPEND),所以要小心运行ALTER语句只有一次

      请注意,您可能必须删除并重新创建任何依赖于my_old_schema.my_table 的视图。 更新:如果您经常这样做,您应该使用WITH NO SCHEMA BINDING 创建您的视图,它们将继续指向正确的表,而无需重新创建。

      【讨论】:

      • 由于视图的问题,我建议创建视图“没有架构绑定”。
      • 这种方法需要注意的一点是,虽然它非常快,但它也会在操作结束时清空源表。学到了这个很难,我希望我已经在 ALTER TABLE ... APPEND 操作上完成了 RTFM 的所有重要步骤,在运行它两次并以空的源表和目标表结束之后。答案是有效的。
      • 作为一个没有被这件事烧死的人,让我说亚马逊只是让你从一个空表中追加,没有任何警告、确认或任何东西,这是不可原谅的。之后信息中甚至没有任何内容,告诉您您刚刚丢失了数据。简直无脑。
      【解决方案4】:

      我就是这样做的。

      -- 如果您已经有一个备份,则删除

      DROP TABLE IF EXISTS TABLE_NAME_BKP CASCADE;
      

      --创建两个备份,一个工作,最后会被删除,另外一个是真正的备份

      SELECT * INTO TABLE_NAME_BKP FROM TABLE_NAME;
      SELECT * INTO TABLE_NAME_4_WORK FROM TABLE_NAME;
      

      --我们也可以做下面的 ALTER,但是这包含主键约束名称,因此你不能创建具有相同约束名称的新表

      ALTER TABLE TABLE_NAME RENAME TO TABLE_NAME_4_WORK;
      

      -- 确保您已复制

      SELECT COUNT(*) FROM TABLE_NAME;
      SELECT COUNT(*) FROM TABLE_NAME_4_WORK; 
      

      -- 创建新表架构

          DROP TABLE IF EXISTS TABLE_NAME CASCADE;
      
          CREATE TABLE TABLE_NAME     (
             ID           varchar(36)     NOT NULL,
             OLD_COLUMN   varchar(36),
             NEW COLUMN_1 varchar(36)
          )
          compound sortkey (ID, OLD_COLUMN, NEW COLUMN_1);
      
          ALTER TABLE TABLE_NAME
          ADD CONSTRAINT PK__TAB_NAME__ID
          PRIMARY KEY (id);
      

      -- 将旧数据复制到新数据

      INSERT INTO TABLE_NAME (
           id,    
           OLD_COLUMN)
       (SELECT     
           id,        
           OLD_COLUMN FROM TABLE_NAME_4_WORK) 
      

      -- 删除工作表 TABLE_NAME_4_WORK

       DROP TABLE TABLE_NAME_4_WORK;
      

      -- 比较 BKP 和新表行,并保留 BKP 表一段时间。

       SELECT COUNT(*) FROM TABLE_NAME_BKP;
      
       SELECT COUNT(*) FROM TABLE_NAME;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-24
        • 1970-01-01
        • 2019-10-27
        • 1970-01-01
        • 2018-06-13
        • 2021-12-30
        • 2016-11-24
        • 2017-11-03
        相关资源
        最近更新 更多