Mysql复习

1.SQL基础知识

1.1 select执行顺序

顺序 说明 是否必须使用
select all(默认)/distinct(找不同) 要返回的列/表达式
from 检索数据的表 仅仅在从表中选择数据时使用
where 行级别过滤
group by 分组说明 仅仅在按照组计算聚集时使用
having 组级别过滤(选分组)
order by asc(默认)/desc(降序) 输出排序顺序
*limit * 输出行数(limit x,y 就是从x行输出到y行)

image-20231121192527482

1.2 选择数据库(USE指令)

输入 : USE crashcourse 
输出 : Database changed

1.3 展示数据库和表(SHOW指令)

1. 数据库、表、列、用户、权限等信息被存储在数据库和表中(一般内部表不让直接访问)
2. 展示数据库: show databases;
3. 展示数据库内表: show tables; (返回当前选择的数据库内可用表的列表)
4. 展示表列: show columns from XXX;
5. 展示服务器状态信息: show status
6. 展示特定数据库mysql语句: show create database
7. 展示特定表mysql语句: show create table
8. 展示授予用户安全权限: show grants
9. 展示服务器错误/警告信息: show errors / show warnings 

1.4 数据模型

1.4.1 关系型数据库(RDBMS)

image-20231116220225940

1.5 Mysql客户端启动方式

image-20231117212521219

1.6 SQL通用语法和分类

1.6.1 语法

image-20231117212650151

1.6.2 分类

image-20231117212751196

2.SQL四大语法

2.1 DDL 数据定义语言

image-20231119211435655

2.2 DML 数据操作语言

image-20231119215028254

2.3 DQL 数据查询语言

image-20231121192527482

2.4 DCL 数据控制语言

image-20231122162805124


3.检索数据(select语句)

3.1 检索单列

//检索user表中name列
    select name 
    from user      

3.2 检索多列(逗号分隔)

//检索user表中name还有id和price列
    select name,id,price 
    from user

3.3 检索所有列(通配符[*])

//检索user表中所有列
    select * 
    from user

3.4 检索不同行的值(distinct关键字)

//检索user表中不同的name列
    select distinct name 
    from user

满足条件

1. 必须放在列名前面  ---   distinct 列名    
2. 只能返回不同的值(唯一)
3. 应用于所有列

3.5 检索前n行(limit子句)

//检索user表中name列的前五行
    select name
    from user
    limit 5  //不多于5行

//为得出下一个5行,可以指定要检索的开始行和行数
    select name 
    from user
    limit 5,5  //从第五行开始检索5行 

注意事项

1. 行0  ---  检索出来的第一行是行0 (limit 1,1将检索出第二行)
2. 行数不够  ---   有多少输出多少
3. 替换语句:  limit 4 offset 3 <--> limit 3,4 (从行3开始取4行)

3.6 检索特定表的列

//检索user表内的name列
    select user.name
    from user

排序检索数据(order by子句)

单列排序

//从user表中查name列(根据字母顺序排序)
    select name
    from user
    order by name; //order by子句

多列排序(逗号分隔)

//先对三个列查询出来之后对name和price列进行排序
    select name,id,price
    from user
    order by name,price  //首先根据名字name  然后根据价格price

//注意:
    对于上述例子输出:仅在多个行具有相同的name值时才对price值进行排序(name列中所有值都是唯一,就不会按照price排序)

指定排序方向(desc/asc关键字)

//desc按照Z到A降序   --  
//asc按照A到Z升序(默认)

//根据价格降序排序产品(最贵的排在前面)
    select price,id,name
    from user
    order by price desc; //根据price排序 desc说明是降序

//多个列排序
    select price,id,name
    from user
    order by price desc,id; //只有price降序!!!

//找到列中某几个行
    select price,id,name
    from user
    order by price desc  //desc是降序(从高到低)
    limit 1;  //找到最贵的!!!

过滤数据(where子句)

举例

//语句顺序: select -- from -- where -- order by -- limit 
    select distinct name //找到不同的name
    from user
    where name='宋亚翔'  //限定找name是宋亚翔
    order by name desc  //根据name降序排序
    limit 5,5; //从第五行开始输出五行

where子句操作符

检查单值

//检测出name叫宋亚翔的一行
    select name,price
    from user
    where name='宋亚翔';

不匹配检查(不等于操作符)

//在user表中找id不是1003的结果
    select id,name
    from user
    where id<>1003; //where id!=1003

范围值检查(between)

//在user标准中找price在5-10的信息 展示名字和对应价格
    select name,price
    from user
    where price between 5 and 10;

空值检查(is null)

//检查有没有人的价格是null
    select name
    from user
    where price is null;

数据过滤(组合where子句)

多个子句就需要用and/or方式使用

and操作符

//找到名字为宋亚翔并且购买物品价格小于10的所有产品的名字和价格
    select name,id
    from user
    where id='宋亚翔' and price<=10;

or操作符

//检索名字由任一个指定叫宋亚翔或者刘伟的产品name和id
    select name,id
    from user
    where id='宋亚翔' or id='刘伟';

or和and优先级

优先级: and > or (适当给与()区分)

//两者共同使用必须用括号()区分
    select name,price
    from user
    where (id='宋亚翔' or id='刘伟') and price>=10;

in操作符(功能和or一样)

//检索名字是宋亚翔或者刘伟的信息根据name升序排序出name和price
    select name,price
    from user
    where id in('宋亚翔','刘伟')
    order by name;

//in操作符优点:
    1. 使用长的合法选项清单时,in操作符的语法更清楚而且直观
    2. 使用in操作符,计算次序更容易管理
    3. in操作符速度执行更快
    4. in能动态建立where子句

