【儒冠多误身】MySQL个人学习笔记

7 篇文章 0 订阅
2 篇文章 0 订阅

儒冠多误身

个人学习笔记

MySQL从入门到精通视频教程(2012)

MySQL5.1参考手册

MySQL个人学习笔记

问题总结

1. 报错

  • error 1064,语法错误
  • error 1366(HY000),客户端没有声明字符集

2. 设置字符集

  • 如果服务器、连接器、客户端都使用的gbk字符集,可简写为:set names gbk;

  • set character_set_client = gbk;#声明客户端是gbk
       
    set character_set_connection = utf8;#声明连接器为utf8
        
    set character_set_results = gbk;#声明返回值是gbk
    

3. 跳出执行

  • \c,不执行该段代码

4. 破解数据库密码

  1. 通过任务管理器或者服务管理,关掉mysqld(服务进程)
  2. 通过命令行 + 特殊参数开启mysqlMysqld --skip-grant-tables
  3. 此时,mysqld服务进程已经打开,并且,不需要权限检查
  4. mysql -uroot无密码登录服务器
  5. 修改权限表
    • use mysql;
    • update user set Password = password('123456') where user = 'root';
    • flush privileges;

入门语句

  1. 连接服务器

    mysql -uusername -p

  2. 查看所有库

    show databases;

  3. 创建库

    create database demo charset utf8;

  4. 删除库

    drop database demo;

  5. 选择库

    use demo

  6. 查看表

    show tables;

  7. 创建简单表

    create table stu(
    id int,
    name varchar(20)
    )engine myisam charset utf8;
    
  8. 删除表

    drop table stu

  9. 改表名

    rename table stu to newstu

  10. 插入数据

    insert into newstu values
    <1,'zhangsan'>,
    <2,'lisi'>,
    <3,'wangwu'>;
    
  11. 清空表

    truncate newstu;

    • truncate,相当于删除表后,重建一张同结果的表-全新的表;
    • delete from class;
      • delete,删除表的所有行,如果有自增列,

增删改查

创建表

create table class(
id int primary key auto_increment,
sname varchar(10) not null default '',
gender char(1) not null default '',
company char(40) not null default '',
salary decimal(6,2) not null default 0.00,
fanbu smallint not null default 0
)engine myisam	charset utf8;

查看表结构

desc stu;

show create table stu;#查看stu表创建语句

增 insert

  • 往哪张表添加行
  • 添加哪几列
  • 分别是什么值
insert into class
(id,sname,gender,salary,fanbu)
values
(1,'张三','男','8888.67','234');

# 插入部分列
insert into class
(sname,gender,salary)
values
('王五','男',8888.68);

# 插入所有列,可不声明待插入列
insert into class
values
(3,'李四','女','新浪',5678.99,200);
  • 注意,插入所有列时,不要因为id为自增,就忽略列与值的一一对应。
    • 填上id
  • 增加多行
insert into class
(sname,company,salary)
values
('刘备','皇叔',15.28),
('孙策','江东集团',56.34),
('曹操','枭雄',88.56);

select * from stu;

改 update set where

  • 改哪张表
  • 改哪几列
  • 改为什么值
  • 再哪些行生效
update class
set
fanbu = fanbu + 200
where id = 6;

## 多条件
update class
set
fanbu = 500
where gender='男' and salary > 8000;
  • where expression

    • where +表达式

    • 只要表达式为真,则改行就发挥作用

    • update class
      set
      salary = salary + 1000
      where 1; #全部改,因为1恒为真
      

删 delete from where

  • 删哪个表
  • 删哪几行: where expression
delete from class
where salart > 88888 and gender = '女';

查 select

  • select * from table1,table2;#两表的笛卡尔积(集合相乘)
    

查询模型

  • 列就是变量,再一行上,列的值都在变化
  • where条件是表达式,再哪一行上表达式为真,哪一行就取出来
  • 查询结果集,在结构上可以当成表看


建表

数值型

整型

