grade是什么类型 mysql_MYSQL 总结

数据基础

SQL语法顺序

1.建库

create database mydatabase;

也可以做个判断

create database if not exists mydatabase;

2.删库

drop database mydatabase ;

也可以做个判断

drop database if exists mydatabase;

mysql 中两个字符串拼接

select concat(username,password) 结果 from table ; 结果是全别名as可省略

3.默认值 default默认值,comment注释 engine引擎

create table if not exists student(

id int(4) not null auto_increment comment '学号id',

name varchar(20) not null default '匿名' comment '姓名',

age int(4) not null comment '年龄',

primary key(id)

) ENGINE=INNODB DEFAULT CHARSET=utf8

4.查看建库,建表语句,表结构

show create database mydatabase; 查看建库语句

show create table mytable; 查看建表语句

desc mytable 查看表结构

5.查看mysql中文件位置

show variables like '%dir%';

6.修改表

1.alter table user rename to user1 //修改表名 user-->user12.alter table user1 comment 'user表' //修改表注释

3.alter table user1 add passwd varchar(20) not null //增加passwd列

4.alter table user1 modify column passwd int(20)//修改字段类型

5.alter table user1 change passwd passwd1 varchar(20)//修改字段名字(要指定字段类型)

6.alter table user1 add sex int(1) default 0 after name;//在某个字段后面加列

7.alter table user1 change sex sex int(1) after passwd1 //调整字段顺序 sex出现了两次

8.alter table user1 add primary key(id)//增加主键

9.alter table user1 modify id int(10) not null auto_increment; //添加自增 前提是主键

10.alter table drop sex//删除某个字段

11.drop table user1 //删除表

7.插入

insert into student(id,name) values(1,'wh');

insert into student values(1,'wh'); //如果列名一一对应可以不同写列名

insert into student(id,create_time) values(2,current_time);//插入当前时间 字段类型是 datatime 可以插入current_time 表示当前时间

8.删除

delete from student;//student是表名 清空数据

delete from student where id =1 //清楚某条数

TRUNCATE

truncate table student;//删除学生表

delete,truncate,drop区别? delete 和truncate 都是删除表中的数据,不删除表,表结构索引不变。 delete可以具体到删除哪行,truncate 直接删完。 delete保留自增计时器,truncate直接将自增计数器清空 如果在开启了一个事务,delete删了之后如果取消还可以回滚, truncate直接删了,和事务无关 droptable student 是直接把表删了。

9.更新

update mytable set age=18 where id between 2 and 4;//将id2,4的age变为18岁

update mytable set age=18,username='wx123' where id =1;//将id=1的,名字,年龄变为 wx123,18

10.查询

select * from student ;//查全部数据

select concat('姓名:',name) as '新名字' from student;//查出name 在前面加个姓名: 列名改为concat

select distinct name from b;//去重name 相同的不要。但这样只有name字段,如果要其他字段不可以;

例如 select distinct name,id from b;//这样 虽然显示id,name,但是去重条件是name,id都相等才去重

所有用下面语句 group by分组,以什么为一组

select id,name from b group by name;//以name为分组,也可以实现去重

select name,age+1 as '加一岁 ' from b;//查询name age 并将age+1

where子句 条件 and or not

select * from a where id<10 or id>20; //选择出id<10或者id>10

select * from a where id between 10 and 20;//10~20

select * from a where id>10 and age<18;//id>10且age<18

select * from a where age !=10; //查年龄不是10岁的

select * from a where not age=10;

模糊查询null,like,in

like

select * from a where name like '王_' //一个下划线代表一个字 这里是查 王X

select * from a where name like '王%' //第一个字是王的

select * from a where name like '%王%' //查名字中有王的

in 里面根具体的值,不能%模糊查

select * from b where id in(1,2,3) //查出id 是1,2,3的

null

select * from b where id is null;//id为空

select * from b where id is not null;//ID不为空

join 多表联查

JOIN ..ON 固定语法

inner join :

SELECT a.*,u.user_name FROM article as a inner join user as u on a.user_id=u.user_id;join1

left join :

SELECT a.*,u.user_name FROM article as a left join user as u on a.user_id=u.user_id;join2

right join :

SELECT a.*,u.user_name FROM article as a right join user as u on a.user_id=u.user_id;join3

上面三种是最常见的。区别

inner join 是他们通过条件匹配的 a.user_id=u.user_id; 只显示两个相等的行

left join 即使他们的不符合匹配条件 也会将左表中的数据全部查出,如图join2所示 即使右表中没有与之对应的那行数据。

right join同理,右表中的数据全部查出,即使不匹配,所有如图join3所示,左表没有与之对应的那行数据

JOIN ON 有的后面还会跟where 。 on是判断条件,where 时等值查询,可以理解为在on判断条件之后,在进行一次筛选。

