一文学会MySQL数据库——小白零基础保姆级教程,从安装-配置环境开始——不能再细了!(持续更新,求赞求收藏!)

                                                                                ——目前运行速度最快的 SQL 语言数据库之一 

一、数据库介绍 

1.数据库概述

数据库就是存储数据的仓库,其本质是一个文件系统,按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作

随着互联网的高速发展,大量的数据在不断的产生,伴随而来的是如何高效安全的存储数据和处理数据,而这一问题成为了信息时代的一个非常大的问题,而使用数据库可以高效的有条理的储存数据

        优点:

可以结构化存储大量的数据;
可以有效的保持数据的一致性、完整性;
读写效率极高。

2.数据库分类

数据库又分为关系型数据库非关系型数据库。

关系型数据库 :指采用了关系模型来组织数据的数据库。
关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。

 初学阶段,我们可以先简单的将关系型数据库理解为一个Excel表格:

非关系型数据库:又被称为NoSQLNot Only SQL )意为不仅仅是SQLNoSQL 最普遍的定义是“非关联型的”,强调 Key-Value 的方式存储数据。

Key-Value结构存储: Key-value数据库是一种以键值对存储数据的一种数据库,类似Java中的map可以将整个数据库理解为一个大的map每个键都会对应一个唯一的值。

3.常见的数据库 

关系型数据库

非关系型数据库

4.总结

1.数据库就是存储数据的仓库,用户可以对数据库中的数据进行增加,修改,删除及查询操作。
2.数据库分为关系型数据库和非关系型数据库。
3.常用的关系型数据库有:MySQL,Oracle,DB2,SQLserver,sqlite
4.常用的非关系型数据库有:Redis,Hbase,MongoDB

二、MySQL数据库

  1.MySQL数据库介绍

MySQL 是一个 关系型数据库管理系统 ,在 WEB 应用方面, MySQL 是最好的 RDBMS (Relational Database Management System 关系数据库管理系统 ) 应用软件,它是由瑞典 MySQL AB 公司开发,目前属于 Oracle 旗下产品, MySQL 是最流行的关系型数据库管理系统中的一个
MySQL 的特点 :
1. MySQL 开源 的,不需要支付额外的费用。
2. MySQL 支持大型的数据库。可以 处理拥有上千万条记录 的大型数据库。
3. MySQL 使用 标准的 SQL 数据语言 形式。
4. MySQL 可以 安装在不同的操作系统 ,并且 提供多种编程语言的操作接口 。这些编程语言包括 C C++ Python Java Ruby 等等。

 2.MySQL数据库的版本和安装

版本介绍

MySQL Community Server 社区版本,开源免费,但不提供官方技术支持。
MySQL Enterprise Edition 企业版本,需付费,可以试用 30 天。
MySQL Cluster 集群版,开源免费。可将几个 MySQL Server 封装成一个 Server
MySQL Cluster CGE 高级集群版,需付费。
MySQL Workbench GUITOOL 一款专为 MySQL 设计的 ER 实体关系数据模型 / 数据库建模工具。它是著名的数据库设计工具 DBDesigner4 的继任者。 MySQL Workbench 又分为两个版本,分别是社区版( MySQL Workbench OSS )、 商用版( MySQL WorkbenchSE )。

 下载

        MySQL是开源免费的,可以直接去官网下载最新版MySQL下载地址如下:

建议选择安装版进行安装,点击 Go to Download Page 进行安装。
点击  Download  后会跳转到如下页面,点击左下角的  No thanks, just start my download.  开始下载。

 ​​​​​​​

安装

下载完成后打开安装包,稍等片刻后,选择开发者默认的安装方式,点击下一步即可。
此后按照流程安装即可,遇到 Next 下一步),和 Execute 执行)直接点击即可,点击 Execute 后需要等待几分钟。
直至出现 Account and Roles 输入数据库密码,此处输入密码务必记住,用于之后登陆数据库。
继续点击 Next ,出现 finish 后点击,完成安装。

3.环境变量的添加

添加环境变量——在终端使用MySQL需要添加环境变量

添加环境变量的 目的:输入终端命令时,可以搜索对应的可执行文件。
首先找到 mysql 的安装目录,并且定位到 mysql 文件,将地址栏内容进行复制。

  默认的安装路径: C:\Program Files\MySQL\MySQL Server 8.0\bin

        找到此电脑右键点击选择属性,弹出如下界面,选择高级系统设置,不同版本系统位置可能不太一样,耐心寻找一下。