占据空间存储范围
tinyint1字节-128~127;
0~255
smallint2字节-215~215 -1
0~216-1
mediuint3字节-223~223-1
0~224
int4字节-231~231-1
0~232
bigint8字节-263~263-1
0~264
int系列的参数:(M) unsigned zerofill
  • 不加特殊说明,默认为是有符号;
  • 设置为无符号,col_1 smallint unsigned
  • (m) zerofill,col_2 int(5) zerofill
    • (m),表示数据的宽度
    • 要与zerofill同时使用
create table demo_1(
sname varchar(20) not null default '',
age tinyint not null default 0
)engine myisam charset utf8;

alter table demo_1 add score tinyint unsigned not null default 0;# unsigned
alter table demo_1 add snum smallint(5) zerofill not null default 0;# <m> 必须和zerofill一起使用

浮点型:float(M,D),会有损精度

  • float(M,D),decimal(M,D)
    • M叫”精度“—>浮点数的“总位数”,而D是“标度” —>小数点后几位;
    • float(6,2)总6位,小数点后2位。
create table salary1(
sname varchar(20) not null default '',
salary float(8,2),
bouns float(6,2) unsigned not null default 0.00
)engine myisam charset utf8;

定点数:decimal(M,D)

  • 把整数部分和小数部分,分开存储;
  • 比float精确;

字符串型

Char(M)定长字符

  • char(M),定长字符串,存储M个长度、字符
    • M:[0,255]
    • 长度不够的 在尾部用 空格 补齐
    • 末尾若要存储空格,无法读取

Varchar(M)变长字符

  • varchar(M),变长字符串,存储[0,M]个长度
    • M:[0,65535]
    • 实际占用空间:i字符 + (1~2)个字节
  • varchar 存储:列内容前有1~2个字节,标志该列内容的长度

Text文本类型

  • 搜索速度较慢
  • 可存储较大文本
  • Text不加默认值,加了也没用
  • 不是特别大的内容,建议用char,varchar。

Blob:二进制类型

  • blob是二进制类型,用来存储图形、音频等信息。
  • 防止因为字符集问题,导致信息丢失。

日期时间类型,记得加引号

类型说明标准格式范围存储
date日期YYYY-MM-DD1000-01-01
9999-12-31
3字节
time时间HH:MM:SS-838:59:59
838:59:59
3字节
datetime日期时间YYYY-mm-dd
HH:ii:ss
1000-01-01 00:00:00
9999-12-31 23:59:59
8字节
year年份类型YYYY和YY(不推荐)1901~21551字节
TimeStamp时间戳4字节

Date日期

alter table demo add birth date not null default '0000-00-00';

Time时间

alter table demo add sign time not null default '00:00:00';

Datetime 时间时间类型

alter table demo add logintime datetime not null default '0000-00-00 00:00:00';

Year 年类型

alter table demo add sj year not null default '0000';

TimeStamp时间戳

create table demo_1(
ts timestamp default CURRENT_TIMESTAMP;
)engine myisam charset utf8;

建表

初步建表

create table member(
id int unsigned not null primary key auto_increment,
username char(20) not null default '',
gender char(1) not null default '',
weight tinyint unsigned not null default 0,
birth date not null default '0000-00-00 00',
salary decimal(8,2) not null default 0.00,
lastlogin int unsigned not null default 0,
intro varchar(1500)
)engine myisam charset utf8;

优化

  • 对上表的优化
    • username char(20)列,虽然浪费存储空间,但提高查询速度,可以接受。
    • intro varchar(1500) ,考虑到个人简介,更新频率并不高,推荐把intro列单独拿出来,另放一张表里
create table member(
id int unsigned not null auto_increment primary key,
username char(20) not null default '',
gender char(1) not null default '',
weight tinyint unsigned not null default 0,
birth date not null default '0000-00-00 00',
salary decimal(8,2) not null default 0.00,
lastlogin int unsigned not null default 0
)engine myisam charset utf8;
  • 优化思路
    • 优化:时间 与 空间 的取舍
    • 频繁用到的信息,优先考虑效率,存储到一张表中
    • 不常用的信息比较占据空间的信息,存储到辅表中。

