数据库备份,视图

1   数据库编程(了解)

数据库中可以编写并保存一段程序,做数据运算

 

 视图View

 

  存储过程Procudure

 

  函数Function

 

  触发器Trigger

 

扫描二维码关注公众号,回复: 2662594 查看本文章

mysql数据库编程能力较弱,很多功能无法实现

2   变量

2.1    用户会话变量

一个客户端与服务器连接期间的变量

 

set @v1= 123;

select @v1;

 

2.2    局部变量

begin... end; 是一对大括号,局部变量只能在 begin  end之间使用,end结束后,变量消失

使用 declare 关键字来定义局部变量

 

delimiter;    结束符改成 ;

 

delimiter//      结束符改成//

 

创建复杂的存储过程中间会用到;结束符,如果几个;放在一起,MySQL只会识别第一个,以后的不会识别,这样会及

 

其不完整

 

begin

 

   declarev2 int default 123;

   selectv2;

   select@v1;

end//

 (上面无法执行,只是参考)

3  视图

3.1    简单视图

视图本质就是一个查询语句

SELECT* FROM t_goods

WHEREcategory_id=238

CREATEVIEW v_goods AS

SELECT* FROM t_goods

WHEREcategory_id=238

SELECT* FROM v_goods

DELIMITER$$ 设定一个标识符,标识结束$$

USE`tedu_store`$$ 打开指定数据库tedu_store

DROPVIEW IF EXISTS `v_goods238`$$ 如果此视图已经存在,就删除

CREATEALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINERVIEW `v_goods238` AS

SELECT

`t_goods`.`id` AS `id`,

`t_goods`.`category_id` AS `category_id`,

`t_goods`.`item_type` AS `item_type`,

`t_goods`.`title` AS `title`,

`t_goods`.`sell_point` AS `sell_point`,

`t_goods`.`price` AS `price`,

`t_goods`.`num` AS `num`,

`t_goods`.`barcode` AS `barcode`,

`t_goods`.`image` AS `image`,

`t_goods`.`status` AS `status`,

`t_goods`.`priority` AS `priority`,

`t_goods`.`created_time` AS `created_time`,

`t_goods`.`modified_time`AS `modified_time`,

`t_goods`.`created_user` AS `created_user`,

`t_goods`.`modified_user`AS `modified_user`

FROM`t_goods`

WHERE(`t_goods`.`category_id` = 238)$$

DELIMITER;

3.1    多级关联视图

CREATEVIEW v_cat_goods AS

SELECTc.name,g.item_type,g.title FROM t_goods g

LEFTJOIN t_goods_category c

ONg.category_id=c.id

SELECT* FROM v_cat_goods

视图在大型项目中被废除!!!!

视图过程是把查询所有的记录都查询回来,然后再过滤数据,过滤掉非238.

如果这张表中有一千万数据。数据量大时无法优化。

Java程序可以吗?mybatis它直接处理,返回结果数据。结果就比视图快。

4   存储过程

存储过程是存储在数据库服务器中的一段过程代码

优点:

Jsp-java-database(proc)

存储过程离数据库最近,所以它执行代码效率最高的。

Client(brower)-WebServer(tomcat)-DatabaseServer(mysql)

 

WebServerDatabaseServer,在企业中,WebServer一般服务器即可,但是DatabaseServer是所有服务器中最好的。甚

至大型项目,小型机。Unix+Oracle

废除:

  1. 写数据库代码(存储过程-单独学习语法,无法断点,system.out没有输出,几乎无法调试。DBA),写java代码(人员众多,好调试)。后期维护。不好维护。Java好维护。

  2. 存储过程不好写,质量不好控制。

4.1    定义存储过程

--  修改结束符

delimiter //

 

--  创建存储过程p1

createprocedure p1()

begin  --  大括号开始

   -- 定义局部变量v2

   declare v2int default 123;

   select v2; --  显示v2变量的值

