mysql基础知识

来源:互联网 发布:铜排折弯最简单的算法 编辑:程序博客网 时间:2024/06/09 21:24

1.什么是SQL

(Structured Query Language) 结构查询语句


2.SQL语言分类:

2.1 数据查询语言DQL

数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE
子句组成的查询块:
SELECT <字段名表>
FROM <表或视图名>
WHERE <查询条件>

2.2 数据操纵语言DML

数据操纵语言DML主要有三种形式:
1) 插入:INSERT
2) 更新:UPDATE
3) 删除:DELETE

2.3 数据定义语言DDL

数据定义语言DDL用来创建数据库中的各种对象-----表、视图、
索引、同义词、聚簇等如:
CREATE TABLE/VIEW/INDEX/SYN/CLUSTER
| | | | |
表 视图 索引 同义词 簇

2.4 数据控制语言DCL

数据控制语言DCL用来授予或回收访问数据库的某种特权,并控制
数据库操纵事务发生的时间及效果,对数据库实行监视等


3.我常用的表操作语句:

1.mysql -h localhost -uroot -p123456 -- 以root用户连接本地数据库
2. show databases; -- 查看MySQL服务中所有的数据库
3. use database; -- 更改操作的数据库对象
4.\c --取消执行当前未输入mysql语句
5. show tables; -- 查看该操作数据库对象中所有的数据表名和视图名
6.desc table_name/view_name;--查看表/视图结构;
7.truncate table_name; --清空表数据【表结构依然不变】-- 和delete from table_name;是不同的
8.show create table table_name/view; --查看建表/视图过程
9.show table status [\G]; -- 查看数据库中所有表信息【\G:以竖行显示信息】
10.show table status where name = table_name [\G]; -- 查看数据库中指定表信息【\G:以竖行显示信息】
11.rename table_name; --改表名
12.drop table table_name; --删除表
13.drop view view_name; -- 删除视图
SQL语言之DML部分@数据库操作语言【搬运数据】--"员工"


4.常用操作:增[insert] 删[delete] 改[update] 查[select]


1.INSERT:

insert into table_name (col1, col2,....) values (value1, value2,....)---**"插入值"与"列"要一一对应**
2.DELETE

delete      from     表名      where      条件【不加条件删除整个表】       --对于关系型数据库:”增"和"删"都是相对整个一行数据来说的
3.UPDATE

update   表名    set      列1=新值1,列2=新值2...   where    条件    ---修改指定列(修改所有就不用加where)
4.★★★SELECT★★★

select(列1,列2,列3,....)      from      表名       where      条件           limit 0,100;
[时间函数:select uid,userid,username,email,FROM_UNIXTIME(addtime,'%Y年%m月%d') from members]

【更新和删除操作要注意:where条件记得要加,除非对生活心灰意冷了否则还是加上比较好--不加影响的将是整个表的数据】
select的5种子句:
where子句;--条件查询
group by子句;--分组查询
having 子句;--筛选查询
order by子句;--排序查询
limit 子句;--范围查询

5种子句写的时候要有严格的顺序:where | group by | having | order by | limit


5.SELECT条件查询模型深入理解


====列是"变量"=====变量就可以计算=====

select uid, name, age+1 from user;   

--从user表中查找所有uid, name,age三列,并给age列所在值+1

==where是"表达式"==值为真【true】假【false】==
select * from user where id=5;--从user表中查找所有列,当id为5
【判断所在行id=5?==>返回true则输出】
select * from user where 1;--从user表中查找所有列,当条件恒真--【输出所有】
select * from user where 0;--从user表中查找所有列,当条件恒假--【返回Empty】
select 语句还可以配合算数运算符、逻辑运算符和位运算符以及相关函数写出更高效率的查询语句

【当然要注意运算符的优先级】
查询的实质:对磁盘上的数据文件进行查询得到结果集,并将结果集存放到内存中,其余就是对内存结果集的操作
 
 

6.group by

作用:把行中相同的值 按 字段 分组
语法:group by col1,col2,...colN
运用场合常见于统计场合,如按栏目计算帖子数,

where    针对表中的列发挥作用,查询数据
having  针对查询结果中的列发挥作用,筛选数据

where   查询后的结果保存在磁盘上以文件的方式
having  对where的结果进行删选,结果保存在内存中


7.order by

磁盘上的数据文件可能已经排好序也可能没排好序,没排好用order by就需要在内存里排好序,很耗资源的

8.子查询

where子查询--内存查询的结果作为外存查询sql的比较条件

Where型子查询:

指把内层查询的结果作为外层查询的比较条件.

典型题:查询最大商品,最贵商品

Where型子查询
如果 where 列=(内层sql),则内层sql返回的必是单行单列,单个值
如果 where 列 in (内层sql), 则内层sql只返回单列,可以多行.
select goods_id,goods_name,cat_id from ecs_goods where goods_id in (select max(goods_id) from ecs_goods group by cat_id);


From 型子查询: 把内层的查询结果当成临时表,供外层sql再次查询
    典型题:查询每个栏目下的最新/最贵商品
select * from (select goods_id,cat_id,goods_name from ecs_goods order by goods_id desc) as t group by cat_id;

Exists子查询 : 把外层的查询结果,拿到内层,看内层的查询是否成立.
select * from category
where exists (select * from goods where goods.cat_id=category.cat_id);


9.union

union合并的是"结果集",不区分在自于哪一张表.

Uion的条件是各语句取出的列数是一样,列名没有要求,以第一条sql的列名为准,
Union后的结果有重复(即某2行,或N行,所有的列,值都一样),这种情况是比较常见的,默认会去重.如果不想去重用union all,

uion语句字句 order by没有用,可以对合并后的语句排序。


10.奇怪的NULL查询


对于NULL=NULL==>返回假;==>NULL是什么都没有,所以不能比较!使用is null 才能查询
select * from user where name is not null --查询出user表中name字段不为空的信息

【对于数据表中,null不利于数据表优化操作,所以数据表中一般都对字段设置not null】


null不是对象,''是对象
从'',你就可以知道这是一个字符串类型的数据,是一个长度为零的字符串。 从NULL,你只能知道这里没有赋过值,是空的,他不属于任何数据类型。

我们在数据库实际使用中,一般把字符串型变量默认为'',数值型变量默认为0,这样才能保正在进行逻辑运算时不产生类型不匹配的错误。SQL SERVER中函数为:

ISNULL(变量,值),如

 null不是值,它表示数值未知或者不确定