修改表

增加列

【加的列在表的最后】
alter table 表名 add 列名称 列类型 列参数;
alter table demo add col_1 int unsigned;

【指定添加的位置】
alter table 表名 add 列名称 列类型 列参数 after 某列;
alter table demo add gender char(1) not null default '' after id;

【放在最前面】
alter table 表名 add 列名称 列类型 列参数 first;
alter table demo add col_f int unsigned not null default 0 first;

删除列

alter table 表名 drop 某列;
alter table demo drop col_f;

修改列

  • 修改列类型alter table modify
alter table 表名 modify 某列 列新类型 新参数;
alter table demo modify gender char(4) not null default '';
  • 修改列名 change
alter table 表名 change 某列 新列名 列类型 参数;
alter table demo change id uid int unsigned;

综合练习

# 创建表
create table test(
id int unsigned not null auto_increment primary key,
username char(20) not null default '',
gender char(1) not null default '',
salary decimal(8,2) not null default 0.00,
weight tinyint unsigned
)engine myisam charset utf8;
# 修改列
alter table test add col_2 int unsigned not null after username;
alter table test modify col_2 int unsigned not null default 0;
alter table test add col_3 char(3) not null default '' first;
alter table test change col_3 nid int unsigned not null default 0;
alter table test drop col_1;
# 修改列的元素值
update test set  salary = salary*1.1 where salary < 20000;
update test set username = '路飞', gender = 1 where id = 6 and salary > 50000;
# 删除列中的元素
select from test
where salary >90000 and id > 20;


select *,col1,distinct(col2),count(distinct col)
from table1
where 1
group by col1
having 
order by col2
limit 5 offset 3;
  • 把列当做变量看
  • 5种子句
    • where 查询条件
    • group by 分组
    • having 筛选
    • order by 排序
    • limit offset

优先级

  1. 括号()
  2. not
  3. and
  4. or

where 查询

  • where 对上的数据发挥作用
    • 结果列 不发挥作用
    • 结果列不在from表中
  • in () 散点集合
    • 括号内 区分大小写
    • not in ()
  • between and 区间
    • 包括边界值 []
  • and or
    • 括号
    • where 条件1 and (条件2 or 条件3) and 条件4
  • like 模糊匹配
    • 通配符
      • % 任意字符
      • _ 单一字符

NULL

  • null是一种类型,比较时只能用

    • where col is NULL;
    • where clo1 is not null;
  • null效率不高,影响索引效率

    • create table demo(
      id int unsigned not null auto_increment primary key,
      salary float(8,2) unsigned not null default 0.00
      )engine myisam charset utf8;
      

group分组

  • 类似Python的groupby【+】统计函数

    • 分了组 +统计函数 配合使用 更有意义
  • select 
    	city,count(1)
    from
    	table1
    group by
    	city
    order by
    	count(salary) desc;
    # 按城市分组,统计职位数,按职位数排序-降序
    
    create table result(
    	name varchar(20) default null,
        subject varchar(20) default null,
        score tinyint(4) default null
    )engine myisam charset utf8;
    
    insert into reselt
    values
    ('张三','语文',90),
    ('张三','数学',59),
    ('张三','政治',30),
    ('李四','语文',36),
    ('王五','语文',80),
    ('王五','数学',90),
    ('王五','政治',100),
    ('李四','数学',50)
    
    select name,avg(score),sum(score<60) as g from result
    group by name
    having g >1;
    

having 筛选

  • 可对 结果集,筛选。

order by 排序

  • 对 结果集,排序。
  • order by col desc降序
  • order by col asc升序,默认不写
  • 多列排序order by 1 desc, 2 asc, col3 desc;
  • order by 2对结果集中的各列,可用数字代替具体的列,以1代表第一列,类推。

