MySQL必知必会(第4版)整理笔记

参考书籍:

BookName:《SQL必知必会(第4版)》

BookName:《Mysql必知必会(第4版)》

Author: Ben Forta

说明:本书学习笔记

1、了解SQL

  1.1 数据库基础

    1.1.1 数据库

      数据库是一个以某种有组织的方式存储的数据集合,即保存有组织的数据的容器(通常是一个文件或一组文件)。

      数据库软件应称为数据库管理系统(DBMS)。

    1.1.2 表

      表是一种结构化的文件,可用来存储某种特定类型的数据。

      模式,关于数据库和表的布局及特性的信息。

    1.1.3 列和数据类型

      列,表中的一个字段,存储表中的某部分信息。

      所有表都是由一个或多个列组成的。

      数据类型,所允许的数据的类型。每个表列都有相应的数据类型,它限制(或允许)该列中存储的数据。

    1.1.4 行

      行,表中的一个记录。

      表中的数据都是按行存储的,所保存的每个记录存储在自己的行内。

    1.1.5 主键

      主键,一列(或一组列),其值能够唯一标识表中每一行。

      表中的任何列都可以作为主键,只要满足:

        (1)任意两行都不具有相同的主键值;

        (2)每一行都必须具有一个主键值;

        (3)主键列中的值不允许修改或更新;

        (4)主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)。

  1.2 什么是SQL 

    SQL是Structured Query Language(结构化查询语言)的缩写。SQL是一种专门用来与数据库沟通的语言。

2、MySQL简介

  数据所有的存储、检索、管理和处理实际上是由数据库软件——DBMS完成的。

  MySQL是一种DBMS,即它是一种数据库软件。

  DBMS可分为两类:一类为基于共享文件系统的DBMS,另一类为基于客户机——服务器的DBMS。

3、使用MySQL

  3.1 连接

    为了连接到MySQL,需要以下信息:

    (1)主机名(计算机名),如果连接到本地MySQL服务器,为localhost;

    (2)端口(如果使用默认端口3306之外的端口);

    (3)一个合法的用户名;

    (4)用户口令。

  3.2 选择数据库

    在最初连接到MySQL时,没有任何的数据库打开供使用,故在能执行任意数据库操作前,需要选择一个数据库,可使用USE关键字。

          

    这里显示出的Database changed消息是mysql命令行实用程序在数据库选择成功后显示的。

    必须先使用USE打开数据库,才能读取其中的数据。

  3.3 了解数据库和表

    数据库、表、列、用户、权限等的信息被存储在数据库和表中,可用MySQL的SHOW命令来显示这些信息。

    

    SHOW DATABASES;  返回可用数据库的一个列表。

    SHOW TABLES;  返回当前选择的数据库可用表的列表 。

    SHOW COLUMNS FROM test_demo;  SHOW COLUNNS要求给出一个表名,它对每个字段返回一行,行中包含字段名、数据类型、是否允许NULL、健信息

                     、默认值以及其他信息(如字段名的auto_increment)。

    SHOW STATUS;  用于显示广泛的服务器状态信息。

    SHOW CREATE DATABASE;  用来显示创建特定数据库。

    SHOW CREATE TABLE;  用来显示创建特定表。

    SHOW GRANTS;  用来显示授权用户(所有用户或特定用户)的安全权限。

    SHOW ERRORS;SHOW WARNINGS; 用来显示服务器错误或警告信息。