进入高级系统设置之后,点击环境变量按钮,即可进入环境变量配置界面。
找到系统变量中的 path 变量,点击编辑,进入编辑界面。
选择新建,将刚才的赋值的 mysql 文件的地址粘贴到文本框中,点击确定,完成环境变量配置。

检测环境变量是否配置成功

在底部搜索栏输入cmdEnter键唤出终端窗口。

输入mysql -VV要大写),输出如下内容则配置成功。

登录MySQL数据库

MySQL是一个需要账户名密码登录的数据库,登陆后使用,它提供了一个默认的root账号,使用安装时设置的密码即可登录,有3种登录方式。
第一种方式: mysql - uroot -p666666
         (root为用户名,666666为密码,此时系统警告在命令行界面上使用密码可能不安全)

第二种方式: mysql - uroot –p    回车 

        输入密码

                        

第三种方式:

mysql  --host=ip地址 --user=用户名 --password=密码

4.MySQL图形化开发工具-DataGrip

概述

DataGrip是JetBrains公司推出的管理数据库的产品,功能非常强大,可以兼容各种数据库,另外,JetBrains公司还有一款知名的IDE开发工具IDEA,用户体验非常不错。

下载地址:https://www.jetbrains.com/datagrip/download/#section=windows

安装

下载完成后打开安装程序,选择安装路径,一直点击 Next 即可安装。
直到 Finish 点击完成安装,并打开应用。
选择Evaluate for free 免费试用 30 天。

 创建工程

点击File->New->Project新建DataGrip工程

输入项目名称,点击确定。

选择新项目打开方式:This Windows在本窗口中打开),New Windows在新窗口中打开), Attach附加模式

连接数据库 

选择 Database 下的 ,点击 DataSource 菜单下的 MySQL
填写对应的参数,连接数据库:连接名, IP ,用户名,密码等,点击 OK 完成连接。
注意:如果第一次使用,需要下载mysql 驱动文件。 

点击连接名称之后的按钮可以选择所要使用的数据库

界面及书写方式调整

设置文字大小: File--->settings--->Editor---->Font

设置关键字大写:File-->settings-->Editor-->Code Style-->SQL-->MySql(需要设置的数据库)-->Case 

自动排版布局: File--->settings--->Editor---->Code Style--->SQL--->MySql( 需要设置的数据库 )---> Queries
自动 排版快捷键: ctrl + alt +L

5.总结

1. MySQL 的特点:免费,支持大型数据库,标准的 SQL 语言形式,跨平台。
2. 课程使用的版本时 MySQL8.0 版本。
3. MySQL 登录的两种方式:

        方法一:mysql -uroot -p123456

        方法一:mysql -uroot –p   回车 

        输入密码

        方法三:mysql --host=IP地址 --user=用户名 --password=密码

三、SQL语句

1.SQL语句介绍

 SQL语句

结构化查询语言(Structured Query Language)简称SQL,是关系型数据库管理系统都需要遵循的规范,是数据库认识的语句。不同的数据库生产厂商都支持SQL语句,但都有自己特有内容。

举例:

普通话:各数据库厂商都遵循的ISO标准。

方言:数据库特有的关键字。

2.SQL语句分类

1、数据定义语言:简称DDL(Data Definition Language)

用来定义数据库对象:数据库,表,列等。
关键字:create,alter,drop等

2、数据操作语言:简称DML(Data Manipulation Language)

用来对数据库中表的记录进行更新。
关键字:insert,delete,update等

3、数据查询语言:简称DQL(Data Query Language)

用来查询数据库中表的记录。
关键字:select,from,where等

4、数据控制语言:简称DCL(Data Control Language)

用来定义数据库的访问权限和安全级别,及创建用户。

3.SQL通用语法

1、SQL语句可以单行或多行书写,以分号结尾。

  select from students;

2、可使用空格和缩进来增强语句的可读性

 select

           *

from

        student;

3、MySQL数据库的SQL语句不区分大小写,关键字建议使用大写

例:SELECT * FROM user; 等于 select * from user;

4、可以使用 /**/,--,# 的方式完成注释

/**/:多行注释,在注释区域内可以随意换行

-- # :单行注释,写在语句开头,换行后注释截止。

单行注释快捷键:ctrl+/

4.SQL常用数据类型

MySQL 中定义数据字段的类型对数据库的优化是非常重要的。

MySQL 支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。

数值类型

日期和时间类型

字符串类型 

注意:

