MySQL学习日记——《MySQL必知必会》笔记整理(下):游标部分有更正

十、创建和操纵表

1、primary key关键字:指定表的主键。

2、语句格式化:忽略空格,可分行。

3、处理现有的表:一般是先删除该表在创建,否则名称相同则会覆盖原表。

如果只要在这张表不存在的时候创建,则是可以在表名后增加一个 if not exists

4、null值:没有值或缺值。

5、auto_increment:本列每增加一行时自动增量,每执行一个insert操作,自动给该列增量,给下一列赋予一个可用的值。

每个表只允许有一个auto_increment列,而且它必须被索引(如,通过使它成为主键)

last_insert_id()获取最后自动增量的id值。

6、default关键字:指定默认值。

不支持使用函数作为默认值,只支持常量。

7、引擎类型

(1)默认引擎一般是myisam。

(2)建表时指定引擎engine=语句。

(3)几个重要引擎

innodb:一个可靠额事务处理引擎,不支持全文本检索。

memory:在功能上等同于myisam,但由于数据是存储在没存(不是磁盘)中,速度很快,特别适用于临时表。

myisam:一个性能极高的引擎,支持全文本检索,但是不支持职事务处理。

MySQL所支持的引擎完整列表以及之间的差别:https://dev.mysql.com/doc/refman/5.0/en/storage_engines.html

(4)引擎类型可以混用。

(5)外键不能跨引擎。一个引擎的表不能引用使用不同引擎的表的外键。

8、alter table :更改表结构。

增加一个列:alter table A add A.b char(20)

删除一个列:alter table A drop column A.b

9、定义外键

alert table A add constraint a_A_B foreign (b) references B (b)

10、复杂的表结构更改一般需要手动删除过程

(1)用心的列布局创建一个新表

(2)使用insert select 语句把数据从旧表复制到新表,如有必要可以使用转换函数和计算字段。

(3)检验包含所需数据的新表

(4)重命名旧表(如果确定删除旧表)

(5)用旧表原来的名字重命名新表

(6)根据需要,重新创建触发器、存储过程、索引和外键。

11、使用alter 应该谨慎,最好在使用前完整备份,包括模式和数据。

12、删除表:drop table A

13、重命名表:rename A to B


十一、视图

1、视图是虚拟表,只包含使用时的动态检索数据的查询。

2、视图常见应用

(1)重用SQL语句。

(2)简化复杂的SQL操作。

(3)使用表的组成部分而不是整个表。

(4)保护数据。可以给用户授予表的特定部分访问权而不是整张表的访问权。

(5)更改数据格式和表示。

3、视图的规则和限制

(1)唯一命名(2)数目无限制(3)足够访问权限(4)可嵌套(5)可使用order by (6)不能索引,不能有关联的触发器或者默认值(7)可以和表一起使用

4、使用视图

(1)create view :创建视图

(2)show create view viewname:查看创建的视图

(3)drop view viewname:删除视图

(4)更新视图:先drop再create,或者create  or replace view

5、利用视图简化复杂的联结

(1)常见应用是隐藏复杂的SQL:创建可重用的视图。

(2)重新格式化检索出来的数据,经常使用的时候,可以创建一个视图。

(3)用视图过滤不需要的数据。

(4)使用视图简化计算字段。

(5)试图可更新,删除,插入。更新一个视图就是更新基表。

(6)并非所有的视图都可以更新。

如果视图定义有以下操作,则不能进行更新:分组(使用group by 和having)、联结、子查询、并、聚集函数、distinct、导出(计算)列。

(7)视图主要用于数据检索。


十二、存储过程

1、存储过程:为以后的使用而保存的一条或者多条MySQL语句的集合。可将它视为批文件,但不仅仅限于批处理。

2、使用理由

(1)通过把处理封装在容易使用的单元中,简化复杂的操作。

(2)不要求反复建立一系列处理步骤,保证了数据的完整性。防止错误保证数据的一致性。

(3)简化对变动的处理。提高安全性,通过存储过程限制对基础数据的访问减少数据的讹误机会。

(4)提高性能。

(5)存在一些只能在单个请求中的MySQL元素和特性,存储过程可以使它们来编写更强大更灵活的代码。

3、缺点

(1)存储过程的编写比基本SQL语句复杂,编写存储过程需要更高的技能,和更丰富的经验。

(2)可没有没有创建存储过程的访问。一般管理员创建存储过程,允许用户访问,但是不允许用户创建存储过程。