4、检索数据

  补充:(1)多条SQL语句必须以分号(;)分隔。

     (2)SQL语句不区分大小写,一般建议所有SQL关键字使用大写,而对所有列和表明使用小写。

     (3)在处理SQL语句时, 其中所有空格都被忽略;SQL语句可以在上一行给出,也可以分成许多行。

  4.1 SELECT语句

    SELECT语句,它的作用是从一个或多个表中检索信息。

    为了使用SELECT检索表数据,必须至少给出两条信息——想选择什么,以及从什么地方选择。

  4.2 检索单个列

    SELECT prod_name FROM products;  

    所需的列名在SELECT关键字之后给出,FROM关键字指出从其中检索数据的表名。    

  4.3 检索多个列

    在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。

    SELECT prod_id, prod_name, prod_price FROM products;

    指定3个列名。

  4.4 检索所有列

    在实际列名的位置使用星号(*)通配符,SELECT语句可以检索所有的列而不必逐个列出他们。

    SELECT * FROM products;  

    虽然使用通配符可能会使人省事不用明确列出所需列,但检索不需要的列通常会降低检索和应用程序的性能。

  4.5 检索不同的行

    SELECT vend_id FROM products;

    vend_id 为其他与products相关联的表的主键,但为products的某列。

    SELECT DISTINCT vend_id FROM products;

    DISTINCT筛选重复数据。使用DISTINCT关键字,它必须直接放在列名的前面。DISTINCT关键字应用于所有列而不仅仅是前置它的列。

  4.6 限制结果

  DISTINCT筛选重复数据。使用DISTINCT关键字,它必须直接放在列名的前面。DISTINCT关键字应用于所有列而不仅仅是前置它的列。

  4.6 限制结果

    为了返回第一行或前几行,可使用LIMIT字句。

    SELECT prod_name FROM products LIMIT 5;    --LIMIT 5 指示MySQL返回不多于5行。

    SELECT prod_name FROM products LIMIT 5,5;  --LIMIT 5,5 指示MySQL返回从行5开始的5行。第一个数为开始位置,第二个数为要检索的行数。

    其他写法:SELECT prod_name FROM products LIMIT 4 OFFSET 3 --从行3开始取4行,同LIMIT 3,4。

  4.7 使用完全限定的表名

    表名可以是完全限定的。

    SELECT products.prod_name FROM crashcourse.products;   --products为表名,crashcourse为数据库名。

5、排序检索数据

  5.1 排序数据

    关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。

    子句,SQL语句由子句构成,有些子句是必须的,而有的是可选的;一个子句通常由一个关键字和所提供的数据组成。

    使用ORDER BY 子句明确地排序SELECT检索出来的数据。

    SELECT prod_name FROM products ORDER BY prod_name;   --指示MySQL对prod_name列以字母顺序排序数据。

    提示:用非检索的列排序数据是完全合法的。

  5.2 按多个列排序

    为了按多个列排序,只要指定列名,列名之间用逗号分开即可。

    SELECT prod_id, prod_name, prod_price

    FROM products

    ORDER BY prod_price, prod_name;  --先按prod_price排序,后按prod_name排序(当prod_price唯一时,prod_name忽略排序)

  5.3 指定排序方向

    数据排序默认为生序排序,为进行降序排序,必须指定DESC关键字。

    SELECT prod_id, prod_price, prod_name

    FROM products

    ORDER BY prod_price DESC;

    提示:(1)DESC 关键字只应用到直接位于其前面的列名;

       (2)如果想在多个列上进行降序排列,必须对每个列指定DESC关键字;

       (3)与DESC相反的关键字是ASC,在升序排序时可以指定它。

    其他:在给出ORDER BY子句时,应该保证它位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY之后。

6、过滤数据

  使用SELECT语句的WHERE子句指定搜索条件

  6.1 使用WHERE子句

    只检索所需数据需要指定搜索条件(search criteria),搜索条件也称为过滤条件(filter condition)。

    在WHERE语句中,数据根据WHERE子句中指定的搜索条件进行过滤。

    SELECT prod_name, prod_price

    FROM products

    WHERE prod_price=2.50;

    其他:在同时使用ORDER BY 和WHERE子句时,应该让ORDER BY位于WHERE之后。

  6.2 WHERE子句操作符

    说明:<> 不等于, != 不等于,BETWEEN 在指定的两个值之间

    6.2.1 检查单个值(<, >, =, <=,>=)

    6.2.2 不匹配检查(!= 和<>)

    6.2.3 范围值检查

      在使用BETWEEN时,必须指定两个值,所需范围的低端值和高端值,这两个值必须用AND关键字分隔。

      SELECT prod_name, prod_price

      FROM products

      WHERE prod_price BETWEEN 5 AND 10;

    6.2.4 空值检查

      在创建表时,表设计人员可以指定其中的列是否可以不包含值。在一个列不包含值时,称为包含空值NULL。

      WHERE子句IS NULL检查具有NULL值的列。

      SELECT prod_name

      FROM products

      WHERE prod_price IS NULL;

