OpenText Analytics Database 旧Vertica

技術情報サイト

Analytics Database

MySQLからVerticaへの移行について

公開日:
更新日:
その他
#移行

はじめに

他のデータベース(以下、DB)からVerticaへの移行概要については、「Verticaへの移行について」でご紹介しました。今回は、MySQLを例にあげてテーブル、SQL文をVerticaで利用するまでの具体的な手順を解説します。

はじめに

MySQLからの移行ステップ

Verticaに移行するまでのステップと各ステップにおける作業対象のDBは、以下のとおりです。

MySQLからの移行ステップ

ステップ1. Verticaインストール、DB作成

まず、はじめにVerticaのインストールを行い、DBを作成します。Verticaのインストールは、Vertica Community Edition(無償)をダウンロードし、rpmを展開するだけなので簡単です。

ステップ2. テーブルのDDL出力

MySQLのテーブルをVertica用のテーブルに置換えるために「show create table」コマンドや「mysqldump」コマンドでテーブルのDDLを出力します。「MySQL Workbench」などのツールを使うことで、簡単にDDLを出力することもできます。

構文1

mysql> show create table <テーブル名>;

実行例1

mysql> show create table test1;
+-------+----------------------------------------------
| Table | Create Table
+-------+----------------------------------------------
| test1 | CREATE TABLE `test1` (
  `col1` tinyint(4) DEFAULT NULL,
  `col2` varchar(30) DEFAULT NULL,
  `col3` datetime DEFAULT NULL,
  KEY `col1` (`col1`)
) ENGINE=InnoDB DEFAULT CHARSET=sjis |
+-------+----------------------------------------------
1 row in set (0.00 sec)

構文2

# mysqldump <データベース名> <テーブル名> -u <ユーザ名> -p <パスワード> --no-data

実行例2

# mysqldump testdb test1 -u root -p --no-data
Enter password: *****
-- MySQL dump 10.13  Distrib 5.7.12, for Linux (x86_64)
--
-- Host: localhost    Database: testdb
-- ------------------------------------------------------
-- Server version       5.7.12-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `test1`
--

DROP TABLE IF EXISTS `test1`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `test1` (
  `col1` tinyint(4) DEFAULT NULL,
  `col2` varchar(30) DEFAULT NULL,
  `col3` datetime DEFAULT NULL,
  KEY `col1` (`col1`)
) ENGINE=InnoDB DEFAULT CHARSET=sjis;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on YYYY-MM-DD hh:mm:ss

ステップ3. テーブルのDDL変換

MySQLとVerticaで利用可能なデータ型を比較して、Verticaが対応しているデータ型に置換えます。以下は、MySQLとVerticaのデータ型のマッピング表です。

数値型

MySQL

Vertica

データ型分類

データ型

データ範囲

データ型

データ範囲

整数型

TINYINT

-128~127

TINYINT

-9,223,372,036,854,775,807~
9,223,372,036,854,775,807

※INT,INTEGER,
 INT8,SMALLINT,
 TINYINT,BIGINT
 は全て同じ64bit 整数データ型の
 シノニムです。

SMALLINT

-32,768~32,767

SMALLINT

-9,223,372,036,854,775,807~
9,223,372,036,854,775,807

※INT,INTEGER,
 INT8,SMALLINT,
 TINYINT,BIGINT
 は全て同じ64bit 整数データ型の
 シノニムです。

MEDIUMINT

-8,388,608~8,388,607

----

(対応データ型無し)

INT
INTEGER

-2,147,483,648~2,147,483,647

INT
INTEGER

-9,223,372,036,854,775,807~
9,223,372,036,854,775,807

※INT,INTEGER,
 INT8,SMALLINT,
 TINYINT,BIGINT
 は全て同じ64bit 整数データ型の
 シノニムです。

BIGINT

-9,223,372,036,854,775,808~
9,223,372,036,854,775,807

BIGINT

-9,223,372,036,854,775,807~
9,223,372,036,854,775,807

※INT,INTEGER,
 INT8,SMALLINT,
 TINYINT,BIGINT
 は全て同じ64bit 整数データ型の
 シノニムです。

固定小数点型

DECIMAL

任意の精度及びスケール指定
(整数部小数部併せて65桁まで)

DECIMAL

任意の精度及びスケール指定
(整数部小数部併せて1024桁まで)