4、执行存储过程:MySQL称存储过程的执行为调用,因此执行存储过程的语句为call。

(1)call接受存储过程的名字,以及传递给它的任何参数。

(2)存储过程可以显示结果也可以不显示结果。

5、创建存储过程(以之前一个项目中的例子为例)

#插入表数据
DELIMITER $$
DROP PROCEDURE IF EXISTS `add_table` ;
CREATE PROCEDURE `add_table`(in TABLENAME varchar(50), ANOTHERNAME varchar(100),TABLEDESC varchar(200), CRUSER varchar(30), CRTIME datetime,OWNERTYPE int(11),OWNERID int(11))
  BEGIN
    SELECT @TABLEINFOID:= (IFNULL(max(TABLEINFOID+1),1)) from TABLEINFO ;
    INSERT INTO `TABLEINFO` (`TABLEINFOID`, `TABLENAME`, `ANOTHERNAME`, `TABLEDESC`, `CRUSER`, `CRTIME`, `OWNERTYPE`, `OWNERID`) VALUES ( @TABLEINFOID, TABLENAME, ANOTHERNAME ,TABLEDESC , CRUSER , CRTIME,OWNERTYPE ,OWNERID );

  END $$
DELIMITER ;

这是初始化SQL里面的一个在表‘TABLEINFO’里面插入一条数据。

(1)DELIMITER $$ :定义结束符号为$$。

MySQL中默认以;为结束符,但是存储过程要执行完整的语句,其中包含分号,因此需要重新定义一个结束符。在存储过程结束后在重新把结束符还原回来。

详细解释可参考博客:MySql中 delimiter 详解

(2)DROP PROCEDURE IF EXISTS `add_table` ;这一行语句是保证存储过程的唯一性,如果已经存在就删除该存储过程。

(3)add_table 为存储过程名称。

(4)用create procedure '存储过程名称'()语句来创建存储过程。

(5)如果存在参数,在()中列举出来,格式为(参数类型  参数  参数的数据类型)。无参数则为空。

参数类型:in 输入参数;out 输出参数;inout  输入输出参数。

详细内容可以参考博客:mysql中的存储过程之无参数,in、out、inout参数的讲解

(6)begin和end语句用来限制存储过程体。

(7)@TABLEINFOID:= (IFNULL(max(TABLEINFOID+1),1))表示定义变量;语句的意思是获取当前表最大的id,自增加一,赋予给变量TABLEINFOID,如果当前表没有数据,就把1赋予给变量。

(8)MySQL的变量都必须以@开头。

6、调用存储过程

call add_table ( 'Assessment', '评测系统', '系统', 'admin', '2017-7-31 00:00:00', 1, 1);

7、存储过程实际上是一种函数,因此需要()。

8、删除存储过程:DROP PROCEDURE IF EXISTS `add_table`。

9、参数

(1)变量:内存中一个特定的位置,用来存储临时数据。

(2)select @TABLEINFOID,可以获得当前变量的值。

10、智能建立建立存储过程

(1)comment关键字:不必须,如果给出,将在 show procedure status 的结果中展示。

(2)增加注释:在前面增加‘--’,当存储过程比较复杂的时候,注释十分必要。

(3)参数可以是布尔值,在存储过程中可以使用if语句来进行条件判断。

(4)declare:定义局部变量,指定变量名和数据类型。

(5)select a  into b:把变量a的值保存到变量b中。

(6)if语句还支持elseif和else子句(牵着使用then子句,后者不使用),属于流控制语句。

(7)show procedure status:获得包括由谁创建、何时创建等详细信息的存储过程列表。

(8)限制过程状态结果:为限制其输出,可以使用like指定一个过滤模式。

example:show procedure status like‘order’;


十三、游标

1、游标:是一个存存储在MySQL服务器上的数据库查询,它不是一条select语句,而是被该语句检索出来的结果集。存储了游标之后,应用程序可以根据需要滚动或者浏览其中的数据。

2、游标主要应用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或者进行更改。

3、MySQL游标只能用于存储过程(和函数)。

4、使用游标的步骤

(1)使用前,必须声明(定义)它。定义要使用的select语句。

(2)一旦声明后,必须打开游标以供使用。用前面的select语句把数据实际检索出来。

(3)对于填有数据的游标,根据需要取出检索各行。

(4)在结束游标使用时,必须关闭游标。

5、创建游标

(1)使用declare语句创建。declare命名游标,并定义相应的select语句,根据需要带where和其他子句。

