本文介紹RDS MySQL DuckDB分析執行個體的相容性。
以下相容性說明內容均需開啟duckdb_sql_normalization參數。
支援的資料類型
在下表中,僅列出DuckDB分析執行個體與MySQL存在差異的資料類型。
類型 | MySQL資料類型 | 相容性說明 |
字元類型 |
| 僅支援UTF8系列的字元集和校對規則。 |
時間類型 |
| DuckDB分析執行個體支援範圍為 而MySQL支援範圍為 |
| DuckDB分析執行個體支援範圍為 對於範圍在 | |
| DuckDB分析執行個體支援範圍為 對於範圍在 | |
空間資料類型 |
| 不相容 |
SELECT語句限制
字元集轉換
對於字元集轉換函式,無論目標字元集為何值,都將統一轉換為
utf8mb4字元集交由DuckDB執行。例如:SELECT convert(id using gbk) FROM t1; SELECT cast(id AS CHAR CHARACTER SET utf8mb4) FROM t1;時間間隔單位(Interval unit)
不支援以下時間間隔單位。
YEAR_MONTH, DAY_HOUR, HOUR_MINUTE, DAY_MINUTE, HOUR_SECOND, DAY_SECOND, SECOND_MICROSECOND, HOUR_MICROSECOND, DAY_MICROSECOND, MINUTE_SECOND, MINUTE_MICROSECOND, SQL_TSI_HOUR子查詢
不支援等值非標量子查詢。例如:
SELECT * FROM t1 WHERE (id, col1) = (SELECT id, col1 FROM t1);BINARY(num)類型轉換
不支援顯式轉換為
BINARY(num)資料類型,其中的binary位元將被忽略。例如:SELECT CAST('abc' AS binary(1));UNSIGNED類型轉換
不支援顯式轉換為
UNSIGNED資料類型。例如:SELECT CAST(1 AS UNSIGNED);
類型轉換問題
為確保執行效率,DuckDB分析執行個體在執行過程中採用強型別約束機制。在查詢執行時,系統會根據上下文自動進行類型轉換,這種轉換稱為隱式類型轉換。對於無法通過隱式方式完成轉換的情境,您需要使用CAST或CONVERT函數顯式指定類型轉換,以確保查詢能夠正確執行。
函數中支援的隱式類型轉換規則
“/”表示不涉及隱式轉換,“✔️”表示支援隱式轉換,“✖️”表示不支援隱式轉換。
常規字串類型代指MySQL中的
CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、JSON、SET和ENUM。二進位字串類型代指MySQL中的
BINARY、VARBINARY、BIT、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。不支援大範圍整數類型轉換為小範圍整數類型。
轉換至基礎標量類型
源類型 | 隱式轉換至基礎標量類型 | ||
字串字面量 | 數值字面量 | ||
基礎標量 | 字串字面量 | / | ✖️ |
數值字面量 | ✖️ | / | |
數值 | BOOLEAN | ✖️ | ✖️ |
整數類型 | ✖️ | ✖️ | |
FLOAT | ✖️ | ✖️ | |
DOUBLE | ✖️ | ✖️ | |
DECIMAL | ✖️ | ✖️ | |
字串 | 常規字串 | ✖️ | ✖️ |
二進位字串 | ✖️ | ✖️ | |
日期與時間 | YEAR | ✖️ | ✖️ |
DATE | ✖️ | ✖️ | |
TIME | ✖️ | ✖️ | |
DATETIME | ✖️ | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | |
轉換至數實值型別
源類型 | 隱式轉換至數實值型別 | |||||
BOOLEAN | 整數類型 | FLOAT | DOUBLE | DECIMAL | ||
基礎標量 | 字串字面量 | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ |
數值字面量 | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ | |
數值 | BOOLEAN | / | ✖️ | ✖️ | ✖️ | ✖️ |
整數類型 | ✖️ | / | ✔️ | ✔️ | ✔️ | |
FLOAT | ✖️ | ✔️:僅支援轉換為BIGINT | / | ✔️ | ✖️ | |
DOUBLE | ✖️ | ✔️:僅支援轉換為BIGINT | ✖️ | / | ✖️ | |
DECIMAL | ✖️ | ✔️ | ✔️ | ✔️ | / | |
字串 | 常規字串 | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ |
二進位字串 | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
日期與時間 | YEAR | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ |
DATE | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
TIME | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
DATETIME | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
轉換至字串類型
源類型 | 隱式轉換至字串類型 | ||
常規字串 | 二進位字串 | ||
基礎標量 | 字串字面量 | ✔️ | ✖️ |
數值字面量 | ✖️ | ✖️ | |
數值 | BOOLEAN | ✖️ | ✖️ |
整數類型 | ✔️ | ✖️ | |
FLOAT | ✔️ | ✖️ | |
DOUBLE | ✔️ | ✖️ | |
DECIMAL | ✔️ | ✖️ | |
字串 | 常規字串 | / | ✖️ |
二進位字串 | ✖️ | / | |
日期與時間 | YEAR | ✔️ | ✖️ |
DATE | ✔️ | ✖️ | |
TIME | ✔️ | ✖️ | |
DATETIME | ✔️ | ✖️ | |
TIMESTAMP | ✔️ | ✖️ | |
轉換至日期與時間類型
源類型 | 隱式轉換至日期與時間類型 | |||||
YEAR | DATE | TIME | DATETIME | TIMESTAMP | ||
基礎標量 | 字串字面量 | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
數值字面量 | ✔️ | ✖️ | ✖️ | ✖️ | ✖️ | |
數值 | BOOLEAN | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
整數類型 | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
FLOAT | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
DOUBLE | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
DECIMAL | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
字串 | 常規字串 | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
二進位字串 | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
日期與時間 | YEAR | / | ✖️ | ✖️ | ✖️ | ✖️ |
DATE | ✖️ | / | ✖️ | ✔️ | ✔️ | |
TIME | ✖️ | ✖️ | / | ✔️ | ✔️ | |
DATETIME | ✖️ | ✖️ | ✖️ | / | ✔️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | ✔️ | / | |
類型比較中支援的隱式轉換規則
DuckDB分析執行個體在類型轉換和比較規則上具有更高的嚴格性和一致性,但在某些情境下可能與MySQL存在行為差異。具體如下:
字串到日期的隱式轉換:字串隱式轉換為日期時,如果字串格式無法正確解析為有效日期值,SQL查詢將報錯並執行失敗。
整數類型之間的比較規則:不同整數類型之間進行比較時,DuckDB分析執行個體會統一向取值範圍更大的整數類型進行轉換。
多元運算式的類型轉換順序:對於
col1 in (col2, col3, col4, ...)、col1 between col2 and col3、coalesce(col1, col2, col3, ...)等多元運算式,會按照順序進行類型轉換。YEAR類型的相容性差異:在DuckDB分析執行個體中,YEAR類型會被轉換為INTEGER類型進行比較,可能與MySQL存在不相容。例如:
CREATE TABLE t1 (id YEAR PRIMARY KEY); INSERT INTO t1 VALUES (1980); SELECT * FROM t1 WHERE id BETWEEN 70 AND 90; # MySQL查詢結果 +------+ | id | +------+ | 1980 | +------+ # DuckDB分析執行個體查詢結果 Empty set.布爾類型的字串轉換規則:DuckDB分析執行個體支援將
'1'、'0'、'yes'、'no'、'true'、'false'六種字串轉換為BOOLEAN類型,其餘字串轉換會報錯;而MySQL會將'1'轉換為true,其餘字串均轉換為false。因此,如下SQL可能會存在結果不一致問題:CREATE TABLE t1 (id INT PRIMARY KEY); INSERT INTO t1 VALUES (1); SELECT id FROM t1 WHERE 'true'; # MySQL查詢結果 Empty set # DuckDB分析執行個體查詢結果 +------+ | id | +------+ | 1 | +------+
當不同類型的資料進行比較時,系統會按下表規則,將資料“轉換為同一類型”後進行比較;對於不支援(✖️)的類型比較,會直接報錯。
常規字串類型代指MySQL中的
CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、JSON、SET和ENUM。二進位字串類型代指MySQL中的
BINARY、VARBINARY、BIT、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。
與基礎標量類型比較
源類型 | 與基礎標量類型比較 | ||
字串字面量 | 數值字面量 | ||
基礎標量 | 字串字面量 | 字串 | 數值字面量 |
數值字面量 | 數值字面量 | 較大範圍的數實值型別 | |
數值 | BOOLEAN | BOOLEAN | 較大範圍的數實值型別 |
整數類型 | 整數類型 | 較大範圍的數實值型別 | |
FLOAT | FLOAT | 較大範圍的數實值型別 | |
DOUBLE | DOUBLE | 較大範圍的數實值型別 | |
DECIMAL | DECIMAL | 較大範圍的數實值型別 | |
字串 | 常規字串 | 常規字串 | 數值字面量 |
二進位字串 | 二進位字串 | ✖️ | |
日期與時間 | YEAR | YEAR | 較大範圍的數實值型別 |
DATE | DATETIME | ✖️ | |
TIME | TIME | ✖️ | |
DATETIME | DATETIME | ✖️ | |
TIMESTAMP | TIMESTAMP | ✖️ | |
與數實值型別比較
源類型 | 與數實值型別比較 | |||||
BOOLEAN | 整數類型 | FLOAT | DOUBLE | DECIMAL | ||
基礎標量 | 字串字面量 | BOOLEAN | 整數類型 | FLOAT | DOUBLE | DECIMAL |
數值字面量 | 較大範圍的數實值型別 | 較大範圍的數實值型別 | 較大範圍的數實值型別 | 較大範圍的數實值型別 | 較大範圍的數實值型別 | |
數值 | BOOLEAN | BOOLEAN | 整數類型 | FLOAT(不等式比較✖️) | DOUBLE(不等式比較✖️) | DECIMAL(不等式比較✖️) |
整數類型 | 整數類型 | 整數類型 | FLOAT | DOUBLE | DECIMAL | |
FLOAT | FLOAT(不等式比較✖️) | FLOAT | FLOAT | DOUBLE | FLOAT | |
DOUBLE | DOUBLE(不等式比較✖️) | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
DECIMAL | DECIMAL(不等式比較✖️) | DECIMAL | FLOAT | DOUBLE | DECIMAL | |
字串 | 常規字串 | BOOLEAN | 整數類型 | FLOAT | DOUBLE | DECIMAL |
二進位字串 | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
日期與時間 | YEAR | INTEGER | 較大範圍的整數類型 | FLOAT | DOUBLE | DECIMAL |
DATE | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
TIME | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
DATETIME | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
與字串類型比較
源類型 | 與字串類型比較 | ||
常規字串 | 二進位字串 | ||
基礎標量 | 字串字面量 | 常規字串 | 二進位字串 |
數值字面量 | 數值字面量 | ✖️ | |
數值 | BOOLEAN | BOOLEAN | ✖️ |
整數類型 | 整數類型 | ✖️ | |
FLOAT | FLOAT | ✖️ | |
DOUBLE | DOUBLE | ✖️ | |
DECIMAL | DECIMAL | ✖️ | |
字串 | 常規字串 | 常規字串 | 二進位字串 |
二進位字串 | 二進位字串 | 二進位字串 | |
日期與時間 | YEAR | INTEGER | ✖️ |
DATE | DATE | ✖️ | |
TIME | TIME | ✖️ | |
DATETIME | DATETIME | ✖️ | |
TIMESTAMP | TIMESTAMP | ✖️ | |
與日期與時間類型比較
源類型 | 與日期與時間類型比較 | |||||
YEAR | DATE | TIME | DATETIME | TIMESTAMP | ||
基礎標量 | 字串字面量 | YEAR | DATETIME | TIME | DATETIME | TIMESTAMP |
數值字面量 | 較大範圍的數實值型別 | ✖️ | ✖️ | ✖️ | ✖️ | |
數值 | BOOLEAN | INTEGER | ✖️ | ✖️ | ✖️ | ✖️ |
整數類型 | 較大範圍的整數類型 | ✖️ | ✖️ | ✖️ | ✖️ | |
FLOAT | FLOAT | ✖️ | ✖️ | ✖️ | ✖️ | |
DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
DECIMAL | DECIMAL | ✖️ | ✖️ | ✖️ | ✖️ | |
字串 | 常規字串 | INTEGER | DATE | TIME | DATETIME | TIMESTAMP |
二進位字串 | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
日期與時間 | YEAR | INTEGER | ✖️ | ✖️ | ✖️ | ✖️ |
DATE | ✖️ | DATE | ✖️ | DATETIME | TIMESTAMP | |
TIME | ✖️ | ✖️ | TIME | ✖️ | ✖️ | |
DATETIME | ✖️ | DATETIME | ✖️ | DATETIME | DATETIME | |
TIMESTAMP | ✖️ | TIMESTAMP | ✖️ | DATETIME | TIMESTAMP | |
可能出現的查詢結果不一致問題
數值運算
浮點數的大小比較存在不相容。例如:
CREATE TABLE t1 (id FLOAT PRIMARY KEY); INSERT INTO t1 VALUES (1.22), (1.23), (1.24); SELECT * FROM t1 WHERE t1.id > 1.23; # MySQL查詢結果 +------+ | id | +------+ | 1.23 | | 1.24 | +------+ # DuckDB分析執行個體查詢結果 +------+ | id | +------+ | 1.24 | +------+浮點數的複雜複合運算結果因為浮點誤差會存在不一致。
當整數、DECIMAL類型之間做運算時,結果不能超過該類型的取值範圍,否則可能出現結果溢出導致的執行失敗。
CREATE TABLE t1 (id TINYINT PRIMARY KEY); INSERT INTO t1 VALUES (100); SELECT id * 2 FROM t1; # MySQL查詢結果 +--------+ | id * 2 | +--------+ | 200 | +--------+ # DuckDB分析執行個體查詢結果 ERROR 7577 (HY000): [DuckDB] Out of Range Error: Overflow in multiplication of INT8 (100 * 2)!.
校對規則導致的結果不一致問題
utf8mb4_0900_xx系列的校對規則在部分符號字元的比較中存在不相容。例如:
CREATE TABLE t1 ( id varchar(20) COLLATE utf8mb4_0900_ai_ci PRIMARY KEY );
INSERT INTO t1 VALUES ('!'), ('_');
SELECT * FROM t1 ORDER BY id;
# MySQL查詢結果
+----+
| id |
+----+
| _ |
| ! |
+----+
# DuckDB分析執行個體查詢結果
+----+
| id |
+----+
| ! |
| _ |
+----+IN的向量子查詢對於NULL值的處理
在DuckDB分析執行個體中,IN的向量子查詢對於NULL值的處理存在不相容問題。例如:
CREATE TABLE t1 (id INT PRIMARY KEY, col1 INT);
INSERT INTO t1 VALUES (1, 1), (2, 2);
CREATE TABLE t2 (id INT PRIMARY KEY, col1 INT);
INSERT INTO t2 VALUES (1, NULL);
select (id, col1) in (select id, col1 from t2) from t1;
# MySQL查詢結果
+-----------------------------------------+
| (id, col1) in (select id, col1 from t2) |
+-----------------------------------------+
| NULL |
| 0 |
+-----------------------------------------+
# DuckDB分析執行個體查詢結果
+-----------------------------------------+
| (id, col1) in (select id, col1 from t2) |
+-----------------------------------------+
| NULL |
| NULL |
+-----------------------------------------+對於資料(2, 2),IN後不存在向量首碼的匹配項,MySQL返回0,DuckDB分析執行個體返回NULL。
函數限制
在下表中,僅列出DuckDB分析執行個體與MySQL存在相容性差異的函數。
彙總函式
函數名 | 是否支援 | 使用限制 |
| 是 | 不支援字串類型、DECIMAL類型、日期類型。 |
| 是 | 不支援字串類型、DECIMAL類型、日期類型。 |
| 是 | 不支援字串類型、DECIMAL類型、日期類型。 |
| 否 | / |
數值函數
數值函數不支援BOOLEAN類型。
函數名 | 是否支援 | 使用限制 |
| 否 | / |
| 否 | / |
| 否 | / |
字串函數
MySQL DuckDB嚴格區分二進位字串(BLOB,VARBINARY等)和字串(VARCHAR,TEXT,JSON等),因此以下字串函數使用限制只考慮以字串為輸入,不以二進位字串為輸入。部分能夠以二進位字串為輸入的函數有:CONCAT()、CONCAT_WS()、LENGTH()、MID()、OCTET_LENGTH()、REPEAT()、TO_BASE64(),對於這些函數,如果沒有額外說明,則無使用限制。
函數名 | 是否支援 | 使用限制 |
| 是 | MySQL中 |
| 否 | / |
| 否 | / |
| 否 | / |
| 是 | 該函數的第一個參數需要是字元類型,非字元類型可能會產生與MySQL不一致的結果。 |
| 否 | / |
| 是 | 該函數使用base64解碼規則解碼失敗時會報錯。 |
| 是 |
|
| 否 | / |
| 否 | / |
| 否 | / |
| 是 |
|
| 是 | MySQL中 |
| 否 | / |
| 否 | / |
| 否 | / |
| 是 | 該函數遇到非HEX digit會報錯。 |
| 否 | / |
日期函數
函數名 | 是否支援 | 使用限制 |
| 是 | 如果傳回值超出DuckDB分析執行個體的時間類型資料的取值範圍,會產生結果不一致的問題。 |
| 是 | 不支援 |
| 否 | / |
| 是 | 年份超過9999暫不支援。 |
| 是 | 年份超過9999暫不支援。 |
| 是 | 如果傳回值超出DuckDB分析執行個體的時間類型資料的取值範圍,會產生結果不一致的問題。 |
| 是 |
|
| 是 | 如果傳回值超出DuckDB分析執行個體的時間類型資料的取值範圍,會產生結果不一致的問題。 |
| 是 | 不支援DAY TIME格式的輸入,例如: |
| 否 | / |
JSON函數
函數名 | 是否支援 | 使用限制 |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
| 是 | 合并後JSON的欄位順序可能與MySQL中不同。 |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
| 否 | / |
視窗函數
函數名 | 是否支援 | 使用限制 |
| 否 | / |
| 否 | / |