CHAR(n) VARCHAR(n) 中括号中 n 代表 字符的个数 ,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。 CHAR VARCHAR 类型类似,它们的最大长度和是否尾部空格被保留等方面也不同。
BINARY VARBINARY 类似于 CHAR VARCHAR 不同的是它们包含二进制字符串而不是非二进制字符串。也就是说,它们包含 字节字符串 而不是字符字符串。
BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 BLOB 类型: TINYBLOB BLOB MEDIUMBLOB LONGBLOB 。它们区别在于可容纳存储范围不同。
4 TEXT 类型: TINYTEXT TEXT MEDIUMTEXT LONGTEXT 。对应的这 4 BLOB 类型,可存储的最大长度不同,可根据实际情况选择。

5.总结

1. 结构化查询语言(SQL),是关系型数据库管理系统都需要遵循的规范。不同的数据库生产厂商都支持SQL语句,但都有特有内容。
2. SQL 语句分为: 数据定义语言( DDL ),数据操作语言( DML ),数据查询语言( DQL ),数据控制语言( DCL
3. SQL 通用语法:结构灵活,使用分号结尾;不区分大小写;可以使用 / ** / # -- 来进行注释。
4. 常用的数据类型:

字符:charvarchar

整数:int

浮点型:decimal

日期型:datedatetime

四、DDL之数据库操作:database

1.创建数据库

# 直接创建数据库,如果存在则报错

create database 数据库名;   

# 如果数据库不存在则创建
create database if not exists practice1; 

# 创建数据库时设置字符集
create database 数据库名 character set 字符集;

注意:一般情况下我们会使用utf8字符集进行创建,否则可能导致中文乱码情况。 

2.查看MySQL服务器中所有数据库 

# 查看数据库列表

show databases;

 

3.删除数据库 

# 删除指定数据库 practice1

格式:drop database 数据库名称

drop database practice1;

 

4.使用数据库 

# 使用数据库

格式:use 数据库名字;

use pratice;

# 查看正在使用的数据库:

select database();

5.总结

1. 创建数据库: CREATE DATABASE 数据库名;
2. 查看数据库: SHOW DATABASES;
3. 删除数据库: DROP DATABASE 数据库名;
4. 使用数据库: USE 数据库名;

 五、DDL之表操作:table

1.表的创建

# 使用create table进行数据表创建

格式:

create table if not exists 表名(

字段名1  类型(长度) [约束],

字段名2  类型(长度) [约束],

   ...

);

 

2.查看表

# 查看数据库中的所有表:

show tables;

 

# 查看表结构:

格式:desc 表名;

desc category;

3.删除表

# 删除数据库中的表,表必须存在:

格式:drop table 表名;

drop table category;

 

 若表不存在则会报错:

4.修改表结构

 添加字段

# 添加表结构中的字段:

格式:alter  table  表名  add  列名  类型(长度)  [约束];

注意:约束按需求选择添加,可以没有约束,类型必须填写,并只能填写一个类型 

 alter table category add  `desc`  varchar(20);

进行表结构查看:

注意:desc 为关键字,此时必须用中文引号 。但理论上我们再添加字段时不需要给字段名添加``

这里这样写是因为desc是关键字(具有特殊功能或含义的字符),如果非关键字,即可使用如下写法。

 

 修改字段

# 修改表结构中的列名

格式:alter table 表名 change 旧列名 新列名 类型(长度) 约束;

# 为分类表的分类描述字段更换为description  varchar(30)

alter table category change `desc` description varchar(30);

 

删除字段

 # 删除表结构中的列名

格式:alter table 表名 drop 列名; 

# 删除分类表中description这列

alter table category drop description;

 修改表名

# 修改表名

格式:rename table 表名 to 新表名;

# 为分类表category改名成 category2

rename table catgory to catgory2;

5.总结

1. 创建表: CREATE TABLE 表名 ( 字段名 类型 约束 …)
2. 查询表: SHOW TABLES;     DESC 表名;
3. 删除表: drop table 表名;
4. 修改表:

alter  table  表名  add  列名  类型(长度)  [约束];

alter table 表名 change 旧列名 新列名 类型(长度) 约束;

alter table 表名 drop 列名; 

rename table 表名 to 新表名;

六、DML数据操作语言 

1.插入表记录

 # 向表中插入数据

格式:insert into (字段1,字段2,字段3...) values(值1,值2,值3...);

insert into  category2(cid, cname) values('c001','电器');

# 向表中插入所有字段,字段的顺序为创建表时的顺序

格式:insert into values(值1,值2,值3..);

insert into category2 values('c002','服饰',2);

# 一次添加多条数据信息

格式:insert into (字段1,字段2,字段3...) values(值1,值2,值3...),(值1,值2,值3...)…;

insert into category2 (cid, cname) values('03','家电'),('04','调料'),('05',null);

格式:insert into values(值1,值2,值3..),(值1,值2,值3..),…;

insert into category2 values('06','文体',4),('07','粮油',5);

2.更新表记录

# 更新所有记录的指定字段

格式:update 表名 set 字段名=值,字段名=,...;

update category2 set cname  = '饮品'; # 将所有行的cname改为'饮品'

# 更新符号条件记录的指定字段

格式:update 表名 set 字段名=值,字段名=,... where 条件;
update category2 set cname  = '牛奶' where cid = 'c001'; # 将cid为c001的cname修改为牛奶

注意:

1、列名的类型与修改的值要一致

2、修改值得时候不能超过最大长度

3、除了数值类型外,其它的字段类型的值必须使用引号引起

3.删除记录

# 按条件删除记录

格式:delete from 表名 [where 条件];

delete from category where cid = '005‘; # 删除cid为005的纪录

# 清空表记录

格式:truncate table 表名

truncate category;  # 清空表数据

注意:

清空表记录和删除表记录的区别:

使用delete删除表记录时,主键自增序列不清零。

使用truncate删除表记录时,主键自增序列清零。

 4.总结

1. 插入记录: 格式: insert into (字段1,字段2,字段3...) values(值1,值2,值3...),(值1,值2,值3...)…;
2. 更新记录: 格式: update 表名 set 字段名 = 值,字段名 = ,...;
3. 删除记录:

                                delete from 表名 [where 条件];

                                truncate category;

七、SQL约束

1.主键约束

1、PRIMARY KEY 约束唯一标识数据库表中的每条记录。

2、主键必须包含唯一的值。

3、主键列不能包含 NULL 值。

4、每个表都应该有一个主键,并且每个表只能有一个主键。

遵循原则:

1)主键应当是对用户没有意义的

