PythonWeb全栈工程师必备技能之<MySQL开发篇>

emmm...接下来还有<MySQL运维篇>...

(1)数据库的CURD:

--基本使用:

1.选择数据库:

use 数据库名称;

mysql> use test;

Database changed


2.创建数据库:

        create database 数据库名称;

mysql> create database test;

Query OK, 1 row affected (0.07 sec)


3.删除数据库:

drop database 数据库名称;

mysql> drop database test;

Query OK, 0 rows affected (0.05 sec)


4.更新数据库:

alter database 数据库名称 character set 字符集 collate 子句;

mysql> alter database test character set 'utf8';

Query OK, 1 row affected, 1 warning (0.10 sec)


5.创建数据表:

create table 数据表名称(...) engine=数据库引擎名称;

mysql> create table t1(

    -> name varchar(255),

    -> age int) engine=InnoDB;

Query OK, 0 rows affected (0.09 sec)


6.创建临时数据表:

服务器创建的临时表,在session终止时会自动消失。

create temporary table 数据表名;

mysql> create temporary table t2( -- 创建临时表

    -> name varchar(255),

    -> age int);

Query OK, 0 rows affected (0.00 sec)

mysql> show tables;  -- 临时表创建后不会显示

+----------------+

| Tables_in_test |

+----------------+

| t1             |

+----------------+

1 row in set (0.00 sec)

mysql> 

mysql> 

mysql> select * from t2;  -- 查看临时表的数据

Empty set (0.00 sec)

mysql> exit;  -- 退出本次会话后临时表会删除

Bye

mysql> select * from t2;  -- 查看临时表的数据会报错

ERROR 1146 (42S02): Table 'test.t2' doesn't exist


在创建数据表使用create table if not exist 数据表名(...);如果数据表存在的时候就不会存在。

7.根据现有表创建表副本(仅表结构):

create table 新表名 like 原表名;

mysql> select * from t1; -- 向表中插入数据

+-------+------+

| name  | age  |

+-------+------+

| admin |   18 |

| admin |   18 |

| admin |   18 |

| admin |   18 |

| admin |   18 |

| admin |   18 |

+-------+------+

6 rows in set (0.00 sec)


mysql> create table t1_clone like t1;  -- 创建表结构副本

Query OK, 0 rows affected (0.06 sec)


mysql> show tables;  -- 查看表

+----------------+

| Tables_in_test |

+----------------+

| t1             |

| t1_clone       |

+----------------+

2 rows in set (0.00 sec)


mysql> select * from t1_clone;

Empty set (0.00 sec)


8.根据现有表创建表副本(表结构+数据):

create table 新表名 like 原表名;

insert into 新表名 select * from 原表名;


mysql> create table t1_data like t1;

Query OK, 0 rows affected (0.07 sec)


mysql> insert into t1_data select * from t1;

Query OK, 6 rows affected (0.04 sec)

Records: 6  Duplicates: 0  Warnings: 0


mysql> select * from t1_data;

+-------+------+

| name  | age  |

+-------+------+

| admin |   18 |

| admin |   18 |

| admin |   18 |

| admin |   18 |

| admin |   18 |

| admin |   18 |

+-------+------+

6 rows in set (0.00 sec)


9.删除数据表:

drop table 数据表名;

drop table 数据表1, 数据表2...;

drop table if exists 数据表名;


mysql> drop table if exists t1_clone, t1_data;

Query OK, 0 rows affected (0.12 sec)


mysql> show tables;

+----------------+

| Tables_in_test |

+----------------+

| t1             |

+----------------+

1 row in set (0.01 sec)


10.索引数据表:

10.1.创建唯一索引:

1)对于单列索引,不允许出现重复值。

alter table 表名 add index 索引名称(索引列);

create index 索引名称 on 表名(索引列);

2)对于组合索引,不允许出现重复组合。

alter table 表名 add unique 索引名称(索引列);

create unique index 索引名称 on 表名(索引列);

10.2.创建常规(非唯一)索引

会出现值重复的情况。