not操作符

//检索名字除宋亚翔和刘伟之外的所有信息根据name升序排序出name和price
    select name,price
    from user
    where id not in('宋亚翔','刘伟')
    order by name;

通配符过滤(like操作符)

%(0-n个字符)

百分号%可以匹配0/1/n个字符(不能匹配null)

//找到jet起头的产品
    select id,name
    from user
    where name like 'jet%'; //找到 jetxxxx 形式

//找到jet在中间的产品
    select id,name
    from user
    where name like '%jet%'; //找到 XXXjetxXX 形式

_(单个字符)

下划线_总能匹配一个字符(不能多也不能少)

//找到jet前面有一个字符的结果  (1jet 2jet等等)
    select id,name
    from user
    where name like '_jet'; //找到 Xjet形式

正则表达式搜索(regexp)

正则表达式用来匹配文本特殊的串(字符集合)

基本字符匹配(‘X’)

//检索列name包含文本1000的所有行
    select name 
    from user
    where name regexp '1000'  //regexp替换了like位置
   //where name regexp '.1000' //匹配任意一个字符(1000S 2000)
    order by name;

//总结
    1. 使用关键字regexp --> like
    2. 匹配不区分大小写:  可以使用binary区分大小写(默认不区分)
    3.  . 用于匹配单个字符

进行or匹配( | )

//匹配1000或者2000的结果
    select name
    from user
    where name regexp '1000|2000'
    order by name;

匹配单个字符([])

[] 等价于 | 等价于 or (三者都是)

//匹配1或者2或者3 
    select name
    from user
    where name regexp '[123]Ton' //[123]Ton是[1|2|3]Ton缩写
    order by name;

匹配一个/多个字符( - )

//匹配0到9 [0123456789]等价于[0-9]
    select name
    from user
    where name regexp '[1-9]Ton' //匹配数字0到9
    order by name;

匹配特殊字符( \\前导 )

//  \\-表示查找-
    select name
    from user
    where name regexp '\\-'
    order by name;   

找特殊字符必须要\转义(表示后面的字符当做普通字符被识别)

匹配字符类

匹配多个实例

// 第一个\\引导匹配特殊字符 
// [0-9]就是匹配任意数字 
// sticks?就是匹配stick或者sticks (?是匹配前面任何字符的0/1次)        

    select name
    from user
    where name regexp '\\([0-9] sticks?\\)'
    order by name; 

定位符(匹配一个串中任意位置文本)

//匹配以一个数(包括小数点开始的数字)开始的所有产品
//简单搜索[0-9\\.]不行  必须要用^定位符
// where name regexp '^[0-9\\.]'

计算字段

运行时在select语句内创建

1. 字段(field) 基本上和列意思相同
2. 数据库可以区分哪些列是实际的表列,哪些是计算字段
3. 客户机(应用程序)计算字段的数据和其他列数据相同方式返回

拼接字段(Concat()函数)

将值联结到一起构成单个值

//多数DBMS使用 + 或者 || 实现拼接
//使用拼接从user表根据name升序排序 输出格式是 name(price)
    select Concat(name,'(',price,')')
    from user
    order by name;

//例如:  
        宋亚翔(1200)
        张三(230)

删除数据右侧多余空格(RTrim()函数)

//拼接基础上删除右侧多余空格
    select Concat(RTrim(name),'(',RTrim(price),')')
    from user
    order by name;

别名/导出列(AS关键字)

一个字段/值的替换名

//拼接之后删除多余空格的字段  给个songyaxiang的别名就可以引用
    select Concat(RTrim(name),'(',RTrim(price),')') AS songyaxiang
    from user 
    order by name;

算术计算

//输出price和num乘积
    select price*num
    from user
    where name='宋亚翔';

数据处理函数

文本处理函数

//Soundex()函数就是匹配发音相似的函数
//现在user表里面有个人叫宋亚翔 其联络名叫laekkkkkkk(如果输入错误,实际应该是larkkkkkkk)
    select name,lianluoming
    from user
    where Soundex(lianluoming)=Soundex(larkkkkkkk);
//因为larkkkkkkk和laekkkkkkk发音相似,所以Soundex值匹配

日期和时间处理函数

数值处理函数


汇总数据

聚集函数(5个)

运行在行组上,计算和返回单值

avg()某列平均值

通过对表中行数计数并计算特定列值之和,求该列平均值

//从user表中找到价格price列的平均值 结果起个jiage的别名
    select avg(price) as jiage
    from user;

//计算特定列/行的平均值(where语句确定)
//从user表中找到名字叫宋亚翔的所有价格price列的平均值 结果叫jiage别名
    select avg(price) as jiage
    from user
    where id='宋亚翔';

count()某列行数和

1. 使用count(*)对表中行的数目进行计数(不管列中包含的是null还是非空值)
2. 使用count(column)对特定列中具有值得行进行计数(忽略null值)

//从user表中记录所有用户总数 结果给zongshu这个别名
    select count(*) as zongshu
    from user;

max()某列最大值

//从user表中找到最大价格price行 结果给max这个别名
    select max(price) as max
    from user;

min()某列最小值

//从user表中找到最小价格price行 结果给min这个别名
    select min(price) as min
    from user;

sum()某列总和

//从user表计算price总和 结果给sum这个别名
    select sum(price) as sum
    from user;

聚集不同值(distinct/all)

1. all(默认)  所有的行执行计算
2. distinct() 只包含不同的值   必须用于列名

组合聚集函数(select子句)