null是一个属性 ,表示其中无内容,而空是表示数值为空,但有默认值,可能为0.

 NULL的判断不能简单的用=或!= 只能使用IS (NOT) NULL来判断.所以 is not null 和!=null的结果是完全不同的.虽然!=null编译不会报错,但是没有人这样来判断某个字段为null

  在数据库中,空值用来表示实际值未知或无意义的情况。因为空值表示缺少数据,所以空值和其它值没有可比性,即不能用等于、不等于、大于或小于和其它数值比较,当然也包括空值本身(但是在decode中例外,两个空值被认为是等价)。测试空值只能用比较操作符IS NULL 和IS NOT NULL。如果使用带有其它比较操作符的条件表达式,并且其结果依赖于空值,那么其结果必定是NULL。在where条件中,Oracle认为结果为NULL的条件为FALSE,带有这样条件的select语句不返回行,也不返回错误信息。

 新增或修改记录某字段为‘’时,到数据库中此字段就是null(数据库的缺省值也是null)查询时,不能用 的方式,只能 is null或is not null 

三者的区别就是:
isnull是一种类型测试,测试是否为空值(null)类型。
isEmpty是一种值测试,测试是否是空值。但这个不同语言中采用的方法不同。
=""是串测试,测试值是否为空值。

 创建数据库的时候,对某个字段定义了 NOT NULL,但是,在写入数据的时候,空字符串''也能写入成功:

空 (NULL) 值表示数值未知。空值不同于空白或零值。没有两个相等的空值。比较两个空值或将空值与任何其它数值相比均返回未知,这是因为每个空值均为未知。

在写入数据的时候,空字符串'' 也是一个确定的值,所以就算你定义了 NOT NULL 也可以被写入。

在定义中说,空值不与任何值相等。因此不能使用 = null 做判断。在Sql语句中,唯一可以使用 = null的就是update语句中的赋值语句,其他地方都不可以使用。


11.GOUP BY分组与统计函数


group by -- 当出现group by分组中不能配对的情况,该字段取查询时候第一次出现的值
统计函数:
max()--最大值;
min()--取最小值;
avg()--求平均值;    
sum()--求和;
count()--计算行数/条数;    
distinct()--求有多少种不同解;
 

【时间是以时间戳的形式存放的,是int型,max() --最新商品; min() -- 最旧商品】
having筛选结果集

【where子句针对的对象是磁盘上的数据表文件去select的,而select出来后的数据是存放在内存中的一个零时"结果集"】
--因此:当使用where min >200 ;去筛选结果集的时候是不能识别出min字段的
having--针对的对象是内存表结构中的"结果集"

如果同时写了where和having子句,where子句肯定要写在having子句前面,因为having子句是针对where子句查询出来的结果集来操作的

order by排序查询【在内存中排序】 与 limit范围查询【--经典应用:分页类】


12. 连接查询

内连接查询[inner join]、左连接[left join]、右连接[right join]

【MySQL中没有外连接】
详解:http://www.dedecms.com/knowledge/data-base/sql-server/2012/0709/2872.html
内连接:select xxxx from table1 inner join table2 on table1.xx=table2.xx ☛ 交集
左连接:select xxxx from table1 left join table2 on table1.xx=table2.xx ☛ 左表为基础的查询
右连接:select xxxx from table1 right join table2 on table1.xx=table2.xx ☛ 右表为基础的查询


注意:既然左右连接可以互换,尽量用左连接,出于移植时兼容性方面的考虑.

内连接的特点
内连接是左右连接的交集

左右连接的并集,这种叫做外连接,但是,在mysql中不支持外连接


13.SQL语言之DDL


13.1 建"表"过程

申明数据库中各个"列"的过程

☛ create table  table_name ( 列名 列类型 [列属性 列默认值]) ENGINE = 存储引擎 default charset=字符集;

设计"表"结构☛对"列"的优化☛"列"选什么类型?列选什么属性最好?


13.2 列类型知识


数值型:整型、浮点型、定点型 字符串:char varchar text,... 日期时间:datetime, time,
一种类型,占得字节越多,存储越大,也越浪费

13.2.1 :整型列
bigint 8个字节
int 4个字节【1个字节=8位☛4个字节=32位--也就是"1"这个int型只占了32位中1个位】
mediumint 3个字节
smallint 2个字节
tinyint 1个字节 【8位==> 0-255 或 -128 - 127】
1)像tinyint中,默认数值型都是对半正负分配的==>即:正常情况下tinyint是不能存储大于128的数字的!
那么,如何让tinyint存储0-255之间的数呢?
使用unsigned属性【无符号】修饰;

zerofill==>用0填充至固定宽度【学号:1->0001;255 ->0255】

M -> 宽度 tinyint(5)-->宽度为5;

varchar(10)->宽度为10

注意:

①zerofill属性就已经代表了该类型为是unsigned属性了==>负数不需要用0填充

②M属性只有和zerofill配合使用才有意义!宽度是指0填充的宽度,而不是指该列存储的宽度【如:tinyint(1) 可以存储111】


13.2.2浮点列[float/doule]与定点列[decimal]

浮点列:float/double (M,D) [UNSIGNED] [ZEROFILL] -- M表示精度【总位数】,D表示小数点后面的位数
如:float(3,2)--存10==>错误:其实这里有4位了10.00;
float(3,2)==>存9.99正确
定点列decimal[整数部分和小数部分分开来存储的]

浮点数是有精度损失的!定点列更准确


13.2.3 字符型列[char/varchar]

①char(M)--定长;varchar(M) -- 变长

例如:
char(10) -- 放10个字符长度,但是存放1个字符,在内存中依然是占10个字符长度

--char(M) 在磁盘上就占M个字节,磁盘空间利用率可能达到100%


varchar(10) -- 放10个字符长度,但是存放1个字符,在内存中就占了1个字符长度的空格键
--varchar(M) 在内存表中存储时,在表头会增加1-2说明字节存储该字符串长度==>那么内存寻址的时候就能准确找到每一行数据==>实际varchar占M+[1/2]字节
小技巧:一般对于M较小的,都用char!
1).因为varchar的利用率是不可能达到100%!
2).内存的定长寻址会快很多
3).char型,如果不够M个宽度,内存存储时候会用空格在字符右边补齐,取出时候把右侧空格删除
如果用char存储' hello ',取出之后' hello';用varchar存,取出时候' hello '
②text -- 大文本类型;blob -- 二进制类型

例如:论文、博客...等大段文本text
图像、音频等二进制信息用blob类型来存储
意义:blob是使用二进制来存储信息的,因此不需要考虑字符集的问题!
例如0xFF这个字节,在ASCII字符集中被认为是非法的,在入库的时候就会被过滤掉!如果使用blob来存储则不会被过滤
 

