MySQL必知必会学习笔记

MySQL必知必会

1MySQL简介

数据库:保存有组织数据的容器;

数据库管理系统(DBMS):使用数据库管理软件创建和操作数据库;

表(table):数据库中保存数据的特定结构化的清单;

列(column):表中的字段,一张表有一个或多个列组成;

数据类型(datatype):字段允许所保存的数据的类型;

行(row):每一行都是一笔记录数据,也称为record;

主键(primary key):每一行都有一个或一组字段区分唯一行,这一个或一组字段称为主键;

主键满足条件:任意两行数据不具有相同的主键,每行必须有一个主键值,不能为NULL;

多列作为主键时,某列值可以重复,但是所有列值的组合必须是唯一的;

如何更好定义主键?

不更新主键列值,不重用主键列值,不把要更新的列作为主键;

SQL(结构化查询语言):Structured Query Language。

MySQL:是一种DBMS,开源,免费,简单,易用;

DBMS分类:1.基于共享文件系统的DBMS,例如:Microsoft Access,FileMaker;

2.基于客户机-服务器的DBMS,例如:MySQL,Oracle;

MySQL执行工具

Windows安装MySQL后,通过cmd,执行命令行

mysql命令行:

  1. 输入mysql

2.MySQL命令用“;”或“\g”结束,换行不结束;

示例:show databases;

3.输入“quit”或“exit”退出;

4.输入“help”或“\h”获取帮助;

MySQL Administrator:MySQL图形交互客户机;

MySQL Query Browser:MySQL图形交互客户机;

数据库相关命令行:

  1. show databases,显示所有数据库;
  2. use test,访问database:test;

  1. show tables, 显示数据库下所有table;

  1. show columns from test,显示test表所有列;

或者使用 describe test;

  1. show status,显示服务器状态;
  2. show grants,显示授权用户;
  3. show errors或show warnings,显示服务器错误或警告信息;
  4. 使用root账号登陆,查看用户表信息;

命令:mysql -u root -p

命令:show databases,查看所有数据库;

命令:use mysql,操作mysql数据库;

2MySQL查询数据

查询单列值

#2.1查询单个栏位

SELECT prod_name FROM products;

注意:查询语句会返回表products所有prod_name;

查询多列值

#2.1查询多个栏位

SELECT prod_id,prod_name,prod_price FROM products;

查询所有列值

#2.1查询所有栏位

SELECT * FROM products;

查询某列非重复值

#2.1查询所有非重复供应商id

SELECT DISTINCT vend_id FROM products;

注意:当有多列时,使用Distinct会比较所有列值;

查询限定行数数据

#2.1查询2行数据

SELECT * FROM products LIMIT 2;

#2.1查询指定行数据

#从第3行开始,查询1行数据

SELECT * FROM products LIMIT 2,1;

#2.1避免误会,指定limit,offset

SELECT * FROM products LIMIT 1 OFFSET 2 ;

3MySQL排序数据

MySQL排序数据使用Order By子句。

使用查询的列排序

#3.1排序

#使用查询的列排序

SELECT prod_name FROM products ORDER BY prod_name;

注意:字符串类型列按照字符顺序大小排序

使用非查询的列排序

#使用非查询的列排序

SELECT prod_name FROM products ORDER BY prod_price;

注意:这里根据产品价格对查询的产品名进行排序;

多列排序

#多列排序

SELECT prod_id,prod_name FROM products ORDER BY prod_id,prod_name;

指定排序方向

#指定排序方向

SELECT prod_id,prod_name FROM products ORDER BY prod_id DESC,prod_price ASC;

注意:DESC表示降序,ASC表示升序,默认ASC可以不写;

4MySQL过滤数据

MySQL使用Where子句过滤数据

操作符:>,<,<=,>=,=,!=,<>,BETWEEN

筛选数据

#4.1筛选数据

#筛选产品价格大于20的产品

SELECT prod_name FROM products WHERE prod_price > 20;

#筛选产品价格在5~10之间的产品

SELECT prod_name FROM products WHERE prod_price BETWEEN 5 AND 10;

空值筛选

#空值筛选

SELECT cust_name FROM customers WHERE cust_email IS NULL;

AND操作符筛选

AND可以连接多个筛选条件,筛选出符合所有条件的数据行。

#AND操作符

SELECT prod_name FROM products WHERE vend_id = '1001' AND prod_price > 10;

OR操作符筛选

OR可以连接多个筛选条件,只要数据行符合某一个筛选条件就可以筛选出来。

#OR操作符

SELECT prod_name FROM products WHERE vend_id = '1001' OR prod_price < 6;

IN操作符筛选

IN执行速度比OR更快,指定值清单,语句更清晰。

#IN操作符

SELECT vend_id,prod_name FROM products WHERE vend_id IN ('1001','1002');

NOT操作符筛选

使用NOT可以将IN,BETWEEN,EXISTS子句结果取反。

#NOT操作符

