AWS Schema Conversion Toolを使ってNetezzaからRedshiftにスキーマ変換する

2017.01.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

最新のAWS Schema Conversion Tool(SCT)は、Netezza のスキーマを Redshift のスキーマに変換・生成できるようになりましたので、この機能を試してみたいと思います。検証のポイントは、ズバリ2つの異なるDWHのスキーマ定義をどのように解釈して、どのように変換するかです。

AWS Schema Conversion Tool Adds Netezza and Greenplum Sources

AWS Schema Conversion Tool(SCT)とは

AWS Schema Conversion Tool(以降、SCTと略す)はソースデータベースのスキーマ、ビュー、ストアドプロシージャ、関数といったカスタムコードの大部分を自動的にターゲットデータベース互換フォーマットへと変換することにより、異種データベース間の移行を容易にするツールです。

構成

今回はNetezzaと同一ネットワーク上のMacにSCTをインストールしました。SCTはJDBCドライバ経由で Netezza と Redshift 双方に接続します。

20160107-system

SCTとDMS(AWS Database Migration Service)の関係

SCTはDMSが対応してくれないスキーマ移行をサポートしてくれる補助的な位置付けのツールです。

サポートするデータベース

ソースデータベースにはオンプレミス、または Amazon RDS か Amazon EC2、ターゲットデータベースには Amazon RDS または Amazon Redshift か Amazon EC2 のいずれかを使用できます。

AWS Schema Conversion Tool では、以下のOLTPの変換がサポートされています。

ソースデータベース Amazon RDS 上のターゲットデータベース
Microsoft SQL Server (version 2008 and later) Amazon Aurora (MySQL or PostgreSQL), Microsoft SQL Server, MySQL, PostgreSQL
MySQL (version 5.6 and later) Amazon Aurora (PostgreSQL), MySQL, PostgreSQL
Oracle (version 10.2 and later) Amazon Aurora (MySQL or PostgreSQL), MySQL, Oracle, PostgreSQL
PostgreSQL (version 9.1 and later) Amazon Aurora (MySQL), MySQL, PostgreSQL

AWS Schema Conversion Tool では、以下のDWHの変換がサポートされています。

ソースデータベース ターゲットデータベース(Amazon Redshiftのみ)
Greenplum Database (version 4.3 and later) Amazon Redshift
Netezza (version 7.2 and later) Amazon Redshift
Oracle (version 11 and later) Amazon Redshift
Teradata (version 15 and later) Amazon Redshift

AWS Schema Conversion Tool

AWS Schema Conversion Tool - User Guide (英語)

検証用ソースデータベース(Netezza)環境の準備

検証用ソースデータベース(Netezza)

Netezzaに以下のスキーマ作成しました。

  • データベースの管理者ユーザー:admin
  • データベース:cmdb
  • オブジェクトのユーザー:cmuser
  • テーブル:users、categorise、elblogdb、campaigns、情報
  • ビュー:users_vw

検証用テーブルとビュー

テーブルとビューはそれぞれ以下の検証目的で用意しました。

  • usersテーブル:分散キーが1つのテーブル検証
  • categoriseテーブル:分散キーが2つのテーブル検証
  • elblogdbテーブル:分散タイプが「RANDOM」のテーブル検証
  • campaignsテーブル:nvarchar型とnchar型の変換、PRIMARY KEYのテーブル検証
  • 情報テーブル:日本語テーブル名・カラム名変換のテーブル検証
  • users_vwビュー:ビュー検証

検証用スキーマの作成

[nz@netezza ~]$ nzsql -h localhost -u admin -pw AdminA1 -d cmdb
Welcome to nzsql, the IBM Netezza SQL interactive terminal.

Type: \h for help with SQL commands
 \? for help on internal slash commands
 \g or terminate with semicolon to execute query
 \q to quit