alter table 表名 add primary key(索引列);

不支持使用create index语句创建索引。


10.3.Fulltext全文索引:

用于全文索引,只用于myisam表。

alter table 表名 add fulltext 索引名称(索引列);

create fulltext index 索引名称 on 表名称(索引列);

10.4.spatial索引:

alter table 表名 add spatial 索引名称(索引列);

create spatial index 索引名称 on 表名(索引项);

10.5 Hash索引:

不做介绍


10.6删除表索引:

drop index 索引名称 on 表名;

alter table 表名 drop index 索引名称;

10.7删除主键索引:

drop index `primary` on 表名;

alter index 表名 drop primary key;


10.8索引的分类:

1)数据结构角度:

B+Tree索引

Hash索引:

a) 仅能满足=或IN或<=>查询,不能使用范围查询

b) 检索效率高,索引的检索可以一次定位

c) 只有Memory存储引擎支持Hash索引

Fulltext索引:

MyISAM和InnoDB都支持

R-Tree索引:

用于对GIS数据类型创建spatial索引

2)物理存储角度:

聚焦索引

非聚焦索引

3)逻辑角度:

主键索引

a) 主键索引是一种特殊的唯一索引,不允许有空值

b) 普通索引或单列索引

c) 多列索引(复合索引):是指在多个字段上创建的索引,只有在查询条件中使用了创建索引的第一个字段,索引才会被使用。复合索引使用的时候遵循最左前缀集合。

d) 唯一索引或非唯一索引

f) 空间索引:MySQL的空间数据类型有:geometry、point、linestring、polygon

MySQL使用spatial关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引,必须将其声明为not null,空间索引只能存储在存储引擎为MyISAM的表中。

--更改表结构:

1.更改数据类型:

alter table 表名 modify 列名 数据类型;

alter table 表名 change 列名 列名 数据类型;

更改数据类型同时重命名:

alter table 表名 change 列名 新列名 数据类型;


mysql> desc t1;

+-------+--------------+------+-----+---------+-------+

| Field    | Type             | Null   | Key  | Default  | Extra   |

+-------+--------------+------+-----+---------+-------+

| name  | varchar(255) | YES   |          | NULL     |            |

| age     | int(11)           | YES   |          | NULL     |            |

+-------+--------------+------+-----+---------+-------+

2 rows in set (0.01 sec)


mysql> alter table t1 change name first_name varchar(255);

Query OK, 0 rows affected (0.11 sec)

Records: 0  Duplicates: 0  Warnings: 0


mysql> desc t1;

+------------+--------------+------+-----+---------+-------+

| Field      | Type         | Null | Key | Default | Extra |

+------------+--------------+------+-----+---------+-------+

| first_name | varchar(255) | YES  |     | NULL    |       |

| age        | int(11)      | YES  |     | NULL    |       |

+------------+--------------+------+-----+---------+-------+

2 rows in set (0.01 sec)


2.更改列名:

alter table 表名 change 列名 新列名 当前列的定义;

rename table 表名 to 新表名;

rename table 表名 to 新表名,表名 to 新表名...;

3.更改存储引擎:

alter table 表名 engine=引擎名称;


--元数据:

(1)列出服务器上的数据库:

show databases;

(2)列出数据库中的表:

show tables;

(3)显示数据库的create database语句:

show create database 数据库名;

(4)显示数据库中的create table语句:

show create table 表名;

(5)显示表中的类信息:

show columns from 表名;

(6)显示表中的索引信息:

show index from 表名;

(7)显示默认数据库中的表描述信息:

show table status;

(8)显示指定数据库中的表描述信息:

show table status from 数据库名;

--借助infomation_schema获取元数据:

(1)显示information_schema数据库中的表:

show tables in information_schema;

(2)information_schema库中的各个表:

schema、table、views、routines、triggers、event、parameters、partitions、columns与数据库、表、视图、存储过程、触发器、事件、表分区和列有关。

files与用于存储表空间数据的那些文件有关的信息。

