MySQL 連携クエリを実行する
データ アナリストは、データのコピーや移動を行うことなく、MySQL に存在するリレーショナル データを BigQuery から直接リアルタイムでクエリできます。
BigQuery MySQL 連携では、BigQuery Connection API を使用して MySQL データベース エンジンに接続します。その後、EXTERNAL_QUERY 関数を使用して SQL クエリを MySQL に直接送信して実行すると、結果が直接ストリーミングされます。
制限事項
MySQL 連携クエリには、次の制限があります。
EXTERNAL_QUERY関数を使用して実行できるのは、読み取り専用クエリのみです。データ定義言語(DDL)ステートメントとデータ操作言語(DML)ステートメントはサポートされていません。- 連携には
EXTERNAL_QUERY関数を介してのみアクセスできます。MySQL テーブルに直接マッピングされる BigQuery 外部テーブルまたは永続データセットの作成はサポートされていません。 - 連携クエリのレイテンシは、MySQL で直接クエリを実行する場合よりも大幅に長くなる可能性があります。
- 基盤となる接続サービスが、非アクティブな接続を休止状態にする可能性があります。非アクティブな期間の後に MySQL 接続を使用する最初のクエリは、コネクタの初期化中に実行に 1 分以上かかることがあります。
- DNS ピアリングはサポートされていません。VPC ネットワーク内の IP アドレスまたは完全に解決可能なホスト名を使用して接続する必要があります。
- MySQL SQL クエリでは、関数の結果または式を含む列(
SELECT COUNT(*) AS total_countなど)に明示的な列エイリアスを指定する必要があります。エイリアスが設定されていない式では、BigQuery テーブル スキーマ定義で無効な特殊文字を含む列名が生成されます。 - クエリ プロジェクトでの Compute Engine API の使用が VPC Service Controls によって制限されている場合、接続でネットワーク アタッチメントが使用されていると、連携クエリは失敗します。適切な VPC Service Controls の上り(内向き)ルールと下り(外向き)ルールが構成されていることを確認します。
MySQL では、追加の SQL プッシュダウンはサポートされていません。外部の BigQuery クエリのフィルタと集計は、
EXTERNAL_QUERY関数内の内部クエリにプッシュダウンされません。ネットワーク経由で転送される行と列を制限するには、内部の MySQL SQL ステートメント内で述語と列のプロジェクションを直接指定する必要があります。MySQL データベースのユーザー名とパスワードによる認証のみがサポートされています。サードパーティの ID プロバイダ、Kerberos、クラウド プロバイダの IAM 認証はサポートされていません。
クエリで 32 ビット整数列(
TINYINT、SMALLINT、BOOLEAN/TINYINT(1))または単精度浮動小数点数列(FLOAT)が選択されている場合、CREATE TABLE ... AS SELECT(CTAS)ステートメントはUnsupported type INT32またはUnsupported type FLOATエラーで失敗します。クエリ結果を新しい BigQuery テーブルに保存するには、クエリで整数列をINT64に、浮動小数点数列をFLOAT64に明示的にキャストします。CREATE TABLE mydataset.mytable AS SELECT CAST(tiny_col AS INT64) AS tiny_col, CAST(small_col AS INT64) AS small_col, ... FROM EXTERNAL_QUERY(...);
INSERT INTO <table> SELECT ...を使用して既存のテーブルに挿入すると、BigQuery がINT32値とFLOAT値を自動的に拡張してターゲット テーブルのINT64列とFLOAT64列に一致させるため、手動キャストなしで成功します。MySQL の
DECIMAL列とNUMERIC列はBIGNUMERIC(76, 38)にマッピングされますが、MySQL では最大 65 の精度が許可されます。値に 38 桁を超える整数が含まれている場合(精度からスケールを引いた値が 38 を超える場合)、BIGNUMERICの整数範囲を超え、クエリは実行時に失敗します。38 桁を超える整数値に対してクエリを実行するには、EXTERNAL_QUERYステートメントでCHARまたはVARCHARにキャストします。TIMEデータ型は、1 秒未満(マイクロ秒)の値を秒単位に切り捨てます(たとえば、12:34:56.789123は12:34:56になります)。さらに、MySQL のTIMEは-838:59:59から838:59:59までの経過時間をサポートしますが、BigQuery のTIMEは00:00:00から23:59:59.999999までの時刻値のみをサポートします。00:00:00~23:59:59の範囲外の値は、ランタイム クエリエラーの原因になります。マイクロ秒の精度または経過時間の値が必要な場合は、EXTERNAL_QUERYステートメント内で列をCHARまたはVARCHARにキャストします。1582 年 10 月 15 日より前の日付とタイムスタンプは、歴史的なグレゴリオ暦の移行により、10 日間のカレンダー シフトの対象となります。1582 年より前の正確な過去の日付を保持するには、
EXTERNAL_QUERYステートメントでCHARまたはVARCHARにキャストします。
サポートされている MySQL の環境とバージョン
クエリ連携は、次のデプロイ環境で MySQL データベースをサポートします。
- パブリック IP アドレスまたはネットワーク アタッチメント(Cloud VPN または Cloud Interconnect 経由)を介してアクセス可能な、クラウドホスト型またはオンプレミスの MySQL データベース
- Compute Engine またはその他のインフラストラクチャ上のセルフホスト型 MySQL インスタンス
- MySQL 8.4 LTS、8.0
始める前に
BigQuery 管理者が MySQL 接続を作成して、共有していることを確認します。
必要なロール
MySQL をクエリするのに必要な権限を取得するには、プロジェクトに対する BigQuery 接続ユーザー(roles/bigquery.connectionUser)の IAM ロールを付与するよう管理者に依頼してください。ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
データのクエリ
GoogleSQL クエリから MySQL に連携クエリを送信するには、EXTERNAL_QUERY 関数を使用します。
次の例は、BigQuery の mydataset.customers という名前の顧客レコードと MySQL のトランザクション販売注文を結合する連携クエリです。
SELECT c.customer_id, c.name, fo.first_order_date FROM mydataset.customers AS c LEFT OUTER JOIN EXTERNAL_QUERY( 'projects/my-project/locations/us-central1/connections/mysql_prod_conn', '''SELECT CUSTOMER_ID, MIN(ORDER_DATE) AS first_order_date FROM ORDERS GROUP BY CUSTOMER_ID''') AS fo ON fo.customer_id = c.customer_id GROUP BY c.customer_id, c.name, fo.first_order_date;
MySQL テーブル スキーマを表示する
EXTERNAL_QUERY を介して MySQL INFORMATION_SCHEMA ビューにクエリを実行すると、分析を実行する前にデータベース メタデータの検査、テーブルの検出、列スキーマの確認を行うことができます。
すべてのデータベースを一覧表示する
SELECT * FROM EXTERNAL_QUERY( 'projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID', '''SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.SCHEMATA''');
データベース内のテーブルを一覧表示する
SELECT * FROM EXTERNAL_QUERY( 'projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID', """SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'DATABASE_NAME'""");
テーブルの列とデータ型を表示する
SELECT * FROM EXTERNAL_QUERY( 'projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID', """SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'DATABASE_NAME' AND TABLE_NAME = 'TABLE_NAME'""");
データ型マッピング
連携クエリを実行すると、BigQuery は次の表に従って MySQL のデータを GoogleSQL データ型に変換します。
| MySQL のデータ型 | BigQuery のデータ型 |
|---|---|
| 数値型 | |
BOOLEAN、BOOL、TINYINT(1) |
INT64(インタラクティブ クエリ。CREATE TABLE ... AS SELECT の制限事項をご覧ください) |
TINYINT、SMALLINT |
INT64(インタラクティブ クエリ。CREATE TABLE ... AS SELECT の制限事項をご覧ください) |
MEDIUMINT、INT、INTEGER |
INT64 |
BIGINT |
INT64 |
BIGINT UNSIGNED、BIGINT ZEROFILL、SERIAL |
BIGNUMERIC(76, 38) |
DECIMAL、DEC、NUMERIC、FIXED |
BIGNUMERIC(76, 38) |
FLOAT |
FLOAT64(インタラクティブ クエリ。CREATE TABLE ... AS SELECT の制限事項をご覧ください) |
DOUBLE、DOUBLE PRECISION、REAL |
FLOAT64 |
| 日時型 | |
DATE |
DATE |
DATETIME |
DATETIME |
TIMESTAMP |
TIMESTAMP |
TIME |
TIME |
| 文字列型とテキスト型 | |
CHAR |
STRING |
VARCHAR |
STRING |
BINARY |
BYTES |
VARBINARY |
BYTES |
TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB |
BYTES |
TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT |
STRING |
ENUM |
STRING |
SET |
STRING |
料金
連携クエリの実行にかかる費用は、次の 3 つの要因に基づきます。
- MySQL でクエリを実行する際のコンピューティング費用(MySQL データベース プロバイダまたはホスティング環境によって課金されます)
- MySQL から BigQuery にクエリ結果を転送する際の帯域幅費用(データベース ホスティング プロバイダからの下り(外向き)ネットワーク料金)
- BigQuery でクエリを実行するコンピューティング費用
MySQL のコンピューティング費用と下り(外向き)費用は、Google ではなく、MySQL プロバイダまたはインフラストラクチャ ホストから直接請求されます。帯域幅コストを抑えるため、クエリは、最終結果の計算に不要な列と行をすべて除外するように、EXTERNAL_QUERY ステートメントに記述することをおすすめします。
BigQuery で連携クエリを実行しても追加料金は発生しません。BigQuery の料金の詳細については、料金をご覧ください。
接続で Google Cloud ネットワーキング コンポーネントを使用している場合は、次の料金も適用されることがあります。
次のステップ
- MySQL への接続方法を確認する。
- 連携クエリの詳細を確認する。
- 接続の管理について確認する。