bitsCN.com
1.什么是UDF
UDF顾名思义,就是User defined Function,用户定义函数。我们知道,MySQL本身支持很多内建的函数,此外还可以通过创建存储方法来定义函数。UDF为用户提供了一种更高效的方式来创建函数。
UDF与普通函数类似,有参数,也有输出。分为两种类型:单次调用型和聚集函数。前者能够针对每一行数据进行处理,后者则用于处理Group By这样的情况。
2.为什么用UDF
既然MySQL本身提供了大量的函数,并且也支持定义函数,为什么我们还需要UDF呢?这主要基于以下几点:
1)UDF的兼容性很好,这得益于MySQL的UDF基本上没有变动
2)比存储方法具有更高的执行效率,并支持聚集函数
3)相比修改代码增加函数,更加方便简单
当然UDF也是有缺点的,这是因为UDF也处于mysqld的内存空间中,不谨慎的内存使用很容易导致mysqld crash掉。
3.如何编写UDF
UDF的API包括
name_init():
在执行SQL之前会被调用,主要做一些初始化的工作,比如分配后续用到的内存、初始化变量、检查参数是否合法等。
name_deinit()
在执行完SQL后调用,大多用于内存清理等工作。init和deinit这两个函数都是可选的
name()
UDF的主要处理函数,当为单次调用型时,可以处理每一行的数据;当为聚集函数时,则返回Group by后的聚集结果。
name_add()
在每个分组中每行调用
name_clear()
在每个分组之后调用
为了便于理解,这里给出两种UDF类型的API调用图:
下面将就上述几个API进行详细的讲解:
1). name_init
原型:
my_boolname_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
UDF_INIT结构体如下:
字段
类型
描述
maybe_null
my_bool
如果为1表示该UDF可以返回NULL
decimals
unsigned int
返回值为实数时,表示精度,范围0~30
max_length
unsigned long
对于返回值为INTEGER类型值为21,对于REAL类型值为17,对于字符串类型,存储函数最长参数的长度
ptr
char*
额外的指针,我们可以在这里分配内存。通过initd传递给其他API
const_item
my_bool
为1表示函数总是返回相同的值
extension
void*
用于扩展?
UDF_ARGS结构体如下:
字段
类型
描述
arg_count
unsigned int
参数个数
arg_type
enum Item_result*
参数类型数组,记录每一个参数的类型,可以是STRING_RESULT、REAL_RESULT、INT_RESULT以及DECIMAL_RESULT
args
char **
同样是一个数组,用于存储实际数据。
STRING_RESULT与DECIMAL_RESULT类型为char*,INT_RESULT类型为long long*,REAL_RESULT类型为double*,或者一个NULL指针
lengths
unsigned long*
数组,用于存储每一个参数的长度
maybe_null
char *
该数组用于表明每个参数是否可以为NULL,例如
attributes
char **
每个参数的名字
attribute_lengths
unsigned long*
每个参数名字的长度
extension
void*
用于扩展?
Message:用于打印错误信息,该指针本身提供长度为MYSQL_ERRMSG_SIZE,来存储信息;
2).name_deinit
原型:
void name_deinit(UDF_INIT*initid)
该函数会进行一些内存释放和清理的工作,在之前我们提到initid->ptr,我们可以在该区域·进行内存的动态分配,这里就可以直接进行内存释放。
3).name()
原型:针对不同的返回值类型,有不同的函数原型:
返回值类型
函数原型
STRING or DECIMAL
char *name(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error)
INTEGER
long long name(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
REAL
double name(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
当返回值为STRING类型时,参数result开辟一个buffer来存储返回值,但不超过766字节,在length参数中存储了字符串的长度。
每个函数原型还包括了is_null和error参数,当*is_null被设置为1时,返回值为NULL,设置*error为1,表明发生了错误。
4).name_add()和name_clear()
原型:
void name_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error)
void name_clear(UDF_INIT *initid, char *is_null, char *error)
对于聚合类型的UDF,name_addd和name_clear会被反复调用。
4. 两个例子
下面将举两个简单的例子,一个单次调用型函数,一个聚集类型函数,来描述写一个UDF的过程。
1)接受一个参数,并返回该参数的值
//初始化
my_booludf_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count != 1){ //检查参数个数
strcpy(message,
"udf_intexample() can onlyaccept one argument");
return 1;
}
if (args->arg_type[0] != INT_RESULT){ //检查参数类型
strcpy(message,
"udf_intexample() argumenthas to be an integer");
return 1;
}
return 0;
}
//清理操作
voidudf_int_deinit(UDF_INIT *initid)
{
}
//主函数
long long udf_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
long long num = (*(long long *)args->args[0]); //获取第一个参数值
return num;
}
2)接受一个浮点数类型的参数,并对每个分组进行求和
//初始化
my_booludf_floatsum_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
double *total = (double *) malloc (sizeof(double));
if (total == NULL){ //内存分配失败
strcpy(message,"udf_floatsum:alloc mem failed!");
return 1;
}
*total = 0;
initid->ptr = (char *)total;
if (args->arg_count != 1){ //检查参数个数
strcpy(message, "too moreargs,only one!");
return 1;
}
if (args->arg_type[0] != REAL_RESULT){ //检查参数类型
strcpy(message, "wrongtype");
return 1;
}
initid->decimals = 3; //设置返回值精度
return 0;
}
//清理、释放在init函数中分配的内存
voidudf_floatsum_deinit(UDF_INIT *initid)
{
free(initid->ptr);
}
//每一行都会调用到该函数
voidudf_floatsum_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
double* float_total;
float_total = (double*)initid->ptr;
if (args->args[0])
*float_total += *(double*)args->args[0];
}
//每个分组完成后,返回结果
doubleudf_floatsum(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
double* float_total;
float_total = (double *)initid->ptr;
return *float_total;
}
//在进行下一个分组前调用,设置initid->ptr指向的值为0,以便下一次分组统计
voidudf_floatsum_clear(UDF_INIT *initid, char *is_null, char *error)
{
double *float_total;
float_total = (double *)initid->ptr;
*float_total = 0;
}
3) Mysql-udf-http是一个开源的UDF,可以利用HTTP协议进行REST操作。什么是REST操作呢?REST是一种web service架构风格,其实现基于HTTP协议的四种方法:POST、GET、PUT以及DELETE操作,在mysql-udf-http里分别对应的函数是http_post、http_get()、http_put()、http_delete()。
源码下载:http://curl.haxx.se/download/curl-7.21.1.tar.gz
./configure–prefix={mysql安装目录} –with-mysql=/usr/local/webserver/mysql/bin/mysql_config
Make&& make install
该UDF的实现原理比较简单,主要使用libcurl库函数来实现http协议通信,总共三百多行代码。这里有使用和介绍http://blog.s135.com/mysql-udf-http/
有些比较有趣的功能:
例如,我们可以通过GET方法获取微博中的个人信息,其中1821798401为用户ID
selecthttp_get('http://api.t.sina.com.cn/statuses/user_timeline/1821798401.json?count=1&source=1561596835')
UDF具有非常高的自由度,你可以编写你任何想要实现的功能函数,甚至可以引用MySQL内核的代码和变量。
当然,UDF也有着局限性,如下:
a) 在mysql库下必须有func表,并且在‑‑skip‑grant‑tables开启的情况下,UDF会被禁止;
b) 当UDF挂掉时,有可能会导致mysqld crash掉;
c) 所有的UDF的函数必须是线程安全的,如果非要用全局变量,需要加互斥,尽量在name_init中分配资源,并在name_deinit中释放
d) 需要有insert权限
作者 zhaiwx1987
bitsCN.com
MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

