SQL/MySQL基础

SQL基础

一、数据库操作

创建数据库

  • create database 数据库名称 [character set 字符集 collate 字符集校对规则];
1620220612160.png

查看数据库

  • 查看数据库服务器中的所有数据库:show databases;


    1620220704017.png
  • 查看某个数据库的定义信息:show create database 数据库名称:


    1620220693057.png

修改数据库

  • alter database 数据库名称 character set 字符集 collate 校对规则;
1620220817998.png

删除数据库

  • drop database 数据库名称;


    1620220861403.png

其他数据库操作

  • 切换数据库:use 数据库名称;


    1620220978871.png
  • 查看当前正在使用的数据库:select database();
1620220993373.png

二、数据库表的操作

字段

字段类型对比

Java mysql
byte/short/int/long tinyint/smallint/int/bigint
float float
double double
boolean bit
char/String char和varchar

char和varchar的区别

  • char代表是固定长度的字符或字符串。
    • 例:定义类型char(8),向这个字段存入字符串hello,那么数据库使用三个空格将其补全。
  • varchar代表的是可变长度的字符串。
  • 例:定义类型varchar(8),向这个字段存入字符串hello,那么存入到数据库的就是hello。

Date(date/time/datetime/timestamp)

datetime和timestamp区别

  • datetime就是既有日期又有时间的日期类型,如果没有向这个字段中存值,数据库使用null存入到数据库中
  • timestamp也是既有日期又有时间的日期类型,如果没有向这个字段中存值,数据库使用当前的系统时间存入到数据库中

File(BOLB/TEXT)

  • BOLB:存储图片,文件
  • TEXT:存储大文本

约束

  • 约束作用:保证数据的完整性
  • 单表约束分类:
    • 主键约束:primary key 主键约束默认就是唯一 非空的
    • 唯一约束:unique
    • 非空约束:not null

创建表

  • create table 表名称(字段名称 字段类型(长度) 约束, 字段名称 字段类型(长度) 约束......)
1620221959203.png

查看表

  • 查看某个数据库的所有表:show tables;
1620222048748.png
  • 查看某个表的结构信息:desc 表名;
1620222061663.png

删除表

  • drop table 表名;


    1620222109771.png

修改表

  • 添加列:alter table 表名 add 列名 类型(长度) 约束


    1620222423438.png
  • 修改列类型,长度和约束:alter table 表名 modify 列名 类型(长度) 约束;
1620222642175.png
  • 删除列:alter table 表名 drop 列名;
1620222723439.png
  • 修改列名称:alter table 表名 change 旧列名 新类名 类型(长度) 约束;
1620222781080.png
  • 修改表名:alter table 表名 to 新的表名;
1620222860620.png
  • 修改表的字符集:alter table 表名 character set 字符集;
1620222918344.png

三、对数据库表的记录进行操作(重点)

添加表的记录

语法:

  • 向表中插入某些列:insert into 表名 (列名1,列名2,列名3…) values (值1,值2,值3…)
  • 向表中插入所有列:insert into 表名 values (值1,值2,值3…);

注意事项

  • 值的类型与数据库中表列的类型一致。

  • 值的顺序与数据库中表列的顺序一致。

  • 值的最大长度不能超过列设置最大长度。

  • 值的类型是字符串或者是日期类型,使用单引号引起来。

  • 直接向数据库中插入中文记录会出现错误!!!

    解决方法:

         show variables like '%character%';  --查看数据库中与字符集相关参数:
    
         需要将MySQL数据库服务器中的客户端部分的字符集改为gbk。
    
         找到MySQL的安装路径:my.ini文件,修改文件中[client]下的字符集,重启MySQL的服务器
    

修改表的记录

语法

  • update 表名 set 列名=值,列名=值 [where 条件];

注意事项

  • 值的类型与列的类型一致。
  • 值的最大长度不能超过列设置的最大长度。
  • 字符串类型和日期类型添加单引号。

删除表的记录

语法

  • delete from 表名 [where 条件];

注意事项

  • 删除表的记录,指的是删除表中的一行记录。

  • 删除如果没有条件,默认是删除表中的所有记录。

  • 删除表中的记录有两种做法:

    delete from user;

    删除所有记录,属于DML语句,一条记录一条记录删除。事务可以作用在DML语句上的

    truncate table user;

    删除所有记录,属于DDL语句,将表删除,然后重新创建一个结构一样的表。事务不能控制DDL的

查看表的记录(重点)

注意:SFWGHO(是否违规后):S(select)… F(from)…W(where)…G(group by)…H(having)…O(order by);

语法

  • select [distinct] * 列名 [[as] 别名] from 表 [条件]; (distinct:不重复)