13.2.4enum('value1','value2',...) -- 枚举类型;set('value1','value2',...) -- 集合类型

例如:
enum('男','女') ☛ 该列所存储的值就只能是'男'或'女' ☛ 是个单选值存储
set('value1','value2',...) ☛ 是个复选值存储,但值也只能在列举的元素中选取

注意:set()最多只能列举64个值!


13.2.5 日期时间型列[char/varchar]
year 年 [1个字节] 范围:[1901-2155] ☛ 在insert是,可以简写年后面对两位,但是这样不推荐
【00-69】+2000;【70-99】+1900 ☛ 填写两位,表示1970-2069年✘不要只写后面2个数字
Date 日期 1994-10-29
☛ 以'YYYY-MM-DD HH:MM:SS'格式检索和显示DATETIME值。支持的范围为'1000-01-01 00:00:00'到'9999-12-31 23:59:59'
time 时间 13:02:29
☛ 用'YYYY-MM-DD'格式检索和显示DATE值。支持的范围是'1000-01-01'到 '9999-12-31'
datetime 日期
☛ 以'YYYY-MM-DD HH:MM:SS'格式检索和显示DATETIME值。支持的范围为'1000-01-01 00:00:00'到'9999-12-31 23:59:59'
int unsigned 时间戳 1970-01-01 00:00:00 到当前的秒数

☛ 一般存注册时间,商品发布时间等,并不是用datetime,而是用时间戳存储,因为datetime存储虽然直观,但不便计算


13.2 列属性

列属性 ☛ 默认值[ default ]&& not null


1.NULL不便于查询【注意:空字数串,0都不是NULL--NULL是什么都没有,是不存在】
not null default xxxx
 列属性 ☛ 主键[ primary key ] && 自增[ auto_increment ]

1.此列不重复,能够区分每一行==>列名 primary key auto_increment
一般主键和自增是一起使用的[int类型],不一定一要一起使用!一张表中只能有一个自增的列!
小技巧:
1.很多时候都是用tinyint存储☛性别:0/1 --> 男/女;体重:tinyint 【0-255】....
2.定长存储寻址快,效率高--常用的字段建议定长存储【对于一张表,只有一个变长大字段其他都是定长字段情况下,可考虑将变长单独分出来】
3.一般mysql的列名都用小写
2_7 列的增add/删/改 ☛ 这是对表结构的修改

增:alter table 表名 add 列名 列类型 [列属性] -- 默认该列是存放在表最后的【使用 after 列名 --放在指定列】
删:alter table 表名 drop column 列名 列类型 [列属性]
改:alter table 表名 change 旧列名 新列名 [新列类型] [新列属性]
改:alter table 表名 modify 列名 [新列类型] [新列属性] --modify 不能修改列名


14. 视图


1).什么是视图?

view 又称虚拟表,view其实就一条查询SQL语句的结果集==>将常用的SQL查询结果集虚拟为一张表存放在内存中

create view as 视图名 (查询SQL语句结果集);--当再次使用时:select * from 视图名


2).视图有什么用?【视图实际上存储的就是SQL语句】

①权限的控制!比如:某几个列允许用户查询,而其他列不允许,可以通过视图开放其中的一部分列,达到权限的控制
②简化复杂的查询!比如:查询每个栏目下的商品的平均价格并按平均价格排序,然后查出平均价格前3高的栏目
①create view v as select cat_id, avg(shop_price) as pj from goods group by cat_id

②select * from v order by pj limit 0,3


3).视图能不能更新删除修改

①视图【虚拟表】☛ 是物理表的一个"投影",两者是相互影响的☛更改物理表,虚拟表也会更改,同理,更改虚拟表,物理表也会更改!
但是:如果虚拟表中含有函数(经过计算...),则不能修改!【即物理表和虚拟表的列能一一对应,则虚拟表中该列能修改--改一行影响一行】
①create view as v select cat_id, avg(shop_price) as pj from goods group by cat_id
②update v set pj = 80 where cat_id=11;--报错!因为修改结果不能正确映射回到goods表中所有shop_price中

同理:增加和删除操作也是和修改一样


4).视图放在什么地方?

①对于VIEW存储的SQL语句是简单的select语句,所以当对视图查询时候就是对SQL语句的拼接==>对物理表的间接拼接查询(合并:merge)
②对于VIEW存储的SQL语句已经是逻辑复杂的select语句了,这时对视图的拼接查询会更麻烦!
==>这时候mysql会先执行视图的创建语句,把结果集形成一张临时表,再对临时表(temptable)进行操作
MySQL数据库中可以通过algorithm(算法)定义对视图的处理情况 create algorithm = merge/temptalbe view v_name as ...
[不写该属性,则由MySQL自行判断]



15. 存储引擎[ENGINE]


1).什么是存储引擎?

即:保存"数据"的形式【格式】
MYISAM:【处理快-相对不安全-不支持事务】
good.frm--说明书[声明表结构的表具体语句]
good.MYD--数据内容
goods.MYI--目录[索引文件]
InnoDB【安全-处理慢-支持事务】--只有.frm文件,其余表的其余全部内容存放在了一个文件中
Memory【存放在内存中--一关机就没有了】



16.字符集与乱码问题


1.什么是乱码?

对计算机来说,没有"乱码",只有0/1==>乱码:人看不懂!
2.为什么会乱码?

①导致原因:文字本来的字符集与展示的字符集不一致
==>一般统一utf8;
②服务器和客户端字符集不一致!
客户端[GBK提交数据]==>连接器处理[转换为数据库字符集]==>数据库[UTF8存放数据]【无论连接器转不转,最终存放到数据库中都是UTF8】
数据库[UTF8存放数据]==>连接器处理[转换为客户端字符集]==>客户端[GBK显示数据]

☛由于客户端和数据库字符集不同导致的乱码==>在提交和显示数据的时候,要"说清楚"字符集
==>"我"要什么字符集?==>客户端:set character_set_client =gbk;【谁连接服务器谁就是客户端,客户端字符集是多变的】
==>"你"接受什么字符集?==>数据库:set character_set_results=utf8;
==>"转换"用什么字符集?==>连接器:set character_set_connection = gbk/utf8[都可以]
只需要将3者的字符集设置一致不会乱码了!==>set names gbk/utf8 ==> 1句好比3句强
UTF8:包含中文,韩文,日文,英语,繁体字...国际化
GBK:只有简体中文

gbk2123:简体中文+英文


3.怎么能不乱码?