SYSTEM.ADMIN(ADMIN)=> CREATE USER cmuser WITH PASSWORD 'CmuserA1';
CREATE USER
SYSTEM.ADMIN(ADMIN)=> CREATE DATABASE cmdb;
CREATE DATABASE
SYSTEM.ADMIN(ADMIN)=> CREATE GROUP cm_group WITH USER cmuser;
CREATE GROUP
SYSTEM.ADMIN(ADMIN)=> GRANT LIST ON cmdb TO cm_group WITH GRANT OPTION;
GRANT
SYSTEM.ADMIN(ADMIN)=> GRANT Create External Table, Create Sequence, Create Synonym, Create Table, Create Temp Table, Create View TO cm_group;
GRANT
SYSTEM.ADMIN(ADMIN)=> GRANT backup, create sequence, create synonym, create table, create external table, create temp table, create view, restore TO cm_group;
GRANT
SYSTEM.ADMIN(ADMIN)=> alter database cmdb owner to cmuser;
ALTER DATABASE
SYSTEM.ADMIN(ADMIN)=> \c cmdb cmuser CmuserA1
You are now connected to database cmdb as user cmuser.

CMDB.CMUSER(CMUSER)=> \l
 List of databases
 DATABASE | OWNER
----------+--------
 CMDB | CMUSER
 SYSTEM | ADMIN
(2 rows)