SELECT a.*,u.user_name FROM article as a right join user as u on a.user_id=u.user_id where starts !=null ;

扩展3表查询 查出文章名,下面的评论人的姓名和评论内容。

user article comment 三个表 先分为两个表,查出数据,在和第三个表查询

select a.article_title,u.user_name as '评论人',c.content

from article as a

inner JOIN comment as c

ON c.article_id=a.article_id

上面先查出文章下面的评论id,和内容

INNER JOIN user as u

on c.comment_userid=u.user_id

通过评论查出对应的用户名

where a.article_id=1 //这里意思是查出article_id 为1的文章

自连接

用一张表的某行的某字段,去这张表其他行的某字段去查询值。

我们现在有个评论表

评论id,评论用户的id,评论用户的姓名,被评论用户的id,我们现在想在这张表中 查出被评论用户的姓名怎么查。 关键点在于把这张表看成两张表。这样可以理解a表中的tocommentid 要去B表中的 通过commentid 查询到comment_id(被评论用户的姓名) ,实际上是一张表,通过取别名的方式当做两张表而已。

SELECT

c.comment_id,

c.comment_userid,

c.comment_username,

c.to_userid AS to_commentid

FROM

`comment` c

上图查询中的sql语句。 而现在,我们要再多查出一列"被评论用户的姓名"

所以看下面的sql,增加了一列即可。

SELECT

c.comment_id,

c.comment_userid,

c.comment_username,

c.to_userid AS to_commentid,

c2.comment_username AS '被评论人姓名'

FROM

`comment` c,

`comment` c2

where c.to_userid=c2.comment_id

where条件 表1中的to_userid去第二张‘comment’表找字段相等的即可

排序 order by

ascend 升序(默认 ),descend降序

select * from student order by grade asc;//查询出学生表中所有信息 按成绩排序,默认升序 asc可省略

select * from student order by grade desc;//降序

分页 limit 还有一种瀑布流,往下拉一直有

select student_name,grade from gradetable where subject='数学' order by grade desc limit 0,10;//在成绩表里查出前10学生的姓名和成绩

前面的0代表从起始位从0开始 ,后面的10,是往后查询条数 为10

如果limit 10,5 意思是起始位是10,往后查询5条

子查询 (重点)

之前像select * from b where id=10; =10是写死的

而子查询是where里面嵌套一个查询, where后面根的值是计算出来的,不是写死的

eg1.现在我们要查出 爱好游泳学生的全部信息 ,首先爱好游泳的同学的全部信息 都在student表里

我们可以直接 select * from student 获得

爱好游泳需要在hobby_table表里查 select student_id from hobby_table where hobby='游泳';

后来通过 student表中的student_id 和hobby_table表中的student_id 将他们连起来

select * from student where student_id=(

select student_id from hobby_table where hobby='游泳'

)

用之前将的连表查询是

SELECT s.* FROM student AS s

INNER JOIN hobby_table AS h

ON s.student_id = h.student_id

WHERE h.hobby = '游泳'

通过join多表联查,和where子查询 我们不难发现,如果只是需要多经过几次的判断,(子查询里面嵌套一个查询),用子查询,多表联查都可以,逻辑上 可能子查询好理解一点,但是如果我们还需要查询显示出另一张表其他字段,只能用多表联查。例如多个 hobby字段,select s.* 加上 h.hobby即可,而子查询只是经过判断 哪个student_id符合,不能加上字段。

一些函数

group by分组

查某个科目的平均成绩

select subject_name,AVG(student_grade)

from result as r

inner join subject as s

on r.subjectno = s.subjectno

group by r.subjectno;

如果此时有个判断条件平均分大于80,之前这么写

select subject_name,AVG(student_grade)

from result as r

inner join subject as s

on r.subjectno = s.subjectno

where AVG(student_grade)>80

group by r.subjectno;

在这里会发现报错了 原因是过滤分组查询的次要条件需要用having

改为如下sql

select subject_name,AVG(student_grade)

from result as r

inner join subject as s

on r.subjectno = s.subjectno

group by r.subjectno

having AVG(student_grade)>80;

MD5 加密 不可逆 相当于一个字典

insert into b(id,name) values(md5(1213131),'xx'); //插入 将id MD5加密一下

select * from b where id =md5(1213131);//查到对应数据

进阶

下面的内容某些讲的可能没有什么关联。

索引

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。

添加索引ALTER table [表明] add [索引种类] index [索引名] (`column`)

create [可加索引种类] index [索引名] on [表名](字段)

删除 DROP INDEX `indexname`

主键索引

主键 : 能唯一标识一条记录

特点 :

最常见的索引类型

确保数据记录的唯一性

确定快速定位到数据

唯一索引

作用 : 避免同一个表中某数据列中的值重复

与主键索引的区别

主键索引只能有一个