7、数据过滤

  7.1 组合WHERE子句

    为了进行更强的过滤,MySQL允许给出多个WHERE子句以AND字句的方式或OR子句的方式使用。

    7.1.1 AND操作符

      用来指示检索满足所有给定条件的行。

    7.1.2 OR操作符

      指示检索匹配任一条件的行。

    7.1.3 计算次序

      SQL在处理OR操作符前,优先处理AND操作符。

      使用圆括号明确地分组相应的操作符。

  7.2 IN操作符

    IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN取的合法值是由逗号分隔的清单,全都括在圆括号中。

    SELECT prod_name, prod_price

    FROM products

    WHRER vend_id IN (1002,1003)

    ORDER BY prod_name;

  7.3 NOT操作符

    WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。

    

 8、用通配符进行过滤

  使用LIKE操作符进行通配搜索,以便对数据进行复杂过滤。

  8.1 LIKE操作符  

    8.1.1 百分号(%)通配符

      在搜索串中,%表示任何字符出现任意次数。

      SELECT prod_id, prod_name

      FROM products

      WHERE prod_name LIKE 'jet%';

      其他:(1)'%jet%'首尾   、 'je%t'中间

         (2)%代表搜索模式中给定位置的0个、1个或多个字符。

         (3)不能匹配NULL

    8.1.2 下划线(_)通配符

      下划线只匹配单个字符。

9、用正则表达式进行搜索

  9.1 正则表达式介绍

    正则表达式的作用是匹配文本,将一个模式(正则表达式)与一个文本串进行比较。

  9.2 使用MySQL正则表达式

    MySQL仅支持多数正则表达式实现的一个很小的子集。、

    9.2.1 基本字符匹配

      SELECT prod_name

      FROM products

      WHERE prod_name REGEXP  '1000'

      ORDER BY prod_name;

      它告诉MySQL,REGEXP后所跟的东西作为正则表达式处理。

      “.”是正则表达式语言中一个特殊的字符,它表示匹配任意一个字符。

      MySQL中的正则表达式匹配不区分大小写,为了区分大小写,可使用BINARY关键字,如WHERE prod_name REGEXP BINARY 'JetPacl .000'

    9.2.2 进行OR匹配

      为搜索两个串之一,使用‘|’,它为正则表达式的OR操作符,表示匹配其中之一。

      SELECT prod_name

      FROM products

      WHERE prod_name REGEXP '1000|2000'

      ORDER BY prod_name;

    9.2.3 匹配几个字符之一

      使用一组用‘[   ] ’括起来的字符,匹配其中任意单一字符。

      SELECT prod_name

      FROM products

      WHERE prod_name REGEXP '[123] Ton'

      ORDER BY prod_name;

      在集合的开始处放置一个‘^’,可否定一个字符集。

    9.2.4 匹配范围

      集合可用来定义要匹配的一个或多个字符。简化使用‘—’,例如 [123456]等同于[1-6]

    9.2.5 匹配特殊字符

      正则表达式内具有特殊意义的所有字符都必须转义‘\’

      

      

     9.2.6 匹配字符类

      

     9.2.7 匹配多个实例

      

     9.2.8 定位符

      

      SELECT prod_name

      FROM products

      WHERE prod_name REGEXP '^[0-9\.]'

      ORDER BY prod_name;

      

10、创建计算字段

  10.1 计算字段

    字段(field)与列的意思相同。

  10.2 拼接字段

    拼接(concatenate),将值联结到一起构成单个值。

    SELECT Concat(vend_name ,  ' ('   ,  RTrim(vend_country)  ,   ')'  ) AS vend_title

    FROM vendors

    ORDER BY vend_name;

    Concat()需要一个或多个指定的串,各个串之间用逗号分隔。

    RTrim()函数去掉值右边的所有空格。LTrim()函数去掉值左边的所有空格、Trim()去掉左右两边的空格。

    AS 关键字赋予别名使计算字段存储,从而被应用。

  10.3 执行算术计算

    

    

     用圆括号可以区分优先顺序。

11、使用数据处理函数

  11.1 函数

  11.2 使用函数

    11.2.1 文本处理函数

      

        Soundex是一个将任何文本串转换为描述其语音表示的字母数字模式的算法,使其能对串进行发音比较而不是字母比较。

    11.2.2 日期和时间处理函数

      

     11.2.3 数值处理函数

      

    

12、汇总数据

  12.1 聚集函数

    

    COUNT()函数如果指定列名,则指定列的值为空的行被COUNT()函数忽略,但如果COUNT()函数中用的是星号(*),则不忽略。

    AVG()、MAX()、MIN()、SUM()函数忽略列值为NULL的行。

  12.2 聚集不同值

  12.3 组合聚集函数