example:

#案例
CREATE PROCEDURE orders()
BEGIN
  DECLARE youbiaotest CURSOR
  FOR
  SELECT ordername FROM workorder;
END 

存储过程完成后,游标就消失了,因为游标局限于存储过程。

(2)打开和关闭游标

打开:open orders;存储检索出的数据以供浏览和滚动。

关闭:close orders;释放游标所使用的所有内部内存和资源。

(3)隐含关闭:如果没有明确关闭游标,MySQL将会在自动到达end语句时自动关闭它。

6、使用游标数据(重难点)

(1)在一个游标被打开后,fetch语句用来分别访问检索出来数据的每一行。

fetch指定检索什么数据(所需的列),检索出来的数据存储在什么地方。

它还向前移动游标中的内部行指针,使下一行fetch语句检索下一行(不重复读取同一行数据)。

(2)循环检索数据,从第一行到最后一行。

#案例二
DROP PROCEDURE IF EXISTS proorders;
DROP TABLE IF EXISTS ordertotals;

DELIMITER $$
CREATE PROCEDURE proorders ()
BEGIN
 -- declare local variables(声明局部变量)
  DECLARE done boolean DEFAULT 0 ; 
  DECLARE o INT ; 
  DECLARE t VARCHAR(100) ; 

  -- declare the cursor
 DECLARE ordernums CURSOR 
  FOR
  SELECT WORKORDERID,DEPARTMENT FROM wcmworkorder; 

  -- declare continue handler
 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1 ; 

  -- CREATE a table to store thr results
 CREATE TABLE IF NOT EXISTS ordertotals (
       order_num INT,
              total VARCHAR(100)
      );

  -- open the sursor
 OPEN ordernums ; 

  -- loop through all rows
 REPEAT
   -- get order number and dept
  FETCH ordernums INTO o,t ; 
   
    -- insert order and total into ordertotals
    INSERT INTO ordertotals(order_num, total)
           VALUES(o, t);

SELECT t;
  -- end of loop
 UNTIL done END REPEAT; 

  -- close the cursor
 CLOSE ordernums ;
END ;$$

DELIMITER ; 

CALL proorders ();

①MySQL里声明字符变量要带上允许的长度,否则会报错1064。声明的变量要和游标选出来的数据类型相匹配。

②DECLARE ordernums CURSOR  FOR SELECT WORKORDERID,DEPARTMENT FROM wcmworkorder; 定义游标

③DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1 ; 

这行代码的意思是没有数据返回时,程序继续,同时设置done的值为1。‘02000’也可以用not found 代替。

关于handler异常处理可以参考:Mysql 异常处理--condition和handler

handler命令和实现方法:http://www.jb51.net/article/88732.htm

比较通俗易懂的使用案例:mysql游标的使用

MySQL常用的循环案例:MySQL中的while、repeat、loop循环

MySql中游标的定义与三种使用方式(2)

④fetch用来检索当前行的WORKORDERID,DEPARTMENT到变量o和t中,不对数据做任何处理。

⑤UNTIL done END REPEAT; done为1时结束循环。

⑥OPEN/CLOSE ordernums ;打开或者关闭游标。

⑦CALL proorders ();调用进程。

7、MySQL的错误代码(英文):https://dev.mysql.com/doc/refman/8.0/en/error-handling.html


十四、触发器

1、触发器是MySQL在相应一下任何语句而自动执行的一跳MySQL语句(或位于begin和end之间的一组语句):delete、insert、update。其他MySQL语句不支持触发器。

2、创建触发器,必给的4条信息

(1)唯一的触发器名;

(2)关联的触发器表;

(3)触发器应该相应的活动(delete、insert或者update);

(4)触发器何时执行(处理之前或之后)。

3、保持每个数据库的触发器名唯一:在MySQL5中,触发器名必须在每个表中唯一,但不是在每个数据库中唯一。其他每个数据库的触发器名必须唯一。因此,最好实在数据库中保持触发器的唯一性。

4、创建语句

CREATE TRIGGER ordertatals AFTER INSERT ON products FOR EACH ROW SELECT 'order added' INTO @args;

(书中原本的语句没有带 into @args,会导致触发器创建不成功,报错1064)

(1)用create trigger 语句来创建名称为newproduct的触发器。

(2)触发器可以在操作之前或者操作之后执行,这里是after insert,在插入语句执行之后执行。

(3)FOR EACH ROW表示对每个插入行执行。

