数据库

94 阅读16分钟

Docker

Docker 简介

Docker是一个用于开发,交付和运行应用程序的开放平台

通过利用Docker的方法来快速交付,测试和部署代码,可以大大减少编写代码和在生产环境中运行代码之间的延迟。

Docker 能实现,在同一硬件上运行更多工作负载。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,而您可以用更少的资源做更多的事情。

Docker三要素

Docker三要素:镜像、容器、仓库

Docket镜像(lmage):就是一个只读的模版。说像可以用来创建docker谷器,一个镜像可以创建很多容器。Docker利用容器(container)独立运行的一个或一组应用。

容器:是用镜像创建的运行实例。容器可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

仓库(Repository):是集中存放镜像文件的场所。

Docker常用的命令

查看本地镜像:docker images

拉取镜像到本地:docker pull 镜像名称[:tag]

拉取mysql镜像: docker pull mysql:5.6

创建mysql容器,修改超级管理员密码:

docker run -p 127.0.0.1:12345:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.6

-p:表示设置ip地址和端口

127.0.0.1:为本地ip地址

12345:3306:本地端口映射docker服务端口

--name mysql:表示设置的容器名称

-e:设置账户(root)密码

MYSQL_ROOT_PASSWORD=root:设置root用户密码

-d:表示在后台运行

mysql:5.6:表示镜像名称

查看正在运行的容器:docker ps

查看所有容器:docker ps -a

删除停止运行的容器:docker rm [容器id]

删除正在运行的容器:docker rm -f [容器id]

删除本地镜像:docker rmi -f 镜像ID(镜像名称:版本)

启动容器:docker start 容器名称(容器id)

eg: docker start mysql5

进入容器:docker exec -it 容器名称(容器id) /bin/bash

eg: docker exec -it mysql5 /bin/bash

进入mysql控制台:mysql -u用户名 -p密码

eg: mysql -uroot -proot

退出mysql容器:exit

回到windows控制台:ctrl + p + q

数据库

数据库即数据的仓库,在数据库中提供了专门的管理系统,对数据库中的数据进行集中的控制和管理。能高效的对数据进行存储、检索。

数据在数据库中的存储形式:

层次模型

网状模型

关系模型

关系型数据库:关系型数据库取源于关系模型,关系模型认为世界是由实体和联系组成的。而关系型数据库,是一种以表作为实体,以主键和外键作为联系的数据库结构。

主键:在关系数据库表中,用于标识每一行唯一性的列,称为主键列。主键有两个特点:不能重复,不能为空。

外键:在关系数据库表中,外键用来表达表和表之间关联关系的列。

关系型数据库的关系主要有: 一对一、一对多、多对多

  • 一对一:一条主表(被引用方)记录对应一条从表(引用方)记录,同时一条从表记录对应一条主表记录。
公民表身份表
公民编号姓名公民编号身份证号
1张三112345
2李四267890

张三的身份证号为12345,身份证号为67890的是李四

  • 一对多:一条主表记录对应多条从表记录,同时一条从表记录对应一条主表记录
公民表汽车表
公民编号姓名汽车编号汽车品牌公民编号
1张三1宝马1
2李四2奔驰2
3王五3大众1
4红旗3
5丰田3

张三拥有一辆宝马,一辆大众,宝马的车主是张三

  • 多对多:一条主表记录对应多条从表记录,同时一条从表记录对应多条主表记录,依靠中间表维护多对多的联系。
老师表中间表学生表
老师编号姓名老师编号学生编号学生编号姓名
1张三111张一一
2李四122张三三
3王五213李思思
254李依伊
325冯悦阅

张三教了张一一和张三三两个学生,张一一的老师有张三和李四

在关系型数据库中,引用方称为从表,被引用方称为主表。从表利用外键,引用主表的主键,从而建立两个表之间的联系。所以,外键在从表中定义。(从表中有外键,主表中没有外键,有主键)

数据库管理系统(DBMS)