13、分组数据

  13.1 分组数据

    分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算

  13.2 创建分组

    SELECT vend_id, COUNT(*) AS num_prods

    FROM products

    GROUP BY vend_id;

    GROUP BY子句指示MySQL按vend_id排序并分组数据;

    GROUP BY 子句出现在WHERE子句之后,ORDER BY子句之前。

  13.3 过滤分组

    HAVING过滤分组,规定包括哪些分组,排除哪些分组。

    WHERE 和 HAVING 类似,但是WHERE 过滤行,HAVING 过滤分组。

    SELECT cust_id, COUNT(*)  AS orders

    FROM orders

    GROUP BY cust_id

    HAVING COUNT(*)>=2;

  13.4 分组和排序

    

  13.5 SELECT子句顺序

    

14、 使用子查询

  14.1 子查询

    SQL允许创建子查询(subquery),即嵌套在其他查询中的查询。

  14.2 利用子查询进行过滤

  14.3 作为计算字段使用子查询

15、联接表

  15.1 联结

    15.1.1 关系表

      外键(foreign key)外键为某个表中的一列,它包含另外一个表的主键,定义了两个表之间的关系

    15.1.2 为什么要使用联结

      联结,一种机制,用来在一条SELECT语句中关联表。

  15.2 创建联结

    SELECT vend_name, prod_name, prod_price

    FROM vendors, products

    WHERE vendors.vend_id = products.vend_id

    ORDER BY vend_name, prod_name;

    15.2.1 WHERE子句的重要性

    15.2.2 内部联结  

      等值联结(equijoin),它基于两个表之间的相等测试。

      其他语法:

        SELECT vend_name, prod_name, prod_price

        FROM vendors INNER JOIN products

        ON vendors.vend_id=products.vend_id;

      这两个表之间的关系是FROM子句的组成部分,以INNER JOIN指定。

    15.2.3 联结多个表

      每个联结关系用AND拼接

16、创建高级联结

  16.1 使用表别名

    别名除了用于列名和计算字段外,SQL还允许给表名起别名。

  16.2 使用不同类型的联结

    16.2.1 自联结

    SELECT p1,prod_id, p1.prod_name

    FROM products AS p1, products AS p2

    WHERE p1.vend_id=p2.vend_id

    AND p2.prod_id = 'DTNTR';

    16.2.2 自然联结

      自然联结排除多次出现,使每个列只返回一次。

      一般是通过对表使用通配符(SELECT *),对所有其他表的列使用明确的子集来完成。

    16.2.3 外部联结

      SELECT customers.cust_id, orders.order_num

      FROM customers LEFT OUTER JOIN orders

      ON customers.cust_id=orders.cust_id;

      在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右边的表,LEFT指出的是OUTER JOIN左边的表)

  16.3 使用带聚集函数的联结

17、组合查询

  利用UNION操作符将多条SELECT语句组合成一个结果集 

  17.1 组合查询

    MySQL允许执行多个查询,并将结果作为单个查询结果集返回。这些组合查询称为并(union)或复合查询(compound query) 

    两种情况下需要使用组合查询:

    (1)在单个查询中从不同的表返回类似结构的数据

    (2)对单个表执行多个查询,按单个查询返回数据

  17.2 创建组合查询

    在各条语句之间放上关键字UNION

    SELECT vend_id, prod_id, prod_price

    FROM products

    WHERE prod_price <=5

    UNION

    SELECT vend_id,prod_id,prod_price

    FROM products

    WHERE vend_id  IN (1001,1002)

    OEDER BY vend_id, prod_price;

    如果想返回所有匹配行,可使用UNION ALL而不是UNION

    在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后