//使用四个函数
    //从user表中算出行总数 最大最小和平均价格并且给与别名
        select count(*) as count,
                min(price) as min,
                max(price) as max,
                avg(price) as avg
        from user;

分组数据(group by和having子句)

创建分组(group by子句)

分组在select语句的group by子句中建立

//计算每个id对应的产品个数
//例如:  宋亚翔有7个产品 刘伟有3个产品
    select id,count(*) as count
    from user
    group by id  //根据id分组
    order by id; //根据id升序

// 书写顺序:
     group by
    having
    order by
    limit

过滤分组(having子句)

//where过滤行,having子句过滤分组

//从orders表中查找每个id和总数 然后按照id升序排序 给结果的每行给别名orders 
//主要是我们只要count大于等于2的结果
    select id,count(*) as orders
    from orders
    group by id
    having count(*)>=2;

分组(group by)和排序(order by)区别

//检索总计订单价格大于等于50的订单的订单号和总计订单价格
    select id,sum(quantity*price) as jiage
    from user
    group by num   //根据num分组
    having sum(quantity*price)>=50  //过滤分组
    order by price;  //根据价格升序排序

子查询(嵌套在其他查询中的查询)

//说明情况:
    orders表: 每个订单(订单号,客户ID,订单日期)
    customers表: 实际的客户信息
    orderitems表:各订单的物品存储

//子查询执行顺序:
    从内向外处理

利用子查询过滤

两个以上select语句嵌套

作为计算字段使用子查询

//问题:
    需要显示customers表中每个客户的订单总数
    (订单和相应的客户ID存储在orders表)

//1. 从customers表中检索客户列表
//2. 对于检索出来的客户,统计其在orders表中订单的数目

//1.对客户10001的订单进行计数
    select count(*) as orders
    from orders
    where id=10001;

//2.为了对每个客户执行count(*)计算,应该作为一个子查询
    select name,state,(select count(*) 
                       from orders 
                       where orders.id=customers.id)   as orders
    from customers
    order by name;

相关子查询(涉及外部查询的子查询)


联结表(多表联系)

关系表

主键(primary key) : 唯一的标识
外键(foreign key) : 外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之前的关系

笛卡尔积(乘积)

由没有联结条件的表关系返回的结果(h表1*h表2)

表别名

1. 列起名(select子句) + 表别名(from子句)

    //列别名
        select count(*) as jia  //结果起别名叫jia
        from user
        where id='宋亚翔';

    //表别名
        select name,price
        from customers as c,orders as o,orderitems as oi  //给三个表起别名
        where c.id=o.id and oi.num=c.num;  //where子句直接就用了别名

不同类型的联结(四种联结)

1. 内部联结/等值联结(简单联结)
2. 自联结
3. 自然联结
4. 外部联结 
    4.1 左外部联结
    4.2 右外部联结 

组合查询(union操作符)

并(union)/复合查询

//使用组合查询条件:
    1. 在单个查询中从不同的表返回类似结构的数据
    2. 对单个表执行多个查询,按单个查询返回数据

创建组合查询(union操作符)

只是给出每条select语句,在各条语句之间放入关键字union

//价格<=5的所有物品的一个列表 + 包括供应商1001和1002生产的所有物品(不考虑价格)

//分开写select语句
//1. 找到价格<=5的所有物品的一个列表
    select id,price
    from products    
    where price<=5;

//2. 找到供应商1001和1002生产的所有物品
    select id,price
    from products
    where id in(1001,1002);

//3. 组合两条语句
    select id,price
    from products    
    where price<=5;
    union
    select id,price
    from products
    where id in(1001,1002);

//4. 使用多条where子句
    select id,price
    from products    
    where price<=5 or id in(1001,1002);

union规则

1. 必须两条以上的select语句组成
2. union中的每个查询必须包含相同的列,表达式或者聚集函数
3. 列数据类型必须兼容(不必完全相同,DBMS可以隐含转换的类型)

包含重复行(union all)

查询结果集中自动去除重复行(和多个where子句组合一样)

组合查询结果排序(必须在最后一条select语句之后)

只能使用一条order by子句(但是排序却在所有select语句中起作用)


全文本搜索(比like和正则表达式更好!)

全文本搜索(建表时启用)

并非所有引擎都支持全文本搜索

1. MyISAM(5.5以前)
    支持全文本搜索(√)

2. 和InnoDB(5.5以后)
    不支持全文本搜索(×)

启用全文本搜索支持(fulltext子句)

创建表的时候使用fulltext子句

//create table语句接受fulltext子句(给出被索引列的一个逗号分隔的列表)

create table user
(
    note_id int     not null 
    pro_id char(20)  not null,
    note_date datetime not null,
    note_text text null,
    primary key(note_id),
    fulltext(note_text)   //mysql根据fulltext子句指示给它进行索引,进行全文本搜索(索引会根据数据改变重新索引)
)ENGINE=MyISAM;  //myisam引擎支持全文本搜索

执行全文本搜索(Match()和Against()函数)

select的时候使用match()和against()函数

1. Match()指定被搜索的列 
2. Against()指定要使用的搜索表达式     

//检索单列
    select note_text 
    from productnotes
    where match(note_text) against('rabbit');    

//match(note_text)表明mysql针对note_text列进行搜索
//against('rabbit')表明对制定此rabbit作为搜索文本搜索

注意:
    match()里面的值必须和fulltext()里面的值相同(指定多列必须列出多列次序也要正确)

like匹配和全文本搜索对比

1. 全文本搜索可以对结果进行排序(较高等级的行先返回)
2. 全文本搜索中数据是索引的,速度v更快

查询扩展(搜索相关结果 with query expansion)