关系数据库只是一个保存数据的容器,大多数数据库依靠一个称为数据库管理系统(Database Management System,简称DBMS)的软件来管理数据库中数据。

数据库引擎分类

数据库引擎

数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。

不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。

InnoDB存储引擎

InnoDB是事务型数据库的首选引擎,提供交互、回滚、崩溃恢复能力的事务安全能力,并可以实现并发控制,InnoDB是默认的mysql引擎。

MylSAM引擎

MylSAM拥有较高的插入、查询速度、但不支持事务

MEMORY存储引擎

MEMORY存储引擎将表中的数据存储到内存中,为查询和引用其他数据提供快速访问。主要用于数据量不大的临时数据。

SQL

SQL是结构化查询语言(Structured Query Language)英文缩写,是一种用于管理关系型数据库,并与数据库中的数据进行通讯的计算机语言。

SQL与RDBMS协同工作,来定义数据库结构、存储数据、操纵数据、获取数据、控制数据的访问以及确保数据的完整性。

SQL语言的分类

数据定义语言---DDL ----创建、修改、删除数据库的内部数据结构

数据查询语言---DQL ---- 用于数据库中数据查询

数据操作语言 ---DML ---- 用于数据库中数据的修改,包括添加、删除、修改等

数据控制语言---DCL ---- 用于控制数据库的访问权限

SQL语句

创建数据库:CREATE DATABASE mydb;

eg:CREATE DATABASE 数据库名;

建好数据库以后,需要设置编码集为utf-8,否则,插入的记录不支持中文。

删除数据库:DROP DATABASE 数据库名;

eg:DROP DATABASE mydb;

数据库数据类型

数据库数据类型决定了,表中列的存储数据类型。分为5种:

整型-------int

浮点型------float、double、decimal(m,d)

字符串型-----char(定长字符串,如果内容不满以空格填充)、varchar(可变长度字符串,以内容长度作为数据长度)

日期型-------date(年月日)、time(时分秒)、dateTime(年月日时分秒)

二进制型-----BLOB二进制型的长文本数据

创建表:create table 表名;

eg:create table t_student;

删除表:drop table 表名;

drop table t_student;

删除某一条数据:delete from 表名 where 删除条件;

delete from t_student where id=1;

查询所有数据:select * from t_student;

查询某一条数据:select s_name ,s_phone from t_student;

增加多条数据,只对mysql有效:insert into t_student(s_name,s_phone) values ('张三','12345'), ('张四','12345');

修改数据:update t_student set s_name='9527',s_phone='123456789' where id=1;

关系型数据库基础

管理表

添加列:

ALTER TABLE 表名 ADD 字段名 字段类型;

修改列:

ALTER TABLE 表名 CHANGE 原字段名 新字段名 字段类型;

删除列:

ALTER TABLE 表名 DROP COLUMN 字段名;

删除表中所有记录:

delete from s_student;

删除表中所有记录:

truncate table t_student;

区别:

1、TRUNCATE TABLE 会清空表中所有的记录,delete from而可以按条件删除记录.

2、delete 会记录日志,意味着删除后的数据还可以恢复,但是效率低。TRUNCATE不会记录日志,删除后的数据不会恢复,但是效率高。

查询

SELECT s_name,s_sex FROM t_student;

SELECT * FROM t_student;

显示所有学生,并显示该学生的成绩是否合格(给数据添加别名)

SELECT s.*,IF (s_grade>=80,'优秀','合格') grade FROM t_student s;

条件查询

  • 排除重复记录 DISTINCT:去除重复记录

SELECT DISTINCT 字段 FROM 表名;

eg:SELECT DISTINCT s_sex FROM t_student;

  • 返回限定行(limit(m,n) ),第一个参数为起始记录数(m),第二个参数为显示记录数(n),只管返回的条数。

SELECT * FROM 表名 LIMIT m,n;

eg:SELECT * FROM t_student LIMIT 3,3;

SELECT * FROM t_student LIMIT 4; 等价于:SELECT * FROM t_student LIMIT 0,4;

