Mysql第四章 存储程序&触发器&用PoweDesigner设计数据库

一、存储程序

存储程序指的一组存储和执行在数据库服务器端的程序。存储程序总是在服务器的进程或者线程的内存中执行的。

(一)存储过程 create procedure sel_procedure([参数])

(A)定义:

类似于方法,有过程名称,参数列表,过程体组成。
过程创建,过程调用。

-- 声明
        delimiter //
        create PROCEDURE selEmpByNo(eno int)
        begin
           select ename from emp where empno = eno;
        end; 
        //
        -- 调用
        call selEmpByNo(7788);
(B)参数有三种模式:
  • IN:默认。 由外部将参数传入过程。
  • OUT: 可以由存储过程将值传出。
  • INOUT: 可以传入也可以传出。
(C)分支语句
#分支:
delimiter //
        create procedure score_level(score int)
        begin
           -- 声明变量
          declare v_level varchar(20);
          if score >= 90 then
              set v_level = 'A';
            elseif score >=80 then
          set v_level = 'B';
          elseif score >= 70 then
          set v_level = 'C';
          else
          set v_level = 'D';
          end if;   
        select v_level;     
        end;
      //
(D)循环
  • While 条件 do … end while;
  • Loop…….end loop; (leave)
  • Repeat … end repeat; (until)
#循环:
     While 条件 doend while;
     Loop…….end loop;   (leave)
     Repeatend repeat;  (until)
   #while
        delimiter //
        create procedure calc1()
      begin
          declare i int;
            declare sum int;
            set i = 1;
            set sum = 0;
            while i<=100 do
              set sum = sum + i;
              set i = i+1;
            end while;
            select sum;
        end;
        //
        call calc1();


        #loop
        delimiter //
        create procedure calc2()
      begin
          declare i int;
            declare sum int;
            set i = 1;
            set sum = 0;
            lip:loop
              set sum = sum + i;
              set i = i+1;
                if i>100 then
                  leave lip;
                end if;
            end loop;
            select sum;
        end;
        //
        call calc2();

        #repeat
        delimiter //
        create procedure calc3()
      begin
          declare i int;
            declare sum int;
            set i = 1;
            set sum = 0;
            repeat
              set sum = sum + i;
              set i = i+1;
                until i>100
            end repeat;
            select sum;
        end;
        //
        call calc3();

(二)存储函数:有参数和返回值。 create function fun_sel([参数])

-- 存储函数(eno查询ename)
        delimiter //
        create function fun_sel(eno int)
        returns varchar(20)  -- 返回值的类型
        DETERMINISTIC -- 确定
        begin
             declare v_name varchar(20);
           select ename into v_name from emp where empno = eno;
             return v_name;
        end;
        //
        select fun_sel(7788);
存储过程和存储函数的区别:
  • 1.关键字不同,存储过程为procedure,存储函数为function;
  • 2.存储过程通过参数模式返回值,函数可以通过return返回值
  • 3.存储过程可以作为独立调用的个体,函数必须作为sql的一部分进行调用。

三、触发器 create trigger trig_name

触发器不能手动调用也不能传递参数。由事件触发。Mysql里增删改会触发。
Mysql只支持行级触发器,Oracle支持表级触发器。

#语法格式:
CREATE
    [DEFINER = { user | CURRENT_USER }]
    TRIGGER trigger_name
    trigger_time trigger_event
    ON tbl_name FOR EACH ROW
    [trigger_order]
    trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name

例子

delimiter //
        create trigger tri_stu
        after delete
        on stu for each row
        begin
          insert into student(sname,cid) values(old.sname,old.cid);
        end;
        //
触发器影响性能。

二、视图和索引

(一)视图 create view view_name

(A)视图定义:是实体表的一个虚拟映射,在数据库中没有物理结构存在。
(B)视图
  • 1.视图数据来自于基表,
  • 2.视图可以使用增删改查的功能,视图增删改功能会修改基表数据。
  • 所以视图创建是为了查找,不是为了增删改。
(C)基本语法
create view view_emp
        as
        select * from emp where deptno = 10 with check option;

select * from view_emp; 
update view_emp set deptno = 20;

drop view view_emp;
(D)视图特点
  • 1.简化开发。存储之前查找出来的集合。
  • 2.安全性。只映射出一部分内容公开给别人看。
  • 3.定制化数据。拆分或组合字段信息。

(二)索引 create index index_name on table(id)

索引是为提高查询效率设计的数据结构。本质需要文件存储,需要维护。

#创建索引
create index index_sid on stu(sid);
#销毁索引
drop index index_sid on stu;
(A)索引的添加规则
  • 1.数据量较大
  • 2.添加索引在高奇数时
  • 3.不能添加过多索引(需要维护)
  • 4.默认是B树索引
(B)不适合添加
  • 增删改过多的操作。增删改操作不能超过5%。

三、数据库设计

(一)三大范式(减少冗余)

层层递进,一层比一层要求严格