2)永远也不要更新主键。

3)主键不应包含动态变化的数据,如时间戳、创建时间列、修改时间列等。

4) 主键应当由计算机自动生成。

添加主键约束:
创建表时,在字段描述处,声明指定字段为主键:

删除主键约束:

如需撤销 PRIMARY KEY 约束,请使用下面的 SQL:


alter table persons1 drop primary key ;

 

 2.自动增长 

 我们通常希望在每次插入新记录时,数据库自动生成字段的值。

我们可以在表中使用 auto_increment(自动增长列)关键字,自动增长列类型必须是整型自动增长列必须为键(一般是主键)

下列 SQL 语句把 "persons2" 表中的 "id" 列定义为 auto_increment 主键

 向persons添加数据时,可以不为Id字段设置值,也可以设置成null,数据库将自动维护主键值:

insert into persons2(first_name,last_name) values('Bill','Gates');
insert into persons2(id,first_name,last_name) values(
null,'Bill','Gates’);

3.非空约束

NOT NULL 约束强制列不接受 NULL 值。

NOT NULL 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。

下面的 SQL 语句强制 "id" 列和 "last_name" 列不接受 NULL 值:

 

4.唯一约束

 UNIQUE 约束唯一标识数据库表中的每条记录。

UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。

PRIMARY KEY 拥有自动定义的 UNIQUE 约束。

请注意:

每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。

 

5.默认值约束

默认 DEFAULT: 当不填写字段对应的值会使用默认值,如果填写时以填写为准。 

 

6.总结

       1.主键约束:唯一标示,不能重复,不能为空。

1)主键应当是对用户没有意义的

2)永远也不要更新主键。

3)主键不应包含动态变化的数据,如时间戳、创建时间列、修改时间列等。

4) 主键应当由计算机自动生成。

2. 自动增长:

我们可以在表中使用 auto_increment(自动增长列)关键字,自动增长列类型必须是整型自动增长列必须为键(一般是主键)

3. 非空约束:

NOT NULL 约束强制列不接受 NULL 值。

4. 唯一约束:

UNIQUE 约束唯一标识数据库表中的每条记录。

UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。

PRIMARY KEY 拥有自动定义的 UNIQUE 约束。

5. 默认值约束

如果插入数据时不指定当前字段的值,则查询该字段是否有默认值,如果有则插入默认值。

八、数据查询语言

 1.简单查询

select查询 :

# 根据某些条件从某个表中查询指定字段的内容

格式:select [distinct]*| 列名,列名 from 表 where 条件

简单查询:(先创建一个表product)