table_constraints、key_column_usage与约束条件的表和列有关的信息。

statistics与表索引特性有关的信息。

referential_constraints与外键有关的信息。

character_sets、collations、collation_character_set_applicability与支持的字符集、每种字符集的排序规则、以及每种排序规则与其字符集之间的映射关系的信息。

engines、plugins与存储引擎和服务器插件有关的信息。

user_privileges、schema_privileges、table_privileges、column_privileges与全局、数据库、表和列的权限分配有关的信息,分别来自于mysql的user、db、tables_priv和column_priv表。

global_variables、session_variables、global_status、global_status全局和会话的系统变量与状态变量值。

processlist与服务器内执行的线程有关。


--多表查询:

(1)使用连接实现多表查询:

mysql> select * from t2;

+------+------------+

| id   | first_name      |

+------+------------+

|    2 | Hello              |

|    2 | World            |

|    3 | Hi                   |

+------+------------+

3 rows in set (0.00 sec)


mysql> select * from t1;

+------+-------+

| id   | name      |

+------+-------+

|    1 | tom        |

|    1 | alice        |

|    1 | amy        |

+------+-------+

3 rows in set (0.00 sec)

(1.1)内连接:

没有指定条件,从t1中的表中的每一行数据都与t2表中的每一行数据匹配,这将会形成卡迪尔积!!!

mysql> select * from t1 inner join t2;

+------+-------+------+------------+

| id   | name  | id   | first_name        |

+------+-------+------+------------+

|    1 | tom   |    2 | Hello                  |

|    1 | alice |    2 | Hello                   |

|    1 | amy   |    2 | Hello                 |

|    1 | tom   |    2 | World                |

|    1 | alice |    2 | World                  |

|    1 | amy   |    2 | World                |

|    1 | tom   |    3 | Hi                       |

|    1 | alice |    3 | Hi                        |

|    1 | amy   |    3 | Hi                       |

+------+-------+------+------------+

9 rows in set (0.00 sec)

加入条件进行过滤:

mysql> select * from t1 inner join t2 where t2.id=t1.id;

Empty set (0.00 sec)

没有匹配的数据,返回空集。

(1.2)左连接、右连接:

内连接只会显示在两个表中都匹配的行,外连接除了显示同样的匹配结果,还可以把其他表在另一个表里没有匹配出来的行也显示出来。左连接和右连接属于外连接。左连接使用left join,右连接使用right join。

左连接的工作方式:

1.先指定用于对两个表里的行进行匹配的列。

2.当左表中的数据与右表中的数据匹配的时候,匹配的数据会连接成为一个新的行。

3.当左表中的数据与右表中的数据没有匹配的时候,将会与右表中的空行作为一个行显示。

4.右连接与左连接相反。

--向左表中插入匹配的数据:

mysql> insert into t1(id, name) values(2, "Toms");

Query OK, 1 row affected (0.08 sec)


mysql> insert into t1(id, name) values(2, "Toms");

Query OK, 1 row affected (0.04 sec)


mysql> insert into t1(id, name) values(3, "Toms");

Query OK, 1 row affected (0.11 sec)

--执行左连接操作:

mysql> select * from t1 left join t2 on t1.id=t2.id;

+------+-------+------+------------+

| id   | name  | id   | first_name |

+------+-------+------+------------+

|    2 | Toms  |    2 | Hello      |

|    2 | Toms  |    2 | Hello      |

|    2 | Toms  |    2 | World      |

|    2 | Toms  |    2 | World      |

|    3 | Toms  |    3 | Hi         |

|    1 | tom   | NULL | NULL       |

|    1 | alice | NULL | NULL       |

|    1 | amy   | NULL | NULL       |

+------+-------+------+------------+

8 rows in set (0.00 sec)

--执行右连接操作:

mysql> select * from t1 right join t2 on t1.id=t2.id;

+------+------+------+------------+

| id   | name | id   | first_name |

+------+------+------+------------+

|    2 | Toms |    2 | Hello      |

|    2 | Toms |    2 | World      |