18、全文本搜索

  18.1 理解全文本搜索

    使用全文本搜索时,MySQL不需要分别查看每个行,不需要分别分析和处理每个词。MySQL创建指定列中各词的一个索引,搜索可以针对这些词进行。这样,MySQL可以

  快速有效地决定哪些词匹配(哪些行包含它们),哪些词不匹配,它们匹配的频率,等等。

  18.2 使用全文本搜索

    18.2.1 启用全文本搜索支持

      CREATE TABLE productnotes

      (

        note_id    int    NOT NULL   AUTO_INCREMENT,

        prod_id    char(10)  NOT NULL,

        note_date      datetime NOT NULL,

        note_text    text     NULL,

        PRIMARY   KEY(note_id),

        FULLTEXT(note_text)

      )  ENGINE=MyISAM;

      CREATE TABLE语句定义表productnotes并列出它所包含的列。

      为了进行全文搜索,MySQL根据子句FULLTEXT(note_text)的指示对它进行索引。FULLTEXT索引单个列,也可以指定多个列。

      在定义之后,MySQL自动维护该索引,即在增加、更新或删除行时,索引随之自动更新。

    18.2.2 进行全文本搜索

      在索引之后,使用两个函数Match()和Against()执行全文本搜索,其中Match()指定被搜索的列,Against()指定要使用的搜索表达式。

      SELECT note_text

      FROM productnotes

      WHERE Match(note_text)  Against('rabbit');

    18.2.3 使用查询扩展

      查询扩展用来设法放宽所返回的全文本搜索结果的范围。

      SELECT note_text

      FROM productnotes

      WHERE Match(note_text) Against('anvils'  WITH QUERY EXPANSION)  

    18.2.4 布尔全文搜索

      SELECT note_text

      FROM productnotes

      WHERE Match(note_text) Against('heavy -rope*'  IN BOOLEAN MODE);

      -rope*明确指示MySQL排除包含rope*的行。

      

19、插入数据

  利用SQL的INSERT语句将数据插入表中

  19.1 数据插入

    INSERT用来插入(或添加)行到数据库,使用的使用方式:

    (1)插入完整的行

    (2)插入行的一部分

    (3)插入多行

    (4)插入某些查询的结果

  19.2 插入完整的行

    INSERT要求指定表名和被插入到新行中的值。

    INSERT INTO customers(

            cust_addr,

            cust_city

          )

    VALUES(

      NULL,

      'Pep E'

    );

  19.3 插入多个行

    使用多条INSERT语句,每条语句用一个分号结束。

  19.4 插入检索出的数据

    INSERT INTO customers(列名1)

    SELECT 列名1

    FROM other_customers;

20、更新和删除数据

  20.1 更新数据

    可采用两种方式使用UPDATE:(1)更新表中特定的行;(2)更新表中所有行

    基本的UPDATE语句由3部分组成:(1)要更新的表;(2)列名和它们的新值;(3)确定要更新行的过滤条件。

    UPDATE customers

    SET cust_email='example@qq.com',

      cust_name='enheng'

    WHERE cust_id=1005;

    SET命令用来将新值赋给被更新的列。

    更新多个列时,只需要使用单个SET命令,每个‘列=值’对之间用逗号分隔    

    删除某个列的值,可设置它为NULL。

  20.2 删除数据

    可采用两种方式使用DELETE:(1)删除表中特定的行;(2)删除表中所有行

    DELETE FROM customers

    WHERE cust_id=10006;

    DELETE删除整行而不是删除列。

    如果想从表中删除所有行,不要使用DELETE,可使用TRUNCATE TABLE语句。

21、创建和操纵表

  21.1 创建表

    为了利用CREATE TABLE 创建表,必须给出下列信息:

    (1)新表的名字,关键字CREATE TABLE之后给出

    (2)表列的名字和定义,用逗号分隔    

    CREATE TABLE productnotes  

      (

        note_id    int    NOT NULL   AUTO_INCREMENT,

        prod_id    char(10)  NOT NULL   DEFAULT  1,

        note_date      datetime NOT NULL,

        note_text    text     NULL,

        PRIMARY   KEY(note_id),

        FULLTEXT(note_text)

      )  ENGINE=InnoDB;

    每列的定义以列名(它在表中是唯一的)开始,后跟列的数据类型。

    表的主键可以在创建表时用PRIMARY KEY关键字指定。

    主键只能使用不允许NULL值的列。

    AUTO_INCREMENT告诉MySQL,本列每增加一行时自动增量,每个表只允许有一个这样的列,而且它必须被索引。

    SELECT_last_instert_id(),此语句返回最后一个AUTO_INCREMENT值。

    默认值用列定义中的DEFAULT关键字指定。

    ENGINE指定数据库引擎

  21.2 更新表

    使用ALTER TABLE更改表结构,必须给出下面的信息:

      (1)在ALTER TABLE之后给出要更改的表名(该表必须存在)

      (2)所做更改的列表

    ALTER  TABLE vendors

    ADD vend_phone  CHAR(20);   --添加列必须明确其数据类型

    删除添加的列

    ALTER TABLE vendors

    DROP COLUMN vend_phone;

  21.3 删除表

    DROP TABLE customers2;

    执行这条语句将永久删除该表。

  21.4 重命名表

    RENAME TABLE customers2 TO customers;

 

