数据库概述

为什么要学习数据库

因为数据库可以实现数据持久化到本地;使用完整的管理系统统一管理,可以实现结构化查询,方便管理。

数据库(DB全程为DataBase)是存储数据的容器,将数据通过特定的规则存储在磁盘上。通过数据库管理系统来组织和管理存储在数据库中的数据。

数据库管理系统(DataBase Management System)又称为数据库软件和数据库产品,用于创建或管理数据库(DB)。

结构化查询语言(Structure Query Language)也就是SQL语句。

根据不同的存储类型,可以将数据库分为关系型数据库和非关系型数据库,MySql就属于关系型数据库,关系型数据库管理系统统称为RDBMS,还有Oracle(功能强大、收费)、SQL Server(微软):只能在Windows系统上运行。非关系型数据库有Redis、MongoDB等等。

MySQL的语法规范

  • 不区分大小写,建议关键字大写,表名、列名小写
  • 每句话用;

MySQL的注释要求

  • 单行注释:#注释文字
  •  单行注释:-- 注释文字(要有空格)
  •  多行注释:/* 注释文字 */

MySQL启动

net start mysql80
net stop mysql80

MySQL客户端连接

MySQL自带的客户端命令行

mysql [-h 127.0.0.1] [-p 3306] -u root -p

SQL

SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库。基本上全部的DBMS都支持SQL,并且它简单易学。

数据库存储数据的特点

  • 数据放到表中,表在放到数据库中
  • 一个数据库中可以有多个表,每个表都有自己唯一的名字,用来标识自己。
  • 表具有一些特性,定义了这些数据要在表中如何储存,和Java中构造类时设计类类似。
  • 表是由列组成的,列也可以称为字段,一个表中有一个或多个列组成。
  • 数据库中的数据都是以表存放的,表中的数据都是以行来存储的。

DDL——数据定义语言,用来定义数据库对象(数据库、表、字段)

数据库操作

查询

查询所有数据库

SHOW DATABASES;

查询当前数据库

SELECT DATABASE();

创建

CREATE DATABASES [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排序规则];

删除

DROP DATABASE 数据库名 / [IF EXISTS数据库名];

使用

USE 数据库名;

设计表

设计表的时候需要先确定表名,确定字段名,再规定该字段的数据类型和长度,该表中有的约束有哪些分别在哪些字段上。

除了确定字段的数据类型,对表的创建、修改、删除以及更新(都是对表结构的操作)等都属于DDL操作。

查询当前所有数据库的表

SHOW TABLES;

查询表结构

DESC 表名;

查询指定表的建表语句

SHOW CREATE TABLE 表名;

 数据类型

分类

类型

大小

有符号(SIGNED)范围

无符号范围(SIGNED)范围

描述

TINYINT

1byte

(-128,127)

(0,255)

小整数值

SMALLINT

2bytes

(-32768,

    32767)

(0,65535)

大整数值

MEDIUMINT

3bytes

(-8388608,

   8388607)

(0,16777215)

大整数值

INT或INTEGER

4bytes

(-2147483648,

2147483647)

(0,4294967295)

大整数值

BIGINT

8 bytes

(-3. 402823466 E+38,

3.402823466351 E+38)

(0,2^64-1)

极大整数值

FLOAT

4 bytes

(-3. 402823466 E+38,

3.402823466351 E+38)

0和(1.175494351 E-38, 3.402823466 E+38)

单精度浮点数值

DOUBLE

8 bytes

(-1.7976931348623157 E+308,

1. 7976931348623157 E+308)

0和(2.2250738585072014 E-308, 1.7976931348623157 E+308)

双精度浮点数值

DECIMAL

依赖于M(精度)和D(标度)的值

依赖于M (精度)和D (标度)的值

小数值(精确定点数)

CHAR和VARCHAR的区别:CHAR是定长字符串,VARCHAR是变长字符串,他们的大小范围也是不一样的,CHAR比如给定的长度是10,当存入一个字符时也是占用了10(会用空格进行补位),但VARCHAR给定的长度是10存入一个字符就是占用一个字符的长度。比如存储用户的用户名时,最好还是使用VARCHAR,而性别就占用一个字符,所以使用CHAR就可以。

TINYBLOB存储的是不超过255字符长度的二进制数据,BOLB存储的是二进制形式的长文本数据,像视频、音频都属于二进制数据。

时期类型中有DATE、TIME、YEAR、DATETIME、TIMESTAMP,其中DATE的长度大小为3,范围1000-01-01 至9999-12-31,格式是YYYY-MM- -DD,指的是时期值。TIME指的是时间值或者持续时间,长度也是3,格式是HH :MM:SS 。DATETIME就是将DATE和TIME相结合,是混合日期和时间值,格式为YYYY- -MM- _DD HH:MM:SS。

DML——数据库操纵语言

常用的语法就是insert、update、delete,也就是在表中插入、修改、删除数据。


插入数据


