mysql三个应用场景

时间:2022-09-18 20:34:57

场景一,数据表自动备份(多个数据表字段同步等),使用触发器。如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