条件查询

  • 使用where子句
    • >,<,>=,<=,<>,=
    • like:模糊查询
    • in:范围查询
    • 条件关联:and, or, not

like

可以进行模糊查询,在like子句中可以使用或者%作为占位符。只能代表一个字符,而%可以代表任意个字符。

  • like '李_':名字中必须是两个字,而且是姓李的。
  • like '李%':名字中姓李的学生,李子后可以是1个或任意个字符。
  • like '%四':名字中以四结尾的。
  • like '%王%':只要名称中包含这个字就可以。

in

例:查询英语成绩是69,75,89学生的信息

select * from exam where english in (69,75,89);

排序查询

  • 使用order by 字段名称 asc/desc;

例1:查询学生信息,并且按照语文成绩倒序排序:

select * from exam order by chinese desc;

例2:查询学生信息,先按照语文成绩进行倒序排序,如果成绩相同再按照英语成绩升序排序

select * from exam order by chinese desc,english asc;

分组统计查询

  • 聚合函数使用

    • sum()
    • max()
    • min()
    • count()
    • avg()
  • 分组查询

    • 语法:使用group by 字段名称;

    • where的子句后面不能跟着聚合函数。如果现在使用带有聚合函数的条件过滤(分组后条件过滤)需要使用一个关键字having

      select product,sum(price) from orderitem  group by product having sum(price) > 5000;
      

MySQL基础

一、重置MySQL的密码

  1. 停止MySQL的服务

mysql.png
  1. 在cmd下启动MySQL服务

mysql2.png
  1. 重新开启cmd的命令行

mysql3.png
  1. 修改root的密码

mysql4.png
  1. 结束mysqld的进程

mysql5.png
  1. 重新启动MySQL的服务

mysql6.png

二、数据库的备份

  1. 打开cmd的命令行窗口

mysqldump -u root -p web_test1 >C:/web_test1.sql

三、数据库的还原

  1. 第一种还原方式

    1. 在数据库服务器内部创建数据库:
    2. 在命令行窗口
    
    
  2. 第二种还原方式

    1. 在数据库服务器内部创建数据库:
    2. 切换到该数据库使用source命令还原
    
    

四、多表查询(重难点)

1.交叉连接(不常用)

使用关键字cross join
select * from classes cross join student;
不适用关键字cross join关键字
select * from classes,student;

2.内连接

  1. 显示内连接

    select * from classes c inner join student s on c.cid = s.cno;
    
  2. 隐式内链接

    SELECT * FROM classes c,student s WHERE c.cid = s.cno;
    

3.外连接

  1. 左外连接

    SELECT * FROM classes c LEFT OUTER JOIN student s ON c.cid = s.cno;
    
  2. 右外连接

    select * from classes c right outer join student s on c.cid = s.cno;
    

内外连接的联系

[图片上传失败...(image-29b1f2-1621497027522)]

4.子查询

带in的子查询

查询学生生日在91年之后的班级的信息。

select * from classes where cid in (SELECT cno FROM student WHERE birthday > '1991-01-01');

带exists的子查询

查询学生生日大于91年1月1日,如果记录存在,前面的SQL语句就会执行

select * from classes where exists (SELECT cno FROM student WHERE birthday > '1991-01-01');

带any的子查询

SELECT * FROM classes WHERE cid > ANY (SELECT cno FROM student )

带all的子查询

SELECT * FROM classes WHERE cid > ALL (SELECT cno FROM student)

五、sql练习

查询班级名称,和班级总人数

select c.cname count(*) from classes c, student s where c.cid = s.cno group by c.cname;

查询学生的姓名和学生所选的总课程平均成绩。

SELECT s.sname, AVG(sc.score) FROM student s, stu_cour sc WHERE s.sid = sc.sno GROUP BY s.name;

查询学生的姓名和学生的选课总数,显示选课超过2门学生姓名。

SELECT s.sname, COUNT(*) FROM student s, stu_cour sc WHERE s.sid = sc.sno GROUP BY s.sname HAVING COUNT(*) > 2;

查询平均成绩大于80分的学生的总数。

SELECT COUNT(*) FROM student s WHERE s.sid IN (SELECT sc.sno FROM stu_cour sc GROUP BY s.sid HAVING AVG(sc.score) > 80);

查询学生和平均成绩,但是平均成绩大于01班的任何一个学生的平均成绩。

SELECT s.name,AVG(sc.score) FROM student s, stu_scur sc WHERE s.sid = sc.sno GROUP BY s.sno HAVING AVG(sc.score) > ANY ( AVG(sc.score) FROM student s,stu_cour sc,classes c WHERE s.sid = sc.sno AND c.cid = cs.cno AND c.cname = '01' GROUP BY s.sid);