①文件保存时是否保存为utf8格式
②HTML页面显示时候 :
③创建数据表的时候: create table () charset utf8;

④查询数据的时候:set names utf8;


4.什么是字符校对集?

[utf8-bin==>bin : 二进制排序]==>校对集就是查询排序的标准
 

17. 索引[ index ]


1).查询方式?

当表中有大量记录时,若要对表进行查询:
①全表搜索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记录
☛消耗大量数据库系统时间,并造成大量磁盘I/O操作
②第二种就是在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索引中的ROWID(相当于页码)快速找到表中对应的记录
2).什么是索引?

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息!
--相当于图书的"目录",根据目录,迅速定位查找内容的位置
3).索引优/缺点?

优点:
①加快了查询时对数据的检索速度
②创建唯一性索引,保证数据库表中每一行数据的唯一性
③加速表和表之间的连接

④在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间


缺点:
①索引是另外独立于数据外存放的一个二进制文件==>需要占物理空间( .MYI )
②对表数据进行增、删和改的维护操作时,索引也要动态的变化==>降低了数据增、删、改的维护速度
☛在创建索引之前,您必须确定要使用哪些列以及要创建的索引类型!
☛索引不是越多越好==>一般在查询频率多、且重复度小的列上加!
例如:性别和身份号都需要频繁查询,且表数据量大
==>性别:就只有男和女,定位的时候有太多重复的了,添加索引反而是占用了空间!
==>身份证号:添加索引,身份证号是唯一的,只要快速找到索引就能快速定位
4).索引类型

①key 列名(索引名)==> 普通索引==>纯粹提高查询速度
②unique key 列名(索引名)==> 唯一索引 ==>提高速度,且约束数据唯一性
③primary key 列名 ==> 主键索引==>唯一主键

④fulltext ==> 全文索引 ==> 在中文环境下,基本不起作用,要分词索引,一般用第三方解决方案(如:sphinx)


1. 普通索引 create INDEX name_index on person(name);
2. 唯一索引 create unique INDEX name_age on person(name,age);
3. 主键索引 alter table person MODIFY id int PRIMARY key;
4. 组合索引 create unique INDEX name_age on person(name,age);
5. 全文索引 full text :原理是分词查找


5).索引长度:

[在建立索引时,对列中一部分字符进行索引]
①unique key / key 列名(索引名 (索引长度) )

例如:对于唯一的Email,形式都是.....@qq.com


6).多列索引:

[在建立索引时,对2个或多个列进行索引]
7).冗余索引:

[索引存在覆盖]==>冗余索引有时候在开发中是必要的


8).操作索引:

①查看索引:show index table_name;

②添加索引:alter table table_name add index index_name(column_list )

  创建索引

在执行CREATE TABLE语句时可以创建索引,也可以单独用CREATE INDEX或ALTER TABLE来为表增加索引。

ALTER TABLE

ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。

ALTER TABLE table_name ADD INDEXindex_name (column_list)
ALTER TABLE table_name ADD UNIQUE(column_list)
ALTER TABLE table_name ADD  PRIMARY KEY(column_list)

CREATE INDEX

CREATE INDEX可对表增加普通索引或UNIQUE索引。

CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)

其中table_name是要增加索引的表名,column_list指出对哪些列进行索引,多列时各列之间用逗号分隔。索引名index_name可选,缺省时,

MySQL将根据第一个索引列赋一个名称。另外,ALTER TABLE允许在单个语句中更改多个表,因此可以在同时创建多个索引。




查看索引

show index from tblname;
show keys fromtblname


删除索引

可利用ALTER TABLE或DROP INDEX语句来删除索引。类似于CREATE INDEX语句,DROP INDEX可以在ALTER TABLE内部作为一条语句处理,语法如下。


DROP     INDEX index_name ON  talbe_name
ALTER   TABLE table_name DROP INDEX  index_name
ALTER   TABLE table_name DROP  PRIMARY KEY

其中,前两条语句是等价的,删除掉table_name中的索引index_name。
第3条语句只在删除PRIMARY KEY索引时使用,因为一个表只可能有一个PRIMARY KEY索引,因此不需要指定索引名。如果没有创建PRIMARY KEY索引,

但表具有一个或多个UNIQUE索引,则MySQL将删除第一个UNIQUE索引。
如果从表中删除了某列,则索引会受到影响。对于多列组合的索引,如果删除其中的某列,则该列也会从索引中删除。如果删除组成索引的所有列,则整个索引将被删除。


添加主键索引: alter table table_name add primary key column
删除主键索引: alter table table_name drop primary key;

18.事物

事务:

事务的acid特性

