Mysql学习笔记(一)(有点乱,但是知识点比较齐全)新手必看。

时间:2021-10-14 00:30:44
良好的理解sql语句:
列:理解可以运算的成变量
where: 理解成表达式,放在行中看是否成立
查出来的结果可以当成一张表理解,select 套用select综合查询;


五种查询

  1. where
  2. group 
  3. havding 
  4. order by 
  5. limit

在使用的时候必须按照这五个查询方法的顺序使用,否则语法不通过;即 where group having order by limit 

 

标准的 SQL 的解析顺序为:

   (1).FROM 子句, 组装来自不同数据源的数据

   (2).WHERE 子句, 基于指定的条件对记录进行筛选

   (3).GROUP BY 子句, 将数据划分为多个分组

   (4).使用聚合函数进行计算(max avg min ...)

   (5).使用 HAVING 子句筛选分组

   (6).计算所有的表达式(limit)

select  name  from  score  where  name  not  in  ( select  name  from  score  where  score< 80 )  group  by  name ;

举例说明:

在学生成绩表中 (暂记为 tb_Grade), 把 "考生姓名" 内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分的.

select 考生姓名, max(总成绩)

from  tb_Grade

where name is not null 

group by s_name 

having 总成绩>600

 order by max(从成绩)

 

 

在学生成绩表中 把 "考生姓名" 内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分的.

分析句子:把 姓名分组 选 总成绩 条件:姓名不为空 max 大于 600

   标准顺序的 SQL 语句为:

select 考生姓名, max(总成绩) as max总成绩

   from tb_Grade

   where 考生姓名 is not null

   group by 考生姓名

   having max(总成绩) > 600

   order by max总成绩

   在上面的示例中 SQL 语句的执行顺序如下:

   (1). 首先执行 FROM 子句, 从 tb_Grade 表组装数据源的数据

   (2). 执行 WHERE 子句, 筛选 tb_Grade 表中所有数据不为 NULL 的数据

   (3). 执行 GROUP BY 子句, 把 tb_Grade 表按 "学生姓名" 列进行分组

   (4). 计算 max() 聚集函数, 按 "总成绩" 求出总成绩中最大的一些数值

(5). 执行 HAVING 子句, 筛选课程的总成绩大于 600 分的.

   (7). 执行 ORDER BY 子句, 把最后的结果按 "Max 成绩" 进行排序

   (7).使用 ORDER BY 对结果集进行排序


在命令行窗口下插入mysql数据的时候,如果出现中文乱码无法插入的时候用命令
set names GBK;
插入多行数据的时候可以这样插入
insert into stu(stuid,stuname,stuage)
values
(3,'李四',23),
(4,'wang四',23);中间用逗号分割。

Mysql常用命令:
  1. 登录:mysql 启动mysql服务 cmd —— net start mysql(这个是服务名字)
  2. mysql -h localhost -u root -p (密码)
  3. 敲错 命令用\c回到编辑界面
  4. 查看数据库有多少个库:show databases;
  5. 创建 一个库:create database kuname;
  6. 使用一个库:use tablename;(不用show也行,直接上来就use,前提是你对数据库很了解)
  7. 显示表:show tables;(注意 是多张表:tables)
  8. 删除一个库:dorp  database kuname;\\\\\\\\\\\mysql 不准许修改自己的数据库的名字
  9. mysql中1064是语法错误;
  10. 修改表名:rename table oldtablename to newtableneme(库名是不能改的)
  11. 删除一个表:你猜怎么删除呢?
  12. 查看表结构:desc tablename
  13. 给一个表增加一个字段:alter table tablename add 字段名 类型;例如:alter table admin add age tinyint ;
  14.        如何设置字段类型为无符号的呢?:声明的时候在字段类型后面加上unsigned;(无符号的)
  15. tinyint(M) unsigned zerofill 
  16. copy 一个已经存在的表结构: create table tablename like 已经存在的表的名字 ,这样创建出来的表没有数据,知识结构相同。

 

其中 M代表宽度,但是只有在zerofill时才有效,

unsigned : 无符号

zerofill :0填充 例如:0001 0002 0003 、

char和varchar的区别

char(M) 表示定长字符串,如果实际存储不够M个,则后面加空格补齐,取出来的时候,在把空格去掉,(所以你真想存空格的时候是存不上的)

varchar(M)变长字符串,

速度上:char定长更快一些    选择原则:1,空间利用率 2.速度

text:??

YEAR类型