SELECT vend_id,prod_name FROM products WHERE  vend_id NOT IN ('1001','1002');

LIKE通配符筛选

%表示任何字符出现任意次数。

_表示任意一个字符。

#LIKE通配符

SELECT prod_name FROM products WHERE prod_desc LIKE 'Jet%'

返回产品描述Jet开头的产品名

#_匹配单个字符

SELECT prod_id,prod_name FROM products WHERE prod_id LIKE 'TNT_';

返回产品ID:TNT开头,并且字符长度为4的产品

正则表达式筛选

使用正则表达式匹配指定字符进行数据筛选。

LIKE和REGEXP非常类似,但是LIKE是对完整列值进行匹配(不使用通配符情况),而REGEXP对列的值进行部分匹配,只要出现部分就算匹配。

#正则表达式筛选

SELECT prod_name FROM products WHERE prod_desc REGEXP 'Jet';

#筛选大小写区分

SELECT  prod_name FROM products WHERE prod_desc REGEXP BINARY 'jet';

注意:默认MySQL不区分大小写,使用REGEXP BINARY区分大小写。

#筛选多个子字符串

SELECT prod_name FROM products WHERE prod_desc REGEXP '1|5';

注意:这里筛选产品描述中包含1或者5的产品

#匹配动态字符串,一部分固定,一部分变化

SELECT prod_name FROM products WHERE prod_desc REGEXP '[1-9] ton';

注意:这里匹配”1 ton”到”9 ton”,产品描述包含这些子字符串的产品

#. _特殊字符

#. 正则中表示任意字符

#_ 正则中表示任意一个字符

#如果要匹配.需要使用\\转义

SELECT prod_name FROM products WHERE prod_desc REGEXP '\\.';

字符集定义:

#字符集

SELECT prod_name FROM products WHERE prod_desc REGEXP 's[:alnum:]';

使用元字符进行匹配数目控制:

#控制匹配数量

SELECT prod_name,prod_desc FROM products WHERE prod_desc REGEXP '[[:digit:]]{4}';

使用定位符,对字符匹配位置进行控制:

#定位符位置匹配

SELECT prod_name,prod_desc FROM products WHERE prod_desc REGEXP '^[[:digit:]]|)$';

表示获取产品描述以数字开头,或者产品描述以)结尾的产品

5MySQL计算字段

当存储的字段是需要进行转换,计算或格式化的数据时,需要使用计算字段。

连接计算&算术运算

大多数DBMS使用“+”或者“||”连接字段,但是MySQL使用concat()函数进行字段拼接。

示例:

#5.1计算字段

#字段连接,返回拼接后字段

SELECT CONCAT(vend_name,'(',vend_country,')') AS vend_info FROM vendors;

#字段算术计算

#将每个item数量*单价,计算总价

SELECT prod_id,item_price,quantity,item_price * quantity AS total_price FROM orderitems;

文本函数运算

#函数计算

#大小写转换

SELECT vend_name,UPPER(vend_name) AS up_vend_name  FROM vendors;

SELECT vend_name,LOWER(vend_name) AS low_vend_name FROM vendors;

#返回字符串左或右字符字串

SELECT LEFT(vend_name,10) FROM vendors;

SELECT RIGHT(vend_name,10) FROM vendors;

#返回字符串长度

SELECT vend_name,LENGTH(vend_name) FROM vendors;

#返回字符串子串位置,从1开始计算

SELECT vend_name,LOCATE('n',vend_name) FROM vendors;

#去除字符串左右空格

SELECT vend_name,LTRIM(vend_name) FROM vendors;

SELECT vend_name,RTRIM(vend_name) FROM vendors;

SELECT vend_name,TRIM(vend_name) FROM vendors;

#返回字符串字串

#substring(string,start,length)

SELECT vend_name,SUBSTRING(vend_name,1,5) FROM vendors;

#返回发音类似的字符串

#这里可以返回Jet Set

SELECT vend_name FROM vendors

WHERE SOUNDEX(vend_name) = SOUNDEX('Jit Set')

日期处理函数

#日期函数

#DATE日期

SELECT * FROM orders

WHERE DATE(order_date) = '2005-09-01';

#年月日函数

SELECT * FROM orders

WHERE YEAR(order_date) = 2005

AND MONTH(order_date) = 9

AND DAY(order_date) = 1

#时分秒函数

SELECT HOUR(NOW()),

MINUTE(NOW()),

SECOND(NOW())

FROM orders LIMIT 1;

#日期周几

#星期日为1,星期一为2

SELECT NOW(),DAYOFWEEK(NOW()) FROM orders LIMIT 1;

#当前日期时间

SELECT CURDATE(),CURTIME(),NOW() FROM orders LIMIT 1;

#日期计算

SELECT ADDDATE(CURDATE(),10) FROM orders LIMIT 1;

SELECT ADDTIME('10:10:20',-60*10) FROM orders LIMIT 1;

