場景一,數據表自動備份(多個數據表字段同步等),使用觸發器。如updatelog記錄對資源的所有操作日志,reslastlog記錄資源最后操作的日志信息。同步方式實現如下:
//創建表 DROP TABLE IF EXISTS updatelog; CREATE TABLE `updatelog` ( `id` int(11) NOT NULL AUTO_INCREMENT, `resourceid` int(11) DEFAULT NULL, `log` text, `createtime` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 //必須指定主鍵或unique,不然無法replace DROP TABLE IF EXISTS reslastlog; CREATE TABLE `reslastlog` ( `resourceid` int(11) NOT NULL DEFAULT '0', `log` text, `updatetime` datetime DEFAULT NULL, PRIMARY KEY (`resourceid`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 //創建觸發器 DROP TRIGGER IF EXISTS t_afterinsert_on_updatelog; delimiter // CREATE TRIGGER t_afterinsert_on_updatelog AFTER INSERT ON updatelog FOR EACH ROW BEGIN replace into reslastlog(resourceid,log,updatetime) values(new.resourceid, new.log, new.createtime); END; // delimiter ; DROP TRIGGER IF EXISTS t_afterdelete_on_updatelog; delimiter // CREATE TRIGGER t_afterdelete_on_updatelog AFTER DELETE ON updatelog FOR EACH ROW BEGIN delete from reslastlog where resourceid=old.resourceid; END; // delimiter ; //測試 insert into updatelog(resourceid, log, createtime) values(1, "version 1-0",now()); insert into updatelog(resourceid, log, createtime) values(1, "version 1-1",now()); insert into updatelog(resourceid, log, createtime) values(2, "version 2-2",now()); delete from updatelog where resourceid = 2; //觸發器相關操作 mysql> show triggers; +----------------------------+--------+-----------+--------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+ | Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation | +----------------------------+--------+-----------+--------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+ | t_afterinsert_on_updatelog | INSERT | updatelog | BEGIN replace into reslastlog(resourceid,log,updatetime) values(new.resourceid, new.log, new.createtime); END | AFTER | NULL | | root@localhost | latin1 | latin1_swedish_ci | latin1_swedish_ci | | t_afterdelete_on_updatelog | DELETE | updatelog | BEGIN delete from reslastlog where resouceid=old.resourceid; END | AFTER | NULL | | root@localhost | latin1 | latin1_swedish_ci | latin1_swedish_ci | +----------------------------+--------+-----------+--------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+ 2 rows in set (0.00 sec) drop trigger t_afterinsert_on_updatelog;
場景二,用戶定義函數或者存儲過程實現簡單的后台數據運算。示例如下:
//用戶定義函數 //創建資源基本信息表 CREATE TABLE `baseinfo` ( `id` int(11) DEFAULT NULL, `content` text ) ENGINE=MyISAM DEFAULT CHARSET=latin1; insert into baseinfo values(1,"one"); insert into baseinfo values(2,"two"); insert into baseinfo values(3,"three"); //創建每日資源pv表 CREATE TABLE `dayinfo` ( `id` int(11) DEFAULT NULL, `pv` int(11) DEFAULT NULL, `day` date DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; insert into dayinfo values(1,10,"2014-10-01"); insert into dayinfo values(1,12,"2014-10-02"); insert into dayinfo values(1,16,"2014-10-03"); insert into dayinfo values(2, 30, "2014-10-02"); 查詢資源指定時段降序排列 mysql> select baseinfo.id as id, content, sum(pv) as totalpv from baseinfo,dayinfo where baseinfo.id=dayinfo.id and day>="2014-10-02" and day<="2014-10-03" group by id order by totalpv desc; +------+---------+---------+ | id | content | totalpv | +------+---------+---------+ | 2 | two | 30 | | 1 | one | 28 | +------+---------+---------+ 上面的sql語法非常復雜,如果用UDF會方便簡潔很多。 1,查看用戶定義函數功能是否開啟,ON為開啟 show variables like '%func%'; 2,如果是OFF,則執行下面的操作 set global log_bin_trust_function_creators=1; 3,創建用戶定義函數 delimiter $$ CREATE FUNCTION getTotalPV(targetid int,dayfrom date,dayto date) RETURNS int begin declare totalpv int default 0; set totalpv=(select sum(pv) from dayinfo where id = targetid and day>=dayfrom and day<=dayto); if totalpv is null then set totalpv = 0; end if; return totalpv; end$$ delimiter ; mysql> select id, content, getTotalPV(id, "2014-10-02", "2014-10-03") as totalpv from baseinfo order by totalpv desc; +------+---------+---------+ | id | content | totalpv | +------+---------+---------+ | 2 | two | 30 | | 1 | one | 28 | | 3 | three | 0 | +------+---------+---------+ 4,查看udf定義show create function getTotalPV; //存儲過程 drop procedure if exists getjson; delimiter $$ create procedure getjson ( str1 varchar(1024), str2 varchar(1024), str3 varchar(1024), str4 varchar(1024) ) begin if str1 is NULL then set str1=""; end if; if str2 is NULL then set str2=""; end if; if str3 is NULL then set str3=""; end if; if str4 is NULL then set str4=""; end if; select CONCAT("[",str1,",",str2,",",str3,",",str4,"]") as jsonstr; end;$$ delimiter ; mysql> call getjson("a","b","c","d"); +-----------+ | jsonstr | +-----------+ | [a,b,c,d] | +-----------+ 1 row in set (0.00 sec)
場景三:mysql調用外部應用程序(如表有數據更新后,通過觸發器調用外部應用程序執行任務)
1.lib_mysqludf_sys簡介 mysql中沒有執行外部命令的函數,要調用外部的命令,可以通過開發MySQL UDF來實現,lib_mysqludf_sys 就是一個實現了此功能的UDF庫。 下載地址:https://github.com/mysqludf/lib_mysqludf_sys 2.使用方法 2.1 安裝部署(需要安裝mysql-devel) a) lib_mysqludf_sys.so復制到mysql/lib/plugin目錄下。 b) 在mysql中創建函數(根據需要選取): Drop FUNCTION IF EXISTS lib_mysqludf_sys_info; Drop FUNCTION IF EXISTS sys_get; Drop FUNCTION IF EXISTS sys_set; Drop FUNCTION IF EXISTS sys_exec; Drop FUNCTION IF EXISTS sys_eval; Create FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'lib_mysqludf_sys.so'; Create FUNCTION sys_get RETURNS string SONAME 'lib_mysqludf_sys.so'; Create FUNCTION sys_set RETURNS int SONAME 'lib_mysqludf_sys.so'; Create FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so'; Create FUNCTION sys_eval RETURNS string SONAME 'lib_mysqludf_sys.so'; 2.2 使用此函數 例:在select語句調用mkdir命令 Select sys_exec('mkdir -p /home/user1/aaa') 例:在觸發器中調用外部的腳本(腳本需要可執行權限) Create TRIGGER trig_test AFTER Insert ON <table1> FOR EACH ROW BEGIN DECLARE ret INT; Select sys_exec('/home/user1/test.sh') INTO ret; END