# 1.查询所有的商品. 

select *  from product;

# 2.查询商品名和商品价格.

select pname,price from product;

# 3.查询结果是表达式(运算查询):将所有商品的价格+10元进行显示.

select pname,price+10 from product;

2.条件查询

         

比较查询

# 查询商品名称为“花花公子”的商品所有信息

SELECT * FROM product WHERE pname = '花花公子';

# 查询价格为800商品

SELECT * FROM product WHERE price = 800;

# 查询价格不是800的所有商品

SELECT * FROM product WHERE price != 800;

SELECT * FROM product WHERE price <> 800;

# 查询商品价格大于60元的所有商品信息

SELECT * FROM product WHERE price > 60;

# 查询商品价格等于800元的所有商品信息

SELECT * FROM product WHERE price <= 800;

范围查询

# 查询商品价格在200到1000之间所有商品

SELECT * FROM product WHERE price BETWEEN 200 AND 1000;

# 查询商品价格是200或800的所有商品

SELECT * FROM product WHERE price IN (200,800);

逻辑查询

# 查询商品价格在200到1000之间所有商品

SELECT * FROM product WHERE price >= 200 AND price <=1000;

# 查询商品价格是200或800的所有商品

SELECT * FROM product WHERE price = 200 OR price = 800;

# 查询价格不是800的所有商品

SELECT * FROM product WHERE NOT(price = 800);

模糊查询

# 查询以'香'开头的所有商品

SELECT * FROM product WHERE pname LIKE '%‘;

# 查询第二个字为'想'的所有商品

SELECT * FROM product WHERE pname LIKE '_%‘;

非空查询 

# 查询没有分类的商品

SELECT * FROM product WHERE category_id IS NULL;

# 查询有分类的商品

SELECT * FROM product WHERE category_id IS NOT NULL;

3.排序查询

 # 通过order by语句,可以将查询出的结果进行排序。暂时放置在select语句的最后。

格式:SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;

ASC 升序 ( 默认 )
DESC 降序

# 1.使用价格排序(降序)

SELECT * FROM product ORDER BY price DESC;

# 2.在价格排序(降序)的基础上,以分类排序(降序)

SELECT * FROM product ORDER BY price DESC,category_id DESC;

4.聚合查询

之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个单一的值;另外聚合函数会忽略空值。

# 1查询商品的总条数

SELECT COUNT(*) FROM product;

# 2查询价格大于200商品的总条数

SELECT COUNT(*) FROM product WHERE price > 200;

# 3查询分类为'c001'的所有商品的总和

SELECT SUM(price) FROM product WHERE category_id = 'c001‘;

# 4查询分类为'c002'所有商品的平均价格

SELECT AVG(price) FROM product WHERE categ ory_id = 'c002‘;

# 5查询商品的最大价格和最小价格

SELECT MAX(price),MIN(price) FROM product;

5.分组查询

 分组查询是指使用group by字句对查询信息进行分组。

格式:SELECT 字段1,字段2… FROM 表名 GROUP BY 分组字段 HAVING 分组条件;

分组操作中的having子语句,是用于在分组后对数据进行过滤的,作用类似于where条件

having与where的区别:

1).having是在分组后对数据进行过滤.,where是在分组前对数据进行过滤

2).having后面可以使用分组函数(统计函数),where后面不可以使用分组函数。

#1 统计各个分类商品的个数

SELECT category_id ,COUNT(*) FROM product GROUP BY category_id ;

#2 统计各个分类商品的个数,且只显示个数大于1的信息

SELECT category_id ,COUNT(*) FROM product GROUP BY category_id HAVING COUNT(*) > 1;

6.分页查询

分页查询在项目开发中常见,由于数据量很大,显示屏长度有限,因此对数据需要采取分页显示方式。例如数据共有30条,每页显示5条,第一页显示1-5条,第二页显示6-10条

 格式:

SELECT 字段1,字段2... FROM 表名 LIMIT M,N

M: 整数,表示从第几条索引开始,计算方式 (当前页-1)*每页显示条数

N: 整数,表示查询多少条数据

SELECT 字段1,字段2... FROM 表明 LIMIT 0,5

SELECT 字段1,字段2... FROM 表明 LIMIT 5,5

7.总结

1. 条件查询: select * | 字段名 form 表名 where 条件;
2. 排序查询: SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;
3. 聚合查询函数: count() sum() max() min() avg()
4. 分组查询: SELECT 字段1,字段2… FROM 表名 GROUP BY 分组字段 HAVING 分组条件;
5. 分页查询:

SELECT 字段1,字段2... FROM 表名 LIMIT M,N

M: 整数,表示从第几条索引开始,计算方式 (当前页-1)*每页显示条数

N: 整数,表示查询多少条数据

九、多表操作

1.概述

实际开发中,一个项目通常需要很多张表才能完成。
例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系,接下来我们将在单表的基础上,一起学习多表方面的知识。

 

2.表与表之间的关系

 一对多关系:

 常见实例:客户和订单,分类和商品,部门和员工

一对多建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键

3.外键约束

现在我们有两张表“分类表”和“商品表”,为了表明商品属于哪个分类,通常情况下,我们将在商品表上添加一列,用于存放分类cid的信息,此列称为:外键。

 

此时“分类表category”称为:主表,“cid”我们称为主键。“商品表products”称为:从表,category_id称为外键。我们通过主表的主键和从表的外键来描述主外键关系,呈现就是一对多关系。

外键特点:

从表外键的值是对主表主键的引用。

从表外键类型,必须与主表主键类型一致。

4.一对多操作

 category分类表,为一方,也就是主表,必须提供主键cid

products商品表,为多方,也就是从表,必须提供外键category_id

# 创建分类表

CREATE TABLE category
(
   
cid   VARCHAR(32) PRIMARY KEY,
   
cname VARCHAR(100) #分类名称
);

# 商品表

CREATE TABLE products (
 
pid varchar(32) PRIMARY KEY  ,
  name VARCHAR(40) ,
  price DOUBLE ,
 
category_id varchar(32),
  CONSTRAINT FOREIGN KEY(
category_id) REFERENCES category(cid) # 添加约束
);

#1 向分类表中添加数据

INSERT INTO category (cid ,cname) VALUES('c001','服装');

#2 向商品表添加普通数据,没有外键数据,默认为null

INSERT INTO products (pid,pname) VALUES('p001','商品名称');

#3 向商品表添加普通数据,含有外键信息(category表中存在这条数据)

INSERT INTO products (pid ,pname ,category_id) VALUES('p002','商品名称2','c001');

#4 向商品表添加普通数据,含有外键信息(category表中不存在这条数据) -- 失败,异常

INSERT INTO products (pid ,pname ,category_id) VALUES('p003','商品名称2','c999');

#5 删除指定分类(分类被商品使用) -- 执行异常

DELETE FROM category WHERE cid = 'c001';

5.总结

1. 实际开发中,一个项目通常需要很多张表才能完成。
2. 一对多建表原则:在从表 ( 多方 ) 创建一个字段,字段作为外键指向主表 ( 一方 ) 的主键

从表外键的值是对主表主键的引用。

从表外键类型,必须与主表主键类型一致。

3.从表中引用了主表中的数据,主表中数据不可被删除。

4. 主表中没有数据,从表外键也无法被插入。

十、多表查询

1.多表查询

1.交叉连接查询(基本不会使用-得到的是两个表的乘积) [了解]

语法:select * from A,B;这个结果有问题是错误的----笛卡尔积

2.交集运算:内连接查询(使用的关键字 inner join  -- inner可以省略)

显示内连接:select * from A inner join B on 条件;

3.差集运算:外连接查询(使用的关键字 outer join -- outer可以省略)

左外连接:left outer join

select * from A left outer join B on 条件;

右外连接:right outer join

select * from A right outer join B on 条件;

示例1准备工作:

# 创建heroCREATE TABLE hero

(

hid   INT PRIMARY KEY,

hname VARCHAR(255),

kongfu_id INT

);

# 创建kongfu

CREATE TABLE kongfu

(

kid     INT PRIMARY KEY,

kname   VARCHAR(255)

);

# 插入hero数据

INSERT INTO hero VALUES(1, '鸠摩智', 9),(3, '乔峰', 1),(4, '虚竹', 4),(5, '段誉', 12);

# 插入kongfu数据

  INSERT INTO kongfu VALUES(1, '降龙十八掌'),(2, '乾坤大挪移'),(3, '猴子偷桃'),(4, '天山折梅手');

内连接

 # 内连接(左表存在,右表也存在的数据被保留)

SELECT hname,kname FROM hero INNER JOIN kongfu ON hero.kongfu_id = kongfu.kid

 左连接(左表存在的数据被保留)

        SELECT hname,kname FROM hero LEFT OUTER JOIN kongfu ON hero.kongfu_id = kongfu.kid; 

 # 右连接(右表存在的数据被保留)

SELECT hname,kname FROM hero RIGHT OUTER JOIN kongfu ON hero.kongfu_id = kongfu.kid;

