文章目录
数据库同步到缓存三大方案:
①触发器+UDF
②canal
③go-with-transfer
1.触发器
1.0 触发器同步到缓存缺点:
效率比较低
1.1 触发器定义
触发器(trigger)是MySQL提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行DML操作( insert , delete , update )时就会激活它执行。
1.2 触发器四要素
监视对象: table(监测一张表)
监视事件: insert 、 update 、 delete(这三个是触发器做的事:插入、更更新还是删除)
触发时间: before(插入之后) , after(插入之后)
触发事件: insert (插入数据)、 update(更新数据) 、 delete(删除数据)
1.3 触发器语法解释
CREATE TRIGGER trigger_name --trigger_name是触发器的名字
trigger_time trigger_event --trigger_time触发器的时间
ON tbl_name FOR EACH ROW --trigger_event触发器的时间
--tbl_name 要操作的表
--FOR EACH ROW 针对每一行
[trigger_order]
trigger_body -- 此处写执行语句
-- trigger_body: 可以一个语句,也可以是多个语句;多个语句写在 BEGIN ... END 间
--trigger_body中可以有两个全局对象,分别是NEW和OLD
--具体解释
-- trigger_time: { BEFORE | AFTER }
-- trigger_event: { INSERT | UPDATE | DELETE }
-- trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
1.4 触发器准备(创建两个表+设定触发器:work表、time表、触发器trig_test1)
CREATE TABLE `work` (
`id` INT PRIMARY KEY auto_increment,
`address` VARCHAR (32)
) DEFAULT charset = utf8 ENGINE = INNODB;
CREATE TABLE `time` (
`id` INT PRIMARY KEY auto_increment,
`time` DATETIME
) DEFAULT charset = utf8 ENGINE = INNODB;
CREATE TRIGGER trig_test1 AFTER INSERT
ON `work` FOR EACH ROW
INSERT INTO `time` VALUES(NULL,NOW());
1.5 触发器NEW和OLD解释
- 在 INSERT 型触发器中, NEW 用来表示将要( BEFORE )或已经( AFTER )插入的新数据;
- 在 DELETE 型触发器中, OLD 用来表示将要或已经被删除的原数据;
- 在 UPDATE 型触发器中, OLD 用来表示将要或已经被修改的原数据, NEW 用来表示将要或已经修改为的新数据;
NEW.columnName (columnName为相应数据表某一列名)
OLD.columnName (columnName为相应数据表某一列名)
更加人话的解释:
1)OLD:数据操作之前是OLD
2)NEW:数据操作之后是NEW
3)总结:OLD和NEW都是行数据,可以用例如OLD.X(X是行里面的列)或NEW.X(X是列数)就可以拿到列里面的值
1.6 触发器案例
在下订单的时候,对应的商品的库存量要相应的减少,即买几个商品就减少多少个库存量。
1.6.1 触发器准备(创建订单表order和创建库存表goods,根据下单的数量更新库存表)
CREATE TABLE `goods` (
`id` INT PRIMARY KEY auto_increment,
`name` VARCHAR (32),
`num` SMALLINT DEFAULT 0
);
CREATE TABLE `order` (
`id` INT PRIMARY KEY auto_increment,
`goods_id` INT,
`quantity` SMALLINT COMMENT '下单数量'
);
--定义初始库存表
INSERT INTO goods VALUES (NULL, 'C++', 40);
INSERT INTO goods VALUES (NULL, 'C', 63);
INSERT INTO goodS VALUES (NULL, 'mysql', 87);
INSERT INTO `order` VALUES (NULL, 1, 3);
INSERT INTO `order` VALUES (NULL, 2, 4);
1.6.2 触发器需求1
客户修改订单购买的数量,在原来购买数量的基础上减少2个;
-- delimiter
-- delimiter是mysql分隔符,在mysql客户端中分隔符默认是分号 ;。如果一次输入的语句较多,并且语句中间有分号,这时需要重新指定一个特殊的分隔符。通常指定 $$ 或 ||
delimiter //
CREATE TRIGGER trig_order_1 AFTER INSERT
ON `order` FOR EACH ROW
BEGIN
UPDATE goods SET num = num - 2 WHERE id = 1;
END//
delimiter ;
INSERT
1.6.2 触发器需求2
客户修改订单购买的数量,商品表的库存数量自动改变;
delimiter //方忘记了//也是注释的
CREATE TRIGGER trig_order_2 BEFORE UPDATE
ON `order` FOR EACH ROW --ON 表示针对哪一张表
BEGIN //具体操作:根据老数据更新库存表
UPDATE goods SET num=num+old.quantity-new.quantity WHERE id =
new.goods_id;
END
//
delimiter ;
-- 测试
UPDATE `order` SET quantity = quantity+2 WHERE id = 1;
2.canal
简单描述
定义:canal是阿里巴巴旗下的一款开源项目,java开发。
原理:基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB)
背景:(mysql主从同步原理简介)
canal实现原理:
补充案例(Canal将从mysql更新的数据放到消息队列里面,再开订阅模式给MongoDB或ES):