(4)表示触发器要执行的内容,把‘order added’赋予到变量args里面。

INSERT INTO ordertotals (order_num,total) VALUES (79,'测试');

SELECT @args;

(5)执行语句insert语句之后输出触发器的内容需要select 变量。

(6)FOR EACH ROW 之后可以是一条SQL语句,也可以是begin和end包含的多条SQL语句。

具体详细解释可以参考博客:MySQL触发器使用详解  以及  我的MYSQL学习心得(十二) 触发器

(学习到这里,让我对MySQL必知必会这本书产生了怀疑…… ̄へ ̄……之后会参照其他书本和网上的内容进行综合比对记录)

再次推博,这个条例比较清晰,而且有总结:mysql触发器trigger 实例详解

(7)仅支持表。每个表每个事件只允许一次触发器。因此每张表只允许有6个触发器(insert、delete、update之前之后。)

(8)如果before触发器失败,MySQL将不执行操作请求,如果有after操作,也不执行。

5、删除触发器:drop trigger。

触发器不能更新或者覆盖,只能先删除,然后在重新创建。

6、使用触发器

(1)insert触发器

drop trigger neworder;

create TRIGGER neworder after insert on ordertotals for each row select NEW.order_num  INTO @args;

INSERT INTO ordertotals (order_num,total) VALUES (79,'测试');
SELECT @args;

①在insert触发器的代码内,可以引用一个名为new的虚拟表,用来访问被插入的行。

②在before insert触发器中,new中的值可以被更新(允许更新被插入的值)。

③对于auto_increment 列,new在insert执行之前包含0,在insert执行之后包含新的自动生成值。

备注:before通常用于数据验证和净化(目的是保证插入表中的数据是被需要的数据)。

(2)delete触发器

①在delete触发器代码中,你可以引用一个名为old的虚拟表,访问被删除的行。

②old中的值全部是只读,不能更新。

(3)update触发器

①在update触发器中可以引用一个old的虚拟表访问以前的值,可以引用一个名为new的虚拟表访问更新后的值。

②在before update触发器中,new中的值可能也被更新(允许更改将要用于update更新的值)。

每更新一行是,new中的值(将要用来更新表中的值),都用upper替换。

7、触发器的进一步介绍

(1)创建触发器可能需要特殊的访问权限。

(2)应该用触发器来保证数据的一致性

(3)创建审计跟踪。(把更改记录到另一张表)

(4)触发器不支持call语句,也就是不能从触发器的内部调用存储过程。

十五、管理事务处理

1、事务处理:并非所有的引擎都支持事务处理,myisam不支持明确的事务处理管理,而innodb支持。

2、数据库处理可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行。

3、(1)事务(transaction):指一组SQL语句。

(2)回退(rollback):指撤销指定SQL语句的过程。

(3)提交(commit):指将未存储的SQL语句结果写入数据库表。

(4)保留点(savepoint):指事务处理中设置的临时占位符(place-holder),你可以对它发布回退(与回退整个事务处理不同)。

4、控制事务处理

(1)标识事务的开始:start transaction

(2)rollback只能在一个事务处理内使用。

(3)MySQL语句都是直接针对数据库表执行和编写的。这就是隐含提交,即提交(写或保存)操作是自动进行的。在事务处理模块中,提交不会隐含进行。

(4)隐含事务关闭:当commit或者rollback语句执行后,事务会自动关闭。

5、使用保留点:复杂的事务有时候需要部分撤回或者部分执行。

为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符,这些占位符成为保留点。

example:savepoint delete1;

回退到保留点时:rollback delete1;

6、保留点越多越好,可以更灵活的处理事务。

7、释放保留点:保留点在事务处理完成后自动释放。也可以明确释放→release savepoint。

8、更改默认的提交行为:默认的MySQL行为是自动提交所有的更改。

为指示MySQL不自动提交行为,需要以下语句:set autocommit=0;

9、标志位连接专用:autocommit标志是针对每个连接而不是服务器。


十六、全球化和本地化:介绍MySQL不同的字符集和语言的基础知识。

1、数据库表被用来存储和检索数据。不同的语言和字符集需要以不同的方式存储和检索。

2、MySQL需要适应不同的字符集和检索方式

(1)字符集:字符和符号的集合。

(2)编码:某个字符集内部成员的表示。

(3)校对:规定字符集如何比较的指令。

3、使用字符集和校对顺序