構建MySQL數據庫的步驟包括:1.創建數據庫和表,2.插入數據,3.進行查詢。首先,使用CREATEDATABASE和CREATETABLE語句創建數據庫和表,然後用INSERTINTO語句插入數據,最後用SELECT語句查詢數據。

MySQL適合初學者,因為它易用且功能強大。 1.MySQL是關係型數據庫,使用SQL進行CRUD操作。 2.安裝簡單,需配置root用戶密碼。 3.使用INSERT、UPDATE、DELETE、SELECT進行數據操作。 4.複雜查詢可使用ORDERBY、WHERE和JOIN。 5.調試需檢查語法,使用EXPLAIN分析查詢。 6.優化建議包括使用索引、選擇合適數據類型和良好編程習慣。

MySQL適合初學者,因為:1)易於安裝和配置,2)有豐富的學習資源,3)SQL語法直觀,4)工具支持強大。儘管如此,初學者需克服數據庫設計、查詢優化、安全管理和數據備份等挑戰。

是的,sqlisaprogramminglanguges pecialized fordatamanage.1)它具有焦點,focusingonwhattoachieveratherthanhow.2)sqlisessential forquerying forquerying,插入,更新,更新,和detletingdatainrelationalDatabases.3)

ACID屬性包括原子性、一致性、隔離性和持久性,是數據庫設計的基石。 1.原子性確保事務要么完全成功,要么完全失敗。 2.一致性保證數據庫在事務前後保持一致狀態。 3.隔離性確保事務之間互不干擾。 4.持久性確保事務提交後數據永久保存。

MySQL既是數據庫管理系統(DBMS),也與編程語言緊密相關。 1)作為DBMS,MySQL用於存儲、組織和檢索數據,優化索引可提高查詢性能。 2)通過SQL與編程語言結合,嵌入在如Python中,使用ORM工具如SQLAlchemy可簡化操作。 3)性能優化包括索引、查詢、緩存、分庫分錶和事務管理。

MySQL使用SQL命令管理數據。 1.基本命令包括SELECT、INSERT、UPDATE和DELETE。 2.高級用法涉及JOIN、子查詢和聚合函數。 3.常見錯誤有語法、邏輯和性能問題。 4.優化技巧包括使用索引、避免SELECT*和使用LIMIT。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

禪工作室 13.0.1
強大的PHP整合開發環境

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Dreamweaver CS6
視覺化網頁開發工具