| 類型 | UDF (User Defined Function) | 內建函數 |
| 編譯產物 | 共享庫(.so/.dll) | 編譯進 mysqld 二進制 |
| 部署方式 | CREATE FUNCTION 動態載入 | 重新編譯整個 MySQL |
| 升級影響 | 介面相容即可繼續使用 | 每次升級需重複修改原始碼 |
| 適用場景 | 第三方擴充、快速迭代 | 核心功能、極致效能 |
UDF 開發流程
- 撰寫 C/C++ 原始碼,實作
xxx_init、xxx、xxx_deinit 三個函數
- 編譯為共享庫:
gcc -shared -o myfunc.so myfunc.cc -I/usr/include/mysql
- 放置於 plugin_dir(
SHOW VARIABLES LIKE 'plugin_dir';)
- 註冊:
CREATE FUNCTION myfunc RETURNS INTEGER SONAME 'myfunc.so';
- 使用:
SELECT myfunc(col) FROM tbl;
- 移除:
DROP FUNCTION myfunc;
關鍵介面結構
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
void xxx_deinit(UDF_INIT *initid);
long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
initid->ptr:儲存私有資料指標(如預分配緩衝區)
args->arg_type:參數型別陣列
args->args:參數值陣列
- 回傳
long long(整數)、double(實數)、char*(字串)
安全機制
- 需
INSERT 權限於 mysql.func 表才能建立 UDF
--skip-grant-tables 會停用 UDF 載入
- 共享庫需置於
plugin_dir,防止任意路徑載入
- 函數名不得與內建函數衝突
替代方案:預存函數
純 SQL 撰寫,無需編譯:
CREATE FUNCTION hello(s CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN CONCAT('Hello, ', s, '!');
- 優點:跨平台、無部署依賴、版本升級無影響
- 缺點:複雜運算效能較 C/C++ UDF 低
範例原始碼位置
MySQL 原始碼包含完整範例:sql/udf_example.cc
- 上一篇文章: MySQL 資料匯入全攻略:INSERT、LOAD DATA、mysqlimport 三大方式詳解
- 下一篇文章: MySQL 分頁查詢優化深度解析:從 LIMIT 偏移到 ID 集合快取策略
Copyright ©
程式碼之家 All Rights Reserved