end//  --  大括号结束

 

4.2    调用存储过程

call p1()//

 

4.3    查看存储过程

showprocedure status\G

    所有存储过程

 

showprocedure status where db='db1'\G

    查看指定库中的存储过程

 

showcreate procedure p1\G

 

4.4    删除存储过程

dropprocedure if exists p1//

 

4.5    存储过程的参数

三种参数:

  in       输入参数

  out      输出参数

  inout    既能输入又能输出

 

存储过程参数测试

--  向学生表和联系方式表同时插入数据

--  1) 插入学生数据

--  2) 得到新插入的自增主键值

--  3) 插入联系方式表

传统方式:

  1. 页面填写两张表的数据,学生名称,学生的电话,存在两个表中

  2. 学生表自增主键

  3. 联系表中和学生表的关联(一对一)

CREATE TABLE`t_student` (

`stu_id` int(11) NOTNULL AUTO_INCREMENT,

`name` varchar(20)DEFAULT NULL,

PRIMARY KEY(`stu_id`)

) ENGINE=InnoDBDEFAULT CHARSET=utf8

CREATE TABLE `t_tel` (
  `stu_id` int(11) NOT NULL,
  `tel` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`stu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

DELIMITER//

createprocedure p_student_tel

(in namevarchar(20),

in telvarchar(20), out idint)

begin

   declare vint;-- 定义临时变量用来存自增主键值

   --  插入学生数据

insertinto t_student(name)

   values(name);

   --  获得新生成的自增主键值存到v

   set v= last_insert_id();

   --  插入联系方式数据

   insertinto t_tel(stu_id,tel)

   values(v,tel);

   --  自增主键值存到输出参数id

   set id=v;

end//

 

 

--  调用

CALLp_student_tel('刘强东',13010100808,@id);

 

select from t_student;

select from t_tel;

select @stu_id;

 

 

5   流程控制

5.1    if

if 条件 then

   代码

endif

 

if 条件 then

   代码1

else

   代码2

endif

5.2    case

case

   when 条件1then ...

   when 条件2then ...

   else...

endcase

 

case 变量或表达式

   when 1then ...

   when 2then ...

   else

endcase

 

 

分支判断测试

delimiter//

 

dropprocedure if exists p1//

 

createprocedure p1(in vint)

begin

   if v=1 then

      select 'v的值是1';

   endif;

   case v

      when thenselect 'v的值是2';

      when thenselect 'v的值是3';

      elseselect 'v的值不是2,3';

   endcase;

end//

 

call p1(1)//

call p1(2)//

call p1(3)//

call p1(4)//

 

 

 

 

5.3    while

while 条件 do

   代码

endwhile

 

5.4    loop

--  lp: 循环命名,可以起任意的名字

 

lp:loop

   ...

   if 条件 then

      leavelp; --  指定离开哪个循环

   endif;

   ...

endloop;

 

5.5    repeat

repeat

   代码

until 条件 endrepeat;

 

循环测试

--  新建 tb1 

use db1//

 

droptable if exists tb1//

 

createtable tb1(

   idint primarykey auto_increment,

   numint

)engine=innodb charset=utf8//

 

delimiter//

dropprocedure ifexists p2//

createprocedure p2(inn int)

begin

   declare iint default 0;

   --  while

   while i<n do --i的值从0递增到n-1

      insertinto tb1(num) values(i+1);

      seti=i+1;

   endwhile

   --  loop

   set i=0;

   lp: loop

      insertinto tb1(num) values(i+1);

      seti=i+1;

      if i=n then --i等于n时退出loop循环

         leave lp;

      endif;

   endloop;

   --  repeat

set i=0;

   repeat

      insertinto tb1(num) values(i+1);

      seti=i+1;

   until i=n endrepeat; --i等于n时退出repeat循环

end//

 

call p2(10)//

 

select from tb1//

 

 

6   函数

  函数有返回值

  调用存储过程用call,调用函数直接调

函数不让?

分布式?又放在java

Zookeeper集群管理者,当一台服务的配置更新,zk会自动把配置改变信息更新到其它所有的机器

上。

5.1    创建函数

createfunction fn()

returnsvarchar(100)

begin

   执行代码运算产生计算结果

   return 计算结果;

end//

 

求平方的函数 fn_pow

DELIMITER//

dropfunction if exists fn_pow//

 

createfunction fn_pow(nint)

returns int -- 函数返回什么类型的数据

begin

   declare rint;

   set r= n*n;

   return r; -- 向调用位置返回计算结果

end //

 

select fn_pow(5)//

select *,fn_pow(num) from tb1//

 

 

6.2    查看函数

showfunction status\G

showfunction status where db='test'\G

showcreate function fn_pow\G

5.3    删除函数

 dropfunction if exists fn_pow //

 

7   触发器

对表中的数据操作时,可以触发一段代码执行

三个数据操作:

  insert

  update

  delete

 

两个触发时间:

  before

  after

 

一张表中最多可以有6个触发器

  beforeinsert

  afterinsert

  beforeupdate

  afterupdate

  beforedelete

  afterdelete

 

两个隐含对象

  new

新的数据行

insertnew:要插入的新行

updatenew:修改后的新行

deletenew:没有

 

  old

旧的数据行

insertold:没有

updateold:修改前的旧数据

deleteold:被删除的旧数据

 

  访问新行或旧行数据:

new.id

new.name

old.age

old.tel

7.1    创建触发器


 

操作商品表insert,before,new


 


 

createtrigger  触发时间 on 

foreach row

being

   代码

end;

 

用触发器自动更新updated字段

--  学生表添加 updated字段

altertable t_student

add createddatetime //

--  添加触发器,插入数据时自动填入时间

--  beforeinsert

DELIMITER//

CREATETRIGGER tr_b_i

BEFOREINSERT ON t_student FOR EACH ROW

BEGIN

SETnew.created=NOW();

END//

insertinto t_student(name)

values('tony')//

 

select from t_student//

 

--  添加触发器,修改数据时自动修改时间

 

altertable t_student

add updateddatetime //

DELIMITER//

CREATETRIGGER tr_b_u

BEFOREUPDATE ON t_student FOR EACH ROW

BEGIN

SETnew.updated = NOW();

END//

 

UPDATEt_student SET NAME='tina' WHERE stu_id=2

 

select from t_student//

 

 

--  级联删除,删除主表信息时利用触发器删除子表信息

--  beforedelete

DELIMITER//

CREATETRIGGER tr_b_d

BEFOREDELETE ON t_student FOR EACH ROW

BEGIN

DELETEFROM t_tel WHERE stu_id=old.stu_id;

END//

 

deletefrom t_student where name='a'//

7.2    查看触发器

进入系统库 information_schema

useinformation_schema //

 

查询 triggers 表中触发器信息

select* from triggers\G

7.3    删除触发器

droptrigger 触发器名

级联删除

删除主表的数据时,要先把子表的数据删除。

 

8   数据库的备份、恢复

备份方式:

  1. 冷备份(按月)

  2. 热备份

  1. 定时任务Job(按周,日(凌晨2点),小时)、

  2. 实时备份(主从复制,实时同步)


 

查看数据安装路径

SELECT@@basedir AS basePath FROM DUAL;

 

C:\ProgramFiles\MySQL\MySQL Server 5.5\bin>

使用mysqldump命令备份数据库

使用mysql命令恢复数据库

8.1    备份

退出mysql,在系统命令行执行:

 

下面命令是一行代码,不能折行

 

mysqldump  -uroot-p

--default-character-set=utf8  //表中存的是什么编码

hr>d:\hr.sql  //>文件

 数据库名

 

8.2    恢复

两步恢复:

1)  数据库中新建一个库

createdatabase jtdb2 charset utf8;

2)  系统命令行执行恢复命令

下面命令是一行代码,不能折行

 

mysql-uroot -p

--default-character-set=utf8

jtdb2<d:\jtds.sql    

 

9   索引

9.1    存储过程产生大量数据

1)  创建一个内存表tm engine=memory

2)  创建一个磁盘表td

3)  在存储过程中,循环20000次向内存表插入随机字符串

4)  20000条数据,一批存入磁盘表

5)  清空内存表

 

--  内存表

droptable if exists tm;

createtable tm(

   cvarchar(20)

engine=memory charset=utf8;

 

--  磁盘表

droptable if exists td;

createtable td(

   idint primarykey auto_increment,

   cvarchar(20)

engine=innodb charset=utf8;

--  存储过程

DROPPROCEDURE IF EXISTS gen_data;

DELIMITER//

CREATEPROCEDURE gen_data(IN n INT)

BEGIN

DECLAREi INT DEFAULT 0;

WHILEi<n DO

INSERTINTO tm VALUES (UUID());

SETi=i+1;

ENDWHILE;

INSERTINTO td(c) SELECT c FROM tm;

DELETEFROM tm;

END//

CALLgen_data(1000) 

DROPPROCEDURE IF EXISTS test_insert;

DELIMITER//

CREATEPROCEDURE test_insert(cnt INT)

BEGIN

DECLAREi INT DEFAULT 0;

STARTTRANSACTION;

WHILEi<cnt

DO

INSERTINTO td(c) VALUES(UUID());

SETi=i+1;

ENDWHILE;

COMMIT;

END//

9.2    索引优化

索引其本质是创建了一张索引表,现有表的拷贝

(索引需要代价,插入数据要重写排序)

只拷贝现有表的指定索引字段。重要是做了一件事情:

排序

为什么它要排序呢?为什么排序后就快了呢?

不创建索引,查询时,全表遍历。

折半算法


 


 

用索引提高数据查找效率

--  没有索引,花3.5秒查询

select* from td where c='ab' //

 

--  c字段创建索引,花140秒左右

createindex td_c_index on td(c) //

 

--  有索引查询花费 0.00 

select* from td where c='ab' //

9.3MySQL验证索引的使用-最左前缀特性

复合索引

通过EXPLAIN关键字可以判断查询SQL语句是否使用索引

Possible_keys如果有值就代表使用了哪个索引,如果null就代表查询没有使用索引,全表遍历。

SELECT* FROM tb1

WHEREuser_id=100;


 

SELECT* FROM tb1

WHEREorder_id=300;


 


 

SELECT* FROM tb1

WHEREuser_id=100 AND order_id=300;


 

SELECT* FROM tb1

WHEREorder_id=300 AND user_id=100 ;

没使用索引

EXPLAIN

SELECT* FROM t_goods

WHEREtitle LIKE '%皮面%'

使用索引

EXPLAIN

SELECT* FROM t_goods

WHEREtitle LIKE '皮面%'

没有使用索引

EXPLAIN

SELECT* FROM t_goods

WHEREtitle LIKE '%皮面'


 

EXPLAINSELECT * FROM tb_cart WHERE user_id=1 AND item_id=1

 

EXPLAINSELECT * FROM tb_cart WHERE user_id=1

EXPLAINSELECT * FROM tb_cart WHERE item_id=1

 

查看SQL的执行计划,可以看出第一句、第二句SQL使用了索引,第三句SQL未使用索引。很好的证明了索引左侧前缀特性。

注意:

1)下面的语句违反了左侧前缀的特性,为何仍然可以使用索引呢?因为MYSQL对SQL语句有优化,它会重新组合where条件。

EXPLAINSELECT * FROM tb_cart WHERE item_id=1 AND user_id=1

 

2)没有where条件的查询是不会使用索引的。

猜你喜欢

转载自blog.csdn.net/weixin_41664173/article/details/79203759