YEAR类型是一个单字节类型用于表示年。

MySQL以YYYY格式检索和显示YEAR值。范围是1901到2155。

可以指定各种格式的YEAR值:

·         四位字符串,范围为'1901'到'2155'。

·         四位数字,范围为1901到2155。

·         两位字符串,范围为'00'到'99'。'00'到'69'和'70'到'99'范围的值被转换为2000到2069和1970到1999范围的YEAR值。

·         两位整数,范围为1到99。

1到69 被转换为2001到2069

70到99被转换为1970到1999范围的YEAR值。

请注意两位整数范围与两位字符串范围稍有不同,因为你不能直接将零指定为数字并将它解释为2000。你必须将它指定为一个字符串'0'或'00'或它被解释为0000。

·         函数返回的结果,其值适合YEAR上下文,例如NOW()。

非法YEAR值被转换为0000。

在真正的开发中如表示注册时间,商品发布日期等 很好用datetime类型,因为datetime方便查看但是不方便计算,
开发中应该用时间戳来标识日期,
时间戳:从1970-01-01 00:00:00到当前的秒数,

从一个库insert into 另一个表的数据:
insert into tablename 
select ***** from ;


查询某一列字段:不是查询所有列
select sutid,stuname from stu;

mysql数据类型
整型 分为 :tinyint\ smallint\ mediumint \ int \ bigint
比如声明一个tinyint,默认是一个有符号的,也就是(-128 到 127)

类型

字节

最小值

最大值

 

 

(带符号的/无符号的)

(带符号的/无符号的)

TINYINT

1

-128

127

 

 

0

255

SMALLINT

2

-32768

32767

 

 

0

65535

MEDIUMINT

3

-8388608

8388607

 

 

0

16777215

INT

4

-2147483648

2147483647

 

 

0

4294967295

BIGINT

8

-9223372036854775808

9223372036854775807

 

 

0

18446744073709551615


create table admin(
id int primary key,
username varchar(20),
password varchar(20)
)

如何理解where:把where条件当成一个表达式和每一行对比看是否成立,where 只对硬盘上的表起作用,查询出来的放在缓冲区内的不起作用。

如何理解select 后面的列呢:把列名当成变量来理解,变量是能运算的,

查询每个栏目下积压的货款(商品库存*价格)

select goods_id ,sum(goods_num* goods_pirce) from goods group by goods_id;

查询每个栏目积压的货款,并且货款超过两万的栏目;

select goods_id ,sum(goods_pirce* goods_number)  as huokuan from goods group by goods_id having huokuan > 20000;

模糊查询:like

like 后面加条件 %通配任意字符 _通配单个字符

 

 

之Group by 

把 行 按 字段 分组 (关键字:max min sum count ....)

  1. 查询最贵的商品的价格 select max(goods_price) from goods;
  2. 查询最大商品编号的商品 select max(goods_id) from goods;
  3. 查询最便宜的商品的价格 select min(goods_id) from goods;
  4. 查询所有商品的总库存量 select sum(goods_number) from goods;
  5. 查询每个栏目下最贵商品的数量 select cat_id ,max(shop_price) from goods group by cat_id;
  6. 每个栏目下商品种类 select cat_id count(*) from goods group by cat_id;

 


 

Limit 的使用

 在语句的最后面,起到线限制条目的作用

limit [offset]N

offset:偏移量(可选参数,如果不写,默认为0.从第一条开始选)

N:取出条目(必选参数)

eg:取出数据库中最贵的商品:

select goods_id ,goods_name from goods order by goods_price desc limit 1;

难度点的:去出每个栏目中最贵的商品

select goods_id,goods_name from goods group by goods_id order by desc limit 1;

 


 

子查询:

where型子查询:把内层的查询结果当作外层查询的比较条件

from型子查询:把内层的查询结果当成一张临时表,共外层sql再次查询

exists型子查询: 把外层的查询结果拿到内层,看内层的查询条件是否成立

EG:查询最新发布的商品:

select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods); ????传说中的子查询;

查询  每个 栏目 最贵 的商品:

第一步:先查出 最贵 顺带栏目 的:select max(goods_price) from goods group by goods_id ;

第二步:查询   select goods_id ,goods_name,goods_price where goods_price in (select max(goods_price) from goods group by goods_id);


联合查询:union

联合查询就是两张表或多张不同得表联合查询

查询条件就是:两张表查询出来的列数一致。表的机构可以不一致。