六、MySQL事务

1.事务的概念

事务指的是逻辑上的一组操作,组成这组操作各个逻辑单元要么全都成功,要么全都失败。

2.事务的特性(ACID)

原子性(Atomicity)

原子性:事务的不可分割,组成事务的各个逻辑单元不可分割。

一致性(Consistent)

一致性:事务执行的前后,数据完整性保持一致。

隔离性(Isalotion)

隔离性:事务执行不应该受到其他事务的干扰,侧重于事物之间。

持久性(Durable)

持久性:事务一旦结束,数据就持久化到数据库中。

原子性、隔离性、持久性都是为了保障一致性而存在的,一致性也是最终的目的。

3.事务的隔离级别

如果不考虑隔离性,引发一些安全问题

如果不考虑隔离性(一个事务执行受到其他的事务的干扰),引发一些安全问题,主要体现在读取数据上:

  • 脏读:一个事务读到了另一个事务未提交的数据,导致查询结果不一致
  • 不可重复读:一个事务读到了另一个事务已经提交的update的数据,导致多次查询结果不一致。
  • 虚读/幻读:一个事务读到了另一个事务已经提交的insert的数据,导致多次查询结果不一致。

解决这些安全问题

设置事务的隔离级别(由上到下,安全性依次提高,性能依次降低)

读未提交(READ UNCOMMITTED)脏读,不可重复读,虚读都有可能发生

读提交 (READ COMMITTED)避免脏读。不可重复读和虚读是有可能发生

可重复读 (REPEATABLE READ)避免脏读、不可重复读,虚读有可能发生。

串行化 (SERIALIZABLE)避免脏读,不可重复读,虚读。

4.演示脏读

  1. 开启两个窗口A,B

  2. 设置A窗口的隔离级别为read uncommitted;

    SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted;
    //Mysql的默认隔离级别是REPEATABLE-READ。
    
mysqlAffair.png
  1. 在A,B两个窗口中开启事务

    Mysql中开启事务有两种方式`begin/start transaction`
    

    在执行begin/start transaction命令,它们并不是一个事务的起点,在执行完它们后的第一个sql语句,才表示事务真正的启动 。

  2. 在B窗口中完成转账的功能:

    update account set money = money - 1000 where name= '小张';
    update account set money = money + 1000 where name= '小凤';
    ***** 事务未提交!!!
    
mysqlAffair2.png
  1. 在A窗口中进行查询

    select * from account;
    
mysqlAffair3.png

发现A窗口中已经查询到转账成功了!!!已经发生了脏读:一个事务中已经读到了另一个事务未提交的数据。

5.避免脏读,演示不可重复读

  1. 开启两个窗口A,B

  2. 设置A窗口的隔离级别为read committed;

    SET SESSION TRANSACTION ISOLATION LEVEL read committed;
    
mysqlAffair4.png
  1. 分别在两个窗口中开启事务:

    start transaction;
    
  2. 在B窗口中完成转账

    update account set money = money - 1000 where name= '小张';
    update account set money = money + 1000 where name= '小凤';
    
mysqlAffair5.png

没有提交事务

  1. 在A窗口中进行查询:

    select * from account;
    
mysqlAffair6.png

发现这个时候没有转账成功!!!(没有查询到另一个事务未提交的数据:说明已经避免了脏读

  1. 在B窗口中提交事务

    commit;
    
  2. 在A窗口查询

    select * from account;
    

mysqlAffair7.png

发现这次的结果已经发生了变化!!!(已经发生不可重复读:一个事务已经读到了另一个事务提交的update的数据,导致多次查询结果不一致。

6.避免不可重复读

  1. 分别开启两个窗口A,B

  2. 设置A窗口的隔离级别:repeatable read;

  3. 在A,B两个窗口中开启事务

  4. 在B窗口完成转账

  5. 在A窗口中进行查询

  6. 在B窗口中提交事务

  7. 在A窗口中再次查询

    发现在一个事务中的多次查询结果是一致!!!(已经避免不可重复读)。

7.演示串行化

  1. 开启两个窗口A,B

  2. 设置A窗口的隔离级别:serializable

  3. 分别在两个窗口中开启事务:

  4. 在B窗口中插入一条记录

  5. 在A窗口中进行查询

    发现A窗口已经卡住了(说明事务不允许出现并发,A窗口需要等待B窗口事务执行完成以后,才会执行A窗口的事务。)当B窗口的事务结束(提交或者回滚),那么A窗口马上就会出现结果。

你可能感兴趣的:(SQL/MySQL基础)