多表查询的结果集示意图:

示例2准备工作:

CREATE TABLE category (

  cid VARCHAR(32) PRIMARY KEY ,

  cname VARCHAR(50)

);

CREATE TABLE products(

  pid VARCHAR(32) PRIMARY KEY ,

  pname VARCHAR(50),

  price INT,

  flag VARCHAR(2),    #是否上架标记为:1表示上架、0表示下架

  category_id VARCHAR(32),

  CONSTRAINT products_fk FOREIGN KEY (category_id) REFERENCES category (cid)

);

#分类

INSERT INTO category(cid,cname) VALUES('c001','家电');

INSERT INTO category(cid,cname) VALUES('c002','服饰');

INSERT INTO category(cid,cname) VALUES('c003','化妆品');

#商品

INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p001','联想',5000,'1','c001');

INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p002','海尔',3000,'1','c001');

INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p003','雷神',5000,'1','c001');

INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p004','JACK JONES',800,'1','c002');

INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p005','真维斯',200,'1','c002');

INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p006','花花公子',440,'1','c002');

INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p007','劲霸',2000,'1','c002');

INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p008','香奈儿',800,'1','c003');

INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p009','相宜本草',200,'1','c003');

# 1.查询哪些分类的商品已经上架

# 内连接

SELECT DISTINCT c.cname FROM category c

 INNER JOIN products p ON c.cid = p.category_id

 WHERE p.flag = '1';

# 2.查询所有分类商品的个数

# 左连接

INSERT INTO category(cid,cname) VALUES('c004','奢侈品');

SELECT cname,COUNT(category_id) FROM category c

 LEFT OUTER JOIN products p

  ON c.cid = p.category_id

 GROUP BY cname;

 

2.子查询

子查询:一条select语句结果作为另一条select语法一部分(查询条件,查询结果,表等)。

select ....查询字段 ... from ... 表.. where ... 查询条件

举例: 查询“化妆品”分类上架商品详情

 # 子查询(作为查询条件)

SELECT * FROM products p

 WHERE p.category_id =

 (

  SELECT c.cid FROM category c

   WHERE c.cname='化妆品'

 );

# 作为另一张表

 SELECT * FROM products p ,

   (SELECT * FROM category WHERE cname='化妆品') c

  WHERE p.category_id = c.cid;

# 查询“化妆品”和“家电”两个分类上架商品详情

SELECT * FROM products p

 WHERE p.category_id in

 (

  SELECT c.cid FROM category c

   WHERE c.cname='化妆品' or c.name='家电'

 );

3.自查询

    自查询:左表和右表是同一个表,根据连接查询条件查询两个表中的数据。

    示例:

    创建tb_areas:

CREATE TABLE tb_areas
(
   
id    VARCHAR(30) NOT NULL PRIMARY KEY,
   
atitle VARCHAR(30),
   
pid   VARCHAR(30)
);

插入数据:

INSERT INTO test.tb_areas (id, atitle, pid) VALUES ('1', '广东省', 'null');

INSERT INTO test.tb_areas (id, atitle, pid) VALUES ('2', '河南省', 'null');

INSERT INTO test.tb_areas (id, atitle, pid) VALUES ('3', '深圳市', '1');

INSERT INTO test.tb_areas (id,atitle, pid) VALUES ('4', '广州市', '1');

INSERT INTO test.tb_areas (id,atitle, pid) VALUES ('5', '南山区', '3');

INSERT INTO test.tb_areas (id, atitle, pid) VALUES ('6', '宝安区', '3');

INSERT INTO test.tb_areas (id, atitle, pid) VALUES ('7', '越秀区', '4');

INSERT INTO test.tb_areas (id, atitle, pid) VALUES ('8', '天河区', '4');

插入地区数据后:

select  city.*  form  areas as city  inner  join areas  as  province  on city.pid  =  province.aid  where  province.atitle = '广东省'

3.总结

1.交集运算:内连接查询(使用的关键字 inner join  -- inner可以省略)

内连接:select * from A inner join B on 条件;

2.差集运算:外连接查询(使用的关键字 outer join -- outer可以省略)

左连接:left outer join

select * from A left outer join B on 条件;

右连接:right outer join

select * from A right outer join B on 条件;

十一、窗口函数

1.概述

MySql在8.0的版本增加了对开窗函数的支持,终于可以在MySql使用开窗函数了。