22、使用视图

  22.1 视图

    视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询

    使用联结:

    SELECT cust_name, cust_contact 

    FROM customers, oders, orderitems

    WHERE customers.cust_id = orders.cust_id

    ADD orderitems.order_num=orders.order_num

    ADD prod_id ='TNT2'

    使用视图:

    SELECT cust_name, cust_contact

    FROM productcustomers

    WHERE prod_id ='TNT2'

    productcustomers是整个查询包装成的虚拟表,是一个视图,它不包含表中应该有的任何列或数据,它包含的是一个SQL查询。

    22.1.1 为什么使用视图

    22.1.2 视图的规则和限制

      (1)视图必须唯一命名

      (2)对于可以创建的视图数目没有限制

      (3)为了创建视图,必须具有足够的访问权限

      (4)视图可以嵌套

      (5)ORDER BY能使用

      (6)视图不能索引,也不能有关联的触发器或默认值

      (7)视图可以和表一起使用

  22.2 使用视图

    视图的创建:

      (1)视图用CREATE VIEW语句来创建

      (2)使用SHOW CREATE VIEW viewname;  来查看创建视图

      (3)用DROP删除视图,其语法为DROP VIEW viewname;

      (4)更新视图时,可以先用DROP再用CREATE,也可以直接用CREATE OR REPLACE VIEW

    22.2.1 利用视图简化复杂的联结

      CREATE VIEW productcustomers AS

      SELECT cust_name, cust_contact,prod_id

      FROM customers, orders, orderitems

      WHERE customers.cust_id = orders.cust_id

       AND orderitems.order_num = orders.order_num;

      创建一个productcustomers的视图,联结3个表。

    22.2.2 用视图重新格式化检索出的数据

    22.2.3 用视图过滤不想要的数据

    22.2.4 使用视图与计算字段

    22.2.5 更新视图

      视图通常是可更新的,更新一个视图将更新其基表。

      如果视图定义中以下操作,则不能进行视图的更新:

        (1)分组(使用GROUP BY 和 HAVING)

        (2)联结

        (3)子查询

        (4)并(UNION) 

        (5)函数聚集(MAX()、Count()等)

        (6)DISTINCT(去重)

        (7)导出(计算)列

23、使用存储过程

  23.1 存储过程

    存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。

  23.2 为什么要使用存储过程

  23.3 使用存储过程

    23.3.1 执行存储过程

      MySQL称存储过程的执行为调用。CALL接受存储过程的名字以及需要传递给它的任意参数。

      CALL productpricing(@pricelow,

                @pricehigh,

                @priceaverage);

    23.3.2 创建存储过程

      CREATE PROCEDURE productpricing()

      BEGIN

        SELECT Avg(prod_price) AS priceaverage

        FROM products;

      END;

      存储过程名为productpricing,用CREATE PROCEDURE productpricing()语句定义。

      如果存储过程接受参数,它们将在()中列举出来。

      BEGIN和END语句用来限定存储过程体。

      过程体本身是一个简单的SELECT语句。

      DELIMITER//告诉命令行使用程序使用//作为新的语句结束分隔符,恢复可使用DELIMITER ;  。  

      

      DELIMITER //

      CREATE PROCEDURE productpricing()

      BEGIN

        SELECT Avg(prod_price) AS priceaverage

        FROM products;

      END//

      DELIMITER ;

    23.3.3 删除存储过程

      存储过程在创建之后,被保存在服务器上以供使用,直至被删除。

      删除存储过程,可使用语句:

        DROP PROCEDURE productpricing  IF EXISTS;

      注意: CALL productpricing()时需要有()符号, 删除时后面没有(),只给出存储过程名。

    23.2.4 使用参数

      CREATE PROCEDURE productpricing(

        OUT pl DECIMAL(8,2),

        OUT ph DECIMAL(8,2),

        OUT pa DECIMAL(8,2)

      )

      BEGIN

        SELECT Min(prod_price)

        INTO pl

        FROM products;

        SELECT Max(prod_price)

        INTO ph

        FROM products;

        SELECT Avg(prod_price)

        INTO pa

        FORM products;

      END;

      这个存储过程接受3个参数,每个参数必须具有指定的类型,DECIMAL(8,2)十进制。

      关键字OUT指出相应的参数用来从存储过程中传出一个值(返回给调用者)。

      MySQL支持IN(传递给存储过程)、OUT(从存储过程传出)和 INOUT(对存储过程传入和传出)类型的参数。

      为此调用这个存储过程,必须指定3个变量名。  

       CALL productpricing(@pricelow,

                @pricehigh,

                @priceaverage);

       @后面的名字,它们是存储过程将保存结果的3个变量的名字

       所有MySQL变量都必须以@开始

      为了获得3个值,可使用语句:SELECT @priceaverage, @pricelow, @priceheigh;

    23.2.5 建立智能存储过程

    23.2.6 检查存储过程

      SHOW CREATE PROCEDURE productpricing;  --显示创建一个存储过程。

      SHOW PROCEDURE STATUS; --获得包括何时、由谁创建等详细信息的存储过程列表。