注意:等于(=)在where后面,表示比较,放在set后面,表示赋值

  • 单条件查询

eg:查询所有的男生

SELECT * FROM t_student WHERE s_sex='男';

eg:查询所有的成绩不合格的学生 SELECT * FROM t_student WHERE s_grade<60;

  • 多条件查询

当查询条件有多个时,连接多个条件的运算符有:

and(并且,两个条件都真结果为真,有一个为假,结果都为假)

or(或者,两个条件有一个为真,结果都为真,只有两个条件都为假,结果才是假)

AND

eg:查询90后的学生 SELECT * FROM t_student WHERE s_birthday >='1990-01-01' AND s_birthday <='1999-12-31' AND s_sex ='男';

eg:查询成绩不合格的男生 SELECT * FROM t_student WHERE s_grade <60 AND s_sex='男';

OR 查询王五和张三的信息 SELECT * FROM t_student WHERE s_name='王五' OR s_name='张三';

  • 定义集合关系

定义集合范围: in 或 not in

in操作符表示值在这个值集合里面

eg:SELECT * FROM t_student WHERE s_name IN('9527','李四');

eg:将9527和9528的设置为缺考人员

UPDATE t_student SET s_grade=NULL WHERE s_name IN('9527','9528');

not in操作符表示值不在这个值集合里面,与in 取值相反

eg:SELECT * FROM t_student WHERE s_name NOT IN('9527','李四');

eg:将9527和9528的设置为缺考人员

UPDATE t_student SET s_grade=NULL WHERE s_name IN('9527','9528');

查询null 值不能用=、!=,只能用is null 或者is not null

查询缺考人员 SELECT * FROM t_student WHERE s_grade IS NULL;

查询参考人员 SELECT * FROM t_student WHERE s_grade IS NOT NULL;

  • 模糊查询:用于比较相似的值,利用通配符来实现模糊查询

'_':通配符,匹配任何单个字符

'%':通配符,匹配零个或多个任意字符

eg:查询姓张的学生----"%"

SELECT * FROM t_student WHERE s_name LIKE '张%';

eg:查询姓张,姓名是两个字的学生----" " SELECT * FROM t_student WHERE s_name LIKE '张';

排序

将表中的记录按某个列进行顺序排序,可以指定升序(ASC)或者降序(DESC),如果不做指定默认为升序(ASC)

关键字:ORDER BY

  • 单列排序

eg:查询所有的学生,并且按成绩降序排序 SELECT * FROM t_student ORDER BY s_grade DESC;

eg:查询所有的学生,并且按成绩升序排序(默认升序排列)

SELECT * FROM t_student ORDER BY s_grade ASC;

  • 多列排序:先按某个列进行排序,如果两条记录中该列的值相同,再按第二个列进行排序

eg:查询所有的学生,并且按成绩降序排序,如果两个学生成绩相同,按工资降序排列 SELECT * FROM t_student ORDER BY s_grade DESC,s_money DESC;

条件判断语句

在mysql中,允许根据查询结果值得不同,返回不同得内容

双分支语句

相当于三目运算符,条件满足,返回一个结果;条件不满足,返回另一个结果

eg:

显示所有学生,并显示该学生的成绩是否合格(给数据添加别名)

SELECT s.*,IF (s_grade>=80,'优秀','合格') grade FROM t_student s;

多分支语句

相当于 if......else if......

eg:

-- 查询所有得学生,并且显示该学生得等级(优良中差) SELECT s.* ,(CASE WHEN s_grade IS NULL THEN '缺考' WHEN s_grade >=90 THEN '优' WHEN s_grade >=80 AND s_grade <90 THEN '良' WHEN s_grade >=60 AND s_grade <80 THEN '中' ELSE '差' END

) grade FROM t_student s;

eg: 药品类商品上涨5元,食品类上涨2元,酒类商品上涨10元

UPDATE t_product SET price =price + ( CASE WHEN productType='食品类' THEN 2 WHEN productType='药品类' THEN 5 ELSE 10 END );

聚合函数