通俗的说,一组操作要么都成功执行,要么都不执行。à原子性(atomicity


在所有操作都没有执行完毕之前,其他会话不能够看到中间改变的过程。à隔离性(isolation


事务发生之前和发生之后数据的总额依然匹配。à一致性(consistency


事务产生的影响不能够撤销à持久性(durability


如果出现了错误,事务也不允许撤销,只能够补偿事务

原子性体现的是不可分割性,不可见性。

转账

李三 à支出500,李三-500

赵四 à收到500,赵四+500

关于事务的引擎:选用innoDB/bdb

查看mysql 服务器的模式:

Show variables like ‘zmodez’;

 

语法:

开启事务:

Sql…

Sql…

Commit提交/rollback回滚

注意:当一个事务commit或者roolback之后,事务就已经结束。

只要事务没有提交或回滚,事务处理都会看不见.

 

事物的基本原理(了解)




19.触发器

1. 触发器:trigger,(枪击,扳机,引线)见识某种情况,并触发某种操作。能监视增删改,触发操作:增删改

2. 当向一张表中添加或删除记录时,需要在相关表中进行同步操作。比如:当一个订单产生时,订单所购的商品的库存量相应减少。

当表上某列数据的值与其他表中的数据有联系时。

比如:当某客户进行欠款消费,可以在生成订单时通过设计触发器判断该客户的累计欠款是否超过了最大限度。

当需要对某张表进行跟踪时。

比如:当有新订单产生时,需要及时通知相关人员进行处理,此时可以在订单表上设计添加触发器加以实现。


触发器创建语法之4要素

3. 监视地点:table,监视事件:insert/update/delete,触发时间:after/before,触发事件:insert/update/delete

 

首先需要修改:

Delimiter $,遇到$结束语句开始执行。

创建触发器语法:

Create trigger triggerName

After/before insert/update/delete on 表名

For each row

Begin

Sql语句

End


例如:

--修改分隔符
delimiter $

CREATE TRIGGER name
BEFORE INSERT ON test
for EACH ROW
BEGIN
INSERT INTO mysql_test (id,NAME) VALUES (1,'test');
END$


删除触发器的语法:

 Drop trigger triggerName


for each row

 每一行受影响,触发器都执行,叫做行级触发器;

在oracle中

for each row如果不写,

无论update语句一次影响了多少行,都会只执行1次。mysql目前不支持语句级触发


如何在触发器中引用行的值,

对于insert而言,新增的行用new来表示,行中的每一列的值,用new.列名来表示。

 对于delete来说,原本有一行,后来被删除想引用被删除的这一行,用old来表示,old列名就可以引用被删行中的值。

对于update来说,原本有一行,修改后还是那一行,修改前的数据用old来表示,old列名引用被修改之前行中的值,修改后的数据用new来表示,new列名引用被修改之前前行中的值,

例:

 

触发器里afterbefore的区别

After是先完成数据的增删改,再触发,触发中的语句晚于增删改,不能对前面的增删改产生影响

Before是先完成触发,再增删改,触发的语句先于监视增删改,我们有机会判断,修改即将发生的操作

 

典型案例:

对于所下订单进行判断,如果订单数量>5就是认为恶意订单,强制把所订的商品数量改成5


查看所有的触发器

Show triggers


20.存储过程

存储过程:

类似于函数,就是把一段代码封装起来,当要执行这一段代码时,可以调用该存储过程来实现。在封装语句体里面,可以用if/else,case,while等控制结构,可以进行sql编程。

存储过程就是有业务逻辑和流程的集合, 可以在存储过程中创建表,更新数据, 删除等等。

为什么要使用存储过程

  1. 通过把处理封装在容易使用的单元中,简化复杂的操作(正如前面例子所述)。
  2. 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一(试验和测试)存储过程,则所使用的代码都是相同的。这一点的延伸就是防止错误。需要执行的步骤越多,出错的可能性就越大。防止错误保证了数据的一致性。
  3. 简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,只需要更改存储过程的代码。使用它的人员甚至不需要知道这些变化。

一个简单的存储过程

delimiter $

CREATE  PROCEDURE test(in userid int,out tname char(10))
BEGIN
SELECT name FROM test WHERE test.id=userid
INTO tname;
END

存储过程用create procedure 创建, 业务逻辑和sql写在begin和end之间。mysql中可用call porcedureName ();来调用过程

查看现有的存储过程

Show procedure status


-- 调用过程

该存储过程没有参数, 只是在调用的时候查询了用户表的用户名而已, 调用结果如下

CALL test1(1,@tname);

SELECT * FROM test WHERE name=@tname;

删除存储过程

Drop procedure 存储过程的名字

  1. DROP PROCEDURE IF EXISTS porcedureName; -- 没有括号() 

使用参数的存储过程

  1. create procedure procedureName( 
  2.     out min decimal(8,2), 
  3.     out avg decimal(8,2), 
  4.     out max decimal(8,2) 
  5. BEGIN 
  6.     select MIN(price) INTO min from order
  7.     select AVG(price) into avg from order
  8.     select MAX(price) into max from order
  9. END 

此过程接受三个参数, 分别用于获取订单表的最小、平均、最大价格。每个参数必须具有指定的类

型,这里使用十进制值(decimal(8,2)), 关键字OUT指出相应的参数用来从存储过程传出

一个值(返回给调用者)

MySQL支持IN(传递给存储过程)、OUT(从存储过程传出,如这里所用)和INOUT(对存储过程传入和传出)类型的参数。存储过程的代码位于BEGIN和END语句内,如前所见,它们是一系列SELECT语句,用来检索值,然后保存到相应的变量(通过指定INTO关键字)

为调用此修改过的存储过程,必须指定3个变量名,如下所示:(所有MySQL变量都必须以@开始。)

  1. -- 由于过程指定三个参数, 故调用必须要参数匹配 
  2. call procedureName(@min, @avg, @max);  

该调用并没有任何输出, 只是把调用的结果赋给了调用时传入的变量(@min, @avg, @max)。然后即可调用显示该变量的值。

  1. select @min, @avg, @max

结果如下

@min@avg@max42.00601.002222.00

使用in参数, 输入一个用户id, 返回该用户所有订单的总价格。

  1. create procedure getTotalById ( 
  2.     in userId int
  3.     out total decimal(8,2) 
  4. BEGIN 
  5.     select SUM(r.price) from order r 
  6.     where r.u_id = userId 
  7.     into total; 
  8. END 

调用存储过程

  1. call getTotalById(1, @total); 
  2. select @total;  

结果将返回该用户所有订单的合计价格。

复杂一点的过程, 根据用户id获取该用户的所有订单价格, 并动态的选择是否加税。代码设计如下

  1. create procedure getTotalByUser2( 
  2.     in userId int
  3.     in falg boolean, -- 是否加税标记 
  4.     out total decimal(8,2) 
  5. begin 
  6.     DECLARE tmptotal DECIMAL(8,2); 
  7.     DECLARE taxrate int DEFAULT 6;-- 默认的加税的利率 
  8.      
  9.     select SUM(r.price) from order r 
  10.     where r.u_id = userId 
  11.     into tmptotal; 
  12.      
  13.     if taxable then 
  14.         select tmptotal + (tmptotal/1000*taxrate) into tmptotal; 
  15.     end if; 
  16.      
  17.     select tmptotal into total; 
  18. END 

该过程传入三个参数, 用户id, 是否加税以及返回的总价格,在过程内部, 定义两个局部变量tmptotal和taxrate,把查询出来的结果赋给临时变量, 在判断是否加税。最后把局部变量的值赋给输出参数。

  1. call getTotalByUser2(1, false, @total); -- 不加税 
  2. call getTotalByUser2(1, true, @total);  -- 加税 
  3. select @total;







21.case

mysql数据库中CASE WHEN语句。

case when语句,用于计算条件列表并返回多个可能结果表达式之一。

CASE 具有两种格式:

简单 CASE 函数将某个表达式与一组简单表达式进行比较以确定结果。
CASE 可能是 SQL 中被误用最多的关键字之一。虽然你可能以前用过这个关键字来创建字段,但是它还具有更多用法。例如,你可以在 WHERE 子句中使用CASE。

CASE 搜索函数计算一组布尔表达式以确定结果。 两种格式都支持可选的 ELSE 参数。

语法
简单 CASE 函数:

CASE input_expression    WHEN when_expression THEN result_expression        [ ...n ]        ELSE else_result_expression    END

SELECT      Title,     'Price Range' =     CASE         WHEN price IS NULL THEN 'Unpriced'         WHEN price < 10 THEN 'Bargain'         WHEN price BETWEEN 10 and 20 THEN 'Average'         ELSE 'Gift to impress relatives'     END FROM titles ORDER BY price

详解:https://www.cnblogs.com/hwaggLee/p/5336097.html


21.游标



22.MySQL权限控制

  那么Mysql的权限是如何实现的呢?这就要说到mysql的两阶段验证,下面详细介绍:

第一阶段:服务器首先会检查你是否允许连接。因为创建用户的时候会加上主机限制,可以限制成本地、某个IP、某个IP段、以及任何地方等,

只允许你从配置的指定地方登陆。

第二阶段:如果你能连接,Mysql会检查你发出的每个请求,看你是否有足够的权限实施它。比如你要更新某个表、或者查询某个表,

Mysql会查看你对哪个表或者某个列是否有权限。再比如,你要运行某个存储过程,Mysql会检查你对存储过程是否有执行权限等。


    MYSQL到底都有哪些权限呢?从官网复制一个表来看看:

权限

权限级别

权限说明

CREATE

数据库、表或索引

创建数据库、表或索引权限

DROP

数据库或表

删除数据库或表权限

GRANT OPTION

数据库、表或保存的程序

赋予权限选项

REFERENCES

数据库或表

 

ALTER

更改表,比如添加字段、索引等

DELETE

删除数据权限

INDEX

索引权限

INSERT

插入权限

SELECT

查询权限

UPDATE

更新权限

CREATE VIEW

视图

创建视图权限

SHOW VIEW

视图

查看视图权限

ALTER ROUTINE

存储过程

更改存储过程权限

CREATE ROUTINE

存储过程

创建存储过程权限

EXECUTE

存储过程

执行存储过程权限

FILE

服务器主机上的文件访问

文件访问权限

CREATE TEMPORARY TABLES

服务器管理

创建临时表权限

LOCK TABLES

服务器管理

锁表权限

CREATE USER

服务器管理

创建用户权限

PROCESS

服务器管理

查看进程权限

RELOAD

 

 

服务器管理

执行flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads, refresh, reload等命令的权限

REPLICATION CLIENT

服务器管理

复制权限

REPLICATION SLAVE

服务器管理

复制权限

SHOW DATABASES

服务器管理

查看数据库权限

SHUTDOWN

服务器管理

关闭数据库权限

SUPER

服务器管理

执行kill线程权限

 

    MYSQL的权限如何分布,就是针对表可以设置什么权限,针对列可以设置什么权限等等,这个可以从官方文档中的一个表来说明:

权限分布

可能的设置的权限

表权限

'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'

列权限

'Select', 'Insert', 'Update', 'References'

过程权限

'Execute', 'Alter Routine', 'Grant'

 二、MySQL权限经验原则:

    权限控制主要是出于安全因素,因此需要遵循一下几个经验原则:

    1、只授予能满足需要的最小权限,防止用户干坏事。比如用户只是需要查询,那就只给select权限就可以了,不要给用户赋予update、insert或者delete权限。

    2、创建用户的时候限制用户的登录主机,一般是限制成指定IP或者内网IP段。

    3、初始化数据库的时候删除没有密码的用户。安装完数据库的时候会自动创建一些用户,这些用户默认没有密码。

    4、为每个用户设置满足密码复杂度的密码。

    5、定期清理不需要的用户。回收权限或者删除用户。

三、MySQL权限实战:

    1、GRANT命令使用说明:

    先来看一个例子,创建一个只允许从本地登录的超级用户jack,并允许将权限赋予别的用户,密码为:jack.

mysql> grant all privileges on *.* to jack@'localhost' identified by "jack" with grant option;Query OK, 0 rows affected (0.01 sec)

    GRANT命令说明:
    ALL PRIVILEGES 是表示所有权限,你也可以使用select、update等权限。

    ON 用来指定权限针对哪些库和表。

    *.* 中前面的*号用来指定数据库名,后面的*号用来指定表名。

    TO 表示将权限赋予某个用户。

    jack@'localhost' 表示jack用户,@后面接限制的主机,可以是IP、IP段、域名以及%,%表示任何地方。注意:这里%有的版本不包括本地,以前碰到过给某个用户设置了%允许任何地方登录,但是在本地登录不了,这个和版本有关系,遇到这个问题再加一个localhost的用户就可以了。

    IDENTIFIED BY 指定用户的登录密码。

    WITH GRANT OPTION 这个选项表示该用户可以将自己拥有的权限授权给别人。注意:经常有人在创建操作用户的时候不指定WITH GRANT OPTION选项导致后来该用户不能使用GRANT命令创建用户或者给其它用户授权。

备注:可以使用GRANT重复给用户添加权限,权限叠加,比如你先给用户添加一个select权限,然后又给用户添加一个insert权限,那么该用户就同时拥有了select和insert权限。

    2、刷新权限

    使用这个命令使权限生效,尤其是你对那些权限表user、db、host等做了update或者delete更新的时候。以前遇到过使用grant后权限没有更新的情况,只要对权限做了更改就使用FLUSH PRIVILEGES命令来刷新权限。

mysql> flush privileges;Query OK, 0 rows affected (0.01 sec)

    3、查看权限

查看当前用户的权限:mysql> show grants;+---------------------------------------------------------------------+| Grants for root@localhost                                           |+---------------------------------------------------------------------+| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION || GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION        |+---------------------------------------------------------------------+2 rows in set (0.00 sec)查看某个用户的权限:mysql> show grants for 'jack'@'%';+-----------------------------------------------------------------------------------------------------+| Grants for jack@%                                                                                   |+-----------------------------------------------------------------------------------------------------+| GRANT USAGE ON *.* TO 'jack'@'%' IDENTIFIED BY PASSWORD '*9BCDC990E611B8D852EFAF1E3919AB6AC8C8A9F0' |+-----------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)

    4、回收权限

mysql> revoke delete on *.* from 'jack'@'localhost';Query OK, 0 rows affected (0.01 sec)

    5、删除用户

mysql> select host,user,password from user;+-----------+------+-------------------------------------------+| host      | user | password                                  |+-----------+------+-------------------------------------------+| localhost | root |                                           || rhel5.4   | root |                                           || 127.0.0.1 | root |                                           || ::1       | root |                                           || localhost |      |                                           || rhel5.4   |      |                                           || localhost | jack | *9BCDC990E611B8D852EFAF1E3919AB6AC8C8A9F0 |+-----------+------+-------------------------------------------+7 rows in set (0.00 sec)mysql> drop user 'jack'@'localhost';Query OK, 0 rows affected (0.01 sec)

    6、对账户重命名

mysql> rename user 'jack'@'%' to 'jim'@'%';Query OK, 0 rows affected (0.00 sec)

    7、修改密码


  1、用set password命令mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');Query OK, 0 rows affected (0.00 sec)  2、用mysqladmin  [root@rhel5 ~]# mysqladmin -uroot -p123456 password 1234abcd  备注:  格式:mysqladmin -u用户名 -p旧密码 password 新密码  3、用update直接编辑user表  mysql> use mysqlReading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql> update user set PASSWORD = PASSWORD('1234abcd') where user = 'root';Query OK, 1 row affected (0.01 sec)Rows matched: 1  Changed: 1  Warnings: 0mysql> flush privileges;Query OK, 0 rows affected (0.00 sec)  4、在丢失root密码的时候:  [root@rhel5 ~]# mysqld_safe --skip-grant-tables &[1] 15953[root@rhel5 ~]# 130911 09:35:33 mysqld_safe Logging to '/mysql/mysql5.5/data/rhel5.4.err'.130911 09:35:33 mysqld_safe Starting mysqld daemon with databases from /mysql/mysql5.5/data[root@rhel5 ~]# mysql -u rootWelcome to the MySQL monitor.  Commands end with ; or \g.Your MySQL connection id is 2Server version: 5.5.22 Source distributionCopyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> \s--------------mysql  Ver 14.14 Distrib 5.5.22, for Linux (i686) using  EditLine wrapperConnection id:        2Current database:    Current user:        root@SSL:            Not in useCurrent pager:        stdoutUsing outfile:        ''Using delimiter:    ;Server version:        5.5.22 Source distributionProtocol version:    10Connection:        Localhost via UNIX socketServer characterset:    utf8Db     characterset:    utf8Client characterset:    utf8Conn.  characterset:    utf8UNIX socket:        /tmp/mysql.sockUptime:            36 secThreads: 1  Questions: 5  Slow queries: 0  Opens: 23  Flush tables: 1  Open tables: 18  Queries per second avg: 0.138--------------mysql> use mysqlReading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql> update user set password = PASSWORD('123456') where user = 'root';Query OK, 1 row affected (0.00 sec)Rows matched: 1  Changed: 1  Warnings: 0mysql> flush privileges;Query OK, 0 rows affected (0.00 sec)



23. 常用九大类函数

数据库是用来存储管理数据的,能够少用函数来处理尽量少用==>效率慢
1)、数学函数

abs(x) 返回x的绝对值
bin(x) 返回x的二进制(oct返回八进制,hex返回十六进制)
ceiling(x) 返回大于x的最小整数值==>向上取整
exp(x) 返回值e(自然对数的底)的x次方
floor(x) 返回小于x的最大整数值==>向下取整
greatest(x1,x2,...,xn)返回集合中最大的值
least(x1,x2,...,xn) 返回集合中最小的值
ln(x) 返回x的自然对数
log(x,y)返回x的以y为底的对数
mod(x,y) 返回x/y的模(余数)
pi()返回pi的值(圆周率)
rand()返回0或1的随机值,可以通过提供一个参数(种子)使rand()生成器生成1.
round(x,y)返回参数x的四舍五入的有y位小数的值
sign(x) 返回代表数字x的符号的值
sqrt(x) 返回一个数的平方根
truncate(x,y) 返回数字x截短为y位小数的结果
2)、聚合函数(常用于group by从句的select查询中)

avg(col)返回指定列的平均值
count(col)返回指定列中非null值的个数
min(col)返回指定列的最小值
max(col)返回指定列的最大值
sum(col)返回指定列的所有值之和
group_concat(col) 返回由属于一组的列值连接组合而成的结果
3)、字符串函数

ascii(char)返回字符的ascii码值
bit_length(str)返回字符串的比特长度
concat(s1,s2...,sn)将s1,s2...,sn连接成字符串
concat_ws(sep,s1,s2...,sn)将s1,s2...,sn连接成字符串,并用sep字符间隔
insert(str,x,y,instr) 将字符串str从第x位置开始,y个字符长的子串替换为字符串instr,返回结果
find_in_set(str,list)分析逗号分隔的list列表,如果发现str,返回str在list中的位置
lcase(str)或lower(str) 返回将字符串str中所有字符改变为小写后的结果
left(str,x)返回字符串str中最左边的x个字符
length(s)返回字符串str中的字符数
ltrim(str) 从字符串str中切掉开头的空格
position(substr,str) 返回子串substr在字符串str中第一次出现的位置
quote(str) 用反斜杠转义str中的单引号
repeat(str,srchstr,rplcstr)返回字符串str重复x次的结果
reverse(str) 返回颠倒字符串str的结果
right(str,x) 返回字符串str中最右边的x个字符
rtrim(str) 返回字符串str尾部的空格
strcmp(s1,s2)比较字符串s1和s2
trim(str)去除字符串首部和尾部的所有空格
ucase(str)或upper(str) 返回将字符串str中所有字符转变为大写后的结果
4)、日期和时间函数

curdate()或current_date() 返回当前的日期
curtime()或current_time() 返回当前的时间
date_add(date,interval int keyword)返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:selectdate_add(current_date,interval 6 month);
date_format(date,fmt) 依照指定的fmt格式格式化日期date值
date_sub(date,interval int keyword)返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:selectdate_sub(current_date,interval 6 month);
dayofweek(date) 返回date所代表的一星期中的第几天(1~7)
dayofmonth(date) 返回date是一个月的第几天(1~31)
dayofyear(date) 返回date是一年的第几天(1~366)
dayname(date) 返回date的星期名,如:select dayname(current_date);
from_unixtime(ts,fmt) 根据指定的fmt格式,格式化unix时间戳ts
hour(time) 返回time的小时值(0~23)
minute(time) 返回time的分钟值(0~59)
month(date) 返回date的月份值(1~12)
monthname(date) 返回date的月份名,如:select monthname(current_date);
now() 返回当前的日期和时间
quarter(date) 返回date在一年中的季度(1~4),如select quarter(current_date);
week(date) 返回日期date为一年中第几周(0~53)
year(date) 返回日期date的年份(1000~9999)
一些示例:
获取当前系统时间:select from_unixtime(unix_timestamp());
select extract(year_month from current_date);
select extract(day_second from current_date);
select extract(hour_minute from current_date);
返回两个日期值之间的差值(月数):select period_diff(200302,199802);
在mysql中计算年龄:
select date_format(from_days(to_days(now())-to_days(birthday)),'%y')+0 as age from employee;
这样,如果brithday是未来的年月日的话,计算结果为0。
下面的sql语句计算员工的绝对年龄,即当birthday是未来的日期时,将得到负值。
select date_format(now(), '%y') - date_format(birthday, '%y') -(date_format(now(), '00-%m-%d') < date_format(birthday, '00-%m-%d')) as age from employee
5)、加密函数

aes_encrypt(str,key) 返回用密钥key对字符串str利用高级加密标准算法加密后的结果,调用aes_encrypt的结果是一个二进制字符串,以blob类型存储
aes_decrypt(str,key) 返回用密钥key对字符串str利用高级加密标准算法解密后的结果
decode(str,key) 使用key作为密钥解密加密字符串str
encrypt(str,salt) 使用unixcrypt()函数,用关键词salt(一个可以惟一确定口令的字符串,就像钥匙一样)加密字符串str
encode(str,key) 使用key作为密钥加密字符串str,调用encode()的结果是一个二进制字符串,它以blob类型存储
md5() 计算字符串str的md5校验和
password(str) 返回字符串str的加密版本,这个加密过程是不可逆转的,和unix密码加密过程使用不同的算法。
sha() 计算字符串str的安全散列算法(sha)校验和
示例:
select encrypt('root','salt');
select encode('xufeng','key');
select decode(encode('xufeng','key'),'key');#加解密放在一起
select aes_encrypt('root','key');
select aes_decrypt(aes_encrypt('root','key'),'key');
select md5('123456');
select sha('123456');

6)、控制流函数