24、使用游标

  24.1 游标

    游标(cursor)是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序

  可以根据需要滚动或浏览其中的数据。

  24.2 使用游标

    24.2.1 创建游标

      CREATE PROCEDURE processorders()

      BEGIN

        DECLARE ordernumbers CURSOR

        FOR 

        SELECT order_num FROM orders;

      END;

      DECLARE命名游标,并定义相应的SELECT语句,根据需要带WHERE和其他字句。

    24.2.2 打开和关闭游标

      OPEN ordernumbers;

      CLOSE ordernumbers;

    24.2.3 使用游标数据

      在一个游标被打开后,可以使用FETCH语句分别访问它的每一行,FETCH指定检索什么数据(所需的列),检索出来的数据存储在什么地方。它还向前移动游标中

    的内部行指针,使下一条FETCH语句检索下一行(不重复读取同一行)

25、触发器

  25.1 触发器

    触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句):DELETE、INSERT、UPDATE

  25.2 创建触发器

    创建触发器时,需要给出4条信息:

    (1)唯一的触发器名

    (2)触发器关联的表

    (3)触发器应该响应的活动(DELETE、INSERT、UPDATE)

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

    触发器用CREATE TRIGGER语句创建。

      CREATE TRIGGER newproduct AFTER INSERT ON products

      FOR EACH ROW SELECT 'Product added';

      BEFORE和AFTER决定之前或之后,FOR EACH ROW 定义对每个插入行执行。

    注意:(1)只有表才支持触发器,视图不支持(临时表也不支持)

       (2)触发器按每个表每个事件每次地定义,每个表每个事件每次只允许一个触发器,每个表只支持6次(DELETE、INSERT、UPDATE之前之后)。

  25.3 删除触发器

    触发器不能更新或覆盖,为了修改一个触发器,必须先删除它,然后再重新创建。

    DROP TRIGGER newproduct;

  25.4 使用触发器

    25.4.1 INSERT触发器

      INSERT触发器在INSERT语句执行之前或之后执行

      (1)在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入的行

      (2)在BEFORE INSERT触发器中,NEW中的值也可以被更新(允许更改被插入的值)

      (3)对于AUTO_INCREMENT列,NEW在INSERT执行之前包含0,在INSERT执行之后包含新的自动生成值。

      CREATE TRIGGER neworder AFTER INSERT ON orders

      FOR EACH ROW SELECT NEW.order num;

    25.4.2 DELETE触发器  

      DELETE触发器在DELETE语句执行之前或之后执行

      (1)在DELETE触发器代码内,可以引用一个名为OLD的虚拟表,访问被删除的行

      (2)OLD中的值全部都是只读的,不能更新

      CREATE TRIGGER deleteorder BEFORE DELETE ON orders

      FOR EACH ROW

      BEGIN

        INSERT INTO archive_orders(order_num, order_date, cust_id)

        VALUES(OLD.order_num, OLD.order_date,OLD.cust_id);

      ENG;

    25.4.3 UPDATE触发器

      UPDATE触发器在UPDATE语句执行之前或之后执行

      (1)在UPDATE触发器代码中,可以引用一个名为OLD的虚拟表访问以前(UPDATE语句前)的值,引用一个名为NEW的虚拟表访问新更新的值

      (2)在BEFORE UPDATE触发器中,NEW中的值可能也被更新(允许更改将要用于UPDATE语句中的值)

      (3)OLD中的值全都是只读的,不能更新

      CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors

      FOR EACH ROW SET NEW.vend_state=Upper(NEW.vend_state);