唯一索引可能有多个

普通索引

全文索引

插入100w条数据

DELIMITER $$

CREATE FUNCTION mock_data()

RETURNS INT

BEGIN

DECLARE num INT DEFAULT 1000000;

DECLARE i INT DEFAULT 0;

WHILE i < num DO

INSERT INTO app_user(`name`, `email`, `phone`, `gender`, `password`,

`age`)

VALUES(CONCAT('用户', i), '24736743@qq.com', CONCAT('18', FLOOR(RAND()*

(999999999-100000000)+100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));

SET i = i + 1;

END WHILE;

RETURN i;

END;

SELECT mock_data();

设计一个数据库

为什么要好好设计数据库?

糟糕的数据库设计 :数据冗余,存储空间浪费

数据更新和插入的异常

程序性能差

良好的数据库设计 :节省数据的存储空间

能够保证数据的完整性

方便进行数据库应用系统的开发

数据库设计遵守三大范式:第一范式 :每一列不可再分

第二范式 :满足第一范式,每个字段都和主键有关,每张表只描述一件事。(比如订单表,里面只能有订单方面信息,不可以有其他,例如用户名,职位等)

第三范式 :满足第二范式,每个字段和主键直接相关

规范化和性能的关系在数据规范化的同时 , 要综合考虑数据库的性能

通过在给定的表中添加额外的字段,减少查询用时(连表变为了单表查询)

数据库中可能会听到sql注入,那什么是sql注入,就是通过字符串拼接的方式是用户密码始终为true,继而暴力登录。

解决 java中用PreparedStatement对象,预编译,将sql 中参数变为?占位符,将参数当做字符,直接替换(假如遇到特殊字符会将他转义掉,例如引号),不存在拼接问题了select * from b where id=?

#,$区别

#{} 会预编译,对传入参数加上引号,特殊字符如引号会转义,

传入wh(字符串)

select * from b where name=#{name}

--->select * from b where name="wh"//将传入的wh加上引号

${}

传入wh(字符串)简单字符串拼接

select * from b where name=${name}

--->select * from b where name=wh //报错

应该为

select * from b where name="${name}"

例如表名,列名,order by后面等 动态参数用$

我们mysql逻辑图是什么样的呢?

首先客户端通过身份验证连接上mysql连接器,当我们执行sql时,先查询缓存,如果有命中,直接返回,没有,去分析器:进行词法分析,语法分析,构建一颗语法执行树。优化器:构建执行计划(选择合适的索引),最后上执行器:去执行,返回结果 如果是insert语句,需要将数据放到存储引擎中。

在解析层中有三大缓存操作:1.sql语句缓存 select * from b where id =1构建的语法执行树

2.sql执行计划缓存 select AVG(grade) from b group by ...order by..concat....等一些动态的数据,无法缓存他的缓存树,所以只能缓存他的执行计划:执行顺序,是否要重写等。 找缓存先3后1.找不到在2

3.结果集缓存 上一次的查询结果k---v 最没用mysql逻辑图

mysql 为每个client 分配一个session(理解为socket),在执行事务,会申请一个独立空间(memory allocation),在里面进行解析,优化,执行等操作。

MYSQ为什么用B+?

linux 1页4KB ,cpu每次拿4页,mysql 默认16kb,一次4页 B+一个索引中的一个节点最多8字节,加上指针6字节,最多14b 16kb/14b=1170,如果是数据的话就放的少一点,所以说mysql用B+,是因为B+一个索引Node最大可放16kb,恰好是cpu一次拿的最大值,而索引越节点放的数据越多,相对二叉树,整颗树的高度,就不会太高。(节点放在磁盘上,每次查找都需要去磁盘拿,高度小磁盘IO次数就少)磁盘IO利用率高

undo log是回滚用的,在执行事务的,如果回滚了,事务会顺着undo log日志,回到最初的数据。

redo log是innodb特有的 在innodb引擎层,记录新数据的日志,为事务中每次的变更记录日志,大小是固定的,理解成一个环形,write_pos逆时针写数据,check_point擦数据,将输入写入硬盘中。

Bin log在mysql服务层,它记录了数据库上的所有改变,并以二进制的形式保存在磁盘中;它可以用来查看数据库的变更历史、数据库增量备份和恢复、Mysql的复制(主从数据库的复制)。语句以“事件”的形式保存,它描述数据更改。

binlog有三种模式:ROW(行模式), Statement(语句模式), Mixed(混合模式)。

row

优点:日志内容会非常清楚的记录每条数据详细的变更细节,即使只更新了一个字段,binlog里也会记录所有字段的数据。

缺点:binlog日志会非常大,mysql主从同步时,会产生大量磁盘IO。

statement记录的只是执行语句。

优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。

缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有很多相关问题。

Mixed(混合模式):在Mixed模式下,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值