はじめに
Verticaでのカラムのデータ型の変更についてご紹介致します。
ここでは、以下のような2種類のデータ型の変更について取り上げます。
・データ型の変換(あるデータ型を別のデータ型に変換)
・カラム幅の変更(データ型の種類は変えず、カラム幅を変更)
それぞれについて、以下に記載致します。
データ型の変換
バイナリ型
BINARY型とVARBINARY型の間では変換はできません。
キャラクタ型
すべての変換ができます。
(CHAR型とVARCHAR型の変換など)
数値データ型
INTEGER型、INT型、BIGINT型、TINYINT型、INT8型、SMALLINT型、NUMERIC型(スケール(scale)が18以下と精度(precision)が0の場合)では変換ができます。
ただし、NUMERIC型では精度の値を変更する事はできませんが、スケールの値を変更する事は可能です。「0~18」、「19~37」といった範囲内で変更する事ができます。
BOOLEAN型
他のデータ型への変換はできません。
DATE型とTIME型
変換できません。
浮動小数点型
変換できません
BINARY型 と VARBINARY型
変換できません
カラム幅の変更
カラム幅の変更には、拡張と収縮がありますが、同じデータ型であれば拡張も収縮もする事ができます。
また、Verticaは実際にカラム幅を変更する前に格納されたデータを検証し問題がある場合には変更処理を行いません。
例えば、varchar(20)からvarchar(10)に変更(収縮)するケースで、そのカラムに11文字以上のデータが格納されている場合では、変更してしまう事でデータが途中で切れてしまう事になります。
このような事を防ぐために、Verticaは変更前にデータを検証します。
例
varchar(20)からvarchar(10)に変更(収縮)するとします。
まずは、成功する場合を見てみましょう。
変更(収縮)対象のカラムには、最も長いもので5文字のデータがあるとします。
dbadmin=> CREATE TABLE T1 (COL1 INT, COL2 VARCHAR(20));
dbadmin=> \d T1;
List of Fields by Tables
Schema | Table | Column | Type | Size | Default | Not Null | Primary Key | Foreign Key
--------+-------+--------+-------------+------+---------+----------+-------------+-------------
public | T1 | COL1 | int | 8 | | f | f |
public | T1 | COL2 | varchar(20) | 20 | | f | f |
(2 rows)
dbadmin=> INSERT INTO T1 VALUES(1, 'a');
dbadmin=> INSERT INTO T1 VALUES(2, 'bbb');
dbadmin=> INSERT INTO T1 VALUES(3, 'ccccc');
dbadmin=> COMMIT;
COMMIT
dbadmin=> SELECT * FROM T1;
COL1 | COL2
------+-------
1 | a
2 | bbb
3 | ccccc
(3 rows)この状態でcol2のカラムをvarchar(20)からvarchar(10)に変更(収縮)します。
dbadmin=> ALTER TABLE T1 ALTER COLUMN col2 SET DATA TYPE VARCHAR(10);
ALTER TABLE
dbadmin=> \d T1;
List of Fields by Tables
Schema | Table | Column | Type | Size | Default | Not Null | Primary Key | Foreign Key
--------+-------+--------+-------------+------+---------+----------+-------------+-------------
public | T1 | COL1 | int | 8 | | f | f |
public | T1 | COL2 | varchar(10) | 10 | | f | f |
(2 rows)
dbadmin=> SELECT * FROM T1;
COL1 | COL2
------+-------
1 | a
2 | bbb
3 | ccccc
(3 rows)問題なくカラム幅が変更された事が確認できました。
つぎに、失敗する場合を見てみましょう。
先ほど使ったテーブルをクリアするために一旦dropし、同じデータを挿入します。
ただし、今回は11文字のデータを追加する点が先ほどと異なります。
dbadmin=> DROP TABLE T1;
DROP TABLE
dbadmin=> CREATE TABLE T1 (COL1 INT, COL2 VARCHAR(20));
dbadmin=> \d T1;
List of Fields by Tables
Schema | Table | Column | Type | Size | Default | Not Null | Primary Key | Foreign Key
--------+-------+--------+-------------+------+---------+----------+-------------+-------------
public | T1 | COL1 | int | 8 | | f | f |
public | T1 | COL2 | varchar(20) | 20 | | f | f |
(2 rows)
dbadmin=> INSERT INTO T1 VALUES(1, 'a');
dbadmin=> INSERT INTO T1 VALUES(2, 'bbb');
dbadmin=> INSERT INTO T1 VALUES(3, 'ccccc');
dbadmin=> INSERT INTO T1 VALUES(4, 'ddddddddddd');
dbadmin=> COMMIT;
COMMIT
dbadmin=> SELECT * FROM T1;
COL1 | COL2
------+-------------
1 | a
2 | bbb
3 | ccccc
4 | ddddddddddd
(4 rows)この状態でcol2のカラムをvarchar(20)からvarchar(10)に変更(収縮)します。
dbadmin=> ALTER TABLE T1 ALTER COLUMN col2 SET DATA TYPE VARCHAR(10);
ROLLBACK 2378: Cannot convert column "col2" to type "varchar(10)"
HINT: Verify that the data in the column conforms to the new type
dbadmin=> \d t1;
List of Fields by Tables
Schema | Table | Column | Type | Size | Default | Not Null | Primary Key | Foreign Key
--------+-------+--------+-------------+------+---------+----------+-------------+-------------
public | T1 | COL1 | int | 8 | | f | f |
public | T1 | COL2 | varchar(20) | 20 | | f | f |
(2 rows)varchar(10)に変更してしまうと、4行目にある11文字のデータが切れてしまうため、Verticaはそれを検知して変換作業を行いませんでした。
参考資料
検証バージョンについて
この記事の内容はVertica 9.1で確認しています。