26、管理事物处理

  26.1 事物处理

    并非所有的引擎都支持事物处理。

    事物处理是一种机制,用来管理必须成批执行的MySQL操作,以保证数据库不包含不完整的操作结果。利用事物处理,可以保证一组操作不会中途停止,它们或

  者作为整体执行,或者完全不执行(除非明确指示)。如果没有错误发生,整组语句提交给(写道)数据库表。如果发生错误,则进行回退(撤销)以恢复数据库到

  某个已知且安全的状态。

    事物(transaction)指一组SQL语句

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

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

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

  26.2 控制事物处理

    管理事物处理的关键在于将SQL语句组分解为逻辑快,并明确规定数据何时应该回退,何时不应该回退

    MySQL使用语句标识事物的开始:
      START TRANSACTION

    26.2.1 使用ROLLBACK

      MySQL的ROLLBACK命令用来回退(撤销)语句

      SELECT * FROM ordertotals;  --验证该表不为空

      START TRANSACTION;    --开始一个事物

      DELETE FROM ordertotals;   --删除所有行

      SELECT * FROM ordertotals;   --检查是否空

      ROLLBACK; --回退开始的所有事物

      SELECT * FROM ordertotals;  --验证不为空

      注意:不能回退CREATER或DROP,SELECT语句

    26.2.2 使用COMMIT

      事物处理模块中,提交不会隐含地进行。为了明确的提交,使用COMMIT语句。

      START TRANSACTION;

      DELETE FROM orderitems WHERE order_num=20010;

      DELETE FROM orders WHERE order_num=20010;

      COMMIT;

      提示:最后的COMMIT语句仅在不出错时写出更改。

    26.2.3 使用保留点

      为了支持回退部分事物处理,必须能在事物处理快中合适的位置放置占位符,当需要回退时,可以回退到某个占位符

      创建保留点

      SAVEPOINT delete1;  --每个保留点都取标识它的唯一名字

      为了回退到保留点

      ROLLBACK TO delete1;

    26.2.4 更改默认的提交行为

      指示MySQL不自动提交更改,需要使用以下语句:

      SET autocommit=0;  --autocommit标志决定是否自动提交更改

27、安全管理

  27.1 访问控制

  27.2 管理用户

    MySQL用户账号和信息存储在名为mysql的MySQL数据库中。

    获取所有用户账号列表时

    USE mysql;

    SELECT user FROM user;

    mysql数据库有一个名为user的表,它包含所有用户账号。user表有一个名为user的列,它存储用户登陆名。

    27.2.1 创建用户账号

      创建一个新用户账号,使用CREATE USER语句

      CREATE USER ben IDENTIFIED BY 'p@$$wOrd';

      为重新命名一个用户账号,使用RENAME USER语句

      RENAME USER ben TO bforta;

    27.2.2 删除用户账号

      删除一个用户账号(以及相关的权限),使用DROP USER语句

      DROP USER bforta;

    27.2.3 设置访问权限

      新创建的用户账号没有访问权限,它们能登陆mysql,但不能看到数据,不能执行任何操作数据库操作

      为看到赋予用户账号的权限,使用SHOW GRANTS FOR

      SHOW GRANTS FOR bforta;

      为设置权限,使用GRANT语句,至少给出以下信息:

        (1)要授予的权限

        (2)被授予访问权限的数据库或表

        (3)用户名

      GRANT的用法:

        GRANT SELECT ON crashcourse.* TO bforta;  --此GRANT允许用户在crashcourse.*(crashcourse数据库的所有表)上使用SELECT

      SHOW GRANTS反映这个更改:

        SHOW GRANTS FOR bforta;

      GRANT的反操作为REVOKE,用它来撤销特定的权限。

      GRANT和REVOKE可在几个层次上控制访问权限:
        (1)整个服务器,使用GRANT ALL和REVOKE ALL

        (2)整个数据库,使用ON database.*

        (3)特定的表,使用ON database.table

        (4)特定的列

        (5)特定的存储过程

      授予权限时,可通过列出个权限并用逗号分隔,将多条GRANT语句串在一起

        GRANT SELECT,INSERT ON crashcourse.* TO bforta

    27.2.4 更改口令

      更改用户口令,可使用SET PASSWORD语句

        SELECT PASSWORD FOR bforta=Password('n3w p@$$wOrd');  --新口令必须传递到Password()函数进行加密

      其他

        SET PASSWORD =Password('n3w p@$$wOrd'); --在不指定用户名时,SET PASSWORD更新当前登陆用户的口令

          

    27.2.5 权限表

      

 28、数据类型

  

   

     

   

    

    

      

原文地址:https://www.cnblogs.com/nuochengze/p/12290992.html