本トピックでは、MySQL から Hologres にデータを移行する方法と、移行後のクエリ文および関数の違いについて説明します。この情報は、データ移行をより迅速に完了させるために役立ちます。
データ移行方法
次の表に、利用可能なデータ移行方法、その適用シナリオ、および関連ドキュメントを示します。
ETL (抽出、変換、ロード) 処理では、Flink を使用して MySQL データを読み取り、Hologres に書き込むことができます。
移行カテゴリ | シナリオ | ドキュメント |
単一テーブルのオフライン同期 | この方法を使用して、単一の MySQL テーブルから Hologres にデータをオフラインで同期します。 | |
単一テーブルのリアルタイム同期 | MySQL バイナリロギング (Binlog) を有効にして、単一のテーブルから Hologres にデータをリアルタイムで同期します。 | |
データベース全体のリアルタイム同期 | MySQL データベース全体を Hologres にリアルタイムで同期します。 | |
同期ソリューション | Data Integration は同期ソリューションをサポートしています。同期ルールを設定することで、単一の操作でターゲットデータソースにデータをリアルタイムで同期できます。 同期ソリューションは、データベース内の複数テーブルのバッチ同期、および完全データと増分データの統合同期をサポートしています。このプロセスでは、まず完全データを同期し、その後、増分データをリアルタイムで同期します。 |
データ型のマッピング
MySQL から Hologres に移行する際のデータ型のマッピングについては、次の表をご参照ください。データ型の詳細については、「データ型のリファレンス」をご参照ください。
MySQL から Hologres にデータ型をマッピングする際は、次の点にご注意ください:
Hologres には SMALLINT (2 バイト)、INTEGER (4 バイト)、BIGINT (8 バイト) の 3 つの整数型があります。MySQL には TINYINT (1 バイト)、SMALLINT (2 バイト)、MEDIUMINT (3 バイト)、INT (4 バイト)、BIGINT (8 バイト) の 5 つがあります。MySQL の型を、バイトサイズが等しいかそれ以上の Hologres の型にマッピングしてください。
Hologres は符号なし整数をサポートしていません。符号なしフィールドをマッピングする際は、オーバーフローの可能性を考慮する必要があります。ソースフィールドの値がターゲット型の範囲を超える場合は、そのフィールドを Hologres のより大きな整数型にマッピングしてください。
Hologres の TEXT 型を使用して、MySQL の TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT を置き換えてください。
DECIMAL、NUMERIC、DOUBLE、FLOAT などの浮動小数点型は直接マッピングできます。
タイムゾーンを持たず、YYYY-MM-DD HH:MM:SS 形式を使用する MySQL の DATETIME は、デフォルトで
TIMESTAMPTZ(TIMESTAMP WITH TIME ZONE) にマッピングされます。タイムゾーンのない TIMESTAMP 型を使用するには、同期設定またはテーブル作成文で明示的に指定する必要があります。
MySQL のデータ型 | 移行後の Hologres のデータ型 |
BIGINT | BIGINT |
BIGINT(20) UNSIGNED | TEXT |
| BYTEA |
BIT | BOOLEAN |
|
|
DATE | DATE |
DATETIME |
|
|
|
DOUBLE | DOUBLE PRECISION |
FLOAT | REAL |
INT, INTEGER | INT, INTEGER |
MEDIUMINT | INTEGER |
|
|
SMALLINT | SMALLINT |
TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB | BYTEA |
TINYINT | SMALLINT |
TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT | TEXT |
TIME |
|
TIMESTAMP |
|
| BYTEA |
|
|
| TEXT |
クエリ構文
MySQL と Hologres のクエリ構文は、次の点で異なります。
引用符
Hologres は大文字と小文字を区別しません。大文字と小文字を区別させるには、識別子を二重引用符 ("") で囲む必要があります。
たとえば、
select `A` from bをselect "A" from bに置き換えます。フィルター条件
Hologres では、フィルター条件で厳密な型一致が要求され、デフォルトでは暗黙の型変換は実行されません。例:
サンプルコード:
SELECT * FROM business_module WHERE ds = 20210329;問題:
ds フィールドが Hologres で TEXT 型であり、20210329 が INTEGER 値である場合、このクエリは型不一致エラーを返します:
operator does not exist: text = integer;解決策:
次の例に示すように、Hologres でカスタム型キャストを作成できます:
CREATE CAST (TEXT AS INTEGER) WITH INOUT AS IMPLICIT; CREATE CAST (TEXT AS BIGINT) WITH INOUT AS IMPLICIT; CREATE CAST (TEXT AS DECIMAL) WITH INOUT AS IMPLICIT; CREATE CAST (TEXT AS TIMESTAMP) WITH INOUT AS IMPLICIT; CREATE CAST (NUMERIC AS TEXT) WITH INOUT AS IMPLICIT;
ページネーション
MySQL は
limit 0,10構文を使用します。Hologres では、標準のoffset 0 limit 10構文を使用する必要があります。ソート
MySQL はソートに
desc nulls first asc nulls firstを使用します。Hologres のデフォルトのソート動作はdesc nulls first asc nulls lastです。一貫した動作を保証するには、Hologres のクエリを手動で調整して
order by XXX desc nulls lastを使用する必要があります。グループ化
Hologres は、デフォルトでは FLOAT や DOUBLE などの非厳密な型に対する GROUP BY をサポートしていません。これを解決するには、これらの列を DECIMAL 型に変換するか、次のパラメーターを設定します。
説明この機能には Hologres V0.10 以降が必要です。ご利用のインスタンスがそれより前のバージョンを実行している場合は、Hologres DingTalk グループに参加してテクニカルサポートに連絡し、アップグレードを依頼してください。サポートの利用方法の詳細については、「オンラインサポートの利用方法」をご参照ください。
set hg_experimental_enable_double_equivalent=on;--セッションレベル alter database XXX set hg_experimental_enable_double_equivalent=on;--データベース全体Union
UNION 演算子では、クエリ内の列のデータ型が一致している必要があります。例:
サンプルコード:
SELECT project_id FROM tableA union ALL select project_id from tableB;問題:
tableA の project_id 列が BIGINT 型で、tableB の project_id 列が TEXT 型の場合、MySQL は暗黙の型変換を実行してからクエリ結果を返します。しかし、この SQL 文を Hologres で実行するとエラーが発生します。次のエラーメッセージが返されます:
UNION types bigint and text cannot be matched;解決策:
UNION 操作では、データ型を明示的にキャストする必要があります:
SELECT project_id FROM tableA union ALL select cast(project_id as bigint) from tableB;
関数の使用
Hologres は、ほとんどの PostgreSQL 互換関数をサポートしています。詳細については、「PostgreSQL 互換関数」をご参照ください。MySQL と Hologres の関数の違いについては、次の点にご注意ください。
ゼロ除算
問題:
MySQL では、0 による除算操作は NULL を返します。Hologres では、同じ操作でエラーが返されます:
ERROR: division by zero;解決策:
select a / b from table; -- select a / NULLIF(b,0) from table; に変換します。Hologres V1.3.21 以降では、次の Grand Unified Configuration (GUC) パラメーターを設定して、
0による除算でエラーが発生するのを防ぐことができます。問題が発生した場合は、「一般的なアップグレード準備の失敗エラー」をご参照いただくか、Hologres DingTalk グループに参加してフィードバックを提供してください。サポートの利用方法の詳細については、「追加のオンラインサポートの利用方法」をご参照ください。--MySQL 互換拡張機能を作成 (スーパーユーザー権限が必要。データベースごとに 1 回実行) create extension if not exists mysql_compatible; --ゼロ除算の許容を有効化 (DQL クエリがエラーなしで続行可能に) set mysql_compatible.enable = on;例:
--MySQL 互換拡張機能を作成 (スーパーユーザー権限が必要。データベースごとに 1 回実行) create extension if not exists mysql_compatible; --シナリオ 1:同じ型の定数除算 set mysql_compatible.enable = on; select 1/0; --シナリオ 2:型変換を伴う定数除算 set mysql_compatible.enable = on; select 1.0/0; --シナリオ 3:被除数が列変数 set mysql_compatible.enable = on; select sum(c) / 0 from (select generate_series(1,100) as c) as t; --シナリオ 4:除数が列変数 set mysql_compatible.enable = on; select max(c)/sum(d) from (select generate_series(1,101) as c, generate_series(-50,50) as d) as t; --シナリオ 5:INSERT 中のゼロ除算を許容 create table if not exists test_insert_divide_by_zero(c1 int); set mysql_compatible.strict_mode = off; set mysql_compatible.enable = on; insert into test_insert_divide_by_zero select 100 / 0.0;
整数除算
問題:
余りが出る 2 つの整数を除算すると、MySQL は 10 進数の値を返しますが、Hologres は整数を返し、余りを切り捨てます。
たとえば、5 を 2 で割ると、MySQL では 2.5 が返されますが、Hologres では 2 が返されます。
解決策:
MySQL と同じ結果を得るには、整数の 1 つを浮動小数点型に明示的にキャストする必要があります:
select 1/2::FLOAT;
IF 関数
Hologres は IF 関数をサポートしていません。代わりに CASE WHEN 式を使用する必要があります。
IFNULL 関数
MySQL の IFNULL 関数は、Hologres の
COALESCE(x,y)関数で置き換えることができます。LENGTH 関数
MySQL の LENGTH 関数は、Hologres の
CHAR_LENGTH(string)関数で置き換えることができます。
よくある質問
MySQL と Hologres での複数列に対する COUNT DISTINCT の結果の不一致
原因
MySQL では、
count(distinct column_1, column_2, ...)式は、指定された列のいずれかに NULL 値が含まれている行を除外します。Hologres では、
count(distinct(column_1, column_2, ...))式は、指定された列の一部に NULL 値が含まれている場合でも行を含みます。解決策
Hologres で MySQL の動作を再現するには、クエリを
count(distinct column_1 || column_2 || ...)のように再書き込みします。例
CREATE TABLE count_distinct_test ( a text, b text ); INSERT INTO count_distinct_test VALUES ('a', 'b'), ('a', NULL), (NULL, 'b'), ('a', 'b'); -- Hologres の複数列 COUNT DISTINCT SELECT count(distinct(a, b)::text) FROM count_distinct_test; -- 結果 count ------- 3 (1 row) -- MySQL の動作に一致する Hologres のクエリ SELECT count(distinct a||b) FROM count_distinct_test; -- 結果 count ------- 1 (1 row)