约束

对于innodb存储引擎本身而言,提供了以下几种约束:

primary key

unique key

foreign key

default

not null

约束的创建可以采用以下两种方式:

表建立时就进行约束定义;

利用alter table 命令来进行创建约束。

对于主键约束来说,其默认约束名为primary。而对unique key 约束而言,默认约束名和列名一样,也可以自定义约束名。foreign key 约束似乎会有一个比较神秘的默认名称。

例 :

create table test(

id  int ,

id_card varchar(20) ,

name varchar (20) not null ,

country   char(20)  default   'china ',

primary key (id),

unique key(id_card)

)

看见这样的约束,通常都会产生一个疑问,primary key,unique key ,不就是索引嘛,那这和索引有啥区别呢,其实这两个确实创建了索引,也创建了约束。

但是索引和约束在概念上还是有不同的,约束是从逻辑上来说,规范数据,保证数据完整性;索引是数据结构,既有逻辑上的概念,也有数据的物理存储方式。

在从约束上来讲,还有一种数据数据定义上的约束,enum 和set :

sex  enum ('男','女'),  

还有一种约束可以用触发器来实现,触发器的作用是在执行insert 、delete、和update命令之前或之后自动调用sql命令后存储过程。

最多可以为一个表创建6个触发器,即insert、update、delete的before和after。

现金表:

CREATE TABLE `usercash` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
`cash` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

错误表:

CREATE TABLE `user_cash_err_log` (
`usehost` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
`id` int(11) NOT NULL,
`user` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
`old_cash` int(10) unsigned NOT NULL,
`new_cash` int(10) unsigned NOT NULL,
`time` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

创建触发器

 

DELIMITER $$

CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `test`.`trg_usercash_update` BEFORE UPDATE
ON `test`.`usercash`
FOR EACH ROW BEGIN

IF new.cash-old.cash>0 THEN
INSERT INTO user_cash_err_log SELECT USER(),old.id,old.user,old.cash,new.cash,NOW();
SET new.cash=old.cash;
END IF;


END$$

DELIMITER ;

这个示例是在更新usercash表前,调用触发器,判断新的金额是否大于表中的金额,假如大于表中的金额则向错误表中插入错误信息,同时设置新的金额为表中的金额。

这里面还隐藏了一个错误,如果new.cash-old.cash是一个负数,则会报错,因为定义的cash字段是无符号的。

 

 这时需要改写一下触发器 IF CAST(new.cash AS SIGNED)-CAST(old.cash AS SIGNED)>0 THEN  把字段属性转化一下。

 

posted @ 2020-08-23 09:51  wongchaofan  阅读(178)  评论(0编辑  收藏  举报