mysql有4个函数是用来进行条件操作的,这些函数可以实现sql的条件逻辑,允许开发者将一些应用程序业务逻辑转换到数据库后台。
mysql控制流函数:
case when[test1] then [result1]...else [default] end如果testn是真,则返回resultn,否则返回default
case [test] when[val1] then [result]...else [default]end  如果test和valn相等,则返回resultn,否则返回default
if(test,t,f)   如果test是真,返回t;否则返回f
ifnull(arg1,arg2) 如果arg1不是空,返回arg1,否则返回arg2
nullif(arg1,arg2) 如果arg1=arg2返回null;否则返回arg1
这些函数的第一个是ifnull(),它有两个参数,并且对第一个参数进行判断。
    ==>如果第一个参数不是null,函数就会向调用者返回第一个参数;如果是null,将返回第二个参数。
如:select ifnull(1,2), ifnull(null,10),ifnull(4*null,'false');
nullif()函数将会检验提供的两个参数是否相等,如果相等,则返回null,如果不相等,就返回第一个参数。
如:select nullif(1,1),nullif('a','b'),nullif(2+3,4+1);
和许多脚本语言提供的if()函数一样,mysql的if()函数也可以建立一个简单的条件测试,这个函数有三个参数:
    ==>第一个是要被判断的表达式,如果表达式为真,if()将会返回第二个参数,如果为假,if()将会返回第三个参数。