show character :显示所有可用字符集和以及每个字符集的描述和默认校对。

show collation:查看所支持校对的完整列表。

4、确定数据库使用的字符集和校对

show variables like ‘character%’;

show variables like ‘collation%’;

5、字符集很少是服务器范围的设置。允许对表和列设置。

6、校对对用order by 子句检索出来的数据排序起着重要的作用。

7、select的其他collate子句:除了在order by中使用,还可以在group by、having、聚集函数、别名等中使用。


十七、安全控制

1、MySQL服务器的安全基础:用户对他们访问的数据有适当的访问权,既不能多也不能少。

2、防止无意识错误;给不同的角色创建对应权限的账号,尽可能不使用root。

3、获取所有账号列表:

use MySQL;

select user from user;

4、一般可以借助图形用户界面使用数据库,也可以使用SQL语句创建。

create user ben identified by ‘XXX’;

5、指定散列口令:identified by 指定的口令为纯文本,MySQL将在保存到user表之前对其进行加密。为了作为散列指定口令,使用identified by password。

6、使用grant和insert语句也可以创建账号。

7、rename user:重命名用户账号。

8、删除用户账号(及相关权限):drop user yonghu。

9、设置访问权限:show grants for yonghu;

10、grant的用法:

grant select on shujuku.* to yonghu;

这个grant 是允许用户在数据库shujuku所有的表都可以使用select语句。

11、grant的反操作是revoke,用来撤销指定的权限。

example:revoke select on shujuku.* to yonghu;

12、grant和revoke可控制访问权限的层次:

(1)整个服务器,使用grant all 和revoke all;

(2)整个数据库,on database.*;

(3)特定的表,on database.table;

(4)特定的列;

(5)特定的存储过程;

13、未来授权:使用grant和revoke的时候,用户账号必须存在,但是涉及的对象却不一定。因此可能存在数据库或者表还没有创建,但是权限已经有了。

14、简化多次授权:可通过列出各个权限,并用逗号隔开,将多条grant语句串在一起:

grant  select ,insert on database.* to  yonghu;

15、更改口令:使用set password 语句。


十八、数据库维护

1、备份数据:MySQL数据库是基于磁盘的文件,普通备份系统和例程就能备份MySQL数据库。但是文件总是处于打开和使用的状态,普通文件副本不一定总是有效。

解决方案:

(1)使用命令MySQLdump转存所有数据库内容到某个外部文件。

(2)可用命令实行程序MySQLhotcopy从一个数据库复制所有数据。

(3)可以使用MySQL的backup table 或者select into outfile转存所有数据到某个文件。

2、首先刷新未写数据:为了保证所有数据被写到磁盘,可能需要在备份数据前使用flush tables语句。

3、进行数据库维护

(1)analyze table:用来检查表键是否正确。

(2)check table:用来针对许多问题对表进行检查。

(3)changed:检查自最后一次检查以来改动过的表。

(4)extended:执行最彻底的检查。

(5)fast:只检查未正常关闭的表。

(6)medium:检查所有被删除的链接并进行键检查。

(7)quick:只进行快速扫描。

(8)repair table:修复相应的表。

(9)optimize table:删除大量表后,收回所用空间,优化表的性能。

4、诊断启动问题

几个重要的mysqld重要选项

(1)--help显示帮助——一个选项列表。

(2)--safe-mode装载减去某些最佳配置的服务器。

(3)--verbose显示全文本消息,与help联合使用。

(4)--version显示版本信息然后退出。

5、日志文件:错误日志、查询日志、二进制日志、缓冲查询日志。


十九、改善性能

1、硬件建议。

2、专属服务器。

3、调整分配。

4、MySQL是多用户多线程的DBMS,可以用show processlist 显示所有进程,kill命令终结某个特定的进程。

5、测试选择最优化语句。

6、explain语句让MySQL解释它将如何执行一跳select语句。

7、检索正确的数据类型。

8、检索合适的数据和数据量。

9、有的操作支持delayed关键字,使用它,将会把控制立刻调回使用程序,一旦有可能就实际执行该操作。

10、导入数据时,应关闭自动提交。

11、必须索引数据库表以改善数据库检索性能。

12、有复杂的or语句时,可以使用union联结。

13、索引根据需要添加。

14、like很慢,最好使用fulltext。

15、数据库是不断变化的实体。

16、最重要的规则,每条规则在特定的条件下会被打破。



猜你喜欢

转载自blog.csdn.net/ai_girls/article/details/80453650