※NUMERIC,DECIMAL,
 NUMBER,MONEY
 は全て同じ数値データ型の
 シノニムです。

NUMERIC

任意の精度及びスケール指定
(整数部小数部併せて65桁まで)

NUMERIC

任意の精度及びスケール指定
(整数部小数部併せて1024桁まで)

※NUMERIC,DECIMAL,
 NUMBER,MONEY
 は全て同じ数値データ型の
 シノニムです。

浮動小数点型

FLOAT

-3.402823466E+38~
-1.175494351E-38
0
1.175494351E-38~3.402823466E+38

FLOAT

64ビットのIEEE-754浮動小数点形式で格納
(指定できる最大精度は53桁まで)

※DOUBLE PRECISION,
 FLOAT(n),FLOAT8,REALは、
 FLOATのシノニムです。

DOUBLE

-1.7976931348623157E+308~
-2.2250738585072014E-308
0
2.2250738585072014E-308~
1.7976931348623157E+308

DOUBLE

64ビットのIEEE-754浮動小数点形式で格納
(指定できる最大精度は53桁まで)

※DOUBLE PRECISION,
 FLOAT(n),FLOAT8,REALは、
 FLOATのシノニムです。

文字列型

MySQL

Vertica

データ型分類

データ型

データ範囲

データ型

データ範囲

文字列型

CHAR(M)

固定長文字列
Mは文字数を指定、
0から255文字

CHAR(M)

固定長文字列
Mはバイト数を指定、
1 から65,000バイト

VARCHAR(M)

可変長文字列
Mは文字数を指定、
0から65535バイト

VARCHAR(M)

可変長文字列
Mはバイト数を指定、
1から65,000バイト

TINYTEXT

最長255(2の8乗-1)バイト

----

(対応データ型無し)

TEXT

最長65,535
(2の16乗-1)バイト

VARCHAR(M)

可変長文字列
Mはバイト数を指定、
1から65,000バイト

MEDIUMTEXT

最長16,777,215
(2の24乗-1)バイト

LONG VARCHAR(M)

可変長文字列
Mはバイト数を指定、
1 から32,000,000バイト

LONGTEXT

最長4,294,967,295
または
4GB(2の32乗-1)バイト

日付/時刻型

MySQL

Vertica

データ型分類

データ型

データ範囲

データ型

データ範囲

日付/時刻型

DATE

フォーマット:
 'YYYY-MM-DD'
範囲:
 '1000-01-01'~
 '9999-12-31'

DATE

フォーマット:
 'YYYY-MM-DD'
範囲:
 '22500983562558975-11-30 BC'~
 '22500983562558974-02-02 AD'

DATETIME

フォーマット:
 'YYYY-MM-DD HH:MM:SS'
範囲:
 '1000-01-01 00:00:00'~
 '9999-12-31 23:59:59'

DATETIME

フォーマット:
 'YYYY-MM-DD HH:MM:SS'
範囲:
 '290279-12-22 19:59:05.224194 BC'~
 '294277-01-09 04:00:54:775806'

※DATETIME,
 SMALLDATETIMEは
 TIMESTAMPのシノニムです。

TIMESTAMP

フォーマット:
 'YYYY-MM-DD HH:MM:SS'
範囲:
 '1970-01-01 00:00:01.000000'~
 '2038-01-19 03:14:07.999999'

TIMESTAMP

フォーマット:
 'YYYY-MM-DD HH:MM:SS'
範囲:
 '290279-12-22 19:59:05.224194 BC'~
 '294277-01-09 04:00:54:775806 AD'

※DATETIME,
 SMALLDATETIMEは
 TIMESTAMPのシノニムです。

TIME

フォーマット:
 'HH:MM:SS'
範囲:
 '-838:59:59.000000'~
 '838:59:59.000000'

TIME

フォーマット:
 'HH:MM:SS'
範囲:
 '00:00:00.00'~
 '23:59:60.999999'

YEAR[(2|4)]

フォーマット:
 YYYY
範囲:
 1901~2155 (4桁の場合)
 70~69 (2桁の場合)
デフォルトは4桁

----

(対応データ型無し)

バイナリ/BLOB型

MySQL

Vertica

データ型分類

データ型

データ範囲

データ型

データ範囲

バイナリ型

BINARY(M)

固定長バイナリバイト文字列
Mはバイト数を指定、
0から255バイト

BINARY(M)

固定長バイナリバイト文字列
Mはバイト数を指定、
1 から65,000バイト

