เปลี่ยนประเภทข้อมูลคอลัมน์ใน Amazon Redshift


85

จะเปลี่ยนประเภทข้อมูลคอลัมน์ในฐานข้อมูล Amazon Redshift ได้อย่างไร

ฉันไม่สามารถเปลี่ยนประเภทข้อมูลคอลัมน์ใน Redshift ได้ มีวิธีใดในการแก้ไขประเภทข้อมูลใน Amazon Redshift หรือไม่


6
"สร้างตารางตามที่เลือก ... " และออกแบบตารางใหม่ของคุณด้วยประเภทคอลัมน์ที่ดีกว่า
Guy

คำตอบ:


137

ตามที่ระบุไว้ในเอกสาร ALTER TABLEคุณสามารถเปลี่ยนความยาวของ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)


4
แก้ไขหรือเปลี่ยนแปลงคำสั่ง DDL ใด ๆ ที่กระทำโดยทันทีโดยไม่คำนึงถึงสภาพอากาศว่ามีการทำธุรกรรมหรือไม่
Raniendu Singh

@RanienduSingh ฐานข้อมูลบางส่วนรองรับคำสั่ง DDL แบบธุรกรรม ฉันไม่พบรายการที่เชื่อถือได้ แต่คำสั่ง DDL ส่วนใหญ่ใน Redshift ดูเหมือนจะทำงานในธุรกรรม อย่างไรก็ตามฉันคิดว่าการจัดลำดับการดำเนินการใหม่ที่คล้ายกับวิธีการที่อธิบายไว้ที่นี่ (เปลี่ยนชื่อเพิ่มอัปเดตวาง) อาจมีประสิทธิภาพมากกว่า: simple.com/engineering/safe-migrations-with-redshift
Matt Good

1
มันเป็นมูลค่า noting ว่ามันเป็นไปได้ที่จะเพิ่มขนาดของคอลัมน์ varchar - การดูคำตอบ user0000 ด้านล่างและเชื่อมโยงไปยังเอกสาร ( docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html )
วิลลิส

1
@Tomasz Tybulewicz คุณช่วยอัพเดทคำตอบของคุณรวมถึงคำตอบของ user0000 ได้ไหม คำตอบของคุณถูกต้องในเวลานั้น แต่ฉันเข้าใจผิด โชคดีที่ฉันอ่านคำตอบของ user0000 เช่นกัน
Vzzarr

43

เพื่อหลีกเลี่ยงการเปลี่ยนแปลงสคีมาที่กล่าวถึงโดย 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;

1
นี่เป็นวิธีที่เราใช้เช่นกันเพื่อหลีกเลี่ยงการคัดลอกข้อความไม่ตรงแนว
smb

1
โปรดทราบว่ามุมมองใด ๆ ที่เคยเลือกจากตารางเก่ายังคงชี้ไปที่ตารางเก่า drop tableแบบสอบถามจะแสดงข้อผิดพลาดการพึ่งพาซึ่งสามารถ แต่ไม่ควรละเลย

1
ขอบคุณสำหรับสิ่งนี้มันมีประโยชน์มาก ฉันใช้มันบนโต๊ะที่มี 31 ล้านแถวและใช้เวลาเพียง 3 นาทีโดยใช้ประเภท dc1.large เยี่ยมมาก! ฉันยังใช้รูปแบบที่ง่ายกว่าเล็กน้อย:INSERT INTO <TABLE_NAME> SELECT * FROM <TABLE_NAME>_OLD;
ทอม

การห่อหุ้มด้วย TRANSACTION มีความสำคัญมาก
louis_guitton

16

(อัปเดตล่าสุด) เป็นไปได้ที่จะเปลี่ยนประเภทของคอลัมน์ varchar ใน Redshift

ALTER COLUMN column_name TYPE new_data_type

ตัวอย่าง:

CREATE TABLE t1 (c1 varchar(100))

ALTER TABLE t1 ALTER COLUMN c1 TYPE varchar(200)

นี่คือลิงค์เอกสาร


นี้ทำงานได้อย่างสมบูรณ์ ซับที่ดีที่จะไม่เปลี่ยนสคีมาเลย แต่อัปเดตประเภทข้อมูล นี่น่าจะเป็นคำตอบใหม่ล่าสุด!
Timothy Mcwilliams

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;

ปัญหาเดียวในการสร้างตารางใหม่คือคุณจะต้องให้สิทธิ์อีกครั้งและหากตารางใหญ่เกินไปจะต้องใช้เวลาสักครู่


1
นี่ค่อนข้างคล้ายกับคำตอบที่มีอยู่จาก Wolli เพื่อเปลี่ยนชื่อแล้วคัดลอกข้อมูลตารางเก่าลงในสคีมาใหม่ ทั้งสองจะคงลำดับคอลัมน์ไว้ แต่โซลูชันนี้ด้วยตารางชั่วคราวต้องคัดลอกข้อมูลสองครั้ง หนึ่งครั้งเพื่อคัดลอกลงในตารางชั่วคราวและอีกรายการหนึ่งเพื่อคัดลอกกลับไปที่ตารางใหม่ การเปลี่ยนชื่อตารางควรจะเร็วขึ้นด้วยการทำสำเนาเพียงชุดเดียว
Matt Good


3

Redshift เป็นฐานข้อมูลคอลัมน์ไม่อนุญาตให้คุณแก้ไขประเภทข้อมูลโดยตรงอย่างไรก็ตามด้านล่างนี้เป็นแนวทางหนึ่งที่จะเปลี่ยนลำดับคอลัมน์

ขั้นตอน -

1. ตารางแก้ไขเพิ่มคอลัมน์ใหม่ลงในตาราง 2. อัปเดตค่าคอลัมน์ใหม่ด้วยค่าคอลัมน์เก่า 3. ปรับเปลี่ยนตารางเพื่อวางคอลัมน์เก่า 4. ตารางเพื่อเปลี่ยนชื่อคอลัมน์เป็นคอลัมน์เก่า

หากคุณไม่ต้องการเปลี่ยนลำดับของคอลัมน์วิธีแก้ปัญหาก็คือ

1. สร้างตารางชั่วคราวด้วยชื่อคอลัมน์ใหม่

  1. คัดลอกข้อมูลจากตารางเก่าไปยังตารางใหม่

  2. วางโต๊ะเก่า

  3. เปลี่ยนชื่อ newtable เป็น oldtable

  4. สิ่งสำคัญอย่างหนึ่งสร้างตารางใหม่โดยใช้คำสั่ง like แทนการสร้างแบบธรรมดา


2

วิธีนี้ใช้ได้กับการแปลงคอลัมน์ 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;

0

ยกเลิกการดาวน์โหลดและคัดลอกด้วยกลยุทธ์การเปลี่ยนชื่อตารางควรเป็นวิธีที่มีประสิทธิภาพที่สุดในการดำเนินการนี้หากการรักษาโครงสร้างตาราง (ลำดับแถว) เป็นสิ่งสำคัญ

นี่คือตัวอย่างที่เพิ่มเข้ามาในคำตอบนี้

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;

-2

สำหรับการอัปเดตคอลัมน์เดียวกันใน redshift สิ่งนี้จะใช้ได้ดี

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

คุณสามารถมีหลายประโยคโดยใช้และเพื่อขจัดความสับสนสำหรับ sql

ไชโย !!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.