• MySQL用户自定义函数


      从很早开始,MySQL就支持用户自定义函数(UDF)。存储过程只能使用SQL来编写,而UDF没有这个限制,你可以使用支持C语言调用约定的任何编程语言来实现。

      UDF必须事先编译好并动态链接到服务器上,这种平台相关性使得UDF在很多方面都很强大。UDF速度非常快,而且可以访问大量操作系统的功能,还可以使用大量库函数。使用SQL实现的存储函数在实现一些简单操作上很有优势,诸如计算球体上两点之间的距离,但是如果操作涉及到网络交互,那么只能使用UDF了。同样地,如果需要一个MySQL不支持的统计聚合函数,而且无法使用SQL编写的存储函数来实现的话,通常使用UDF是很容易实现的。

      能力越大,责任越大。所以在UDF中的一个错误很可能会让服务器直接崩溃,甚至扰乱服务器的内存或者数据,另外,所有C语言具有的潜在风险,UDF也都有。

      提示:和使用SQL语言编写存储程序不同,UDF无法读写数据表——至少,无法在调用UDF的线程中使用当前事务处理的上下文来读写数据表。这意味着,它更适合用作计算或者与外面的世界交互。MySQL已经支持越来越多的方式和外面的资源交互了。Brian Aker和Patrick Galbraith创建的与memcached通信的函数就是一个UDF很好的案例。

      如果打算使用UDF,那么在MySQL版本升级的时候需要特别注意做相应的改变,因为很可能需要重新编译这些UDF,或者甚至需要修改UDF来让它能在新的版本中工作。还需要注意的是,你需要确保UDF是线程安全的,因为它们需要在MySQL中执行,而MySQL是一个纯粹的多线程环境。

      现在已经有很多写好的UDF直接提供给MySQL使用,还有很多UDF的示例可供参考, 以便完成自己的UDF。现在UDF最大的仓库是http://www.mysqludf.org。

      下面是一个用户自定义函数NOW_USEC()的代码:

    #include <my_global.h>
    #include <my_sys.h>
    #include <mysql.h>
    #include <stdio.h>
    #include <sys/time.h>
    #include <time.h>
    #include <unistd.h>
    extern "C" {
       my_bool now_usec_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
       char *now_usec(
                      UDF_INIT *initid,
                      UDF_ARGS *args,
                      char *result,
                      unsigned long *length,
                      char *is_null,
                      char *error);
    }
    my_bool now_usec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
       return 0;
    }
    char *now_usec(UDF_INIT *initid, UDF_ARGS *args, char *result,
                   unsigned long *length, char *is_null, char *error) {
      struct timeval tv;
      struct tm* ptm;
      char time_string[20]; /* e.g. "2006-04-27 17:10:52" */
      char *usec_time_string = result;
      time_t t;
      /* Obtain the time of day, and convert it to a tm struct. */
      gettimeofday (&tv, NULL);
      t = (time_t)tv.tv_sec;
      ptm = localtime (&t);
      /* Format the date and time, down to a single second. */
      strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
      /* Print the formatted time, in seconds, followed by a decimal point
       * and the microseconds. */
      sprintf(usec_time_string, "%s.%06ld
    ", time_string, tv.tv_usec);
      *length = 26;
      return(usec_time_string);
    }

      参考前一章中的案例学习,可以看到如何使用用户自定义函数来解决一些棘手的问题。在Percona Toolkit中也使用了UDF来完成一些工作,例如髙效的数据复制校验,或者在Sphinx索引之前使用UDF来预处理一些问题等。UDF是一款非常强大的工具。

     

    作者:小家电维修

    相见有时,后会无期。

  • 相关阅读:
    美多商城项目(一)
    Linux安装Qt
    mysql之初体验
    Linux系统编程目录
    Linux 多线程
    进程间通信
    Linux进程
    Linux文件IO(简易)
    Linux常用基本操作
    重绘
  • 原文地址:https://www.cnblogs.com/lizexiong/p/15549392.html
Copyright © 2020-2023  润新知