AmazonRedshiftで列のデータ型を変更する


85

Amazon Redshiftデータベースの列データ型を変更するにはどうすればよいですか?

Redshiftで列のデータ型を変更できません。Amazon Redshiftでデータ型を変更する方法はありますか?


6
「selectとしてテーブルを作成...」そして、より適切な列タイプで新しいテーブルを設計します。
ガイ

回答:


135

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
ALTERまたはそれに関しては、DDLステートメントは、トランザクションにラップされているかどうかに関係なく、すぐにコミットします。
Raniendu Singh 2016

@RanienduSingh一部のデータベースは、トランザクションDDLステートメントをサポートしています。信頼できるリストが見つかりませんが、RedshiftのほとんどのDDLステートメントはトランザクションで機能しているようです。ただし、ここで説明するアプローチ(名前の変更、追加、更新、削除)と同様の操作の並べ替えは、より堅牢になる可能性があると思い
Matt Good

1
varchar列のサイズを増やすことが可能になったことは注目に値します-以下のuser0000の回答とドキュメントへのリンク(docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html)を参照してください
willis

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 2017年

1
古いテーブルから選択するために使用されたビューは、引き続き古いテーブルを指していることに注意してください。drop tableクエリが可能依存関係のエラーが表示されますが、バイパスすべきではありません。

1
これをありがとう、それは本当に役に立ちました。3100万行のテーブルで使用しましたが、dc1.largeタイプを使用すると3分しかかかりませんでした。すごい!また、少し単純な形式を使用しましたINSERT INTO <TABLE_NAME> SELECT * FROM <TABLE_NAME>_OLD;
トム

TRANSACTIONでカプセル化することは非常に重要である
louis_guitton

16

(最近の更新)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)

これがドキュメントのリンクです


これは完全に機能します。スキーマをまったく変更せず、データ型を更新する優れたワンライナー。これは新しく更新された答えになるはずです!
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の既存の回答と非常によく似ています。どちらも列の順序を維持しますが、一時テーブルを使用するこのソリューションでは、データを2回コピーする必要があります。1回は一時テーブルにコピーし、もう1回は新しいテーブルにコピーして戻します。テーブルの名前変更は、1つのコピーを実行するだけでより速くなるはずです。
マットグッド

4
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;

3

Redshiftは列型データベースであるため、データ型を直接変更することはできませんが、以下は列の順序を変更する1つのアプローチです。

手順-

1.テーブルを変更してテーブルにnewcolumnを追加します2.newcolumn値をoldcolumn値で更新します3.テーブルを変更してoldcolumnを削除します4.テーブルを変更してcolumnnの名前をoldcolumnに変更します

列の順序を変更したくない場合、解決策は次のようになります。

1.新しい列名で一時テーブルを作成します

  1. 古いテーブルから新しいテーブルにデータをコピーします。

  2. 古いテーブルをドロップ

  3. newtableの名前をoldtableに変更します

  4. 重要なことの1つは、単純な作成ではなく、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

テーブル構造(行の順序)を保持することが重要な場合はテーブルの名前変更戦略を使用したUNLOADおよびCOPYが、この操作を実行するための最も効率的な方法です。

これがこの答えに追加する例です。

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の混乱を取り除くために、andを使用してwhereに複数の句を含めることができます

乾杯!!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.