count---统计行的数量

  • count(*)---统计所有符合条件的记录

eg:统计商品表里面有几种商品 SELECT COUNT(*) FROM t_product;

eg:统计商品表里面有几种食品类商品

SELECT COUNT(*) FROM t_product WHERE productType='食品类';

  • count(列名)---只统计非空列

eg: 统计参考学生的数量 SELECT COUNT(s_grade) FROM t_student;

  • count( DISTINCT 列名)---只统计非空不重复的列

eg:统计有几类商品 SELECT COUNT(DISTINCT productType) FROM t_product;

sum---统计某个列的总和

  • sum(列名)

eg:统计所有商品的总价 SELECT SUM(price) FROM t_product;

avg---统计某个列的平均值,只统计非空列

eg:统计参考学生的平均分 SELECT AVG(s_grade) FROM t_student;

eg:统计所有学生的平均分,统计所有列

SELECT SUM(s_grade)/COUNT(*) FROM t_student;

max---统计某个列的最大值

min---统计某个列的最小值(不统计空值)

eg:统计最高分和最低分 SELECT MIN(s_grade),MAX(s_grade) FROM t_student;

分组查询

分组:group by

分组(group by)就是将指定规则中相同的数据进行“小区域”(组)的划分,然后针对若干个“小区域”进行数据处理。

分组执行在where以后,是对where条件筛选的结果进行分组。

分组后,查询列只能出现分组列和聚合函数

eg:统计每一类商品的数量 SELECT productType,COUNT(*) '数量' FROM t_product GROUP BY productType;

group by 写在where后面

eg:统计价格在50元以上每类商品的数量 SELECT productType '类别',COUNT(*) '数量' FROM t_product WHERE price>50 GROUP BY productType;

多列分组

多列分组:在group by 后面可以跟多个列,多个列的值完全相同算一个组。

eg:统计每个厂家生产不同类别商品数量,厂家和类别都相同算一个组 SELECT productType '类别' ,factory '厂家',COUNT(*) '数量' FROM t_product GROUP BY productType,factory;

having是对分组以后的结果进行筛选,执行在分组之后

eg:查看商品类别数量在3个以上的类别 SELECT productType '类别' ,COUNT( ) '数量' FROM t_product GROUP BY productType HAVING COUNT( ) >3;

where和having的区别

where执行在分组之前,不能跟聚合函数。having 执行在分组之后,是对分组结果进行筛选,一般使用聚合函数进行筛选。

基本查询SQL语句的执行顺序

要学好查询SQL就必须掌握SQL的执行顺序,后执行的字句,可以使用前执行子句中的计算结果、定义别名等。

执行顺序:

1、执行 from 查询表

2、执行 where 进行条件筛选

3、执行 group by 分组

4、执行 select 查询列

5、执行 having 对分组的结果进行筛选

6、执行 order by 排序

7、执行 limit 返回限定行

子查询

在一个查询语句中再嵌套一个查询语句,称为子查询。

eg:查询比豆干价格更高的商品 SELECT * FROM t_product WHERE price>(SELECT price FROM t_product WHERE productName='豆干');

select中嵌入子查询

eg:查询所有员工的姓名以及该员工所处的部门 SELECT e_name '员工姓名', (SELECT d_name FROM t_dept WHERE pk_deptId=fk_deptId) '部门名称' FROM t_employee;

from中嵌入子查询

子查询嵌在from之后,相当于临时表。也就是将子查询查询的结果,当作表来用。注意:子查询的结果必须加别名

eg:查询张勇和钱二所处理的事务 SELECT * FROM (SELECT e_name,(SELECT d_info FROM t_dept WHERE pk_deptId=fk_deptId) info FROM t_employee) eminfo WHERE e_name='张勇';

where中嵌入子查询

  • 在where中嵌入子查询,如果子查询的结果返回单行单列(查询结果只有一个值),外查询才可以使用 =、!=、>、>=、<、<=