#日期之差

SELECT DATEDIFF('2005-10-04','2010-12-05') FROM orders LIMIT 1;

#灵活计算日期

#INTERVAL单位:

#MICROSECOND:微秒

#SECOND:

#MINUTE:分钟

#HOUR:小时

#DAY:

#WEEK:

#MONTH:

#QUARTER:季度

#YEAR:

SELECT DATE_ADD(NOW(),INTERVAL -25 HOUR) FROM orders LIMIT 1;

数值处理函数

#数值处理函数

#绝对值

SELECT ABS(-100) FROM orders LIMIT 1;

#余弦值

SELECT COS(1) FROM orders LIMIT 1;

#正弦值

SELECT SIN(1) FROM orders LIMIT 1;

#正切值

SELECT TAN(1) FROM orders LIMIT 1;

#随机数

SELECT RAND() FROM orders LIMIT 1;

#圆周率

SELECT PI() FROM orders LIMIT 1;

#平方根

SELECT SQRT(2) FROM orders LIMIT 1;

#e指数值

SELECT EXP(1) FROM orders LIMIT 1;

#余数10%4

SELECT MOD(10,4) FROM orders LIMIT 1;

聚集函数

AVG函数会忽略NULL值行;

COUNT(*)函数不会忽略NULL值行;

COUNT(column)函数会忽略NULL值行;

MAX函数忽略NULL值行;

MIN函数忽略NULL值行;

SUM函数忽略NULL值行;

#汇总函数

#均值

SELECT AVG(prod_price) AS avg_price FROM products;

#计算列数

SELECT COUNT(*) FROM products;

#最大值

SELECT MAX(prod_price) AS max_price FROM products;

#最小值

SELECT MIN(prod_price) AS min_price FROM products;

#加总

SELECT SUM(prod_price) AS sum_price FROM products;

#使用DISTINCT,汇总不同行

SELECT COUNT(DISTINCT prod_id),COUNT(*) FROM productnotes;

6MySQL数据分组

使用GROUP BY实现数据分组

#数据分组

#获取每个customer订单数

SELECT cust_id,COUNT(cust_id) FROM orders

GROUP BY cust_id;

#WITH ROLLUP

#返回每个分组统计值,以及汇总的统计值

SELECT cust_id,COUNT(cust_id) FROM orders

GROUP BY cust_id

WITH ROLLUP;

使用HAVING子句,对分组汇总数据进行筛选

#筛选订单数大于2的客户id

SELECT cust_id,COUNT(cust_id) FROM orders

GROUP BY cust_id

HAVING COUNT(cust_id) > 1;

注意:WHERE和HAVING区别在于WHERE在分组前过滤,HAVING在分组统计后过滤;

SELECT中各种子句执行顺序:

SELECT:查询语句

FROM:选择查询表

WHERE:行级过滤

GROUP BY:分组

HAVING:分组过滤

ORDER BY:排序

LIMIT:限制行数

7MySQL子查询

MySQL中不同信息存储在不同表中,当要查询复合信息时,需要用到子查询。子查询总是从里到外执行的。

示例:

查询购买了产品ID为’FB’的客户名称

#子查询

#分步执行

#获取订单号:2000520009

SELECT order_num FROM orderitems

    WHERE prod_id = 'FB')

#根据订单号获取订单对应客户id

SELECT cust_id FROM orders

WHERE order_num IN (20005,20009);

#获取客户信息

SELECT cust_name FROM customers

WHERE cust_id = 10001;

#使用子查询

SELECT cust_name FROM customers

WHERE cust_id IN(

    SELECT cust_id FROM orders

    WHERE order_num IN (

        SELECT order_num FROM orderitems

            WHERE prod_id = 'FB')

        );

#将子查询作为计算字段

SELECT cust_name,(

    SELECT COUNT(*)

    FROM orders

    WHERE cust_id = customers.cust_id) AS order_num

    FROM customers;

8MySQL连接查询

MySQL使用JOIN进行连表查询。通过JOIN可以将多个Table信息进行连接查询。

#内连接查询

#查询供应商名称,地址,产品id,产品描述

SELECT

vend_name,

vend_address,

prod_id,prod_desc

FROM vendors

INNER JOIN products

WHERE vendors.vend_id  = products.vend_id ;

自联结

使用别名简化表名

#自联结

#查找产品“FB"的供应商提供的所有产品id,产品名

SELECT

a.prod_id,

a.prod_name

FROM

products AS a

INNER JOIN

products AS b

WHERE a.vend_id = b.vend_id

AND b.prod_id = 'FB'

外连接

左外联和右外联

左外联:保留左边表所有数据

右外联:保留右边表所有数据

#左外联

#统计所有客户各自订单数

SELECT

a.cust_name,

a.cust_id,

COUNT(b.order_num) AS n_order

FROM customers AS a

LEFT OUTER JOIN orders AS b

ON a.cust_id = b.cust_id

GROUP BY a.cust_id;

