cari
Rumahpangkalan datatutorial mysqlMySQL:如何编写UDF_MySQL

MySQL:如何编写UDF_MySQL

Jun 01, 2016 pm 01:44 PM
bagaimanapenyimpananpengguna

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
Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Bilakah anda harus menggunakan indeks komposit berbanding indeks lajur tunggal?Bilakah anda harus menggunakan indeks komposit berbanding indeks lajur tunggal?Apr 11, 2025 am 12:06 AM

Dalam pengoptimuman pangkalan data, strategi pengindeksan hendaklah dipilih mengikut keperluan pertanyaan: 1. Apabila pertanyaan melibatkan pelbagai lajur dan urutan syarat ditetapkan, gunakan indeks komposit; 2. Apabila pertanyaan melibatkan pelbagai lajur tetapi urutan syarat tidak ditetapkan, gunakan pelbagai indeks lajur tunggal. Indeks komposit sesuai untuk mengoptimumkan pertanyaan berbilang lajur, manakala indeks lajur tunggal sesuai untuk pertanyaan tunggal lajur.

Bagaimana untuk mengenal pasti dan mengoptimumkan pertanyaan perlahan di MySQL? (Log pertanyaan perlahan, prestasi_schema)Bagaimana untuk mengenal pasti dan mengoptimumkan pertanyaan perlahan di MySQL? (Log pertanyaan perlahan, prestasi_schema)Apr 10, 2025 am 09:36 AM

Untuk mengoptimumkan pertanyaan perlahan MySQL, SlowQuerylog dan Performance_Schema perlu digunakan: 1. Dayakan SlowQueryLog dan tetapkan ambang untuk merakam pertanyaan perlahan; 2. Gunakan Performance_Schema untuk menganalisis butiran pelaksanaan pertanyaan, cari kesesakan prestasi dan mengoptimumkan.

MySQL dan SQL: Kemahiran Penting untuk PemajuMySQL dan SQL: Kemahiran Penting untuk PemajuApr 10, 2025 am 09:30 AM

MySQL dan SQL adalah kemahiran penting untuk pemaju. 1.MYSQL adalah sistem pengurusan pangkalan data sumber terbuka, dan SQL adalah bahasa standard yang digunakan untuk mengurus dan mengendalikan pangkalan data. 2.MYSQL menyokong pelbagai enjin penyimpanan melalui penyimpanan data yang cekap dan fungsi pengambilan semula, dan SQL melengkapkan operasi data yang kompleks melalui pernyataan mudah. 3. Contoh penggunaan termasuk pertanyaan asas dan pertanyaan lanjutan, seperti penapisan dan penyortiran mengikut keadaan. 4. Kesilapan umum termasuk kesilapan sintaks dan isu -isu prestasi, yang boleh dioptimumkan dengan memeriksa penyataan SQL dan menggunakan perintah menjelaskan. 5. Teknik pengoptimuman prestasi termasuk menggunakan indeks, mengelakkan pengimbasan jadual penuh, mengoptimumkan operasi menyertai dan meningkatkan kebolehbacaan kod.

Huraikan proses replikasi master-hamba MySQL.Huraikan proses replikasi master-hamba MySQL.Apr 10, 2025 am 09:30 AM

MySQL Asynchronous Master-Slave Replikasi membolehkan penyegerakan data melalui binlog, meningkatkan prestasi baca dan ketersediaan yang tinggi. 1) Rekod pelayan induk berubah kepada binlog; 2) Pelayan hamba membaca binlog melalui benang I/O; 3) Server SQL Thread menggunakan binlog untuk menyegerakkan data.

Mysql: Konsep mudah untuk pembelajaran mudahMysql: Konsep mudah untuk pembelajaran mudahApr 10, 2025 am 09:29 AM

MySQL adalah sistem pengurusan pangkalan data sumber terbuka. 1) Buat Pangkalan Data dan Jadual: Gunakan perintah Createdatabase dan Createtable. 2) Operasi Asas: Masukkan, Kemas kini, Padam dan Pilih. 3) Operasi lanjutan: Sertai, subquery dan pemprosesan transaksi. 4) Kemahiran Debugging: Semak sintaks, jenis data dan keizinan. 5) Cadangan Pengoptimuman: Gunakan indeks, elakkan pilih* dan gunakan transaksi.

MySQL: Pengenalan mesra pengguna ke pangkalan dataMySQL: Pengenalan mesra pengguna ke pangkalan dataApr 10, 2025 am 09:27 AM

Pemasangan dan operasi asas MySQL termasuk: 1. Muat turun dan pasang MySQL, tetapkan kata laluan pengguna root; 2. Gunakan arahan SQL untuk membuat pangkalan data dan jadual, seperti CreateTatabase dan Createtable; 3. Melaksanakan operasi CRUD, gunakan memasukkan, pilih, kemas kini, padamkan arahan; 4. Buat indeks dan prosedur tersimpan untuk mengoptimumkan prestasi dan melaksanakan logik kompleks. Dengan langkah -langkah ini, anda boleh membina dan mengurus pangkalan data MySQL dari awal.

Bagaimanakah kolam penampan InnoDB berfungsi dan mengapa penting untuk prestasi?Bagaimanakah kolam penampan InnoDB berfungsi dan mengapa penting untuk prestasi?Apr 09, 2025 am 12:12 AM

Innodbbufferpool meningkatkan prestasi pangkalan data MySQL dengan memuatkan data dan halaman indeks ke dalam ingatan. 1) Halaman data dimuatkan ke dalam bufferpool untuk mengurangkan cakera I/O. 2) Halaman kotor ditandakan dan disegarkan ke cakera secara teratur. 3) Pengurusan Data Pengurusan Algoritma LRU Penghapusan. 4) Mekanisme pembacaan memuatkan halaman data yang mungkin terlebih dahulu.

MySQL: Kemudahan Pengurusan Data untuk PemulaMySQL: Kemudahan Pengurusan Data untuk PemulaApr 09, 2025 am 12:07 AM

MySQL sesuai untuk pemula kerana mudah dipasang, kuat dan mudah untuk menguruskan data. 1. Pemasangan dan konfigurasi mudah, sesuai untuk pelbagai sistem operasi. 2. Menyokong operasi asas seperti membuat pangkalan data dan jadual, memasukkan, menanyakan, mengemas kini dan memadam data. 3. Menyediakan fungsi lanjutan seperti menyertai operasi dan subqueries. 4. Prestasi boleh ditingkatkan melalui pengindeksan, pengoptimuman pertanyaan dan pembahagian jadual. 5. Sokongan sokongan, pemulihan dan langkah keselamatan untuk memastikan keselamatan data dan konsistensi.

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual

MinGW - GNU Minimalis untuk Windows

MinGW - GNU Minimalis untuk Windows

Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.

VSCode Windows 64-bit Muat Turun

VSCode Windows 64-bit Muat Turun

Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

EditPlus versi Cina retak

EditPlus versi Cina retak

Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod