宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

作者:Poetry 转自:http://blog.poetries.top/2016/05/26/mysql%E7%AC%94%E8%AE%B0%E6%95%B4%E7%90%86/

 

第一部分:DML–数据库操作语言

常用表管理语句:

set names gbk;–设置字符编码
查看所有数据库:show databases;
查看所有表:show tables
查看表结构:desc 表名/视图名
use 表名;–选择表
查看建表过程:show create table 表名
查看建视图过程:show create view 视图
查看所有详细表信息:show table status\G让结果显示好看一些)
查看某张表详细信息:show table status where name=’goods(表名)’\G
删除表:drop table 表名
删除视图:drop view 视图名;
删除列:alter table drop column 指定列
改表名:rename table oldName to newName
更新表:update 表名 set 字段
插入数据:insert into 表名 value)
清空数据:truncate 表名;相当于删除表在重建)
写错语句退出:\c
让结果显示好看一些:\G

insert:

insert into 表名 插入列与值要严格对应

数字不必加单引号 字符串必须加单引号

例子:insert into testage,name)values10,’小明’);

update操作:

例子:update user set age=8 where name=lianying;(注意where条件不加会影响所有行,需要小心)

delete操作:

不可能针对某一列删除 要删必须一行
delete from 表名 where 添加

delete from user where uid=1;(必须加上添加,否则全部数据删除)

select查找:

select * from 表名(全部查出)
select uid,name from user where uid>10;
select * from user where uid=11;

select查询模型(重要):

select * from 表名 where 1(where是一个表达式 为真则取出来 为假不取)

把列看成变量,既然是变量就能参与运,。这个过程称为广义投影(比如:取出两列参与运算) 也可以带到函数里面计算

查询练习:

子查询可以查出一个栏目下所有字栏目的商品
模糊查询:where 字段 like ‘%A%’ –%代表任意字符 _代表单一字符

注意:NULL:查询方法: select * from test where name is (not)null

group分组与统计函数:

统计函数:
max)
count)
avg)
min)
sum)

在sql中重复要用的语句:用as名字新变量,以便调用

select goods_id,goods_name,market_price-shop_price) as save from goods

having — 对查询出来的结果集进行筛选
where 不能写在having后面

order by :默认升序asc) 降序asc(排序很浪费资源)
select goods_id,goods_name,shop_price from goods order by shop_price desc;

limit用法:(做分页类能用到)

限制取出条目(limit有两个参数 :偏移量 取出的条目)

select goods_id,goods_name,shop_price
-> from goods
-> order by shop_price desc
-> limit 0,3;

子句的查询陷阱:

5种语句有严格的顺序,where ,group by,having,order by,limit
不能颠倒顺序

例子: #语句有严格的顺序

mysql> select id,sumnum)
-> from
-> select * from a union select * from b) as temp
-> group by id
-> having sumnum)>10
-> order by sumnum) desc
-> limit 0,1;

子查询:

where字查询:(内层的查询结果作为外层的比较条件)

静态的:select goods_id,goods_name from goods where goods_id=32;
动态的:select goods_id,goods_name from goods where goods_id=select maxgoods_id) from goods);

#取出每个栏目下最新的商品:
select goods_id,cat_id,goods_name from goods where goods_id in select maxgoods_id) from goods group by cat_id);

from子查询:
#每个栏目下最新的商品:
mysql> select goods_id,goods_name from select * from goods where 1 order by cat_id desc) as tmp
-> group by cat_id;

exists子查询:

#查询栏目下是否有商品
mysql> select * from category
-> where existsselect * from goods where goods.cat_id=category.cat_id)

内连接查询(重要):

内连接是左右连接结果的交集

select xxx from
table1 inner jion table2 on table1.xx=table2.xx

mysql> select boy.hid,boy.bname,girl.hid,girl.gname
-> from
-> boy inner join girl on boy.hid=girl.hid;

左连接特点:

以左表的数据为标准,去找右表的数据,查不到的为NULL

#左连接
mysql> select boy.hid,boy.bname,girl.hid,girl.gname
-> from
-> boy left join girl on boy.hid=girl.hid;

#右连接
mysql> select boy.hid,boy.bname,girl.hid,girl.gname
-> from
-> boy right join girl on boy.hid=girl.hid;

mysql> select goods_id,cat_name,goods_name,shop_price
-> from
-> goods left join category on goods.cat_id= category.cat_id
-> where goods.cat_id=4;

union查询:
把2条或多条的额查询结果,合并成1个结果集

sql1 N行
sql2 M行
sql1 union sql2,N+M行

union语句必须满足一个条件:各语句取出的列数要相同

union语句中不用写order by 因为sql合并后得到总的结果集可以order by 字句order by失去意义

场景:2条语句,各自的where非常复杂,可以简化成简单的条件在union

注意:使用union时,完全相等的行将会被合并
合并是比较耗时的操作,一般不让union合并,使用union all 可以避免合并 对速度有提升

mysql> select * from a
-> union all #union all 可以避免重复语句合并
-> select * from b;

mysql> select goods_id,cat_id,goods_name,shop_price from goods where cat_id=2
-> union
-> select goods_id,cat_id,goods_name,shop_price from goods where cat_id=4;

第二部分:DDL数据库定义语言(建表)

create table 表名 (
列1 列类型 [列属性 默认值]
列2 列类型 [列属性 默认值]

);
engine = 存储引擎
chartset = 字符集

建表过程:声明表头的过程,也就是声明列的过程

选择合理的列类型 合理的列宽度(即放下内容 又不浪费磁盘空间)

列选什么类型的列 列给什么样的属性

数值型–整形,浮点型,定点型

字符串型–char varchar text

日期时间类型–2012-12-13 14.25.36

整形列:

类型: 字节: 最小值: 最大值:

bigint — 8字节 -9223372036854775808 18446744073709551615
int — 4字节 –2147483648 4294967295
mediunint — 3字节 -8388608 8388607
smallint — 2字节 -32768 32767
tinyint — 1字节 -128 127

整行列的可选参数:

unsigned 无符号,列的值从0开始不为负
zerofill M(宽度)适合用于 学号 编码等固定宽度的数字,可以用0填充至固定宽度

学号:1–0001

注意:zerofill属性默认决定是unsigned

浮点列与定点列:

float(M,D)M是精度总位数 D代表小数点后面的位数
double

float/double 范围区别和decimal相比:浮点数存储有精度的损失

decimal 定点型更精确

字符型列:

charM)–char10)只能存10个字符

char型:如果不够M个字符,内部会用空格补齐,取出时在把右侧空格删掉
注意:这意味着 右侧本身有空格将会丢失

varcharM)–用多少占多少–自动扩展
varchar不会丢失空格

速度上:定长char快一些 在一定范围内用char定长寻址快 速度快
M比较短20个以内用char

text:存大段文本
blob:是二进制类型 用来存图像信息 音频等二进制信息
blob意义在于防止因为字符集的问题导致信息丢失

enum枚举类型:是定义好 值就在某几个枚举范围内
gender emum’男’,’女’) insert 只能选其中之一

日期时间类型:
year:存年份
date:存年份日期2016-18
time:存时分秒
datetime:年月日时分秒

mysql> create table t8
-> ya year,
-> dt date,
-> tm time,
-> dttm datetime);
-> insert into t8 ya,dt,tm) values2015,’2015-12-18′,’18:28:36′);

列的默认值:

1、NULL查询不方便
2、NULL索引效率不高
3、实际中避免列的值为NULL

如何避免:声明列NOT NULL default默认值

mysql> create table t10
-> id int not null default 0,
-> name char10) not null default ”
-> );

主键与自增:

主键primary key 此列不重复,能区分每一行

primary key,auto_increment一般那两个一起出现)

注意:一张表列只能有一列为auto_increment 且此列必须加索引(index key)

优化:
定长(char)与变长(varchar)分离
常用与不常用列分离

能提高表的查询效率

列的删除与增加:(列的增删改)

alter table 表名 add 列名 列类型 列属性 默认在表的最后
alter table 表名 drop column 指定列–删除列
alter table 表名 add列名 列类型 列属性 [after 指定列的后面]

alter table 表名 change height要修改的) shengao(被修改后的) smallint
alter table 表名 modify 列名 要改成的新的属性

#alter table t12 modify shengao bigint;

视图:(存储的都是语句)
view被称为虚拟表,view是sql语句的查询结果(物理表的一个映射结果,物理表一改变,视图表也改变)

view好处:
1、权限控制可用:
比如某几个列允许用户查询,其他不允许
可通过视图开放其中一列或几列,起到权限控制作用

2、简化复杂的查询

3、视图能更新?
如果视图的每一行是与物理表一一对应的可以
view的行是由物理表多行经过计算得到的结果,view不可以更新

视图的algorithm:

对于检查查询形成的view,在对view查询时,如order by where
可以把建视图语句+查视图的语句===合并成==>查物理的语句
这种视图的算法叫merger(合并)

引擎的概念:

mysql 5.0以上默认的引擎是innoDB 一般建表时指定引擎

myisam引擎存储的数据可以直接考出来拿去用
innDB要把数据导出来

myisam和innDB引擎区别:

mysiam innDB

批量插入的速度: 高 低
存储限制: 没有 64TB

字符集与乱码问题:

字符集、校对集排序规则)、乱码

文字本来的字符集与展示的字符集不一致导致

客户端编码设置:set names gbk/utf8;
表设置编码:create table )charset utf8;
服务器端utf8/gbk 都可
网页的话:mate:charset=utf8;

索引:

索引是数据的目录,能快速定位行数据的位置
索引提高了查询的速度,降低了增删改的速度,并非越多越好
一般在查询频率的列上加,而且在重复低列上加效果好

key 普通索引
unique key 唯一键
primary key 主键索引
fulltext 全文索引(在中文环境下几乎无效,一般用第三方解决方案:如sphinx)

索引长度:建索引时,可以只索引列的前一部分的内容比如:前十个字符 key emailemail10));

多列索引:就是把2列或者多列的值,看成一个整体,然后键索引

冗余索引:在某个列上可能存在多个索引

索引操作:

查看索引:show index from goods\G
删除索引:alter table 表名 drop index 索引名
或者:drop index 索引名 on 表名

添加:alter table 表名 add [index \unqiue]索引名列名)

添加主键索引:alter table 表名 add primary key 列名
删除主键索引:alter table 表名 drop primary key

常用函数:

一、数学函数

absx) 返回x的绝对值
binx) 返回x的二进制(oct返回八进制,hex返回十六进制)
ceilingx) 返回大于x的最小整数值
expx) 返回值e(自然对数的底)的x次方
floorx) 返回小于x的最大整数值
greatestx1,x2,…,xn)返回集合中最大的值
leastx1,x2,…,xn) 返回集合中最小的值
lnx) 返回x的自然对数
logx,y)返回x的以y为底的对数
modx,y) 返回x/y的模(余数)
pi)返回pi的值(圆周率)
rand)返回0到1内的随机值,可以通过提供一个参数种子)使rand)随机数生成器生成一个指定的值。
roundx,y)返回参数x的四舍五入的有y位小数的值
signx) 返回代表数字x的符号的值
sqrtx) 返回一个数的平方根
truncatex,y) 返回数字x截短为y位小数的结果

二、聚合函数常用于group by从句的select查询中)

avgcol)返回指定列的平均值
countcol)返回指定列中非null值的个数
mincol)返回指定列的最小值
maxcol)返回指定列的最大值
sumcol)返回指定列的所有值之和
group_concatcol) 返回由属于一组的列值连接组合而成的结果

三、字符串函数

asciichar)返回字符的ascii码值
bit_lengthstr)返回字符串的比特长度
concats1,s2…,sn)将s1,s2…,sn连接成字符串
concat_wssep,s1,s2…,sn)将s1,s2…,sn连接成字符串,并用sep字符间隔
insertstr,x,y,instr) 将字符串str从第x位置开始,y个字符长的子串替换为字符串instr,返回结果
find_in_setstr,list)分析逗号分隔的list列表,如果发现str,返回str在list中的位置
lcasestr)或lowerstr) 返回将字符串str中所有字符改变为小写后的结果
leftstr,x)返回字符串str中最左边的x个字符
lengths)返回字符串str中的字符数
ltrimstr) 从字符串str中切掉开头的空格
positionsubstr,str) 返回子串substr在字符串str中第一次出现的位置
quotestr) 用反斜杠转义str中的单引号
repeatstr,srchstr,rplcstr)返回字符串str重复x次的结果
reversestr) 返回颠倒字符串str的结果
rightstr,x) 返回字符串str中最右边的x个字符
rtrimstr) 返回字符串str尾部的空格
strcmps1,s2)比较字符串s1和s2
trimstr)去除字符串首部和尾部的所有空格
ucasestr)或upperstr) 返回将字符串str中所有字符转变为大写后的结果

四、日期和时间函数

curdate)或current_date) 返回当前的日期
curtime)或current_time) 返回当前的时间
date_adddate,interval int keyword)返回日期date加上间隔时间int的结果int必须按照关键字进行格式化),如:selectdate_addcurrent_date,interval 6 month);
date_formatdate,fmt) 依照指定的fmt格式格式化日期date值
date_subdate,interval int keyword)返回日期date加上间隔时间int的结果int必须按照关键字进行格式化),如:selectdate_subcurrent_date,interval 6 month);
dayofweekdate) 返回date所代表的一星期中的第几天1~7)
dayofmonthdate) 返回date是一个月的第几天1~31)
dayofyeardate) 返回date是一年的第几天1~366)
daynamedate) 返回date的星期名,如:select daynamecurrent_date);
from_unixtimets,fmt) 根据指定的fmt格式,格式化unix时间戳ts
hourtime) 返回time的小时值0~23)
minutetime) 返回time的分钟值0~59)
monthdate) 返回date的月份值1~12)
monthnamedate) 返回date的月份名,如:select monthnamecurrent_date);
now) 返回当前的日期和时间
quarterdate) 返回date在一年中的季度1~4),如select quartercurrent_date);
weekdate) 返回日期date为一年中第几周0~53)
yeardate) 返回日期date的年份1000~9999)

一些示例:

获取当前系统时间:select from_unixtimeunix_timestamp));
select extractyear_month from current_date);
select extractday_second from current_date);
select extracthour_minute from current_date);
返回两个日期值之间的差值月数):select period_diff200302,199802);
在mysql中计算年龄:
select date_formatfrom_daysto_daysnow))-to_daysbirthday)),’%y’)+0 as age from employee;
这样,如果brithday是未来的年月日的话,计算结果为0。
下面的sql语句计算员工的绝对年龄,即当birthday是未来的日期时,将得到负值。
select date_formatnow), ‘%y’) – date_formatbirthday, ‘%y’) -date_formatnow), ’00-%m-%d’) 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’ when2+2)<>4 then ‘not ok’ end asstatus;
select name,ifisactive = 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 ifencrypt’sue’,’ts’)=upass,’allow’,’deny’) as loginresultfrom users where uname = ‘sue’;#一个登陆验证

七、格式化函数

date_formatdate,fmt) 依照字符串fmt格式化日期date值
formatx,y) 把x格式化为以逗号隔开的数字序列,y是结果的小数位数
inet_atonip) 返回ip地址的数字表示
inet_ntoanum) 返回数字所代表的ip地址
time_formattime,fmt) 依照字符串fmt格式化时间time值
其中最简单的是format)函数,它可以把大的数值格式化为以逗号间隔的易读的序列。

示例:

select format34234.34323432,3);
select date_formatnow),’%w,%d %m %y %r’);
select date_formatnow),’%y-%m-%d’);
select date_format19990330,’%y-%m-%d’);
select date_formatnow),’%h:%i %p’);
select inet_aton’10.122.89.47′);
select inet_ntoa175790383);

八、类型转化函数

为了进行数据类型转化,mysql提供了cast)函数,它可以把一个值转化为指定的数据类型。类型有:binary,char,date,time,datetime,signed,unsigned
示例:

select castnow) as signed integer),curdate)+0;
select ‘f’=binary ‘f’,’f’=cast’f’ as binary);

九、系统信息函数

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

示例:

select database),version),user);
selectbenchmark9999999,logrand)*pi)));#该例中,mysql计算logrand)*pi))表达式9999999次。