limit 限制条目

  • limit [offset,] N

    • offset:偏移量
    • N:取出条目
    • offset,如果不写,则相当于,limit 0, N
  • limit 2,3
    limit 3 offset 2
    # 偏移2行,取第3~第5
    

子查询

  • 注意select * from (select * from table1 where 1),内层的sql语句,别用*!!!

where型子查询

  • 把内层的查询结果作为外层查询的比较条件
    • 典型题:查询最大商品、最贵商品
    • where 列 = (内层sql),内层sql返回的只能是单行、单列
    • where 列 in (内层sql),内层sql返回的只能是单列,可多行
select companyid,companyname from demo
where companyid = (select max(companyid) from demo);	
select companyid,companyname,city from demo
where companyid in (
    select max(companyid) from demo group by city)
# 各个城市下companyid最大的公司的名称信息

from型子查询

  • 把内层的查询结果当成临时表,供外层sql再次查询
    • 典型题:查询每个栏目下的最新、最贵商品
select * from (
	select companyid,city,education,bottom from demo
	) as tmp #临时表
	group by 

exists型子查询

  • 把外层sql的结果,拿到内层sql取测试,如果内层sql成立,则该行取出。
select * from table1 as t1
where exists (select * from table2  as t2 where t1.col_name = t2.col_name)
limit 5

多表连接

# 创建表
create table matchs(
matchid int unsigned not null default 0,
hostteamid int unsigned not null default 0,
matchresult varchar(20) not null default '',
matchtime DATE
)engine myisam charset utf8;

alter table matchs add guestteamid int UNSIGNED not null default 0 after hostteamid;

create table team (
teamid int unsigned not null default 0,
teamname VARCHAR(20) not null default ''
)engine myisam charset utf8;

insert into matchs
values
(1,1,2,'2:0','2006-05-21'),
(2,2,3,'1:2','2006-06-21'),
(3,3,1,'2:5','2006-06-25'),
(4,2,1,'3:2','2006-07-21');

insert into team
VALUES
(1,'国安'),
(2,'申花'),
(3,'传智联队')

update team set teamname = '公益联队' where teamid = 3;

两表做 全相乘

  • 从行角度看,两表每一行,两两相乘

  • 从列角度看,结果集中的列,是两表的列名的相加

  • select * from table1,table2;
    
    select table1.col1,table2.col1,table2.col3,table1.col2 from table1,table2  where table1.col1 = table2.col1;
    # 两表 全相乘 效率低、耗内存
    
  • ambiguous,模糊不清

    • 表明.列名

join连接

  • 出于移植时,兼容性的考虑,尽量用左连接。

  • MySQL不支持,外连接

  • 两次left join

    • 注意 as 的表名不一

    • select t1.teamname,matchresult,t2.teamname,matchtime from matchs m
      left join team t1 on m.hostteamid = t1.teamid
      left join team t2 on m.guestteamid = t2.teamid
      where matchtime between '2006-06-01' and '2006-07-01'
      order by hostteamid
      

拼接 union/union all

  • union 合并的是结果集

    • 需要两个结果集的字段数量相等才能用union
  • 从单张表查询,用union

    • 让结果集列名【一致】:对列名as为统一别名
    select col2 as a,col3 as b from table1 where col >a
    union
    select col5 as a,col6 as b from table1 where col <b;
    
  • 从两张表查询,用union

    select cola as aa,colb as bb from table1 where col = 1
    union
    select colc as aa,cold as bb from table2 where col = 2;
    
  • 思考

    • 当结果集的列名不一致,直接用union时:

      • 列名以第一个sql语句列名为准
    • 当取出的两个结果集有重复,有相同的行,用union

      • 这种情况比较常见,默认会去重
    • 不想去重union all

      • select * from table1
        union all
        select * from table2
        
    • 使用条件

      • 只要结果集列数相同 就可以使用 union
      • 列的类型不一,也能union,但拼接意义不大
    • union后的结果集,再操作

      • order by:(sql1 order by col) union (sql2 order by col) order by col
        • 外层order by 是针对合并后的结果集,排的序
        • 内层order by 语句,在执行期间,就被MySQL的代码分析器给优化掉了。
      • limit:(sql1 order by col limit 3) union (sql2 order by col limit 2)
        • 因为有limit,所以order by 影响返回值,内层order by 发挥作用
      • 针对是否影响结果集,MySQL判断是否优化掉内层的order by。
  • 练习题

    create table a(
    id char(1),
    num int)
    engine myisam charset utf8;
    
    create table b(
    id char(1),
    num int)
    engine myisam charset utf8;
    
    insert into a
    values
    ('a',5),('b',10),('c',15),('d',20);
    
    insert into b
    VALUES
    ('b',3),('c',88),('d',99),('e',88);
    
    
    # 先拼接,再分组求和
    # 用 union all
    SELECT id,sum(num) from 
    (select id,num FROM a 
    union ALL
    SELECT * from b) as tmp
    GROUP BY id;
    