开窗函数的语法结构:

         # 关键字 :partiton by 和 order by

        <开窗函数> over ([partiton by <分组用列清单>]

                             order by <排序用列清单>)

MySql中支持的窗口函数有很多,这里重点给大家介绍三个:row_number(),rank(),dense_ra 

在本人的另一篇博客中,对窗口函数做了更加全面详细的讲解,想深入了解窗口函数的小伙伴,可以参考掌握MySQL窗口函数window functions这一篇就够了!(详解+示例+代码,简单粗暴)) 

窗口函数介绍 :

row_number(),rank(),dense_rank()这三个函数都是用于返回结果集的分组内每行的排名

三者区别:

row_number:不管排名是否有相同的,都按照顺序1,2,3…..n

rank:排名相同的名次一样,同一排名有几个,后面排名就会跳过几次

dense_rank:排名相同的名次一样,且后面名次不跳跃

2.案例

数据准备:

create table employee (empid int,ename varchar(20) ,deptid int ,salary decimal(10,2));

insert into employee values(1,'刘备',10,5500.00),(2,'赵云',10,4500.00),(2,'张飞',10,3500.00),(2,'关羽',10,4500.00),(3,'曹操',20,1900.00),(4,'许褚',20,4800.00),(5,'张辽',20,6500.00),(6,'徐晃',20,14500.00),(7,'孙权',30,44500.00),(8,'周瑜',30,6500.00),(9,'陆逊',30,7500.00);

对employee表中按照deptid进行分组,并对每一组的员工按照薪资进行排名:

SELECT

  empid,

  ename,

  deptid,

  salary,

  row_number() over (PARTITION BY deptid ORDER BY salary DESC) AS row_number1,

  rank() OVER (PARTITION BY deptid ORDER BY salary desc) AS rank2,

  dense_rank() OVER (PARTITION BY deptid ORDER BY salary desc) AS dense_rank3

FROM

 employee;

 TOPN

对employee表中按照deptid进行分组,并对每一组的员工按照薪资进行排名,取各组中的前两名员工信息

select *

From

(SELECT

  empid,

  ename,

  deptid,

  salary,

  rank() over (PARTITION BY deptid ORDER BY salary DESC) AS row_number1 

FROM

 employee

) t

Where t.row_number1 <3;

3.总结

开窗函数常用于求 TOPN 的场景
row_number() over()
rank() over()
dense_rank() over()

 十二、事务

1.概述:

        事务(transaction)指的是逻辑上的一组操作, 组成该操作的各个逻辑单元, 要么全部执行成功, 要么全部执行失败.
        大白话: 同生同死.
    名词解释:
        一组操作:   张三 -> 李四, 转1000元
        逻辑单元:
            逻辑单元1: 张三账户 - 1000元
            逻辑单元2: 李四账户 + 1000元
   

2.事务相关的SQL语句:

        start transaction;  或者 begin;       开启事务
        commit;                              提交事务, 即: 保存结果.
        rollback;                            事务回滚, 相当于把数据还原到事务执行之前的状态.
        select @@transaction_isolation;      查看事务的隔离级别.
        set session transaction isolation level read uncommitted;   # 临时设置事务的隔离级别
   

3.事务的特点:  ACID

        原子性: 指的是组成事务的各个逻辑单元已经是最小单位, 不可分割.
        一致性: 指的是事务执行前后, 数据结果应该保持一致.
        隔离性(Isolation): 指的是一个事务在执行期间, 不应该受到其它事务的干扰.
        持久性: 指的是事务执行后, 结果会被永久保存到数据表中.
    如果1个事务在执行期间, 受到了其它事务的干扰, 可能会发生一些列的问题:
        关于写:
            丢失更新.
        关于读:
            脏读, 不可重复读, 虚读.

    细节:
        1. MySQL默认开启了事务的自动提交功能, 每个SQL语句都是1个单独的事务, 执行之后, 会自动提交结果.
        2. 隔离级别主要有4个, 分别是: read uncommitted, read committed, repeatable read, serializable
            read uncommitted:
                会发生脏读, 不可重复读, 虚读.
            read committed:
                会发生不可重复读, 虚读.  解决了: 脏读
            repeatable read:
                会发生虚读.  解决了: 脏读, 不可重复读
            serializable:
                串行化读法, 加锁的思路, 可以解决所有.
        3. MySQL数据库的默认隔离级别是: repeatable read

    扩展: 
        脏读解释: 也叫, 读-未提交
            一个事务读取到了另一个事务还没有来得及提交的事务, 导致多次查询结果不一致.     即: 事务影响事务了.

  • 36
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值