|    2 | Toms |    2 | Hello      |

|    2 | Toms |    2 | World      |

|    3 | Toms |    3 | Hi         |

+------+------+------+------------+

5 rows in set (0.00 sec)


(2)使用子查询实现多表检索:

(2.1)IN、NOT IN查询:

mysql> select * from t1 where id in (select id from t2);

+------+------+

| id   | name |

+------+------+

|    2 | Toms |

|    2 | Toms |

|    3 | Toms |

+------+------+

3 rows in set (0.00 sec)

(2.2)带关系比较运算符的子查询:

带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户确切知道内层查询返回单个值时,可以用>、<、=、>=、<=、!=或<>等比较运算符。

mysql> select * from t1 where id < (select id from t2 where id=3);

+------+-------+

| id   | name  |

+------+-------+

|    1 | tom   |

|    1 | alice |

|    1 | amy   |

|    2 | Toms  |

|    2 | Toms  |

+------+-------+

5 rows in set (0.00 sec)

(2.3)ALL、ANY、SOME子查询:

a)当比较的值小于等于子查询返回的每个值的时候,<=ALL的结果为真。

b)当比较的值小于等于子查询返回的任意值的时候,<=ANY的结果为真。

c)SOME与ANY同义。

(2.4)exists、not exists子查询:

只会测试某个子查询是否返回了行。

(2.5)相关子查询:

相关子查询引用了外层查询里的值,所以他也会依赖于外层查询。因为有了这种联系,所以相关子查询不能脱离外层查询作为一条独立的查询去执行。

(2.6)FROM子句中的子查询:

在FROM中使用在查询是为了生成某些值。

Tips:有相当一部分子查询命令可以改进为连接。连接的效率有时会比子查询的更好,因此如果使用一条select语句需要花费很长时间才能执行完毕,那么可以尝试把它改写为一个连接。

(3)使用UNION实现多表查询:

mysql> create table t1(

    -> id int,

    -> name varchar(255)

    -> );

Query OK, 0 rows affected (0.05 sec)


mysql> create table t2(

    -> id int,

    -> first_name varchar(255)

    -> );

Query OK, 0 rows affected (0.05 sec)


mysql> create table t3(

    -> id int,

    -> last_name varchar(255)

    -> );

Query OK, 0 rows affected (0.04 sec)


mysql> insert into t1(id, name)values(1, 'xiaowang');

Query OK, 1 row affected (0.07 sec)


mysql> insert into t1(id, name)values(2, 'xiaoli');

Query OK, 1 row affected (0.11 sec)


mysql> insert into t2(id, first_name)values(1, 'xiao');

Query OK, 1 row affected (0.10 sec)


mysql> insert into t2(id, first_name)values(2, 'xiao');

Query OK, 1 row affected (0.00 sec)


mysql> insert into t3(id, last_name)values(1, 'wang');

Query OK, 1 row affected (0.08 sec)


mysql> insert into t3(id, last_name)values(1, 'li');

Query OK, 1 row affected (0.00 sec)


mysql> select t1.id from t1 union select t2.id from t2 union select t3.id from t3;

+------+

| id   |

+------+

|    1 |

|    2 |

+------+

2 rows in set (0.00 sec)


union的特性:

a)列名和数据类型:

union的结果集里的列名来自于第一个select语句里的列名。union中的第二个以及后面的select必须选取相同个数的列,但是各个列不必具备有相同名字和数据类型。

通常情况下,同一条union语句里的各响应的列都具备相同的数据类型。如果他们不一样,那么MySQL会进行必要的数据转换。

列是根据位置,而不是根据名字来匹配的。

b)重复行处理:

默认情况下,union会将重复的行去除。如果想保留重复的行,就需要将所有的union改为union all。

c)排序与限制:

如果想将union结果作为一个整体进行排序,那么需要用括号把每一个select 语句括起来,并在最后那个select语句后面加上order by子句,因为union会使用第一个select语句里的列名,所以order by必须使用引用的那些名字,而不是最后一个select语句中的名字。