VARBINARY(M)

可変長バイナリバイト文字列
Mはバイト数を指定、
0から65535バイト

VARBINARY(M)

可変長バイナリバイト文字列
Mはバイト数を指定、
1から65,000バイト

BLOB型

TINYBLOB

最長255(2の8乗-1)バイト

----

(対応データ型無し)

BLOB

最長65,535
(2の16乗-1)バイト

BINARY(M)
VARBINARY(M)

BINARY(M)
固定長のバイナリ文字列
Mはバイト数を指定、
1から65,000バイト

VARBINARY(M)
可変長のバイナリ文字列
Mはバイト数を指定、
1から65,000バイト
※BYTEA,RAWは
 VARBINARYのシノニムです。

MEDIUMBLOB

最長16,777,215
(2の24乗-1)バイト

LONG VARBINARY(M)

可変長rawバイトのデータを保持
Mはバイト数を指定、
1から32,000,000バイト

LONGLOB

最長4,294,967,295
または
4GB(2の32乗-1)バイト

ENUM/SET型

MySQL

Vertica

データ型分類

データ型

データ範囲

データ型

データ範囲

ENUM/SET型

ENUM

列挙値の数
(最大 65,535 個の値)
1 または 2 バイト

----

(対応データ型無し)

SET

セットメンバーの数
(最大 64 メンバー)
1、2、3、4、または 8 バイト

----

(対応データ型無し)

ステップ4. テーブル作成

置換えたテーブル定義をもとに、Verticaでテーブルを作成します。一例ですが、MySQLからVerticaに置換えて、テーブルを作成した結果は以下のとおりです。

【MySQL】