eg:查询和钱二同一个部门的员工 SELECT * FROM t_employee WHERE fk_deptId=(SELECT fk_deptId FROM t_employee WHERE e_name='钱二');

  • 如果子查询返回的结果是多行单列,外查询只能用in 或not in

eg:查询和张勇和周军同一个部门的员工 SELECT * FROM t_employee WHERE fk_deptId IN (SELECT fk_deptId FROM t_employee WHERE e_name IN('张勇','周军'));

  • all运算符:

    和子查询 结果逐一比较,必须全部满足时表达式的值才为真

eg:查询所有比食品类商品价格更高的商品 SELECT * FROM t_product WHERE price > ALL (SELECT price FROM t_product WHERE productType='食品类');

SELECT * FROM t_product WHERE price>(SELECT MAX(price) FROM t_product WHERE productType='食品类');

  • any运算符:

    和子查询的结果逐一作比较,其中一条记录满足条件则表达式的值就为真

eg:查询比任意食品类价格高的商品 SELECT * FROM t_product WHERE price > ANY (SELECT price FROM t_product WHERE productType='食品类') AND productType!='食品类';

SELECT * FROM t_product WHERE price>(SELECT MIN(price) FROM t_product WHERE productType='食品类') AND productType!='食品类';

  • exits运算符:

    判断子查询是否存在数据,如果存在则表达式为真,反之为假。not exits 相反。

eg:

其他嵌入子查询的方式

子查询的分类

子查询分为:相关子查询非相关子查询

相关子查询

在外查询中,每查询一条记录,需要重新做一次字查询,这种称为相关子查询。相关子查询的执行,依赖于外部查询的数据,外部查询返回一行,子查询就执行一次。所以,相关子查询效率很低。

非相关子查询

在主查询中,子查询只需要执行一次,子查询的结果不再变化。子查询结果供主查询使用,这种查询方式称为非相关子查询。

区分相关子查询,还是非相关子查询。主要看子查询是否能单独运行,子查询是否依赖外查询的查询结果。如果子查询需要依赖外查询查询结果,不能单独运行,就是相关子查询。如果子查询不需要依赖外查询查询结果,可以单独运行,就是非相关子查询。

数据的完整性

数据完整性=数据准确性+数据可靠性

为了防止垃圾数据的产生,从而影响数据库的执行效率!

数据完整性分4类:

实体完整性、域完整性、引用完整性、自定义完整性

实体完整性

保证每行所代表的实体能相互区别,不能存在两条一模一样的记录。

  • 实体完整性的实现方式:

主键约束

主键(Primary Key)是表中的一到多个列,主键列不能为空,也不能重复。一个表只能有一个主键

适合做主键的列,需要满足四个条件:

1、值必须唯一

2、值不能为空

3、不能带业务含义

4、值不能变化

身份证不适合做主键。身份证中国人才有,外国人没有(值可能为空)。身份证具有业务含义。身份证可能发生变动(一代身份证、二代身份证)

唯一约束

唯一约束是指给定列的所有值必须唯一,该列在表中每一行的值必须唯一。它和主键约束的区别在于该列可以为空,并且可以在一张表中给多个列设置唯一约束。

建表在字段后面加unique

eg:create table 表名(

......

phone vachar(20) unique

);

域完整性

域完整性:保证指定列的数据的有效性(mysql对域完整性支持不好)

  • 实现方式:

非空约束(not null)

指定列的值,不能插入null值。

默认值(default)

添加记录时,如果该列的值不做插入,那么以默认值插入。

检查约束(check)

检查插入列的有效性(mysql不支持)

CREATE TABLE t_em( pk_emId INT PRIMARY KEY AUTO_INCREMENT, e_name VARCHAR(20) NOT NULL,-- 非空 e_static ENUM('在职','离职') DEFAULT '在职',-- 默认值 e_money INT CHECK(e_money>1000 AND e_money<50000)-- check检查

);

引用完整性

从表外键中出现的数据,必须在主表主键列中出现

  • 实现方式:

外键约束

外键是描述表与表之间联系的一个列。是表中的列