函数

注意

  • mysql函数肯定要影响查询速度

    • 应该在建表时,通过合理的表结构,减少函数的使用
  • 如果确实要用函数,以时间函数为例

    • 在mysql中用data_format,在python中用pd.to_datetime(df[‘col’],format = ),优先放在业务逻辑层,即python中处理。
  • 在查询时使用了函数,最大的一个坏处,以data_format(A)为例

    • 则A列的索引将无法使用

    • 如果你针对某列查询,而此列,用上了函数来判断,则此列将不再使用索引

      • select name,email from table1 where right(position('@',email)) = 'qq.com';
        
      • 本来email列是有索引的,可以加快查询速度,但因为你使用的并不是email列,而是函数处理后的email列的返回值,因此结果集中email列的查询就非常缓慢了。

    • 总结:在where条件中,对某列使用了函数,则此列的索引不发挥作用。

字符串函数

  • substring(str,pos)截取字符串

    • substring(str,pos)

    • substring(str from pos)

    • select col1,col2,substring(col2,3) from table1;
      select col1,col2,substring(col2 from 3) from table1;
      # 对col2列,从第3个字符开始,往后截取
      
    • substring(str,pos,len)

      • substring(str from pos for len)
    • select col1,col2 substring(col2,3,5) from table1;
      select col1,col2 substring(col2 from 3 len5) from table1;
      
  • concat 连接字符串

  • concat(col1,col2,……)

  • select col1,col2,concat(col1,substring(col2,3)) from table1;
    # 连接col1和 col2中第3个和之后的字符
    update table1 set col_new = concat(col1,substring(col2,3));
    