UNION合并查询:

UNION必须由两条或以上SELECT语句组成。

UNION的语句查询列必须相同。

UNION会自动去除重复行。

UNION ALL会保留所有行。

#组合查询

#查询供应商id:1001,1002数据

#查询产品ID’Safe'数据

#UNION合并输出

SELECT prod_id,prod_name,vend_id

FROM products

WHERE vend_id IN (1001,1002)

UNION

SELECT prod_id,prod_name,vend_id

FROM products

WHERE prod_name = 'Safe';

9MySQL全文搜索

MySQL并非所有引擎支持全文搜索,只有MyISAM支持全文搜索。InnoDB不支持全文搜索。

示例表productnotes使用MyISAM引擎。

如何启用全文索引支持?

通过CREATE TABLE,FULLTEXT指定支持全文索引支持的数据列

注意:一般在导入数据时不要启用FULLTEXT,需要在导入数据后在更新表启用FULLTEXT

###########################

# Create productnotes table

###########################

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;

使用Match()和Against()进行全文搜索

#全文搜索

SELECT note_text

FROM

productnotes

WHERE

MATCH(note_text)

AGAINST('heavy');

实现方式:将查询字符串匹配程度作为计算列note_rank,没有匹配的值为0,然后筛除note_rank为0的数据,然后对note_rank排序。

#对全文搜索匹配程度排序

#最先找到匹配文本的优先度更高

SELECT

note_text,

MATCH(note_text) AGAINST('heavy') AS note_rank

FROM

productnotes

WHERE

MATCH(note_text)

AGAINST('heavy');

查询拓展:

当‘heavy’直接查询到是权重最高的;

出现‘heavy‘所在行的其他字串在其他地方出现,权重变低;

#查询拓展

SELECT

note_text

FROM

productnotes

WHERE

MATCH(note_text)

AGAINST('heavy' WITH QUERY EXPANSION);

布尔文本搜索:

使用IN BOOLEAN MODE进行布尔文本搜索;

没有FULLTEXT索引,也可以使用布尔文本搜索;

示例1:包含多个单词‘heavy’,’flying’

#必须包含heavy flying

SELECT

note_text

FROM

productnotes

WHERE

MATCH(note_text)

AGAINST('+heavy +flying' IN BOOLEAN MODE);

示例2:包含多个单词中某一个

#包含heavy,stars,Item中某一个单词

SELECT

note_text

FROM productnotes

WHERE

MATCH(note_text)

AGAINST('heavy stars Item' IN BOOLEAN MODE);

示例3:包含短语,整个匹配才返回

#包含短语

SELECT

note_text

FROM productnotes

WHERE

MATCH(note_text)

AGAINST('"Please note"' IN BOOLEAN MODE);

示例4:排除单词

#排除单词

SELECT

note_text

FROM productnotes

WHERE

MATCH(note_text)

AGAINST('rabbit -food -heavy' IN BOOLEAN MODE);

10MySQL数据插入

MySQL使用INSERT INTO执行数据插入。

#插入语句

#这种方式不推荐

#当表结构改变时,这种语句就会报错

#指定对应列每个值

INSERT INTO

customers

VALUES(

NULL,

'tomas',

'445 street',

'Londom',

'BA',

'44443',

'USA',

NULL,

NULL

)

#指定列名对应每个列值

#不需要强制给值的列可以不用

INSERT INTO

customers(

cust_name,

cust_address,

cust_city,

cust_state,

cust_zip,

cust_country

)VALUES(

'tomas',

'445 street',

'Londom',

'BA',

'44443',

'USA'

)

插入多条数据语句:

#插入多条语句

INSERT INTO

customers(

cust_name,

cust_address,

cust_city,

cust_state,

cust_zip,

cust_country

)VALUES(

'tom',

'225 street',

'Londom',

'BA',

'44443',

'USA'

),(

'tian',

'425 street',

'Afeidil',

'CA',

'44423',

'USA'

),(

'jim',

'485 street',

'dayrain',

'CA',

'43323',

'USA'

);

插入查询的数据:

#创建一个新表

#插入筛选后的数据

CREATE TABLE custnew

