MySql的学习笔记

时间:2021-02-14 16:01:22
良好的理解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 索引名;