如:selectif(1<10,2,3),if(56>100,'true','false');
if()函数在只有两种可能结果时才适合使用。然而,在现实世界中,我们可能发现在条件测试中会需要多个分支。
   ---在这种情况下,mysql提供了case函数,它和php及perl语言的switch-case条件例程一样。
case函数的格式有些复杂,通常如下所示:
case [expression to be evaluated]
when [val 1] then [result 1]
when [val 2] then [result 2]
when [val 3] then [result 3]
......
when [val n] then [result n]
else [default result]
end
    这里,第一个参数是要被判断的值或表达式,接下来的是一系列的when-then块,每一块的第一个参数指定要比较的值,如果为真,就返回结果。
    所有的when-then块将以else块结束,当end结束了所有外部的case块时
    ==>如果前面的每一个块都不匹配就会返回else块指定的默认结果。如果没有指定else块,而且所有的when-then比较都不是真,mysql将会返回null。
case函数还有另外一种句法,有时使用起来非常方便,如下:
case
when [conditional test 1] then [result 1]
when [conditional test 2] then [result 2]
else [default result]
end
这种条件下,返回的结果取决于相应的条件测试是否为真。
示例:
mysql>select case 'green'
     when 'red' then 'stop'
     when 'green' then 'go' end;
select case 9 when 1 then 'a' when 2 then 'b' else 'n/a' end;
select case when (2+2)=4 then 'ok' when(2+2)<>4 then 'not ok' end asstatus;
select name,if((isactive = 1),'已激活','未激活') as result fromuserlogininfo;
select fname,lname,(math+sci+lit) as total,
case when (math+sci+lit) < 50 then 'd'
when (math+sci+lit) between 50 and 150 then 'c'
when (math+sci+lit) between 151 and 250 then 'b'
else 'a' end
as grade from marks;
select if(encrypt('sue','ts')=upass,'allow','deny') as loginresultfrom users where uname = 'sue';#一个登陆验证
 

