本文介紹從谷歌BigQuery遷移數據到云原生數據倉庫AnalyticDB PostgreSQL版的過程。
準備工作
- 已準備需要遷移的谷歌BigQuery服務。
- 已準備用于導出谷歌BigQuery數據的谷歌Cloud Storage服務,并創建存儲分區(Bucket)。
- 已創建擁有訪問谷歌Cloud Storage權限的IAM用戶。
- 已開通阿里云對象存儲服務(OSS),OSS的詳細信息,請參見什么是對象存儲OSS。
- 已創建OSS存儲空間,請參見創建存。說明 建議OSS存儲空間與AnalyticDB PostgreSQL版實例在同一地域,便于后續數據導入數據庫中。
- 已創建AnalyticDB PostgreSQL版實例,如何創建實例,請參見創建實例。
步驟一:將谷歌BigQuery的數據導出到谷歌Cloud Storage
將谷歌BigQuery的數據導出到谷歌Cloud Storage需要使用bq命令行工具,關于bq命令行工具的使用方法,請參見使用bq命令行工具。
- 使用bq命令行工具查詢谷歌BigQuery數據集中表的DDL語句并下載至本地設備。具體操作請參見INFORMATION_SCHEMA.TABLES視圖。谷歌BigQuery不提供
show create table
等命令查看表的DDL腳本,但谷歌BigQuery允許您使用內置的用戶自定義函數UDF來查詢特定數據集中表的DDL腳本。 - 通過bq命令行工具,執行
bq extract
命令,將谷歌BigQuery數據集中的表依次導出至谷歌Cloud Storage的存儲分區中。導出相關操作以及數據格式和壓縮類型的說明,請參見導出表數據。導出命令示例如下。bq extract --destination_format AVRO --compression SNAPPY tpcds_100gb.web_site gs://bucket_name/web_site/web_site-**.avro.snappy;
- 查看谷歌Cloud Storage的存儲分區,檢查數據導出結果。
步驟二:將谷歌Cloud Storage上的數據同步到阿里云OSS
通過在線遷移上云服務,將谷歌Cloud Storage上的數據同步到阿里云OSS上。具體操作,請參見遷移實施。
步驟三:創建用于裝載數據的目標表
在AnalyticDB PostgreSQL版實例中創建用于裝載谷歌BigQuery的數據的目標表。目標表結構需與源表結構一致,建表語法,請參見CREATE TABLE 。
谷歌BigQuery與AnalyticDB PostgreSQL版的數據類型和DDL語法對應關系,請參見語法轉換。
步驟四:將OSS數據導入AnalyticDB PostgreSQL版實例
您可以通過COPY命令或OSS外表將數據導入AnalyticDB PostgreSQL版:
- 使用COPY命令導入OSS數據的方法,請參見使用COPY或UNLOAD命令導入或導出數據到OSS。
- 使用OSS外表導入OSS數據的方法,請參見導入OSS數據到本地表。重要 遷移數據時建議使用AVRO格式文件,但AVRO格式文件暫不支持STRUCT和GEOGRAPHY數據類型遷移至AnalyticDB PostgreSQL版。
語法轉換
數據類型
谷歌BigQuery數據類型 | AnalyticDB PostgreSQL版數據類型 |
---|---|
INT64 | BIGINT |
FLOAT64 | FLOAT |
NUMERIC | DECIMAL |
BIGNUMERIC | DECIMAL |
BOOL | BOOLEAN |
BYTES(2字節頭) | BYTES(1字節頭) |
STRING/STRING() | TEXT/VARCHAR() |
DATE | DATE |
DATETIME | TIMESTAMP |
TIME | TIME |
TIMESTAMP | TIMESTAMP |
INTERVAL | INTERVAL |
ARRAY | ARRAY[] |
STRUCT | CREATE TYPE |
JSON | JSON |
GEOGRAPHY | CREATE TYPE/GEOGRAPHY |
DDL
CREATE TABLE
- PARTITION BY(分區表)谷歌BigQuery的分區方式主要有以下三大類:
- 整數范圍分區
對應AnalyticDB PostgreSQL版的數字范圍表分區,可以使用數字數據類型的列作為分區鍵列,AnalyticDB PostgreSQL版數字范圍分區表示例如下。
CREATE TABLE rank (id int, rank int, year int, gender char(1), count int) DISTRIBUTED BY (id) PARTITION BY RANGE (year) ( START (2020) END (2023) EVERY (1), DEFAULT PARTITION extra );
其中EVERY對應谷歌BigQuery的整數范圍分區表中的INTERVAL。
- 時間單位列分區
對應AnalyticDB PostgreSQL版的日期范圍表分區,可以使用單個DATE或TIMESTAMP作為分區鍵列。
谷歌BigQuery中是通過
DAY
、MONTH
和YEAR
來指定分區粒度,在AnalyticDB PostgreSQL版中,您可以通過EVERY(INTERVAL)
來指定分區粒度。AnalyticDB PostgreSQL版日期范圍分區表(分區粒度為天)示例如下。CREATE TABLE sales(id int, date date, amt decimal(10,2)) DISTRIBUTED BY (id) PARTITION BY RANGE (date) ( START (date '2022-01-01') INCLUSIVE END (date '2023-01-01') EXCLUSIVE EVERY (INTERVAL '1 day') );
- 提取時間分區
對應AnalyticDB PostgreSQL版的日期范圍表分區。與時間單位列分區轉換方式不同的是,AnalyticDB PostgreSQL版不支持偽時間列,您需要在建目標表的時候添加
create_time
列。
- 整數范圍分區
- CLUSTER BY(聚簇)
對應AnalyticDB PostgreSQL版DISTRIBUTED BY。谷歌BigQuery每張表中最多有4個聚簇列,而AnalyticDB PostgreSQL版則沒有分布列的數量限制。
- DEFAULT COLLATE
表示ORDER BY、GROUP BY等可以用于比較的運算的排序規則(默認為binary排序規則)。通常情況下,遷移數據時可以忽略該內容。
CREATE EXTERNAL TABLE
谷歌BigQuery與AnalyticDB PostgreSQL版的外表連接信息有所區別。
- 谷歌BigQuery:通過WITH CONNECTION子句指定訪問外部數據的憑證、PROJECT_ID.LOCATION.CONNECTION_ID的形式指定連接名稱。
- AnalyticDB PostgreSQL版:通過LOCATION指定外部數據的憑證和連接信息。
AnalyticDB PostgreSQL版的外表支持FILE、gpfdist、HTTP等協議。如果您將數據存在OSS中,可以通過oss_fdw插件創建OSS外表獲取數據。
CREATE PROCEDURE
可以通過CREATE FUNCTION代替。
其他SQL適配
MERGE語句
在谷歌BigQuery中,MERGE可以將INSERT、UPDATE和DELETE操作合并成一條語句執行操作,操作過程中,MERGE會對比源表和目標表,對于匹配的tuple(元組)可以進行更新或刪除,對于不匹配的tuple可以選擇插入、更新或刪除。
MERGE語句在AnalyticDB PostgreSQL版中可以通過一個事務來完成。例如以下場景,您需要在表中插入新的庫存商品以及庫存數量,如果商品已存在,則更新現有商品的庫存數量,示例如下。
BEGIN;
-- other operations
SAVEPOINT sp1;
INSERT INTO wines VALUES('hateau Lafite 2023', '24');
-- Assume the above fails because of a unique key violation,
-- so now we issue these commands:
ROLLBACK TO sp1;
UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2023';
-- continue with other operations, and eventually
COMMIT;
以主鍵進行匹配時,也可以使用INSERT ON CONFLICT實現。
INSERT INTO wines VALUES('Chateau Lafite 2023', '24') ON CONFLICT (winename) DO UPDATE SET
stock = stock + 24;
SELECT語句
- AnalyticDB PostgreSQL版暫不支持
SELECT * EXCEPT/REPLACE
語句。 - AnalyticDB PostgreSQL版暫不支持通過QUALIFY子句過濾窗口函數中的結果,您可以通過多層嵌套查詢實現。