如果想要限制返回的行数,可以在句末加入limit语句。


至于多表更新与删除类似于多表查询。

插入语句:

insert into 表名称 values(...);

insert into 表名称(...) values(...);

更新语句:

update 表名称 set 列名称=值 where 条件;

删除语句:

delete from 表名称 where 条件;


(2)事务、视图、存储过程:

(2.1)创建并执行事务:

事务是指一组SQL语句,这是一个执行单位,并且在必要的时候可以取消,因为并不是所有的SQL语句都执行成功。

事务的处理是通过提交和回滚实现的,如果某个是事务中的全部语句执行成功,那么可以把它提交到数据库永久的记录到数据库,如果SQL在执行过程中出现错误,事务在出错之前将会回滚到原来的状态。

事务的另一个用途是确保某个操作所涉及的行不会在你正在使用的数据在被其他客户端使用,虽然MySQL提供了对资源的锁定功能,但是仍然不能保证每一个数据库的操作都能达到预想的结果。

事务将多条SQL语句定义为一个单位,可以防止在多客户端环境中可能会发生并发问题。

事务通常具有ACID四个特性:原子性、一致性、独立性、持久性。

原子性:构成事务的所有的语句会是一个逻辑单元。

一致性:数据库在事务的执行前后都是一致的,不能执行事务的一部分。

独立性:事物之间不应该相互影响。

持久性:当事务执行完成时会被永久的保存在数据库中。

默认情况下,MySQL的运行模式是自动提交的,也就是没条语句所做的更改会立即提交到数据库,实际上这是每条语句被当做事务来执行了。如果想要显式的执行事务,那么就需要禁用自动提交模式,并主动告知MySQL什么时候提交数据。

调用start transaction;begin;语句,挂起自动提交模式,再执行本次事务的SQL语句,最后使用commit;语句来结束事务。如果在事务执行过程中出现错误,使用rollback;语句来回滚事务。

事务执行完成之后会回到开始事务之前的模式,如果自动提交模式本来就是金庸的,那么当结束当前事务的时候会执行下一个事务。

另一个执行事务的方法是set autocommit=0;来关闭事务,使用set autocommit=1;来开启事务。

(2.2)回滚部分事务:

回滚整个事务可以使用rollback;语句实现,当需要回滚部分事务的时候,可以使用设置事务保存点来实现。

mysql> create table t1 (id int) engine=InnoDB;

Query OK, 0 rows affected (0.12 sec)


mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)


mysql> insert into t1 values(1);

Query OK, 1 row affected (0.01 sec)


mysql> insert into t1 values(2);

Query OK, 1 row affected (0.00 sec)


mysql> savepoint my;

Query OK, 0 rows affected (0.00 sec)


mysql> insert into t1 values(3);

Query OK, 1 row affected (0.00 sec)


mysql> rollback to savepoint my;

Query OK, 0 rows affected (0.00 sec)


mysql> commit;

Query OK, 0 rows affected (0.08 sec)


mysql> select * from t1;

+------+

| id   |

+------+

|    1 |

|    2 |

+------+

2 rows in set (0.00 sec)

(2.3)事务隔离:

由于MySQL是一个多用户数据库系统,所以不同客户端可能会在同一时间内修改数据。像MyISAM之类的存储引擎使用了表级的锁机制,以保证不同的客户端不能在同一时间修改同一个表。但是这种做法在大量更新操作时,难以保证很好的并发性能。InnDB存储引擎采用的是另一个方法,它是用了比较底层的输定方式,为客户端提供更加细致的表访问控制机制。InnoDB存储引擎是行级锁定,多个客户端不能同时操作一行数据。InnoDB存储引擎实现的事务隔离级别功能能够让客户端对他们想要看到的数据能通过其他事务进行修改。InnoDB提供多种不同的隔离级别:

问题:

a)脏读:在某个事务没有计较的情况下其他事务就能看到这些修改,因此其他事务认为这是修改过的数据,即使那个对数据进行操作的事务进行回滚,从而导致数据行并没有发生修改,而其他事务以为是修改过的。