方式1: INSERT INTO 表名(列1,列2……,列n) VALUES(值1,值2…..,值n);


方式2: INSERT INTO 表名 set 列名1=值1,..列名n=值n;


方式3: INSERT INTO 表名(列1,列2……,列n) VALUES(值1,值2…..,值n),(值1,值2…..,


值n);


方式4:INSERT INTO 表名(列1,列2……,列n) 查询语句(查询的列数与插入列数匹配)



修改数据


UPDATE 表名 SET 列名 = ‘新值’WHERE 条件



删除数据



DELETE FROM 表名 WHERE 条件



TRUNCATE TABLE 表名;清空整张表




DQL——数据查询

数据查询包括基本查询、条件查询(where)、聚合函数、分组查询(group by)、排序查询(order by)和分页查询(limit)。

基本查询

select 字段1,字段2,字段3……   from 表名 ;

select * from 表名;

设置别名

select 字段1 [as别名1],字段2 [as别名2] .. from表名;

去除重复记录
select distinct字段列表from表名;



当然as的使用并不是必要的,as是可以省略的。




条件查询




select 字段1,字段2,字段3……   from 表名 where条件列表;



比较运算符

功能

>

大于

>=

大于等于

<

小于

<=

小于等于

=

等于

<或!=

不等于

BETWEEN ... AND ..

在某个范围之内(含最小、最大值)

IN(..)

在in之后的列表中的值,多选一

LIKE占位符

模糊匹配(匹配单个字符,%匹配任意个字符)

IS NULL

IS NULL


逻辑运算符

功能

AND或&&

并且(多个条件同时成立)

OR或|

或者(多个条件任意-个成立)

NOT或!

非,不是

 

-- 查询年龄在20、21、22的女同学的信息
SELECT * FROM student WHERE gender='女'AND age IN(20,21,22,23);

-- 查询年龄在19-21之间,姓名为三个字的男同学
SELECT * FROM student WHERE gender='男' AND (age BETWEEN 19 AND 21) AND LIKE'___';
 
-- 查询姓刘且三个字的同学(如果只是姓刘就可以使用%)
SELECT * FROM student WHERE LIKE'刘__';

聚合函数