mysql> CREATE TABLE `test1` (
    ->   `col1` tinyint(4) DEFAULT NULL,
    ->   `col2` varchar(30) DEFAULT NULL,
    ->   `col3` datetime DEFAULT NULL,
    ->   INDEX `col1` (`col1`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=sjis
    -> ;
Query OK, 0 rows affected (0.33 sec)

mysql> desc test1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| col1  | tinyint(4)  | YES  | MUL | NULL    |       |
| col2  | varchar(30) | YES  |     | NULL    |       |
| col3  | datetime    | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.05 sec)

【Vertica】

dbadmin=> CREATE TABLE test1 (
dbadmin(>   col1 TINYINT DEFAULT NULL,
dbadmin(>   col2 VARCHAR(90) DEFAULT NULL,
dbadmin(>   col3 DATETIME DEFAULT NULL
dbadmin(> );
CREATE TABLE

dbadmin=> \d test1;
                                       List of Fields by Tables
 Schema | Table | Column |    Type     | Size |     Default     | Not Null | Primary Key | Foreign Key
--------+-------+--------+-------------+------+-----------------+----------+-------------+-------------
 public | test1 | col1   | int         |    8 | NULL::int       | f        | f           |
 public | test1 | col2   | varchar(90) |   90 | NULL            | f        | f           |
 public | test1 | col3   | timestamp   |    8 | NULL::timestamp | f        | f           |
(3 rows)

MySQLからVerticaに置換えるまでのポイントを簡単に纏めました。

・Verticaは列指向DBのため、インデックスは存在しません。作成は不要です。
・MySQLで指定していた「ENGINE」や「CHARSET」の指定はできません。DBキャラクタセットは「UTF8」のみに対応しています。
・Verticaではオブジェクト名を「`」(バッククォーテーション)で囲むことはできません。
・「MySQL:varchar(30)」から「Vertica:varchar(90)」に変更しています。MySQLのカラムサイズの指定は「文字数」ですが、Verticaは「バイト数」の指定のためです。 VerticaのDBキャラクタセットはUTF8なので、マルチバイト1文字は「3バイト」で扱われます。そのため、VerticaのカラムサイズをMySQLの3倍に指定しています。
・Verticaの「tinyint型」は「int型」のシノニムなので、テーブル定義を確認すると「int型」になります。
・Verticaの「datetime型」は「timestamp型」のシノニムなので、テーブル定義を確認すると「timestamp型」になります。

ステップ5. データのCSV出力

Verticaのテーブルにデータを取り込むため、MySQLからデータを「SELECT .. INTO OUTFILE」コマンドでCSVに出力します。MySQLに対応しているETLツールの場合、ETLツールからCSVの出力をすることもできます。

構文

mysql> SELECT * FROM <テーブル名> INTO
OUTFILE ‘<csv>’ FIELDS TERMINATED BY ‘<区切り文字>‘;</csv>

実行例

mysql> SELECT * FROM test1 INTO OUTFILE '/tmp/test1.csv' FIELDS TERMINATED BY ',';
Query OK, 10 rows affected (0.00 sec)

ステップ6. CSVの文字コード変換

VerticaがサポートしているDBキャラクタセットはUTF8のみです。そのため、対象CSVファイルの文字コードがUTF-8形式ではない場合には、以下のコマンドを利用し、エンコーディングする必要があります。文字コードの変換に対応しているETLツールもあるので、ETL側で変換することもできます。MySQLのDBキャラクタセットが、SJISの場合は出力されたCSVファイルもSJISで出力されるので、注意してください。

構文

# nkf -wx <変換元ファイル名> > <変換先ファイル名>
または
# iconv -f <変換元コード名> -t UTF8 <変換元ファイル名> > <変換先ファイル名>
エンコードを確認する場合には、以下のコマンドを実行します。
# nkf -g <変換先ファイル名>

※「iconv」コマンドには文字コードを判定する機能がありません。
※「nkf」コマンドがOS標準パッケージに含まれていない場合には、ソースなどからインストールしてください。

実行例

# nkf -g /tmp/test1.csv
Shift_JIS (LF)
# nkf -wx /tmp/test1.csv > /tmp/test1_utf8.csv
# nkf -g /tmp/test1_utf8.csv
UTF-8 (LF)

# cat test1_utf8.csv
1,北海道,2016-01-01 01:10:35
2,東京,2016-02-24 05:01:30
3,大阪,2016-03-30 12:00:00
4,福岡,2016-04-05 10:10:24
5,神奈川,2016-05-10 08:30:01
6,京都,2016-06-19 03:35:10
7,埼玉,2016-07-01 09:28:15
8,千葉,2016-08-31 21:49:54
9,広島,2016-09-30 15:45:08
10,沖縄,2016-10-01 19:46:15

ステップ7. CSVのデータロード

UTF8に変換したCSVファイルをVerticaの各テーブルに「COPY」コマンドで、ロードします。

構文

dbadmin=> COPY test1 FROM ‘<csv>’ DELIMITER ‘<区切り文字>‘ <オプション>;</csv>

実行例

dbadmin=> COPY test1 FROM '/tmptest1_utf8.csv' DELIMITER ',' DIRECT;
 Rows Loaded
-------------
          10
(1 row)

dbadmin=> select * from test1;
 col1 |  col2  |        col3
------+--------+---------------------
    1 | 北海道 | 2016-01-01 01:10:35
    2 | 東京   | 2016-02-24 05:01:30
    3 | 大阪   | 2016-03-30 12:00:00
    4 | 福岡   | 2016-04-05 10:10:24
    5 | 神奈川 | 2016-05-10 08:30:01
    6 | 京都   | 2016-06-19 03:35:10
    7 | 埼玉   | 2016-07-01 09:28:15
    8 | 千葉   | 2016-08-31 21:49:54
    9 | 広島   | 2016-09-30 15:45:08
   10 | 沖縄   | 2016-10-01 19:46:15
(10 rows)

ステップ8. プロジェクションの最適化

各テーブルへのロード完了後、「admintools」もしくは「Management Console」を利用し、プロジェクションの最適化を実行します。Vertica独自の作業であり、他のDBと大きく違うポイントです。プロジェクションについては、「プロジェクションの概要」で詳しく紹介しています。

ステップ9. アプリの実行SQL洗出し

Verticaで実行できるSQL文に置換えるために、MySQLに対して実行しているSQL文の洗出しをおこないます。アプリーケションで実行しているSQL文のつくりは、恐らく類似しているものが多いと思います。Vertica用にSQL文を置換える場合、以下のように進めると効果的かもしれません。

・幾つかパターンの違うSQL文をピックアップする。そのSQL文に対して、修正ポイントを整理する。
・整理したポイントをもとに、全てのSQL文に対して横展開を実施する。

ステップ10. SQL変換

MySQLに対して実行していたSQL文をVerticaで実行できるようにSQL文を置換えます。Verticaは「ANSI SQL99」に準拠しているため、基本的には他のDBで実行しているSQL文をそのまま利用することができます。ただし、一例となりますが、以下の構文はMySQLから、Verticaに移行する場合は置換えが必要になります。

MySQL

Vertica

説明

SELECT col1, col2, CONCAT(col1,' ',col2) as col3 FROM test1;

SELECT col1, col2, col1 || ' '|| col2 as col3 FROM test1;

CONCAT関数 → 「 || 」に置換する必要があります。

SELECT col1, if(col1='あ','○','×') as col2 FROM test1;

SELECT col1, CASE WHEN col1='あ' THEN '○' ELSE '×' END as col2 FROM test1;

IF文 → CASE文 に置換する必要があります。

SELECT cast(col1 as SIGNED) as cast_value FROM test1;

SELECT cast(col1 as int) as cast_value FROM test1;

CAST関数で、数値型を指定する方法が違います。

SELECT (CASE WHEN SUBSTRING( ' ',2 ,1 ) = 1 THEN 1 ELSE 0 END) as test1 FROM dual;

SELECT (CASE WHEN SUBSTRING( ' ',2 ,1 ) = '1' THEN 1 ELSE 0 END) as test1 FROM dual;

CASE文とSUBSTRING関数を利用し、文字データを比較する場合、指定方法が違います。

SELECT IFNULL(SUBSTRING('1234',2,1),0) + 1 FROM dual;

SELECT IFNULL(SUBSTRING('1234',2,1),'0')::int + 1 FROM dual;

IFNULL文とSUBSTRING関数を利用し、取得結果を加算する場合、データ型の指定する方法が違います。

SELECT DATE_FORMAT(SYSDATE(),'%Y%m') FROM dual;

SELECT TO_CHAR(SYSDATE(),'yyyymmdd') FROM dual;

DATE_FORMAT関数 → TO_CHAR関数 に置換する必要があります。

SELECT DATE_ADD(SYSDATE(),INTERVAL -1 MONTH) FROM dual;

SELECT ADD_MONTHS(SYSDATE(),-1) || ' ' || TO_CHAR(SYSDATE(),'HH24:MI:SS') FROM dual;

(月の計算) DATE_ADD関数 → ADD_MONTHS関数 に置換する必要があります。

SELECT DATE_ADD(SYSDATE(),INTERVAL -1 DAY) FROM dual;

SELECT SYSDATE() -1 FROM dual;

(日の計算) DATE_ADD関数 → SYSDATE関数 に置換する必要があります。

SELECT col1, CASE WHEN col1="あ" THEN "○" ELSE "×" END as col2 FROM test1;

SELECT col1, CASE WHEN col1='あ' THEN '○' ELSE '×' END as col2 FROM test1;

文字データを指定する場合、ダブルコーテェーションは使用できません。

SELECT * FROM test1 where col1 in (1,2);

SELECT * FROM test1 where col1 in ('1','2');

IN句で条件を指定する場合、文字データの指定方法が違います。

SELECT test1.col1 FROM test1 LEFT JOIN test2 on test1.col1 = test2.col1 GROUP BY col1;

SELECT test1.col1 FROM test1 LEFT JOIN test2 on test1.col1 = test2.col1 GROUP BY test1.col1;

複数テーブルで同一列名が存在する場合、曖昧指定はできません。

SELECT col1, col2 FROM test1 GROUP BY col1;

SELECT col1, col2 FROM test1 GROUP BY col1,col2;

GROUP BY句の曖昧指定はできません。

ステップ11. SQL変換後の動作確認

Vertica用に置換えたSQL文の動作確認をおこないます。トライ&エラーの繰り返しの作業です。SQL文が実行できない場合のエラーですが、Verticaは詳しいエラー内容を教えてくれます。そのため、デバッグ作業ですが、比較的容易にできると思います。

実行例

dbadmin=> SELECT col1, col2, CONCAT(col1,' ',col2) as col3 FROM test1;
ERROR 3457:  Function CONCAT(int, unknown, varchar) does not exist, or permission is denied for CONCAT(int, unknown, varchar)
HINT:  No function matches the given name and argument types. You may need to add explicit type casts

dbadmin=> SELECT col1, col2 FROM test1 GROUP BY col1;
ERROR 2640:  Column "test1.col2" must appear in the GROUP BY clause or be used in an aggregate function

検証バージョンについて

この記事の内容はMySQL5.7(InnoDB)、Vertica 7.2で確認しています。

※OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。
 文中の社名、商品名等は各社の商標または登録商標である場合があります。