b)不可重复读:同一个事务使用同一条select语句在每一次读取时会得到不同的结果。如果同一个事务执行两次select语句,另一个事务在上一个事务执行select语句之间执行了数据修改语句,就会发生不可重复读的情况。

c)幻影行:一个事务突然看到一个以前没有见过的行,加入某个事务在执行select语句之后,另一个事务执行了insert语句,如果第一个事务再执行select语句将会看到新增的行,但是这是不存在的,因为第二个事务没有提交。

4种事务隔离级别:

a)read uncommitted:它允许某个事务看到其他事务尚未提交的修改。

b)read committed:允许某个事务看到其他事务已经提交的行修改。

c)repeatable read:如果某个事务同时执行两条select语句,其结果可能是重复的。

d)serializable:与repeatable read类似,但是对事物的隔离更加彻底,主要表现在:只有等到当前事务执行完成才会执行其他事务。

InnoDB的默认事务隔离级别是:repeatable read。

更改默认的事务隔离级别:

a)在启动服务器程序的时候用使用--transaction-isolation选项

b)服务器运行时使用set transaction语句

set global transaction isoation level 级别;

set session transaction isolation level 级别;

set transaction isolation level 级别;


(3)外键:

父表找那个的键值可以关联两个表,子表里的索引会引用父表里的索引。子表的索引值必须与父表中的索引值想匹配或者被设置为NULL,以表明咋父表里不存在与之对应的行。子表中的索引就是外键,在外键的关系中不会出现不匹配的情况,这就是参照完整性。

constraint 约束名称 foreign key  外键名称(索引列) references 表名(索引列) on delete 动作 on update 动作

constraint子句:如果提供这个子句,那么他会为外键提供一个名字,如果省略它,那么InnoDB存储引擎会创建它。

foreign key 子句:外键名称就是外键ID,即使提供外键ID也会被忽略,只有InnoDB为这个外键自动创建索引时才会起作用。

references子句:会列出父表及其索引的名字,让子表里的外键可以引用他们。

on delete子句:可以用它来指定在父表删除行的时候,子表中的记录进行何种操作:

a)on delete on action /on delete restrict子句:与on delete子句一样,默认行为是拒绝在父表中删除行的时候子表的行仍被引用的那些行。

b)on delete cascade 子句:在父表中删除行的时候子表相关联的行也会被删除。

c)on delete set null 子句:在父表删除行的时候子表相关联的行会被置为NULL。

on update子句:

a)on delete on action /on delete restrict子句:与on delete子句一样,默认行为是拒绝在父表中更新行的时候子表的行仍被引用的那些行。

b)on delete cascade 子句:在父表中更新行的时候子表相关联的行也会被更新。

c)on delete set null 子句:在父表更新行的时候子表相关联的行会被置为NULL。


(4)视图:

视图是一种存储对象,是一种虚拟表。视图提供了一种简单的运行复杂查询的方式。

创建视图:

create view 视图名称 as

SQL语句...;

修改视图:

alter view 视图名称 as 

SQL语句...;

删除视图:

drop view 视图名称;


(5)存储程序:

是一种存储对象,具有多种形式。

mysql> select * from t1;

+------+-------+

| id   | name  |

+------+-------+

|    1 | tom   |

|    2 | amy   |

|    3 | alice |

+------+-------+

3 rows in set (0.00 sec)

(5.1)存储函数:

用在表达式中返回某个计算的结果。

mysql> delimiter $

mysql> create function func(number int)

    -> returns int

    -> reads sql data

    -> begin

    ->      return (select id from t1 where id=number);

    -> end$

Query OK, 0 rows affected (0.12 sec)


mysql> delimiter ;

mysql> select func(2);

+---------+

| func(2) |

+---------+

|       2 |

+---------+

1 row in set (0.00 sec)


(5.2)存储过程:

不会直接返回结果,但是可以用来完成一般的运算。

mysql> create procedure proc(number int)

    -> begin

    ->     select * from t1;

    -> end$