1NF:数据的列都是不可分割的原子性。
如一个地址字段内容是:北京市昌平区立水桥路155号;
如果要查找昌平区的所有人,利用like或取子串,效率就很低。
应该将字段拆成  市字段,区字段,路字段。
不能再分。
2NF 所有的非主键信息必须与主键信息相关,如果有联合主键,应与联合主键完全相关,不能与部分主键相关。

(一张表只描述一个事物)

如:用户信息里就不能出现商品的信息。
3NF 所有非主键字段必须与主键直接相关,非主键字段之间不能直接相关。

(即非主键不能与主键传递相关)
- 有时为了提高查询效率,而违反三大范式。

(二)数据库设计

(A)设计步骤

1.需求分析
2.概念结构设计阶段
是整个数据库设计的关键。
设计数据库的E-R概念图,确认需求信息的正确和完整(Entity-Relationship)

(B)实体图设计
(a)图形
  • 矩形:表示实体
  • 菱形:表示联系
  • 椭圆表示实体的属性
(b)实体之间的关系如何在数据库里体现
  • #一对一关系:如个人信息表和档案表
  • 1.约束方式一:外键添加唯一约束
  • 2.约束方式二:主键作为外键
  • #一对多:如部门和员工
  • 约束方式:直接添加外键(简单)
  • #多对多:学生表和课程表
  • 约束方式:需要增加关系管理表,并且设计联合主键
  • 两张表肯定解决不了问题。
一对一例子
---------------------------------------------------
person表
pk
pid   pname   sex
 1     zs     man
 -------------------------------------------------
一对一设计方法一 :外键添加唯一约束
record表 
pk                             fk外键   unique
rid   rcontent       rdate         pid
 1      zs's       1999-09-09       1
 --------------------------------------------------
 一对一设计方法二 :主键作为外键
record表  
pk fk
rid   rcontent       rdate         pid
 1      zs's       1999-09-09       1
-------------------------------------------------- 
多对多例子
----------------------------------------------------
student 学生表
pk
sid     sname
1        zs
2        ls
-----------------------------------------------------
course 课程表
pk
cid
1       java
2       c
----------------------------------------------------
stu-course
sid    cid
1       1
2       1
2       2
1       2
---------------------------------------------------
(c)用PowerDesigner软件设计数据库

先new 概念模型,再设计实体类及其关系,然后tool->生成物理模型;然后DataBase->生成数据库。

1.设计好实体类这里写图片描述
2.设计好实体类后,生成物理模型

这里写图片描述

3.生成数据库

这里写图片描述

四、SQL语言设计优化

(一)设计原则

(A)select语句尽量不用*
(B)用UNION替换OR(适用于索引列)
(C)用EXISTS替代IN、用NOT EXISTS替代NOT IN
(二)以下会导致索引失效
  • ① Not Null/Null 如果某列建立索引,当进行Select * from emp where depto is not null/is null。 则会是索引失效。
  • ② 索引列上不要使用函数,
  • SELECT Col FROM tbl WHERE substr(name ,1 ,3 ) = ‘ABC’(不)
  • SELECT Col FROM tbl WHERE name LIKE ‘%ABC%’ (不)
  • SELECT Col FROM tbl WHERE name LIKE ‘ABC%’ (使用)。
  • ③ 索引列上不能进行计算
  • SELECT Col FROM tbl WHERE col / 10 > 10 则会使索引失效
  • 应该改成SELECT Col FROM tbl WHERE col > 10 * 10
  • ④ 索引列上不要使用NOT ( != 、 <> )
    如:SELECT Col FROM tbl WHERE col ! = 10 应该
    改成:union。
(三)用UNION替换OR(适用于索引列)
  • union:是将两个查询的结果集进行追加在一起,它不会引起列的变化。
  • 由于是追加操作,需要两个结果集的列数应该是相关的,并且相应列的数据类型也应该相当的。
  • union 返回两个结果集,同时将两个结果集重复的项进行消除。 如果不进行消除,用UNOIN ALL.
  • 通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果. 对索引列使用OR将造成全表扫描.
  • 注意, 以上规则只针对多个索引列有效.
  • 如果有column没有被索引, 查询效率可能会因为你没有选择OR而降低.
(四)用EXISTS替代IN、用NOT EXISTS替代NOT IN
  • 在许多基于基础表的查询中, 为了满足一个条件, 往往需要对另一个表进行联接. 在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率.
  • 在子查询中, NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下, NOT IN都是最低效的(因为它对子查询中的表执行了一个全表遍历).
  • 为了避免使用NOT IN, 我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.
  • 高效: SELECT * FROM EMP (基础表) WHERE EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)
  • 低效: SELECT * FROM EMP (基础表) WHERE DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)

五、备份和还原

#备份
Mysqldump -uroot -proot dbname > d:/t.sql;
#还原
mysql -u root -p < C:\backup.sql

猜你喜欢

转载自blog.csdn.net/gegeyanxin/article/details/80627327