ascii(char)返回字符的ASCII码值
bit_length(str)返回字符串的比特长度
concat(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(str)返回字符串str的字符数
ltrim(str)从字符串str中切掉开头的空格
locate(‘子字符’,col)子字符 在字符串中的位置
POSITION(substr IN str)返回子串substr再字符串中第一次出现的位置
quoter(str)用反斜杠转义str中的单引号
repeat(str,x)返回字符串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的所有字符大写结果


数学函数

abs(x)返回x的绝对值
bin(x)返回x的二进制
oct(x)返回x的八进制
hex(x)返回想的十六进制
ceiling(x)返回大于x的最小整数值,向上取整
floor(x)返回小于x的最大整数值,向下取整
exp(x)返回值e(自然对数的底)的x次方
greatest(x1,x2,……)返回集合中最大值
least(x1,x2,……)返回集合在最小值
ln(x)返回x的自然对数
log(x,y)返回x的以y为底的对数
mod(x,y)返回x/y的模(余数)
pi()返回pi的值(圆周率)
rand()生成[0,1]之间的随机值
rand(int)生成重复的随机值
round(x,y)返回参数x的四舍五入的有y位小数的值
sign(x)返回代表数字x的符号的值
sqrt(x)返回一个数的平方根
truncate(x,y)返回数字x截短为y位小数的结果
select floor(666 * 0.88);#打八折,不要零头

update demo set col_number = floor(col_number)*10
where col_number between 30 and 50;
# 将 [30,50]之间的数字,变为30,40,50

# 随机
select rand(1);#生成随机值,且再次运行其产生的结果不变
select rand();#生成随机值,再次运行,其结果改变
select floor(rand()*10 + 5) # 随机生成5~15之间

聚合函数

  • max(col) 最大值
  • min(col) 最小值
  • sum(col) 求总和
  • avg(col) 求均值
  • count()非null值的个数
    • 【绝对行数】所有行数,包括NULL
myisaminnodb
count(1)
count(2)
count(常数)
查询绝对行数查询绝对行数
count(*)查询绝对行数效率低
count(col_name)查询该列不为null的行数查询该列不为null的行数
  • group_concat(col) 返回由属于一组的列值连接组合而成的结果
select group_concat(col,'') from 
# 一般用在分组后,将分组后的列的元素,用‘,’拼接在一起
# 默认用‘,’拼接在一起

日期和时间函数

curdate() 或 current_date()返回当前的日期
curtime() 或 current_time()返回当前的时间
date_add(date,interval int keyword)返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化)
date_format(date,fmt)依照指定的fmt格式格式化日期date值
date_sub(date,interval int keyword)返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化)
dayofweek(date)返回date是一星期的第几天(1~7)
dayofmonth(date)返回date是一个月的第几天(1~31)
dayofyear(date)返回date是一年的第几天(1~366)
dayname(date)返回date的星期名
    • select date_add(current_date,interval 6 month);
      #加上6个月
      
      select date_sub(current_date,interval 6 month);
      #往前数6个月
      
      select dayname(current_date);
      
    from_unixtime(t,fmt)根据指定的fmt格式,格式化unix时间戳ts
    hour(time)返回time的小时值(0~23)
    minute(time)返回time的分钟值(0~59)
    month(date)返回date的月份值(1~12)
    monthname(date)返回date的月份名,英文
    now()返回当前的日期和时间
    quarter(date)返回date再一年中的季度
    week(date)返回日期date为一年中第几周(0~53)
    year(date)返回日期date的年份(1000~9999)
    • select monthname(current_date);
      
      select quarter(current_date);
      

获取当前系统时间

select from_unixtime(unix_timestamp())
union
select extract(year_month from current_date)
union
select extract(day_second from current_date)
union
select extract(hour_minute from current_date)

返回两个日期之间的差值(月数)

select period_diff(201307,current_date);

计算年龄

select date_format(from_days(to_days(now()) - o_days(birthday)),'%y') + 0 as age from employee;
# 如果birthday是未来的年月日的话,计算结果为0

计算员工的绝对年龄

  • 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;
    


格式化函数

date_format(date,fmt)依照字符串fmt格式化日期date
  • select date_format(now(),'%w,%d %m %y %r')
    
    select date_format(now(),'%y-%m-%d') # 现在的年月日
    
    select date_format(20170830,'%Y-%m-%d')
    
    select date_format(now(),'%h:%i:%p') #现在的时间
    

format(x,y)把x格式化为以逗号隔开的数字序列,y是结果的小数位数
  • 把大的数值格式化为以逗号间隔的易读的序列

  • select format(34234.34323432,3)
    
inet_aton(ip)返回ip地址的数字表示
inet_ntoa(num)
time_format(time,fmt)依照字符串fmt格式化时间time值
  • select inet_aton('10.122.89.47')
    
    select inet_ntoa(175790383)
    

类型转化函数

case()

  • 把一个值转化为指定的数据类型

    • binary,char,date,time,datetime,signed,unsigned
  • select cast(now() as signed integer),curdate() +0;
    select 'f' = binary 'f', 'f' = cast('f' as binary);
    

系统信息函数

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

select benchmark(99,log(rand()*pi()))
#mysql计算log(rand()*pi())表达式99次


控制流程函数

case when then end

CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ……] [ELSE result] END CASE WHEN [condition] THEN result[WHEN [condition] THEN result] [ELSE result] END

  • 再第一个方案的返回结果中,value = compare-value

  • 而第二个方案的返回结果是第一种情况的真实结果

  • 如果没有匹配的结果值,则返回结果为ELSE后的结果,如果没有ELSE部分,则返回值为NULL

  • select education,salary,case education
    when '本科' then 1
    when '硕士' then 2
    when '大专' then 0
    when '博士' then 3
    ELSE -1
    END  as '学历'
    from dataanalyst
    order by '学历' desc;
    
    
    

if(expr1,expr2,expr3)-三元表达式

  • 如果expr1是TRUE(expr1 <> 0 and expr1<>NULL),则if()的返回值为expr2,否则返回值为expr3

  • if()的返回值为数字值或字符串值,具体情况视语境而定

  • select education,if(bottom >8,'优先','等待') as vip
    from dataanalyst
    order BY education,vip DESC;
    
    # count(if())
    select city,count(1) from demo
    group by city
    having count(if(companyfullname like '%电子商务%',1,null)>=50;
    

    count()\sum()与if()三元表达式一起用

ifnull(expr1,expr2)

  • 如果expr1不为NULL,则ifnull()返回expr1,否则返回值为expr2

  • select education,ifnull(bottom ,0) as v from dataanalyst order by v ;
    

nullif(expr1,expr2)

  • 如果expr1 = expr2成立,返回值为NULl,否则返回值为expr1

  • select col1,nullif(col2,expr2) from table1;
    
    # 相当于
    select col1,case col2
    when col2 = expr2 then null
    else expr1 
    end
    from table1;
    

其他函数

distinct(col)去重


视图view

  • 在查询中,我们经常把查询结果,当成临时表来看
  • view可以看做一张虚拟表,是通过某种运算得到的一个投影、映射
    • 表改变,视图跟着变
    • 修改视图,也会影响到表
      • 只有, 视图与表,在列名上,一一对应情况:才能修改视图

创建视图

create view 视图名 as select 语句

create view tmp as 
select count(education) as js
from table1
group by education;

调用-view

show tables;# 查看刚刚创建的视图tmp
select * from tmp order by js limit 3;
  • 作用
    • 简化查询
    • 更精细的权限控制
    • 数据多,分表时,可以用到

删除-视图

drop view view_name;
  • windows系统中,表的文件后缀名
    • demo.frm,表的结构
      • tmp.frm,视图view只有.frm后缀名文件
    • demo.MYD,表的数据
    • demo.MYI,表的索引

algorithm 决定view是否创建临时表

  • algorithm=

    • merge
    • temptable
    • undefined
  • algorithm = merge,并不会建立临时表,只是合并的结果

    create algorithm = merge view v1
    as
    select * from demo
    where salary >8000;
    # 
    
  • 对于复杂查询,则需要建立临时表algorithm = temptable

    create algorithm = temptable view v2 
    as 
    select * from demo
    order by salary desc;
    select * from v2 group by education limit 3;
    
  • 如果拿不准是否创建,用algorithm = undefined,让系统做决定

    create algorithm = undefined view v3
    as 
    select 语句;
    


乱码

字符集

  • ASCII 单字节
  • gb2312,双字节,只收录6763个汉字
  • GBK,双字节,完全兼容gb2312,GBK的第2低位,不再局限于129~255,小于127的也能用
    • 收录汉字21003个
    • 符号883个
    • 并提供1894个造字码位
  • ANSI,代表本地字符集
    • 在中国ANSI是GBK
    • 在日本ANSI是JIS
  • Unicode,世界通用的码表,4字节,避免高位浪费
    • Unicode的实现方式成为Unicode转换格式(Unicode TRansformation Format)UTF
      • UTF-8
    • Unicode与utf-8的关系
      • 就像:源文件 与 压缩文件 的关系–>压缩空间,避免浪费
    • utf-8占 几 个字节
      • 不可能定长,否则压缩没有还有什么意义
      • 1~6个字节
    • 如何截取utf8(各国语言都有),无乱码?
      • 从头开始,取1个字节
      • 通过位运算,计算连续的1 的个数
      • 如为0,则截取1个字节
      • 入围N,则截取N个字节
  • 容量
    • gb2312<gbk<utf-8
  • gbk转utf-8?
    • gbk–>Unicode–>utf-8
  • 乱码的原因
    • 解码时与实际编码不一致——可修复:
      • 使编码与解码一致,就不乱码了
    • 传输过程中,编码不一致,导致字节丢失:
      • 不可修复

MySQL中设置字符集

  • 字符集范围设置要求

    • 服务器字符集 >= conntion字符集 >= client字符集

    • 如果服务器、连接器、客户端都是gbk,可简写为:

      • set names gbk;
        
  • 客户端(client)字符集,连接器(conntion)字符集,查询结果字符集,utf8存入服务器

  • 要想不乱码,需要指定客户端的编码:告诉服务器,客户端的编码是gbk

    • 声明客户端是gbk

      set character_set_client = gbk;
      
  • 设置连接器使用utf8

    • 声明连接器为utf8

      set character_set_connection = utf8;
      
  • 设置返回值为gbk

    • 声明返回值是gbk

      set character_set_results = gbk;
      
  • 牵涉到数据库,想不乱码

    1. 正确指定客户端的编码
    2. 合理选择连接器的编码
    3. 正确指定返回内容的编码
      • 举例:
        • 我的网页是utf8,因此client客户端是utf8
        • 我的表是utf8,因此,连接器,utf8
        • 返回值也是utf8
        • 因此set names utf8;

存储引擎

create table demo(
……
……
)engine myisam charset utf8;
  • MySQL表引擎
特点MyisamInnoDB
批量插入的速度
事务安全支持
全文索引支持
锁机制表锁行锁
存储限制没有64TB
B树索引支持支持
哈希索引支持
集群索引支持
数据缓存支持
索引缓存支持支持
数据可压缩支持
空间使用
内存
支持外键支持

事务

  • 事务的4个特性

    • 原子性

      • 2步或N步操作,逻辑上不可分割

      • 要么成功,要么都不成功

      • # 使用事务
        start transaction; # 开启事务
        update demo set salary = salary + 1000 where uname ='zhangsan';
        update demo set salary = salary - 1000 where uname = 'lisi';
        commit; # 提交整个事务
        
        # 模拟扣款失败——原子性
        start transaction; # 开启事务
        update demo set salary = salary + 1000 where uname ='zhangsan';
        update demo set salary = salarys - 1000 where uname = 'lisi'; # 这里故意打错salarys,来模拟扣款失败
        rollback; # 回滚
        
    • 一致性

      • 操作前后,值的变化,逻辑上成立
      • 比如,tinyint来存钱,+300,溢出了,也是失败
    • 隔离性

      • 事务结束前,在其他客户端无法查询事务中的操作变化
    • 持久性

      • 一旦完成,无法撤销

数据加载 读入

create table orders(
orderid int primary key auto_increment,
userid int(11) UNSIGNED not null,
ispaid varchar(3) not null default '',
price decimal(15,2) not null default 0.00,
payTime TIMESTAMP
)ENGINE INNODB charset utf8;

load data local infile 'F:\order_info_utf.csv' into table demo.orders # 加载目标文件
fields TERMINATED by ','; # 设置文件分隔符

时间格式

SELECt payTime,
date(payTime), #只读取年月日
DATE_FORMAT(payTime,'%Y年%m月%d日'), # 格式的转换
DATE_ADD(payTime,INTERVAL 1 day), #加1天
DATE_ADD(payTime,INTERVAL -1 week), # 回溯1周
DATE_ADD(payTime,INTERVAL 1 month), # 加一周
datediff(payTime,curdate()) #payTime 减 今天

from orders
group by date_format(payTime,'%Y%m'), #按年月分组
	month(payTime) # 按月分组
limit 5
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值