如果两张表联合查询出来的数据有相同的行和数值,不指定union的条件情况下会自动去重复,如果不需要去重则加上all

eg:select * from a union select * from b (去重)select * from a union all select * from b (不去重)

取两张表,并把相同的字段的值相加:

select id ,sum(number) from (select * from a union all select * from b) as flag group by id;

如果字句后面后order by 或limit 时 两个字句必须用()扩起来。

order by 配合limit 使用的时候才有意义,如果没有配置limit,order by 会被语法分析器去掉。就想where 1 恒成立时 不影响 性能;


 增加列:

增加列,默认在表的后一列;可以用after类声明新增的列在哪一列后面;第一类用first

alter table tablename add 列名 int *******;

删除列

alter table tablename drop 列名 ;

 修改列:alter table tname change 被修改的列名  声明新列  :alter table m change m mmm int ;


视图:什么是视图???如果

视图是由查询结果生成的一张虚拟表;

create view as select 语句 。

修改视图:和创建一样,把create换成alter ,实质就是覆盖掉旧的视图;


 

  1. 视图与表的关系:
    1. 如果表的数据改变了, 那么视图的数据肯定也改变了。
    2. 视图修改会影响表,但是视图并不总是能增删改的。
      1. 当视图的数据与表数据一一对应的情况下,这个时候修改视图会对表的有影响。同时,对于insert时,视图还应必须包含没有默认值的列。

为什么要有视图:

  1. 方便简化查询,如果总是需要一个查询结果做复杂查询的时候。
  2. 进行权限控制,因为有有的表不方便给别人看。这样就可以创建一个视图给别人看。
  3. 大数据分表是可以用:比如表的行数超过很多时:超过200万 变慢的情况就比较明显了,这个时候就可以把

 

 


事务:四个特性ACDI特性

  1. 指一组操作,要么都执行完,要么不执行--------原子性(原子的不可拆分性)(Atomicity)
  2. 事务发生之前和发生之后数据的总额一定要一致-------一致性(Consistenty)
  3. 所有操作没有完成前,其他会话不能看到事务的过程-----------隔离性(lsolation)
  4. 事务的影响不能撤销------------持久性(Durability)

如果出现了错误,事务也不准许撤销,只能通过补偿性事务。


  数据库备份

1 增量备份

2.整体备份

常用备份命令:

  1. 导出一个库(以库为单位):mysqldump -u root -p -B kuname1 kuname2 kuname3 > D:\\kuname.sql
  2. 导出所有库:mysqldump -u root -p -A >路径/备份名.sql
  3. 导出一个库下所有的表(以表为单位):mysqldump -u root -p kuname >D:\\kuname.sql
  4. 导出库下的一个表:mysqldump -u root -p kuname  t_name1 t_name2 t_name3 >D:\\t_name.sql
恢复命令:
  1. 以库为单位恢复:Mysql> source D:\\***.sql;   一句话ok(已经登录的情况下)
  2. 一表为单位恢复:Mysql> use ku_name

                                     Mysql> source D:\\***.sq;(分两步)

 


 索引:针对数据所建立的目录

好处:加快查询速度

坏处:降低增删改的速度

 

索引的创建原则:

1.不要过度索引

2.在where件最频繁的地方加索引

3.尽量索引散列值,过于集中的值索引意义不大

 

普通索引:index 加快了查询速度

唯一索引:unique 行上的值不能重复

主键索引: primary key 不能重复

全文索引:fulltext (对文章内部索引,不是模糊查询,模糊查询是一行一行的找,效率很低)

查看一张表的索引:

show index from t_name;

建立索引:

alter table 表名 add primary key (列名)

alter table 表明 add index/unique/fulltext 索引名(列名)不写索引名默认和列名相同

删除索引

alter table 表名 drop index 索引名;


 

经典面试题:

 

create table m (
mid int primary key auto_increment,
hid int ,
gid int ,
mres varchar(10),
matime date
);

insert into m
(hid,gid,mres,matime)
values
(1,2,'2:0','2006-05-21'),

(2,3,'1:2','2006-06-21'),

(3,1,'2:5','2006-06-25'),

(2,1,'3:2','2006-07-21');


create table t(
tid int,
tname varchar(10)
);

insert into t
values
(1,'国安'),

(2,'申花'),

(3,'曼联');

select t1.tname,mres,t2.tname,matime from
m left join t as t1
on m.hid = t1.tid

left join t as t2
on m.gid = t2.tid

where matime between '2006-0601' and '2006-07-01';