外键约束是指在外键列加上一个约束,强制外键列引用的数据是正确的。如果违反该约束,则不允许该条数据的修改或插入。

注意:没有外键约束,不代表没有外键

添加外键约束

ALTER TABLE 从表表名 ADD CONSTRAINT 约束名称 FOREIGN KEY (从表外键字段名) REFERENCES t_man(主表主键字段名);

ALTER TABLE t_car ADD CONSTRAINT fk_1 FOREIGN KEY (fk_manId) REFERENCES t_man(pk_manId);

删除主表记录

删除主表记录时,如果该主表记录有从表记录引用,由于有外键约束存在,则无法删除主表记录。

  • 删除主表记录有三种方式:

级联删除:

先将主表记录中关联的从表记录全部删除,然后再删除主表记录

DELETE FROM 从表表名 WHERE 从表外键字段=值; DELETE FROM 主表表名 WHERE 主表主键=值;

DELETE FROM t_car WHERE fx_manId=1; DELETE FROM t_man WHERE pk_manId=1;

外键置空:

先将主表记录中关联的从表记录外键设置为null,然后再删除主表记录

UPDATE 从表表名 SET 从表外键 =NULL WHERE 从表外键=值; DELETE FROM 主表表名WHERE 主表主键=值;

UPDATE t_car SET fk_manId =NULL WHERE fk_manId=2; DELETE FROM t_man WHERE pk_manId=2;

改变状态:

将主表记录中添标识列(有效/无效)。删除主表记录时,将状态修改为无效

自定义完整性

联表查询

如果数据来自多个表,那么可以采用联接查询的方式来实现。表联接就是指将多个表联合在一起实现查询效果。

  • 笛卡尔乘积

    指将两张表的所有数据连接,最后联接的结果数位两张表数量的乘积

表联接分类:内联接,外联接,自联接

内联接:只能查询两个表之间有关联记录的数据

如果汽车没有主人,则不在查询结果中,内联接只能查询有主人的汽车

内联接

联表查询

方法一:

SELECT 需要查询的内容 FROM 主表表名 别名 JOIN 从表表名 别名 ON 主表主键=从表外键;

查询所有的汽车以及该汽车的主人姓名 SELECT c.*,m.m_name FROM t_man m JOIN t_car c ON m.pk_manId=c.fk_manId;

方法二:

SELECT 需要查询的内容 FROM 主表表名 别名 , 从表表名 别名 WHERE 主表主键=从表外键;

查询所有的汽车以及该汽车的主人姓名

SELECT c.*,m.m_name FROM t_man m,t_car c WHERE m.pk_manId=c.fk_manId;

外连接

可以查询除一个表中,所有符合条件的记录,无论该记录是否有关联数据。

SELECT 需要查询的内容 FROM 主表表名 别名 right(left) JOIN 从表表名 别名 ON 主表主键=从表外键;

显示所有公民,以及拥有的汽车数量

SELECT m.m_name,COUNT(m.pk_manId) num FROM t_man m RIGHT JOIN t_car c ON m.pk_manId=c.fk_manId GROUP BY m.pk_manId;

视图

视图可以看做事sql语句的封装,可以看做是临时表,视图查询的结果会随着真实表数据的变化而变化。视图指提供查询功能,不提供数据修改的功能。

创建视图-----create view 视图名 as 查询语句

eg:CREATE VIEW v_partyNum AS SELECT p.partyName,COUNT(m.mspName) num FROM party p LEFT JOIN msp m ON p.partyCode=m.party GROUP BY p.partyCode;

查找视图-----SELECT 查询内容 FROM 视图名; eg:SELECT * FROM v_partyNum;

删除视图-----drop view 视图名

数据规范式

数据库三范式

第一范式

行不重复(每条记录不能完全一样),列不在分(一条记录的列只能有一个值)

第二范式

非主依主(非主键列必须依赖于主键列)。二范式要求一个表只描述一个实体。

第三范式

非主独立(非主键列之间不能有依赖关系)。