能找到可能相关的结果,即使他们并不精确包含所查找的词

//检索note_text列里面和rabbit相关的
    select note_text 
    from productnotes
    where match(note_text) against('anvils' with query expansion);

布尔文本搜索(in boolean mode)

不需要全文本搜索需要建立fulltext索引

1. 要匹配的词
2. 要排斥的词(如果某行包含这个词,则不返回该行,即使它包含其他指定的词也是如此)
3. 排列提示(更重要的词等级更高)
4. 表达式分组
5. 另外一些内容

全文本布尔操作符

//匹配包含heavy但不包含任意以rope开始的词 
    // -排除一个词(词必须不出现!) *是截断操作符
    select note_text
    from productnotes
    where match(note_text) against('heavy -rope*' in boolean mode)

全文本搜索使用说明

1. 许多次出现评率很高,搜索他们没有用处(返回太多结果)
    1.1 所以规定一条50%规则(不用于in boolean mode): 如果一个词出现在50%以上的行,将它作为一个非用词忽略。
2. 如果表中行数<3:全文本搜索不返回结果
3. 忽略词中的单引号(don't索引为dont)
4. 不具有词分隔符(包括日语和汉语)的语言不能恰当地返回全文本搜索结果
5. mysql带有一个内建的非用词(stopword)列表,这些词在索引时候被忽略(出现次数50%以上) 如果想用就覆盖这个列表
6. 在索引全文本数据时,短词被忽略而且要从索引中排除(短语是具有<=3个字符的词)

插入数据(insert语句)

提高整体性能(low_priority)

插入单行

//不安全(高度依赖于列定义次序)
    insert into customers
    values(null,'123','15009272737',null);

//安全但是麻烦(说明自定义的次序和对应值)
    insert into customers(id,glass,num,country)
    values(null,'123','15009272737',null);

插入多行

1. 第一个insert语句;第二个insert语句;
    insert into user()
    values();
    insert into user()
    values();

2. values语句(),();   -- 单条insert语句处理多个插入性能更好!!
    insert into user()
    values(),();

插入检索出的数据(insert select)

一条insert语句和一条select语句组成

从另一表中合并客户列表到你的customers表,将它用insert插入
    insert into customers(id,contact,email,name,address,city,state,zip,country)
    select id,contact,email,name,address,city,state,zip,country
    from custnew;

更新数据(update语句)

1. 更新表中特定行(update set where)
2. 更新表中所有行(update set )

更新特定行(where子句要有)

更新单列信息

//客户10005现在有了电子邮件地址,因此它的记录需要更新
    update customers
    set email='134506293@qq.com'
    where id=10005;

更新多列信息:(逗号分隔)

igonre关键字:保证就算发生错误,也继续更新!!!

//客户10005不仅有了电子邮件地址,而且有了班级信息
    update ignore customers  //ignore保证就算发生错误,也继续更新!!!
    set email='134506293@qq.com',class='软件工程';
    where id=10005;

更新所有行(where子句没有)

//将所有人的邮箱都改成134506293@qq.com
    update customers
    set email='134506293@qq.com'

删除某个列的值(set设置null)

//将10005客户的邮箱一栏删除 就是删除列的信息
    update customers    
    set email=null
    where id=10005;

删除数据(delete)

delete从表中删除行(不删除表本身)

1. 从表中删除特定行()
2. 从表中删除所有行()

删除特定行

//删除customers表中客户10005的信息
    delete 
    from customers
    where id=10005;  //删除的是行(删除列是update中set设置null)

删除所有行()

//删除customers表中所有行信息
    delete 
    from customers

更快删除所有行(truncate table)

删除原来表并且重新创建一个表

输入: truncate table
    速度比delete语句删除所有行速度更快

创建表(create table)

创建表方式(2种)

1. 使用具有交互式创建和管理表的工具(navicat)
2. 使用mysql语句操纵(create table语句)

null值(建表默认null)

null值是没有值,不是空串

//创建orders表
    create table orders
    (
        order_num   int       not null,
        order_date  datetime  not null,
        cust_id     int       not null,
        primary key(order_num)
    )ENGINE=InnoDB;

auto_increment(自动增量)

一个表只允许一个auto_increment列,而且它必须索引(主键)

指定默认值(default关键字)

如果在插入行时没有给出值,mysql会使用默认值(不是null值)

引擎类型(engine)

引擎具体创建表,隐藏在DBMS中

1. MyISAM (5.5以前)  --性能极高引擎
    支持全文本搜索 
    不支持事务处理

2. InnoDB (5.5以后)  --可靠的事务处理引擎
    不支持全文本搜索

更新表(alter table)

给表添加一个列

alter table user
add id char(50);

定义外键

alter table user
add constraint orders foreign key(order_num) references orders(order_num)

删除表(drop table)

//删除表(删除的不是内容)    
    drop table user;

重命名表(rename table)

多个表重命名用逗号隔开

//给user表换成usertwo名
    rename table user to usertwo;

视图(MYSQL5出现)

视图规则和限制

1. 试图必须唯一命名(不能和其他试图/表相同名字)
2. 试图数目没有限制
3. 创建视图必须由足够访问权限(数据库管理人员授予)
4. 试图可以嵌套(从其他试图中检索数据的查询来构建)
5. 试图可以使用order by排序
6. 试图不能索引/触发器/默认值
7. 试图可以和表一起使用

视图SQL语句(create view)

1. 创建视图: create view 
2. 查看创建视图的语句:show create view name
3. 删除视图: drop view name
4. 更新视图: 先drop然后再create / create or replace view 

简化联结(查询可从视图找)

//创建一个名为productcustomers的视图
//联结三个表,返回已订购任意产品的所有客户的列表
    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;

//建立了视图(虚表),可以使用select语句查询任意产品的客户
    select *
    from productcustomers //从视图中查询

存储检索结果方便查找

//单个组合计算列中返回供应商名和位置
    //Concat是拼接函数  RTrim删除右边多余空格
    select Concat(RTrim(name),'(',RTrim(country),')') as hhh  //拼接结果起别名为hhh
    from vendors  //从vendors表
    order by name; //根据名字name升序排序

//假设经常需要这个格式的结果,不必每次需要时候执行联结,可以创建一个视图,需要使用的视图即可
    create view shitu as  //添加视图名shitu
    select Concat(RTrim(name),'(',RTrim(country),')') as hhh  //拼接结果起别名为hhh
    from vendors  //从vendors表
    order by name; //根据名字name升序排序

//之后使用就select查找shitu即可
    select *
    from shitu;

过滤数据

应用于普通的where子句也很有用
//过滤没有电子邮件地址的客户
    create view noemail as
    select id,name,email
    from customers
    where email is not null; //where限定找到没有eamil的用户

简化计算字段使用

之前的所有操作得到的结果赋给一个视图,然后每次查找去找视图即可(简化数据处理)

更新视图(一般用于select语句)

视图可以更新,更新视图将更新其基表

更新视图条件

1. 由于视图本身是虚表(没有数据)所以还是对基表进行增删查改
2. 有以下操作则不能更新:
    1. 分组(group by和having)
    2. 联结
    3. 子查询(嵌套select语句)
    4. 并(union)
    5. 聚集函数(min()/max()/count()/avg()/sum())
    6. distinct(保证唯一)
    7. 计算列(select语句有计算)

存储过程(MySQL5出现)

为以后使用而保存的一条/多条Mysql语句的集合

创建存储过程(create procedure语句)

//一个返回产品平均价格的存储过程
    create procedure productpricing()  //创建存储过程名字为productpricing
    begin
        select avg(price) as priceaverage  //起别名为priceaverage
        from products;
    end;

参数

存储过程并不显示结果,只是把结果返回给你指定的变量

变量(variable)

//in    传递给存储过程
//out   从存储过程传出给调用者
//inout 对存储过程传入和传出

//创建有参数的存储过程
    create procedure productpricing(
        out p1 decimal(8,2),  //out用来从存储过程传出一个值(返回给调用者)
        out ph decimal(8,2),
        out pa decimal(8,2),
    )
    begin
        select min(price)  //p1存储产品最低价格
        into p1            //into插入
        from products;

        select max(price)  //ph存储产品最高价格
        into ph
        from products;

        select avg(price)  //pa存储产品平均价格
        into pa
        from products;
    end;

//调用productpricing存储过程(必须制定三个变量名)
    //变量必须以@开始!!!!!!!!!!!!
    call productpricing(@pricelow,@pricehigh,@priceaverage);

使用存储过程(call语句)

//执行刚创建的存储过程并显示返回的结果(存储过程实际上是一种函数,所以调用要有()符号)
    call productpricing();

执行存储过程(call语句)

//执行名字叫productpricing的存储过程,并且返回产品的最低、最高和平均价格
    call productipricing(@pricelow,@pricehigh,@priceaverage);

删除存储过程(drop procedure语句)

创建之后被保存在服务器上以供使用,直到被删除

//删除刚创建的存储过程
    drop procedure productpricing (if exists);

建立智能存储过程

目前使用的所有存储过程基本上是封装mysql简单的select语句

检查存储过程(show create procedure语句)

//展示ordertotal存储过程
    show create procedure ordertotal;

//展示存储过程何时、谁创建等详细信息的存储过程列表
    show procedure status (like 'xxx');  //like制定过滤模式

游标(cursor)

存储在mysql服务器上的数据库查询,是select语句检索出来的结果集

游标适用范围

1. mysql游标只能用于存储过程(上章讲解)和函数
2. mysql游标主要用于交互式应用,可以根据需要滚动/浏览其中的数据

游标使用步骤

1. 使用前必须定义要使用的select语句
2. 一旦定义,必须打开游标以供使用(用定义好的select语句把数据实际检索出来)
3. 对于填有数据的游标,根据需要取出索引各行
4. 游标使用结束之后,必须关闭游标

创建游标(declare)

//定义名为ordernumbers的游标,使用检索所有订单的select语句
    create procedure processorders()  //创建processorders存储过程
    begin
        declare ordernumbers cursor  //创建游标
        for
        select order_num  //select语句
        from orders;
    end;

打开/关闭游标(open cursor语句)

//打开ordernumbers游标
    open ordernumbers;
//关闭ordernumbers游标        
    close ordernumbers;  //释放游标使用的所有内部内存和资源

使用游标数据(fetch语句)

//从游标中检索单行(第一行)
    create procedure processorders()  //创建存储过程
        begin
            declare o int;  //局部声明的变量
            declare ordernumbers cursor //创建游标
            for
                select order_num  //书写的select语句
                from orders;
            open ordernumbers;  //打开游标
            fetch ordernumbers //检索当前行的order_num列到一个名为0的局部声明的变量中 
            into o;   //插入o游标
            close ordernumbers;  //关闭游标
        end;

//循环检索数据(从第一行到最后一行)
    create procedure processorders()  //创建存储过程
        begin
            declare done boolean default 0;
            declare o int;
            declare ordernumbers cursor  //定义游标
            for
                select order_num
                from orders
            declare cotinue handler for sqlstate '02000' set done=1;
            open ordernumbers;    //打开游标
            repeat
                fetch ordernumbers 
                into o;
            until done end repeat;  //反复执行到done为真
            close ordernumbers;   //关闭游标
        end;    

触发器(MYSQL5支持)

响应增删改三种语句而自动执行的一条mysql语句

触发器定义条件

1. 只能按照每个表每个事件每次地定义(每次只能有一个)
2. 每个表最多支持6个触发器(增删改的之前和之后)
3. 如果需要对一个insert和update操作执行,就必须要定义两个
4. 触发器不能识别执行存储过程的call语句(需要的存储过程代码需要复制到触发器内)

创建触发器(create trigger)

只有表支持触发器(视图和临时表也不可以)

//创建newproduct的新触发器
    create trigger newproduct //创建触发器名
    after insert on products  //定义是插入语句成功执行后执行 
    for each row  //定义每个插入行执行
    select 'chenggong'; //对每个成功的插入显示成功的消息

删除触发器(drop trigger)

//删除刚才的newproduct触发器
    drop trigger new product;

使用触发器(三类六种)

insert触发器(NEW虚拟表)

1. insert触发器代码中,可引用一个名字叫NEW的虚拟表(访问被插入的行)
2. 在before insert触发器中,new的值可以被更新
3. 对于auto_increment列,new在insert执行之前包含0,insert执行之后包含新的自动生成值

//创建一个名叫neworder的触发器 按照after insert on orders执行
    create trigger neworder 
    after insert on orders  //插入一个新订单到orders表
    for each row
    select new.order_num;  //mysql生成一个新订单号保存到order_num

delete触发器(OLD虚拟表)

1. delete触发器代码中,可引用一个名字叫OLD的虚拟表(访问被删除的行)
2. OLD中的值全是只读,不能更新

//创建一个名叫deleteorder的触发器
    create trigger deleteorder
    before delete on orders  //插入一个新订单到orders表
    for each row
    begin
        insert into achive_orders(num,data,id)
        values(OLD.num,OLD.data,OLD.id)
    end;

//用一条insert将要删除的订单保存到achive_orders表

update触发器(OLD虚拟表)

1. update触发器代码中,可引用一个名字叫OLD的虚拟表访问更新的值
2. before update触发器中,new的值可能会被更新
3. OLD中的值全是只读,不能更新

管理事务处理(commit和rollback语句)

MYSQL5.5以后支持的InnoDB引擎支持事务管理

事务知识点

事务(transaction) : 一组sql语句
回退(rollback) : 撤销指定sql语句的过程
提交(commit) : 将未存储的sql语句结果写入数据库表
保留点(savepoint) : 事务处理中设置的临时占位符,你可以对它发布回退

事务开始

会在commit/rollback语句执行后,事务自动关闭

start transaction

rollback命令回退

只能增删改语句(create/drop不能回滚)

//举例

select *
from ordertotals;  //展示ordertotals表内信息

start transaction;  //打开事务

delete
from ordertotals;  //删除ordertotals表中所有行

select *
from ordertotals;  //检验是否为空

rollback;  //回滚打开事务之后的所有语言

select *
from ordertotals;  //显示该表不是空(回滚成功!)

commit语句

//事务处理块中,必须明确提交(使用commit语句)

start transaction; //事务开始

delete
from order        //从order表中删除订单20010  
where num=20010;

delete   
from orders       //从orders表中删除订单20010
where num=20010;

commit; //提交

保留点(savepoint)

设置保留点进行部分提交/回滚

//设置保留点
    savepoint d1;

//回滚到d1点
    rollback to d1;

保留点越多越好:
    更加灵活地进行回退

释放保留点(事务处理完成后自动释放)
    release savepoint(mysql5之后)

更改默认的提交行为(autocommit自动提交)

//mysql默认是自动提交所有更改

//为了让mysql不自动提交更改
    set autocommit=0;

全球化和本地化

字符集(character)和校对顺序(collation)

//重要术语:
    字符集: 为字母和符号的集合
    编码: 为某个字符集成员的内部表示
    校对    : 为规定字符如何比较的指令(影响排序和搜索)

//决定级别:
    服务器/数据库/表级进行

字符集和校对顺序(sql语句)

//显示所有可用的字符集和每个字符集的描述和默认校对
    show character set;

//查看所支持校对的完整列表
    show collation;

//修改所用的字符集和校对
    show variables like 'character%';
    show variables like 'collation%';

//建表时设置字符集和校对
    create table user
    (
        id int,
        name varchar(10)
    )default character set hebrew
     collate hebrew_general_ci;

    //以下三种情况:
        1. 如果两个都设置,就使用这些设置
        2. 只设置字符集,则使用字符集默认的校对
        3. 如果两个都没设置,则使用数据库默认

安全管理

管理用户(存储在名mysql数据库中)

//需要获取所有用户账号列表
    use mysql;  //进入mysql数据库
    selet user
    from user;  //从user数据库中查找user(结果是root)

创建用户账号(create user)

//创建用户名为song
    create uesr song (identified by 'p@$$w0rd');

//identified by 'p@$$w0rd' 纯文本指定口令

//identified by password 散列值指定口令

重命名用户账号(rename user)

//将上面的song用户改名为ya
    rename user song to ya;

删除用户账号(drop user)

//删除上面的ya用户(5以后也删除相关权限)
    drop user ya;

//5之前只能删除用户账号
    1. 先用revoke删除相关权限
    2. 然后使用drop user删除账号

设置访问权限(grants)

//查看赋予用户账号的权限
    show grants for ya;

//设置权限(允许ya用户在user所有表上可以使用select语句)
    grant select on user to ya;

撤销访问权限(revoke)

//撤销上面设置的权限
    revoke select on user from ya;

控制访问权限(层次)

更改口令(set password)

set password for ya=password('自己的口令');

set password (不指定用户名,就更新当前登录用户口令)

数据库维护

备份数据(flush tables之后备份)

刷新未写数据(保证所有数据被写到磁盘)
    1. 先flush tables语句
    2. 然后备份

数据库维护(SQL语句)

//1. 检查表键是否正确
    analyze table user;  //返回状态信息

//2. check table 检查许多有问题的表并且修改
    (MyISAM(5.5以前)表还对索引进行检查)

//3. changed 检查自最后一次检查以来改动过的表

//4. extended 执行最彻底的检查

//5. fast 只检查未正常关闭的表

//6. medium 检查所有被删除的联结并且进行键检查

//7. quick 只进行快速扫描

MyISAM表访问不一致(repair table语句修复)

可能需要使用repair table来修复相应的表(不能经常使用,否则会有更大问题需要解决)

表中删除大量数据(optimize table回收空间)

诊断启动问题(mysqld命令行)

查看日志文件


改善性能(遵守规则)

1. 遵守硬件建议(学习和研究mysql)
2. 关键的生产DBMS应该放在自己的专用服务器上
3. Mysql是一系列默认设置预先配置的,过一段时间就需要调整内存大小等
4. Mysql是一个多用户多线程的DBMS,经常同时执行多个任务,如果出现性能不良等可以使用show processlist 展示所有活动进程/kill命令终结某个进程
5. 尽量找到最优sql语句
6. 一般来说,存储过程 > 一条一条执行其中的各条mysql语句
7. 使用正确的数据类型
8. 要检索多少就检索多少(不要select *)
9. 导入数据时,应该关闭自动提交
10. 必须索引数据库表(提高检索性能)
11. or条件 ---> 多条select语句和union语句
12. 索引尽量使用在常用表上

参考用书

参考《MySQL必知必会》


×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 1.SQL基础知识
    1. 1.1. 1.1 select执行顺序
    2. 1.2. 1.2 选择数据库(USE指令)
    3. 1.3. 1.3 展示数据库和表(SHOW指令)
    4. 1.4. 1.4 数据模型
      1. 1.4.1. 1.4.1 关系型数据库(RDBMS)
    5. 1.5. 1.5 Mysql客户端启动方式
    6. 1.6. 1.6 SQL通用语法和分类
      1. 1.6.1. 1.6.1 语法
      2. 1.6.2. 1.6.2 分类
  2. 2. 2.SQL四大语法
    1. 2.1. 2.1 DDL 数据定义语言
    2. 2.2. 2.2 DML 数据操作语言
    3. 2.3. 2.3 DQL 数据查询语言
    4. 2.4. 2.4 DCL 数据控制语言
  3. 3. 3.检索数据(select语句)
    1. 3.1. 3.1 检索单列
    2. 3.2. 3.2 检索多列(逗号分隔)
    3. 3.3. 3.3 检索所有列(通配符[*])
    4. 3.4. 3.4 检索不同行的值(distinct关键字)
    5. 3.5. 3.5 检索前n行(limit子句)
    6. 3.6. 3.6 检索特定表的列
  4. 4. 排序检索数据(order by子句)
    1. 4.1. 单列排序
    2. 4.2. 多列排序(逗号分隔)
    3. 4.3. 指定排序方向(desc/asc关键字)
  5. 5. 过滤数据(where子句)
    1. 5.1. 举例
    2. 5.2. where子句操作符
    3. 5.3. 检查单值
    4. 5.4. 不匹配检查(不等于操作符)
    5. 5.5. 范围值检查(between)
    6. 5.6. 空值检查(is null)
  6. 6. 数据过滤(组合where子句)
    1. 6.1. and操作符
    2. 6.2. or操作符
    3. 6.3. or和and优先级
    4. 6.4. in操作符(功能和or一样)
    5. 6.5. not操作符
  7. 7. 通配符过滤(like操作符)
    1. 7.1. %(0-n个字符)
    2. 7.2. _(单个字符)
  8. 8. 正则表达式搜索(regexp)
    1. 8.1. 基本字符匹配(‘X’)
    2. 8.2. 进行or匹配( | )
    3. 8.3. 匹配单个字符([])
    4. 8.4. 匹配一个/多个字符( - )
    5. 8.5. 匹配特殊字符( \\前导 )
    6. 8.6. 匹配字符类
    7. 8.7. 匹配多个实例
    8. 8.8. 定位符(匹配一个串中任意位置文本)
  9. 9. 计算字段
    1. 9.1. 拼接字段(Concat()函数)
    2. 9.2. 删除数据右侧多余空格(RTrim()函数)
    3. 9.3. 别名/导出列(AS关键字)
    4. 9.4. 算术计算
  10. 10. 数据处理函数
    1. 10.1. 文本处理函数
    2. 10.2. 日期和时间处理函数
    3. 10.3. 数值处理函数
  11. 11. 汇总数据
    1. 11.1. 聚集函数(5个)
      1. 11.1.1. avg()某列平均值
      2. 11.1.2. count()某列行数和
      3. 11.1.3. max()某列最大值
      4. 11.1.4. min()某列最小值
      5. 11.1.5. sum()某列总和
    2. 11.2. 聚集不同值(distinct/all)
    3. 11.3. 组合聚集函数(select子句)
  12. 12. 分组数据(group by和having子句)
    1. 12.1. 创建分组(group by子句)
    2. 12.2. 过滤分组(having子句)
    3. 12.3. 分组(group by)和排序(order by)区别
  13. 13. 子查询(嵌套在其他查询中的查询)
    1. 13.1. 利用子查询过滤
    2. 13.2. 作为计算字段使用子查询
    3. 13.3. 相关子查询(涉及外部查询的子查询)
  14. 14. 联结表(多表联系)
    1. 14.1. 关系表
    2. 14.2. 笛卡尔积(乘积)
    3. 14.3. 表别名
    4. 14.4. 不同类型的联结(四种联结)
  15. 15. 组合查询(union操作符)
    1. 15.1. 创建组合查询(union操作符)
    2. 15.2. union规则
    3. 15.3. 包含重复行(union all)
    4. 15.4. 组合查询结果排序(必须在最后一条select语句之后)
  16. 16. 全文本搜索(比like和正则表达式更好!)
    1. 16.1. 全文本搜索(建表时启用)
    2. 16.2. 启用全文本搜索支持(fulltext子句)
    3. 16.3. 执行全文本搜索(Match()和Against()函数)
    4. 16.4. like匹配和全文本搜索对比
    5. 16.5. 查询扩展(搜索相关结果 with query expansion)
    6. 16.6. 布尔文本搜索(in boolean mode)
    7. 16.7. 全文本搜索使用说明
  17. 17. 插入数据(insert语句)
    1. 17.1. 提高整体性能(low_priority)
    2. 17.2. 插入单行
    3. 17.3. 插入多行
    4. 17.4. 插入检索出的数据(insert select)
  18. 18. 更新数据(update语句)
    1. 18.1. 更新特定行(where子句要有)
      1. 18.1.1. 更新单列信息
      2. 18.1.2. 更新多列信息:(逗号分隔)
    2. 18.2. 更新所有行(where子句没有)
    3. 18.3. 删除某个列的值(set设置null)
  19. 19. 删除数据(delete)
    1. 19.1. 删除特定行
    2. 19.2. 删除所有行()
    3. 19.3. 更快删除所有行(truncate table)
  20. 20. 创建表(create table)
    1. 20.1. 创建表方式(2种)
    2. 20.2. null值(建表默认null)
    3. 20.3. auto_increment(自动增量)
    4. 20.4. 指定默认值(default关键字)
    5. 20.5. 引擎类型(engine)
  21. 21. 更新表(alter table)
    1. 21.1. 给表添加一个列
    2. 21.2. 定义外键
  22. 22. 删除表(drop table)
  23. 23. 重命名表(rename table)
  24. 24. 视图(MYSQL5出现)
    1. 24.1. 视图规则和限制
    2. 24.2. 视图SQL语句(create view)
    3. 24.3. 简化联结(查询可从视图找)
    4. 24.4. 存储检索结果方便查找
    5. 24.5. 过滤数据
    6. 24.6. 简化计算字段使用
  25. 25. 更新视图(一般用于select语句)
    1. 25.1. 更新视图条件
  26. 26. 存储过程(MySQL5出现)
    1. 26.1. 创建存储过程(create procedure语句)
    2. 26.2. 参数
      1. 26.2.1. 变量(variable)
    3. 26.3. 使用存储过程(call语句)
    4. 26.4. 执行存储过程(call语句)
    5. 26.5. 删除存储过程(drop procedure语句)
    6. 26.6. 建立智能存储过程
    7. 26.7. 检查存储过程(show create procedure语句)
  27. 27. 游标(cursor)
    1. 27.1. 游标适用范围
    2. 27.2. 游标使用步骤
    3. 27.3. 创建游标(declare)
    4. 27.4. 打开/关闭游标(open cursor语句)
    5. 27.5. 使用游标数据(fetch语句)
  28. 28. 触发器(MYSQL5支持)
    1. 28.1. 触发器定义条件
    2. 28.2. 创建触发器(create trigger)
    3. 28.3. 删除触发器(drop trigger)
    4. 28.4. 使用触发器(三类六种)
      1. 28.4.1. insert触发器(NEW虚拟表)
      2. 28.4.2. delete触发器(OLD虚拟表)
      3. 28.4.3. update触发器(OLD虚拟表)
  29. 29. 管理事务处理(commit和rollback语句)
    1. 29.1. 事务知识点
    2. 29.2. 事务开始
    3. 29.3. rollback命令回退
    4. 29.4. commit语句
    5. 29.5. 保留点(savepoint)
    6. 29.6. 更改默认的提交行为(autocommit自动提交)
  30. 30. 全球化和本地化
    1. 30.1. 字符集(character)和校对顺序(collation)
    2. 30.2. 字符集和校对顺序(sql语句)
  31. 31. 安全管理
    1. 31.1. 管理用户(存储在名mysql数据库中)
    2. 31.2. 创建用户账号(create user)
    3. 31.3. 重命名用户账号(rename user)
    4. 31.4. 删除用户账号(drop user)
    5. 31.5. 设置访问权限(grants)
    6. 31.6. 撤销访问权限(revoke)
    7. 31.7. 控制访问权限(层次)
    8. 31.8. 更改口令(set password)
  32. 32. 数据库维护
    1. 32.1. 备份数据(flush tables之后备份)
    2. 32.2. 数据库维护(SQL语句)
    3. 32.3. MyISAM表访问不一致(repair table语句修复)
    4. 32.4. 表中删除大量数据(optimize table回收空间)
    5. 32.5. 诊断启动问题(mysqld命令行)
    6. 32.6. 查看日志文件
  33. 33. 改善性能(遵守规则)
  34. 34. 参考用书
,