逻辑处理



  • case when 条件 then 结果1 else 结果2 end; 可以有多个when
  • ifnull(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回
  • 原本的值
  • if函数:
  • if else的 效果 if(条件,结果1,结果2)

字符函数

  • length():获取参数值的字节个数
  • char_length()获取参数值的字符个数
  • concat(str1,str2,.....):拼接字符串
  • upper()/lower():将字符串变成大写/小写
  • substring(str,pos,length):截取字符串 位置从1开始
  • instr(str,指定字符):返回子串第一次出现的索引,如果找不到返回0
  • trim(str):去掉字符串前后的空格或子串,trim(指定子串 from 字符串)
  • lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度
  • rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度
  • replace(str,old,new):替换,替换所有的子串
-- 学生的学号,统一为五位数,目前不足五位数的统一向前补零
UPDATE student SET studentId=LPAD(studentId,10,0);
-- 通过数据库的函数,生成一个六位数的随机码(rand()生成的是0-1的随机数)
rpad(round(rand()*1000000, 0), 6, 0);


数学函数


  • round(数值):四舍五入,前面输入数值,后面输入保留几位小数
  • ceil(数值):向上取整,返回>=该参数的最小整数
  • floor(数值):向下取整,返回<=该参数的最大整数
  • truncate(数值,保留小数的位数):截断,小数点后截断到几位
  • mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负
  • rand():获取随机数,返回0-1之间的小数

日期函数


  • now():返回当前系统日期+时间
  • curdate():返回当前系统日期,不包含时间
  • curtime():返回当前时间,不包含日期
  • 可以获取指定的部分,年、月、日、小时、分钟、秒
  • YEAR(日期),MONTH(日期),DAY(日期) ,HOUR(日期) ,MINUTE(日期)
  • SECOND(日期)
  • str_to_date:将日期格式的字符转换成指定格式的日期
  • date_format:将日期转换成字符串
  • datediff(big,small):返回两个日期相差的天数
-- 查询学生的在校天数,并按照降序来排列
SELECT NAME,DATEDIFF(CURDATE(),entrydate) AS 'entrydays' FROM student ORDER BY entrydays DESC;

分组函数

  • 功能:用作统计使用,又称为聚合函数或统计函数或组函数
  • 分类:sum 求和、avg 平均值、max 最大值、min 最小值、count 计数 (非空)
  • 以上的分组函数都忽略null值
  • count函数一般使用count(*)来统计行数

流程控制函数

  • case when 条件 then 结果1 else 结果2 end; 可以有多个when
  • ifnull(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回
  • 原本的值
  • if函数:
  • if else的 效果 if(条件,结果1,结果2)

分组查询

SELECT字段列表FROM表名[WHERE 条件] GROUP BY分组字段名[ HAVING分组后过滤条件];

-- 根据性别分组,统计男同学和女同学的数量
select gender,count(*) from student group by gender;
-- 根据性别分组,统计男同学和女同学的平均年龄
select gender,avg(age) from student group by gender;
-- 选出学生年龄大于20,且学生按照学院分类,人数>=3的学院
select department,count(*) depart_count from student where age>20 group by department having depart_count>=3;

where和having的区别

  • 执行的时机不同,where是分组之前进行过滤,having是在分组之后进行过滤,如果where过滤条件没过也不能进入分组。
  • 判断条件不同,where不能对聚合函数进行判断,但是having可以,就比如说上述的SQL语句,使用count来统计学院人数 ,然后再进行过滤大于三个人的学院。

排序查询

排序查询语法

SELECT字段列表FROM表名ORDER BY字段1排序方式1 , 字段2排序方式2;

 排序方式

  • 升序(asc)是默认的
  • 降序(desc)

如果是多字段排序,第一个字段相同时,第二个字段才会排序

-- 根据年龄对男同学进行升序处理(查询结果如果年龄为null,会显示null)
select name,gender,age from student order by age;
-- 根据同学们的年龄进行降序处理,如果年龄相同,再根据学号进行升序处理
select name,gender,age,studentID from student order by age desc,studentID asc;

分页查询

SELECT字段列表FROM表名LIMIT 起始索引,查询记录数;

注意:

  • 最初的起始索引从0开始,起始索引=(查询页码-1)*想查询的数据数量。
  • 分页查询不同的数据库有不同的实现,再MySQL中是limit。
  • 如果想要查询的是第一页数据,可以直接省略,写limit10即可。
-- 一页数据量为5,查询第二页的数据
SELECT * FROM student LIMIT 5,5;
-- 一页数据为10,查询第一页的数据
SELECT * FROM student LIMIT 10;

 SQL查询语句的执行顺序

先执行from查看来自于哪张表,再通过where的条件过滤数据,根据group by进行分组并对分组后的数据使用having进行过滤,通过select选择显式的字段对应的数据,使用order by进行排序,limit进行分页。

DCL——数据控制语言

DCL数据控制语言,用来管理数据库用户、控制数据库的访问权限。

查询用户

USE mysql; 

SELECT * FROM user;

创建用户

CREATE USER '用户名'@'主机名’IDENTIFIED BY '密码' ;

修改用户密码

ALTER USER '用户名’@'主机名’ IDENTIFIED WITH mysql native_ _password BY新密码’ ;

删除用户

DROP USER '用户名'@'主机名' ;

DCL——用户管理 

-- 创建用户summer,只能在当前主机localhost访问,密码是123456
CREATE USER 'summer'@'localhost' IDENTIFIED BY'123456';
-- 创建用户spring,可以在任意主机访问该数据库,密码是123456
CREATE USER 'spring'@'%' IDENTIFIED BY'123456';
-- 修改spring的访问密码
ALTER USER 'spring'@'%' IDENTIFIED WITH mysql_native_password BY '666666';
-- 删除spring
DROP USER 'spring'@'%';

-- 主机名可以使用%通配

DCL——权限控制

查询权限

SHOW GRANTS FOR '用户名’@'主机名’ ;

授予权限

GRANT权限列表ON数据库名表名TO '用户名’@'主机名';

撤销权限

REVOKE权限列表 ON数据库名.表名FROM ‘用户名'@'主机名'; 

  • 多个权限之间可以用,来进行分隔
  • 授权时数据库名和表名可以使用*通配,代表所有

约束

外键约束

添加外键的两种方式

CREATE TABLE表名(

          字段名数据类型,

 

……
         [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名)
);

ALTER TABLE 表名ADD CONSTRAINT 外键名称FOREIGN KEY (外键字段名) REFERENCES主表(主表列名);

外键的删除和更新行为 

行为

说明

NO ACTION

当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 RESTRICT一致)

RESTRICT

当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 NO ACTION一致)

CASCADE

当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。

SET NULL

当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null (这就要求该外键允许取null)。

SET DEFAULT

父表有变更时,子表将外键列设置成一一个默认的值(Innodb不支持)

ALTERTABLE表名ADD CONSTRAINT外键名称FOREIGN KEY (外键字段)

    REFERENCES 主表名(主表字段名) ON UPDATE CASCADE ON DELETE CASCADE;

 多表查询

因为业务之间互相关联,涉及到多张表之间的关系问题,各种表之间也存在着各种联系,主要为多对多、一对多(多对一)、一对一。

  • 在多对多的实现中,建立一张中间表来联系另外的两张表,中间表中需要包含两个各自表中的外键。
  • 在一对多(多对一)的实现中,将外键创建在字段较多的那一张,指向一方的主键。
  • 在一对一的情况下,将单表拆分,将表中的基础字段放在一张表,详细字段再放到另一张表中,提高查找的效率。