7)、格式化函数

date_format(date,fmt) 依照字符串fmt格式化日期date值
format(x,y) 把x格式化为以逗号隔开的数字序列,y是结果的小数位数
inet_aton(ip) 返回ip地址的数字表示
inet_ntoa(num) 返回数字所代表的ip地址
time_format(time,fmt) 依照字符串fmt格式化时间time值
其中最简单的是format()函数,它可以把大的数值格式化为以逗号间隔的易读的序列。
示例:
select format(34234.34323432,3);
select date_format(now(),'%w,%d %m %y %r');
select date_format(now(),'%y-%m-%d');
select date_format(19990330,'%y-%m-%d');
select date_format(now(),'%h:%i %p');
select inet_aton('10.122.89.47');
select inet_ntoa(175790383);

8)、类型转化函数

为了进行数据类型转化,mysql提供了cast()函数,它可以把一个值转化为指定的数据类型。类型有:binary,char,date,time,datetime,signed,unsigned 示例:
select cast(now() as signed integer),curdate()+0;
select 'f'=binary 'f','f'=cast('f' as binary);

9)、系统信息函数

database() 返回当前数据库名
benchmark(count,expr) 将表达式expr重复运行count次
connection_id() 返回当前客户的连接id
found_rows() 返回最后一个select查询进行检索的总行数
user()或system_user() 返回当前登陆用户名
version() 返回mysql服务器的版本
示例:
select database(),version(),user();

selectbenchmark(9999999,log(rand()*pi()));#该例中,mysql计算log(rand()*pi())表达式9999999次。




参考:https://www.cnblogs.com/lms520/p/5427685.html


原创粉丝点击