Query OK, 0 rows affected (0.12 sec)


mysql> delimiter ;

mysql> call proc(1);

+------+-------+

| id   | name  |

+------+-------+

|    1 | tom   |

|    2 | amy   |

|    3 | alice |

+------+-------+

3 rows in set (0.00 sec)


Query OK, 0 rows affected (0.00 sec)

存储过程使用的参数类型:

在参数列表里的参数名前面使用IN、OUT、INOUT。如果没有指定参数类型,默认使用IN。

mysql> delimiter $

mysql> create procedure count_id(IN id_number int, OUT count_number int)

    -> begin

    -> set count_number = (select count(id) from t1 where id > id_number);

    -> end$

Query OK, 0 rows affected (0.04 sec)


mysql> delimiter ;

mysql> call count_id(1, @count_number);

Query OK, 0 rows affected (0.01 sec)


mysql> select @count_number;

+---------------+

| @count_number |

+---------------+

|             2 |

+---------------+

1 row in set (0.00 sec)



(5.3)触发器:

与表关联在一起,当表执行insert、delete、update语句进行修改的时候会自动执行。触发器的定义包含有一条会在触发器激活的时候执行的语句。

触发器的几个好处:

a)触发器可以检查或修改将被插入或用来更新那些数据行。这就意味着我们可以利用触发器实现数据完整性约束,触发器也可以用来过滤数据。

b)触发器可以基于某个表达式来为某个列提供默认值。

c)触发器可以在行删除或者是更新之前先检查当前行的内容。


create trigger 触发器名称

{before|after}

{insert|update|delete}

on 表名

for each row 触发器内容;


触发器内容:

begin

SQL语句...;

end


new与old:

在insert触发器中,new用来表示即将(before)或者是已经(after)插入的数据。

在update触发器中,old用来表示即将或者是已经被修改的原数据,new用来表示即将或者修改为的数据。

在delete触发器中,old用来表示即将或者已经被删除的原数据。

使用方法:new.列名,old是只读的,而new是可以在触发器中使用set赋值的,这样不会再次触发触发器造成循环调用。

查看触发器:show trigger;

删除触发器:drop trigger [if exists] 触发器名称;

触发器的执行顺序:

我们建立的数据库一般都是 InnoDB 数据库,其上建立的表是事务性表,也就是事务安全的。这时,若SQL语句或触发器执行失败,MySQL 会回滚事务,有:

a)如果 BEFORE 触发器执行失败,SQL 无法正确执行。

b)SQL 执行失败时,AFTER 型触发器不会触发。

c)AFTER 类型的触发器执行失败,SQL 会回滚。


(5.4)事件:

会根据在预定的时刻自动执行。

MySQL有一个事件调度器,它可以定时激活多个数据库操作,事件就是一个与计划相关联的存储程序。

计划会定义事件执行的时间或次数,并且还可以定义事件何时强行退出。

事件非常适合于执行那些无人值守的系统管理任务。

默认情况下,事件调度器并不会运行,因此必须先启用它才能使用事件。

配置服务器:

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log

pid-file=/var/run/mysqld/mysqld.pid

default_authentication_plugin=mysql_native_password

event_scheduler=ON  # 写入本行配置

查看事件调度器的状态:

mysql> show variables like 'event_scheduler';

+-----------------+-------+

| Variable_name   | Value |

+-----------------+-------+

| event_scheduler | ON    |

+-----------------+-------+

1 row in set (0.04 sec)

如果要在运行时停止或者是启动:

set global event_scheduler = OFF;

set global event_scheduler = ON;

创建事件:

create event 事件名称 on schedule {at 日期时间 | every 正则表达式  区间 [starts 日期时间] [ends 日期时间]} do 事件内容

事件内容可以是一条简单的SQL语句,也可以是有begin和end构成的复合语句。

启用与禁用事件:

alter event 事件名称 disable;

alter event 事件名称 enable;


未完待续...


猜你喜欢

转载自blog.51cto.com/xvjunjie/2119603
今日推荐