(

  cust_id      int       NOT NULL AUTO_INCREMENT,

  cust_name    char(50NOT NULL ,

  cust_address char(50NULL ,

  cust_city    char(50NULL ,

  cust_state   char(5)   NULL ,

  cust_zip     char(10NULL ,

  cust_country char(50NULL ,

  cust_contact char(50NULL ,

  cust_email   char(255) NULL ,

  PRIMARY KEY (cust_id)

) ENGINE=InnoDB;

#cust_concactnull的数据行插入新表

INSERT INTO

custnew(

cust_name,

cust_address,

cust_city,

cust_state,

cust_zip,

cust_country

)SELECT

cust_name,

cust_address,

cust_city,

cust_state,

cust_zip,

cust_country

FROM customers

WHERE cust_contact IS NULL;

注意:INSERT INTO对应列名可以和SELECT语句中列名不一样,他们是通过位置对应的。

11MySQL数据更新、删除

MySQL使用UPDATE进行数据更新。

示例:

#更新语句

#1.更新单个栏位

UPDATE customers

SET cust_email = 'Coyot@33.com'

WHERE cust_id = 10002;

#2.更新多个栏位

UPDATE customers

SET cust_name = CONCAT(cust_name,'(flag)'),

    cust_email = 'test@33.com'

WHERE cust_id = 10005;

#3.更新多行时,当某一行出错时,忽略继续更新

UPDATE IGNORE products

SET prod_price = prod_price + 10;

MySQL使用DELETE删除数据。

示例:

#删除语句

#删除特定行

DELETE FROM customers

WHERE cust_id = 10009;

#删除所有行

DELETE FROM customers;

12MySQL表的操作

MySQL不仅可以操作表数据,还可以操作表。

可以使用交互式创建和管理表的工具;

也可以直接使用SQL语句创建表;

创建表

示例:

#创建Table

#当创建tablestable名称在当前数据库中必须唯一

#可以使用IF NOT EXISTS,如果table不存在才创建

CREATE TABLE IF NOT EXISTS table1

(

id int  NOT NULL AUTO_INCREMENT,

name char(50) NOT NULL,

address char(255) NULL,

notes text NULL,

PRIMARY KEY (id)

) ENGINE = InnoDB;

#创建table

#使用DEFAULT设置默认值,当插入数据时,没有设置值时使用默认值

CREATE TABLE IF NOT EXISTS table2

(

id int  NOT NULL AUTO_INCREMENT,

name char(50) NOT NULL,

address char(255) NULL,

relation text NULL,

account float DEFAULT 0.0,

PRIMARY KEY (id)

) ENGINE = InnoDB;

数据库引擎类型

InnoDB:可靠的事务处理引擎,不支持全文搜索

MEMORY:和MyISAM,数据存储在内存,速度更快,适合临时表;

MyISAM:高性能引擎,支持全文搜索,不支持事务处理;

不同的表可以使用不同的引擎。但是有外键关系的表之间不能使用不同引擎。

表的更新删除

示例:

#更新表

#添加列

ALTER TABLE table1

ADD age int DEFAULT 0;

#添加多列

ALTER TABLE table1

ADD flag1 char(1),

ADD flag2 char(1);

#删除列

ALTER TABLE table1

DROP COLUMN flag2;

#删除多列

ALTER TABLE table1

DROP COLUMN flag1,

DROP COLUMN age;

#删除Table

#注意:此操作彻底删除table,不能撤销

DROP TABLE table2;

表添加删除外键

#添加外键

ALTER TABLE table2

ADD CONSTRAINT fk_t1_t2

FOREIGN KEY (t1_id) REFERENCES table1(id);

#直接删除外键

ALTER TABLE table2

DROP FOREIGN KEY fk_t1_t2;

表的重命名

使用RENAME TABLE进行表的重命名。

#重命名Table

RENAME TABLE table1 TO t_table1;

#重命名多个table

RENAME TABLE table1 TO t_table1,

             table2 TO t_table2;

注意:复杂表结构更改一般步骤

创建新的列顺序的新表;

使用INSERT SELECT语句复制数据到新表;

检查新表数据;

更改旧表名称;

更改新表名到旧表名;

根据需要创建触发器、存储过程、索引外键;

13MySQL视图操作

MySQL数据库中不同数据存储在不同表中,但是往往业务需要返回的时多个表的联合数据。那么将常用的混合表数据做成视图,简化查询操作。

视图的作用:

1.重用SQL语句;

2.简化复杂的SQL语句;

3.使用表部分数据;

4.保护数据;

5.更改数据格式和表示;

创建视图

#创建视图

#客户购买产品视图

CREATE VIEW cust_order_prod AS

SELECT

cust_name,

prod_name,

prod_price,

quantity

FROM customers,orders,orderitems,products

WHERE customers.cust_id = orders.cust_id

AND orders.order_num = orderitems.order_num

AND orderitems.prod_id = products.prod_id ;

#查询视图

SELECT * FROM cust_order_prod;

使用视图筛选掉部分数据:

#使用视图筛选数据

CREATE VIEW cust_mail_not_null AS

SELECT * FROM customers

WHERE customers.cust_email  IS NOT NULL;

#查询视图

SELECT * FROM cust_mail_not_null;

使用视图创建计算列

#使用视图计算列

CREATE VIEW order_calculate AS

SELECT *,

quantity * item_price AS sum_price

FROM orderitems;

#查询视图

SELECT * FROM order_calculate;

视图更新或删除:

#查看view创建的语句

SHOW CREATE VIEW cust_mail_not_null;

#删除视图

DROP VIEW cust_mail_not_null;

#创建或替换视图

CREATE OR REPLACE VIEW cust_mail_not_null AS

SELECT * FROM customers

WHERE customers.cust_email  IS NOT NULL;

14MySQL存储过程操作

存储过程:是一系列SQL语句的集合,为了实现满足某个或多个业务流程对数据库数据进行操作。

创建存储过程:

#创建存储过程

#创建procedure

CREATE PROCEDURE pro_order_total()

BEGIN

    SELECT

    cust_name,

    SUM(quantity) AS total_quan

    FROM cust_order_prod

    GROUP BY cust_name;

END;

#调用存储过程

CALL pro_order_total();

删除存储过程:

#删除存储过程

DROP PROCEDURE pro_order_total;

创建带参数的存储过程:

#使用有参数的存储过程

CREATE PROCEDURE pro_order_total1(

IN i_name char(50),

OUT o_quan decimal(8,2)

)

BEGIN

    SELECT

    SUM(quantity) AS total_quan

    FROM cust_order_prod

    WHERE cust_name = i_name

    GROUP BY cust_name

    INTO o_quan;

END;

#调用存储过程

CALL pro_order_total1('Coyote Inc.',@total);

#查询返回值

SELECT @total;

15MySQL游标操作

当我们需要在检索数据前进或后退几行是,需要使用MySQL的游标。

在MySQL中,游标只能在存储过程或函数中使用。

#游标使用示例

#只能在存储过程或函数中使用

CREATE PROCEDURE pro_cursor()

BEGIN

    #定义局部变量

    DECLARE total DECIMAL(8,2);

    DECLARE name CHAR(50);

    DECLARE v_rep BOOLEAN DEFAULT 0;

    #游标

    DECLARE custname CURSOR FOR

    SELECT DISTINCT cust_name FROM cust_order_prod;

   

    #定义循环结束响应条件

    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET v_rep = 1;

    #创建table存储结果

    CREATE TABLE IF NOT EXISTS cust_total(

        cust_name char(50),

        total decimal(8,2)

    );

   

    #打开游标

    OPEN custname;

   

    #循环处理

    REPEAT

        #逐行访问name

        FETCH custname INTO name;

       

        #调用procedure获取total数量

        CALL pro_order_total1(name,total);

       

        #结果插入数据表

        INSERT INTO cust_total(cust_name,total)VALUES(name,total);

       

        #循环结束条件

        UNTIL v_rep

    END REPEAT;

    #关闭游标

    CLOSE custname;

   

END;

#调用过程

CALL pro_cursor();

16MySQL触发器操作

触发器:当执行DELETE,UPDATE,INSERT操作时,MySQL自动执行一句或一组SQL语句。

只有表支持触发器;

每个表最多支持6个触发器;

INSERT,UPDATE,DELETE之前或之后触发;

示例:

#创建log

CREATE TABLE t_log(

id int NOT NULL AUTO_INCREMENT,

t_name char(50) NOT NULL,

opt char(100) NOT NULL,

op_date date NOT NULL,

op_time time NOT NULL,

PRIMARY KEY(id)

)ENGINE = InnoDB;

#创建触发器

CREATE TRIGGER newcustomer

AFTER INSERT ON customers

FOR EACH ROW

INSERT INTO t_log(t_name,opt,op_date,op_time)

VALUES('customers','INSERT',CURDATE(),CURTIME());

CREATE TRIGGER changecustomer

AFTER UPDATE ON customers

FOR EACH ROW INSERT INTO t_log(t_name,opt,op_date,op_time)

VALUES('customers','UPDATE',CURDATE(),CURTIME());

CREATE TRIGGER deletecustomer

AFTER DELETE ON customers

FOR EACH ROW INSERT INTO t_log(t_name,opt,op_date,op_time)

VALUES('customers','DELETE',CURDATE(),CURTIME());

#删除触发器

DROP TRIGGER newcustomer;

DROP TRIGGER changecustomer;

DROP TRIGGER deletecustomer;

INSERT触发器

可以使用变量NEW操作被插入的数据;

在BEFORE触发器中,可以更新NEW中被插入的值;

单AUTO_INCREMENT的列,在BEFORE触发器中是0,AFTER触发器中是新的生成值;

BEFORE触发器主要用于数据清洗,数据验证;

AFTER触发器主要用于保存日志等;

#INSERT

#BEFORE触发器

#插入时如果邮件地址为空,更新为none

CREATE TRIGGER insert_before_customer

BEFORE INSERT ON customers

FOR EACH ROW

BEGIN

    DECLARE v_email char(255);

    SELECT NEW.cust_email INTO v_email;

    IF v_email IS NULL THEN

        SET NEW.cust_email = 'none';

    END IF;

END;

NEW可以直接使用,不用定义变量

#INSERT

#BEFORE触发器

#插入时如果邮件地址为空,更新为none

CREATE TRIGGER insert_before_customer

BEFORE INSERT ON customers

FOR EACH ROW

BEGIN

    #DECLARE v_email char(255);

    #SELECT  NEW.cust_email INTO v_email;

    IF NEW.cust_email IS NULL THEN

        SET NEW.cust_email = 'none';

    END IF;

END;

DELETE触发器

可以使用OLD访问被删除的数据;

#创建log表记录删除customer

CREATE TABLE IF NOT EXISTS log_del_cus(

    id int NOT NULL AUTO_INCREMENT,

    cust_id int,

    cust_name char(50),

    cust_address char(50),

    cust_city char(50),

    op_date date NOT NULL,

    op_time time NOT NULL,

    PRIMARY KEY(id)

)ENGINE = InnoDB;

#DELETE

#BEFORE触发器

CREATE TRIGGER delete_before_customer

BEFORE DELETE ON customers

FOR EACH ROW

BEGIN  

    INSERT INTO log_del_cus(

    cust_id,

    cust_name,

    cust_address,

    cust_city,

    op_date,

    op_time)

    VALUES(

    OLD.cust_id,

    OLD.cust_name,

    OLD.cust_address,

    OLD.cust_city,

    CURDATE(),

    CURTIME());

END;

#测试删除数据

DELETE FROM customers

WHERE cust_name = 'Ling';

UPDATE触发器

可以使用OLD访问更新前数据;

可以使用NEW访问更新后数据;

NEW中数据可以被更新;

OLD中数据只可以被访问;

示例:

#UPDATE

#BEFORE触发器

#固定cust_name首字母大写

CREATE TRIGGER update_befor_customer

BEFORE UPDATE ON customers

FOR EACH ROW

BEGIN

    SET NEW.cust_name = CONCAT(

        UPPER(SUBSTRING(NEW.cust_name,1,1)),

        SUBSTRING(NEW.cust_name,2)

        );

END;

#执行更新

UPDATE customers

SET cust_name = 'ling zi'

WHERE cust_name = 'tom'

注意:触发器不支持CALL存储过程,只能将整个存储过程语句copy到触发器语句中。

17MySQL事务操作

MySQL使用ROLLBACK,COMMIT来管理事务。

事务处理是一种机制,用来保证业务过程中,一些必须成批执行的MySQL操作。保证数据库数据完整性。

事务:一组SQL语句;

回退:ROLLBACK,撤销SQL语句;

提交:COMMIT,将为存储的SQL语句结果执行写入数据库;

保留点:SAVEPOINT,事务处理中,临时占位符,可以回退到保留点,不回退整个事务;

事务只能管理UPDATE,INSERT,DELETE操作,不能影响SELECT;

事务也不能回退CREATE,DROP操作;

示例:

#事务处理

#事务开始,一旦COMMIT,ROLLBACK事务结束

SELECT * FROM t_log;

START TRANSACTION;

DELETE FROM t_log;

SELECT * FROM t_log;

ROLLBACK;

SELECT * FROM t_log;

查询t_log表,显示有数据;

Start transaction,开始事务;

Delete删除t_log表数据;

再次查询t_log表,显示没有数据;

执行rollback,回退;

再次查询t_log表,显示有数据;

COMMIT提交事务:

#提交事务

START TRANSACTION

DELETE FROM table2;

DELETE FROM table1;

COMMIT;

SAVEPOINT保留点:

保留点可以定义多个,灵活决定事务执行过程。

保留点在事务COMMIT,ROLLBACK后,自动释放,也可以通过RELEASE SAVEPOINT释放。

#保留点

SELECT * FROM custnew WHERE cust_id = 1;

#开始事务

START TRANSACTION;

UPDATE custnew

SET cust_city = 'sanfi'

WHERE cust_id = 1;

#查看数据

SELECT * FROM custnew WHERE cust_id = 1;

#定义保留点

SAVEPOINT update1;

#更新语句

UPDATE custnew

SET cust_city = 'roll'

WHERE cust_id = 1;

#查看数据

SELECT * FROM custnew WHERE cust_id = 1;

#回滚到保留点

ROLLBACK TO update1;

#查看数据

SELECT * FROM custnew WHERE cust_id = 1;

#释放保留点

RELEASE SAVEPOINT update1;

MySQL更改默认提交模式

#设置自动提交

#autocommit=0关闭自动提交

SET autocommit = 1;

18MySQL全球化本地化

如何查看MySQL支持的字符集

#MySQL字符集

SHOW CHARACTER SET;

如何查看MySQL校对?

校对:规定字符如何比较的指令;

某些字符集对应的校对可能有多个,default表明默认使用的collation。

创建数据库时可以指定使用的字符串和校对;

#查看字符集校对

SHOW VARIABLES LIKE 'character%';

SHOW VARIABLES LIKE 'collation%';

创建Table时指定字符集和校对

示例:

#创建Table时指定字符集,校对

CREATE TABLE table3(

    id int NOT NULL AUTO_INCREMENT,

    name char(50),

    PRIMARY KEY(id)

)DEFAULT CHARACTER SET utf8

COLLATE utf8_general_ci;

查询时可以指定校对

#查询时指定使用指定校对

SELECT * FROM vendors

ORDER BY vend_name COLLATE utf8_general_ci;

19MySQL安全管理

数据库包含许多关键业务数据,为确保数据安全以及完整需要对数据库用户进行访问控制和用户权限管理。

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

示例:

#使用MySQL数据库

#查看用户信息

USE mysql;

SELECT * FROM user;

创建用户账号

使用CREATE USER创建用户账号;

使用IDENTIFIED BY设置用户密码;

可以看到创建出来的用户Host栏位为%,这里值任何IP的主机都可以通过user_select和密码连接数据库。

#创建用户账号

#使用IDENTIFIED BY指定密码

CREATE USER user_select IDENTIFIED BY 'user_select123';

重命名用户账号

RENAME USER重命名用户账号

#重命名用户账户名

RENAME USER user_select TO userSelect;

删除用户账号

使用DROP USER删除用户账号

#删除用户账号

DROP USER userSelect;

设置用户权限

设置用户权限前,需要查看用户所拥有权限

GRANT USAGE ON *.* 表示用户没有任何权限

#查看用户权限

SHOW GRANTS FOR userSelect;

#设置用户权限

#赋予数据库crashcorse所有表查询权限

GRANT SELECT ON crashcourse.* TO userSelect;

赋予权限后查看:

移除用户权限

使用REVOKE  FROM将用户权限移除

#移除用户权限

REVOKE SELECT ON crashcourse.* FROM userSelect;

权限清单:

ALL 除GRANT OPTION外的所有权限;

ALTER 使用ALTER TABLE;

ALTER ROUTINE 使用ALTER PROCEDURE和DROP PROCEDURE;

CREATE 使用CREATE TABLE;

CREATE ROUTINE 使用CREATE PROCEDURE;

CREATE TEMPORARY TABLES 使用CREATE TEMPORARY TABLE;

CREATE USER 使用CREATE USER、DROP USER、RENAME USER和REVOKE

ALL PRIVILEGES;

CREATE VIEW 使用CREATE VIEW;

DELETE 使用DELETE;

DROP 使用DROP TABLE;

EXECUTE 使用CALL和存储过程;

FILE 使用SELECT INTO OUTFILE和LOAD DATA INFILE;

GRANT OPTION 使用GRANT和REVOKE;

INDEX 使用CREATE INDEX和DROP INDEX;

INSERT 使用INSERT;

LOCK TABLES 使用LOCK TABLES;

PROCESS 使用SHOW FULL PROCESSLIST;

RELOAD 使用FLUSH;

REPLICATION CLIENT 服务器位置的访问;

REPLICATION SLAVE 由复制从属使用;

SELECT 使用SELECT;

SHOW DATABASES 使用SHOW DATABASES;

SHOW VIEW 使用SHOW CREATE VIEW;

SHUTDOWN 使用mysqladmin shutdown(用来关闭MySQL);

SUPER 使用CHANGE MASTER、KILL、LOGS、PURGE、MASTER

和SET GLOBAL。还允许mysqladmin调试登录;

UPDATE 使用UPDATE;

USAGE 无访问权限;

示例:

#创建ALL权限账号

CREATE USER userAll IDENTIFIED BY 'userAll123';

#赋予权限

#ALL表示除了GRANT的其他所有权限

GRANT ALL ON crashcourse.* TO userAll;

#查看权限

SHOW GRANTS FOR userAll;

示例:注意权限赋予时,账号的主机地址;

#创建只能call procedure权限账号

#通过@指定host

CREATE USER userPro@127.9.1.1 IDENTIFIED BY 'userPro123';

#赋予权限

#这里我们赋予权限时,自动创建了userPro@%

GRANT EXECUTE ON crashcourse.* TO userPro;

#真实我们需要赋予权限的是userPro@127.9.1.1;

GRANT EXECUTE ON crashcourse.* TO userPro@127.9.1.1;

#查看权限

SHOW GRANTS FOR userPro;

SHOW GRANTS FOR userPro@127.9.1.1;

设置用户密码

使用SET PASSWORD更新密码。

#设置用户密码

SET PASSWORD FOR userPro = password('userPro111'

#不指定用户,默认更新当前用户密码

SET PASSWORD = password('defaultUser123')

20MySQL数据库维护

MySQL可以使用ANALYZE TABLE,CHECK TABLE对表进行检查。

示例:

#检查Table,键值是否正确

ANALYZE TABLE orders;

#检查Table,

CHECK TABLE orders,orderitems;

#只检查最后一次检查,修改过的表

CHECK TABLE  orders,orderitems CHANGED;

#EXTENDED彻底检查

CHECK TABLE orders,orderitems EXTENDED;

#FAST只检测未正常关闭的表

#MEDIUM检查所有被删除的链接,进行键检查;

#QUICK快速扫描

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偶是不器

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值