CMDB.CMUSER(CMUSER)=> create table users(
CMDB.CMUSER(CMUSER)(> userid integer not null,
CMDB.CMUSER(CMUSER)(> username char(8),
CMDB.CMUSER(CMUSER)(> firstname varchar(30),
CMDB.CMUSER(CMUSER)(> lastname varchar(30),
CMDB.CMUSER(CMUSER)(> city varchar(30),
CMDB.CMUSER(CMUSER)(> state char(2),
CMDB.CMUSER(CMUSER)(> email varchar(100),
CMDB.CMUSER(CMUSER)(> phone char(14),
CMDB.CMUSER(CMUSER)(> likesports boolean,
CMDB.CMUSER(CMUSER)(> liketheatre boolean,
CMDB.CMUSER(CMUSER)(> likeconcerts boolean,
CMDB.CMUSER(CMUSER)(> likejazz boolean,
CMDB.CMUSER(CMUSER)(> likeclassical boolean,
CMDB.CMUSER(CMUSER)(> likeopera boolean,
CMDB.CMUSER(CMUSER)(> likerock boolean,
CMDB.CMUSER(CMUSER)(> likevegas boolean,
CMDB.CMUSER(CMUSER)(> likebroadway boolean,
CMDB.CMUSER(CMUSER)(> likemusicals boolean
CMDB.CMUSER(CMUSER)(> )
CMDB.CMUSER(CMUSER)-> DISTRIBUTE ON (userid)
CMDB.CMUSER(CMUSER)-> ;
CREATE TABLE

CMDB.CMUSER(CMUSER)=> create table categorise(
CMDB.CMUSER(CMUSER)(> catid byteint not null,
CMDB.CMUSER(CMUSER)(> subcatid byteint not null,
CMDB.CMUSER(CMUSER)(> catgroup varchar(10),
CMDB.CMUSER(CMUSER)(> catname varchar(10),
CMDB.CMUSER(CMUSER)(> catdesc varchar(50)
CMDB.CMUSER(CMUSER)(> )
CMDB.CMUSER(CMUSER)-> DISTRIBUTE ON (catid, subcatid)
CMDB.CMUSER(CMUSER)-> ;
CREATE TABLE

CMDB.CMUSER(CMUSER)=> create table elblogdb (
CMDB.CMUSER(CMUSER)(> request_timestamp timestamp,
CMDB.CMUSER(CMUSER)(> elb_name varchar(128),
CMDB.CMUSER(CMUSER)(> request_ip varchar(128),
CMDB.CMUSER(CMUSER)(> request_port byteint,
CMDB.CMUSER(CMUSER)(> backend_ip varchar(128),
CMDB.CMUSER(CMUSER)(> backend_port byteint,
CMDB.CMUSER(CMUSER)(> request_processing_time double,
CMDB.CMUSER(CMUSER)(> backend_processing_time double,
CMDB.CMUSER(CMUSER)(> client_response_time double,
CMDB.CMUSER(CMUSER)(> elb_response_code byteint,
CMDB.CMUSER(CMUSER)(> backend_response_code byteint,
CMDB.CMUSER(CMUSER)(> received_bytes bigint,
CMDB.CMUSER(CMUSER)(> sent_bytes bigint,
CMDB.CMUSER(CMUSER)(> request_verb varchar(128),
CMDB.CMUSER(CMUSER)(> url varchar(128),
CMDB.CMUSER(CMUSER)(> protocol varchar(128),
CMDB.CMUSER(CMUSER)(> user_agent varchar(128),
CMDB.CMUSER(CMUSER)(> ssl_cipher varchar(128),
CMDB.CMUSER(CMUSER)(> ssl_protocol varchar(128)
CMDB.CMUSER(CMUSER)(> )
CMDB.CMUSER(CMUSER)-> DISTRIBUTE ON RANDOM
CMDB.CMUSER(CMUSER)-> ;
CREATE TABLE

CMDB.CMUSER(CMUSER)=> create table campaigns (
CMDB.CMUSER(CMUSER)(> id int,
CMDB.CMUSER(CMUSER)(> name nvarchar(64),
CMDB.CMUSER(CMUSER)(> name_short nchar(16),
CMDB.CMUSER(CMUSER)(> start_date date,
CMDB.CMUSER(CMUSER)(> end_date date,
CMDB.CMUSER(CMUSER)(> created timestamp,
CMDB.CMUSER(CMUSER)(> updated timestamp,
CMDB.CMUSER(CMUSER)(> primary key (id)
CMDB.CMUSER(CMUSER)(> )
CMDB.CMUSER(CMUSER)-> DISTRIBUTE ON (id)
CMDB.CMUSER(CMUSER)-> ;
NOTICE: primary key constraints not enforced
CREATE TABLE

CMDB.CMUSER(CMUSER)=> \i infos_jp.sql
CREATE TABLE

CMDB.CMUSER(CMUSER)=> create view users_vw as (select * from users);
CREATE VIEW

検証用スキーマ・テーブル・ビュー

DDL(SQL)を実行して、実際に作成された 検証用スキーマ・テーブル・ビューを確認します。

CMDB.CMUSER(CMUSER)=> \d
 List of relations
 Schema | Name | Type | Owner
--------+------------+-------+--------
 CMUSER | CAMPAIGNS | TABLE | CMUSER
 CMUSER | CATEGORISE | TABLE | CMUSER
 CMUSER | ELBLOGDB | TABLE | CMUSER
 CMUSER | USERS | TABLE | CMUSER
 CMUSER | USERS_VW | VIEW | CMUSER
 CMUSER | 情報 | TABLE | CMUSER
(6 rows)

CMDB.CMUSER(CMUSER)=> \d CAMPAIGNS
 Table "CAMPAIGNS"
 Attribute | Type | Modifier | Default Value
------------+--------------------------------+----------+---------------
 ID | INTEGER | NOT NULL |
 NAME | NATIONAL CHARACTER VARYING(64) | |
 NAME_SHORT | NATIONAL CHARACTER(16) | |
 START_DATE | DATE | |
 END_DATE | DATE | |
 CREATED | TIMESTAMP | |
 UPDATED | TIMESTAMP | |

Constraints:

Name Settings
CAMPAIGNS_PK Primary key(ID)

Distributed on hash: "ID"

CMDB.CMUSER(CMUSER)=> \d CATEGORISE
 Table "CATEGORISE"
 Attribute | Type | Modifier | Default Value
-----------+-----------------------+----------+---------------
 CATID | BYTEINT | NOT NULL |
 SUBCATID | BYTEINT | NOT NULL |
 CATGROUP | CHARACTER VARYING(10) | |
 CATNAME | CHARACTER VARYING(10) | |
 CATDESC | CHARACTER VARYING(50) | |
Distributed on hash: "CATID", "SUBCATID"

CMDB.CMUSER(CMUSER)=> \d ELBLOGDB
 Table "ELBLOGDB"
 Attribute | Type | Modifier | Default Value
-------------------------+------------------------+----------+---------------
 REQUEST_TIMESTAMP | TIMESTAMP | |
 ELB_NAME | CHARACTER VARYING(128) | |
 REQUEST_IP | CHARACTER VARYING(128) | |
 REQUEST_PORT | BYTEINT | |
 BACKEND_IP | CHARACTER VARYING(128) | |
 BACKEND_PORT | BYTEINT | |
 REQUEST_PROCESSING_TIME | DOUBLE PRECISION | |
 BACKEND_PROCESSING_TIME | DOUBLE PRECISION | |
 CLIENT_RESPONSE_TIME | DOUBLE PRECISION | |
 ELB_RESPONSE_CODE | BYTEINT | |
 BACKEND_RESPONSE_CODE | BYTEINT | |
 RECEIVED_BYTES | BIGINT | |
 SENT_BYTES | BIGINT | |
 REQUEST_VERB | CHARACTER VARYING(128) | |
 URL | CHARACTER VARYING(128) | |
 PROTOCOL | CHARACTER VARYING(128) | |
 USER_AGENT | CHARACTER VARYING(128) | |
 SSL_CIPHER | CHARACTER VARYING(128) | |
 SSL_PROTOCOL | CHARACTER VARYING(128) | |
Distributed on random: (round-robin)

CMDB.CMUSER(CMUSER)=> \d USERS
 Table "USERS"
 Attribute | Type | Modifier | Default Value
---------------+------------------------+----------+---------------
 USERID | INTEGER | NOT NULL |
 USERNAME | CHARACTER(8) | |
 FIRSTNAME | CHARACTER VARYING(30) | |
 LASTNAME | CHARACTER VARYING(30) | |
 CITY | CHARACTER VARYING(30) | |
 STATE | CHARACTER(2) | |
 EMAIL | CHARACTER VARYING(100) | |
 PHONE | CHARACTER(14) | |
 LIKESPORTS | BOOLEAN | |
 LIKETHEATRE | BOOLEAN | |
 LIKECONCERTS | BOOLEAN | |
 LIKEJAZZ | BOOLEAN | |
 LIKECLASSICAL | BOOLEAN | |
 LIKEOPERA | BOOLEAN | |
 LIKEROCK | BOOLEAN | |
 LIKEVEGAS | BOOLEAN | |
 LIKEBROADWAY | BOOLEAN | |
 LIKEMUSICALS | BOOLEAN | |
Distributed on hash: "USERID"

CMDB.CMUSER(CMUSER)=> \d USERS_VW
 View "USERS_VW"
 Attribute | Type | Modifier | Default Value
---------------+------------------------+----------+---------------
 USERID | INTEGER | NOT NULL |
 USERNAME | CHARACTER(8) | |
 FIRSTNAME | CHARACTER VARYING(30) | |
 LASTNAME | CHARACTER VARYING(30) | |
 CITY | CHARACTER VARYING(30) | |
 STATE | CHARACTER(2) | |
 EMAIL | CHARACTER VARYING(100) | |
 PHONE | CHARACTER(14) | |
 LIKESPORTS | BOOLEAN | |
 LIKETHEATRE | BOOLEAN | |
 LIKECONCERTS | BOOLEAN | |
 LIKEJAZZ | BOOLEAN | |
 LIKECLASSICAL | BOOLEAN | |
 LIKEOPERA | BOOLEAN | |
 LIKEROCK | BOOLEAN | |
 LIKEVEGAS | BOOLEAN | |
 LIKEBROADWAY | BOOLEAN | |
 LIKEMUSICALS | BOOLEAN | |
View definition: SELECT USERS.USERID, USERS.USERNAME, USERS.FIRSTNAME, USERS.LASTNAME, USERS.CITY, USERS."STATE", USERS.EMAIL, USERS.PHONE, USERS.LIKESPORTS, USERS.LIKETHEATRE, USERS.LIKECONCERTS, USERS.LIKEJAZZ, USERS.LIKECLASSICAL, USERS.LIKEOPERA, USERS.LIKEROCK, USERS.LIKEVEGAS, USERS.LIKEBROADWAY, USERS.LIKEMUSICALS FROM CMUSER.USERS;

CMDB.CMUSER(CMUSER)=> \d "情報"
 Table "情報"
 Attribute | Type | Modifier | Default Value
-----------+------------------------+----------+---------------
 情報ID | INTEGER | |
 情報 | CHARACTER VARYING(255) | |
Distributed on random: (round-robin)

 

Netezzaには「スキーマ」を設定しませんが、テーブル一覧を取得するとSchemaにユーザー名(cmuser)が表示されます。Netezzaでは「データベース > ユーザー(≒スキーマ) > テーブル・ビュー」と階層的に管理するようです。Redshiftではユーザーとは関係なく「データベース > スキーマ > テーブル・ビュー」と階層的に管理します。この違いをどのように変換するのかも後ほど確認したいと思います。

SCTのインストール

SCT Ver1.0系は、以下の4つのOSのインストーラを提供しています。

今回は、主にMac OS X 版のSCTを使用して解説しますが、SCTはEclipseベースなのでOS依存が少なく他のOSでも同様の操作方法で利用できます。

Mac OS X へインストール

ダウンロードしたファイル(aws-schema-conversion-tool-1.0.latest.zip)を展開して、中の AWS Schema Conversion Tool-1.0.502.dmg を開きます。AWS Schema Conversion Tool を Applications フォルダーにドラッグします。

20160107-sct0macosx-install

Microsoft Windows へインストール

ファイルをダブルクリックしてインストーラを実行します。

設定

SCTを起動すると、自動的に起動する Create New Database Migration Project というWizard に従って設定を進めます。

Step1: Select Source

Project Nameと ソースデータベース(Netezza)の接続情報を設定します。[Test Connection]を押して接続が成功すると Netezza Driver Pathの設定は表示されなくなり、[ 次 ]が押せるようになります。Netezzaへは、Netezzaの管理ユーザー(admin)で接続します。

20160109-wizard-step1

 

※ 注意:テーブル・ビューの所有者 cmuserで実行するとNetezzaの定義情報が取得できない

SCTのメッセージとしては出力されませんが、SCTのログファイルを確認したところ、_T_OBJECTの参照権限不足が原因でスキーマの取得で例外が発生しています。

15:16:49.109 [ 30] LOADER ERROR Error executing 'load-all-schemas' query: com.amazon.sct.dbloader.DbLoaderException: org.netezza.error.NzSQLException: ERROR: Permission denied on "_T_OBJECT".
15:16:49.109 [ 30] LOADER ERROR com.amazon.sct.dbloader.DbLoaderException: org.netezza.error.NzSQLException: ERROR: Permission denied on "_T_OBJECT".

対策として、cm_groupに_T_OBJECTのSELECT権限の付与しましたが、SCTで発生する問題は改善しませんでしたので、Netezzaに対してはデータベースの管理ユーザー(admin)で接続しています。

GRANT SELECT ON _T_OBJECT TO cm_group;

Step2: Select Schema

変換対象のデータベース「CMDB」を選択して、[ 次 ]を押します。

20160109-wizard-step2

Step3: Run Database Migration Assessment

ソースデータベースのパースや解析の結果が表示されます。

20160109-wizard-step3-1

ソースデータベースのオブジェクトの分析は全て100%という結果であることが確認できます。

20160109-wizard-step3-2

Step4: Select Target

ターゲットデータベース(Redshift)の接続情報を設定します。RedshiftはRedshiftの管理ユーザー(root)で接続します。[Test Connection]を押して接続が成功すると Amazon Redshift Driver Pathの設定は表示されなくなり、[Finish]が押せるようになります。

20160109-wizard-step4

設定完了

左にソースデータベースであるNetezza、右にターゲットデータベースであるRedshiftが表示されます。

20160109-wizard-result

campaignsテーブルのname_shortカラムがエラーになっていますが、特に影響がないようなのでこのまま進めます。

20160109-convert-schema-error

 

変換

左にソースデータベースのCMDBを右クリックして、[Convert schema]を選択すると、

20160109-convert-schema-target

右にターゲットデータベースの下にcmdb_cmuserスキーマが追加されました。

20160109-convert-schema-source

この cmdb_cmuserを右クリックして、[Save as SQL]を選択すると変換SQLを保存することができます。生成されたSQLファイルは以下のとおりです。

-- ------------ Write DROP-CONSTRAINT-stage scripts -----------

ALTER TABLE cmdb_cmuser.campaigns DROP CONSTRAINT campaigns_pk;

-- ------------ Write DROP-DATABASE-stage scripts -----------

DROP SCHEMA IF EXISTS cmdb_cmuser CASCADE;

-- ------------ Write CREATE-DATABASE-stage scripts -----------

CREATE SCHEMA IF NOT EXISTS cmdb_cmuser;

-- ------------ Write CREATE-TABLE-stage scripts -----------

CREATE TABLE IF NOT EXISTS cmdb_cmuser.campaigns(
id INTEGER NOT NULL,
name CHARACTER VARYING(256),
name_short CHARACTER VARYING(64),
start_date DATE,
end_date DATE,
created TIMESTAMP WITHOUT TIME ZONE,
updated TIMESTAMP WITHOUT TIME ZONE
)
DISTSTYLE KEY
DISTKEY
(
id
);

CREATE TABLE IF NOT EXISTS cmdb_cmuser.categorise(
catid SMALLINT NOT NULL,
subcatid SMALLINT NOT NULL,
catgroup CHARACTER VARYING(10),
catname CHARACTER VARYING(10),
catdesc CHARACTER VARYING(50)
)
DISTSTYLE KEY
DISTKEY
(
catid
);

CREATE TABLE IF NOT EXISTS cmdb_cmuser.elblogdb(
request_timestamp TIMESTAMP WITHOUT TIME ZONE,
elb_name CHARACTER VARYING(128),
request_ip CHARACTER VARYING(128),
request_port SMALLINT,
backend_ip CHARACTER VARYING(128),
backend_port SMALLINT,
request_processing_time DOUBLE PRECISION,
backend_processing_time DOUBLE PRECISION,
client_response_time DOUBLE PRECISION,
elb_response_code SMALLINT,
backend_response_code SMALLINT,
received_bytes BIGINT,
sent_bytes BIGINT,
request_verb CHARACTER VARYING(128),
url CHARACTER VARYING(128),
protocol CHARACTER VARYING(128),
user_agent CHARACTER VARYING(128),
ssl_cipher CHARACTER VARYING(128),
ssl_protocol CHARACTER VARYING(128)
)
DISTSTYLE EVEN;

CREATE TABLE IF NOT EXISTS cmdb_cmuser.users(
userid INTEGER NOT NULL,
username CHARACTER(8),
firstname CHARACTER VARYING(30),
lastname CHARACTER VARYING(30),
city CHARACTER VARYING(30),
state CHARACTER(2),
email CHARACTER VARYING(100),
phone CHARACTER(14),
likesports BOOLEAN,
liketheatre BOOLEAN,
likeconcerts BOOLEAN,
likejazz BOOLEAN,
likeclassical BOOLEAN,
likeopera BOOLEAN,
likerock BOOLEAN,
likevegas BOOLEAN,
likebroadway BOOLEAN,
likemusicals BOOLEAN
)
DISTSTYLE KEY
DISTKEY
(
userid
);

CREATE TABLE IF NOT EXISTS cmdb_cmuser._24773_22577(
_24773_22577id INTEGER,
_24773_22577 CHARACTER VARYING(255)
)
DISTSTYLE EVEN;

-- ------------ Write CREATE-CONSTRAINT-stage scripts -----------

ALTER TABLE cmdb_cmuser.campaigns
ADD CONSTRAINT campaigns_pk PRIMARY KEY (id);

-- ------------ Write CREATE-VIEW-stage scripts -----------

CREATE OR REPLACE VIEW cmdb_cmuser.users_vw (userid, username, firstname, lastname, city, state, email, phone, likesports, liketheatre, likeconcerts, likejazz, likeclassical, likeopera, likerock, likevegas, likebroadway, likemusicals) AS
SELECT
 cmdb_cmuser.users.userid, cmdb_cmuser.users.username, cmdb_cmuser.users.firstname, cmdb_cmuser.users.lastname, cmdb_cmuser.users.city, cmdb_cmuser.users.state, cmdb_cmuser.users.email, cmdb_cmuser.users.phone, cmdb_cmuser.users.likesports, cmdb_cmuser.users.liketheatre, cmdb_cmuser.users.likeconcerts, cmdb_cmuser.users.likejazz, cmdb_cmuser.users.likeclassical, cmdb_cmuser.users.likeopera, cmdb_cmuser.users.likerock, cmdb_cmuser.users.likevegas, cmdb_cmuser.users.likebroadway, cmdb_cmuser.users.likemusicals
 FROM cmdb_cmuser.users;

上記のSQLファイルをRedshiftで実行したところ、問題なく実行できました。

変換結果の確認

usersテーブル:分散キーが1つのテーブル検証

Netezza の DISTRIBUTE ON (userid) は、

DISTSTYLE KEY
DISTKEY
(
userid
)

に変換されました。想定通りの変換結果です。ソートキーの指定は追加したほうが良いでしょう。

categoriseテーブル:分散キーが2つのテーブル検証

Netezza の DISTRIBUTE ON (catid, subcatid) は、

DISTSTYLE KEY
DISTKEY
(
catid
)

に変換されました。Redshiftは分散キーの指定は1カラムのみなのでこのように変換されたことが予想されます。想定通りの変換結果ですが、警告などが表示されませんので注意が必要です。また、ソートキーの指定は追加したほうが良いでしょう。

elblogdbテーブル:分散タイプが「RANDOM」のテーブル検証

Netezza の DISTRIBUTE ON RANDOM は、

DISTSTYLE EVEN

に変換されました。想定通りの変換結果です。ソートキーの指定は必要に応じて追加したほうが良いでしょう。

campaignsテーブル:nvarchar型とnchar型の変換、PRIMARY KEYのテーブル検証

Netezza の nvarchar型とnchar型は、

name CHARACTER VARYING(256),
name_short CHARACTER VARYING(64),

と、それぞれ長さが4倍のvarchar型に変換されました。想定通りの変換結果です。

Netezza の PRIMARY KEY は、

ALTER TABLE cmdb_cmuser.campaigns
ADD CONSTRAINT campaigns_pk PRIMARY KEY (id);

に変換されました。

情報テーブル:日本語テーブル名・カラム名変換のテーブル検証

Netezza の 日本語テーブル名・カラム名は、

CREATE TABLE IF NOT EXISTS cmdb_cmuser._24773_22577(
_24773_22577id INTEGER,
_24773_22577 CHARACTER VARYING(255)
)
DISTSTYLE EVEN;

のように文字コードに変換されるようです。文字列書き換えが必要となりそうです。
※ 2017/05/09現在(Ver.1.0.601-1)では、日本語テーブル・カラムに対応しています。

users_vwビュー:ビュー検証

特に問題なく変換できました。

その他

スキーマ名

「cmdb_cmuser」で生成されていますので、ターゲットのスキーマ名に適宜変更してください。

圧縮タイプ

圧縮タイプが指定されていませんので指定してください。Redshiftはストリーム圧縮以外の様々な圧縮アルゴリズムを利用できます。

ソートキー

ソートキーは指定されていませんが、適切に設定することで不要なデータブロックのスキャンを回避できます。また、分散キーとは別にソートキー(コンパウンドソートキー、インターリーブドソートキー)など、より緻密な最適化が可能です。

分散キー

Netezzaでは、EVENとKEY指定のみですが、RedhisftではALL指定が可能です。マスタ系テーブルのように複数のファクトテーブルと結合が必要になるテーブルに設定することで、簡単に再分散の発生を回避できます。

まとめ

SCTはアーキテクチャや制約が異なる2つのデータベースを完全に変換することが目的ではなく、可能な限り自動化を支援することが真の目的です。機械的な変換はSCTにまかせて、変換できないところに注力することで、手作業で発生しうるヒューマンエラーの防止に有効ではないかと感じました。本格運用はともかく、Redshiftをよくわからない初心者が単純にスキーマを移行するという際にも有効でしょう。

Redshiftは、分散タイプに「ALL」を指定できたり、分散キーとは別にソートキー(コンパウンドソートキー、インターリーブドソートキー)など、より緻密な最適化が可能です。SCTが生成したRedshiftのスキーマは最適なものではなく雛形と考え、より最適化したスキーマの作成や既存設計の改善にご利用して頂きたいところです。