1. 数据库的基本你概念
1.1 为什么要学习数据库?
- 之前我们如果想将一些数据实现永久化存储,可以怎么做呢?没错。使用IO流的技术将数据保存到本地文件中,这是非常的不方便的。
- 假设我有这样一个需求:将下面的user.txt文件中的王五年龄修改为35,该怎么实现呢?
我们要如何实现呢?
- 可以采用字符缓冲流,将每一行数据读取出来,封装为User对象。将多个User对象保存到集合中
- 然后遍历集合,将王五对象的年龄修改为35,再重新将集合中的对象信息写回到文件中
① 使用字符换缓冲流每次读取一行数据 ② 将读取到的数据封装为User对象 ③ 将多个User对象保存到集合中 ④ 遍历集合,判断对象名称是否是王五 ⑤ 是王五,将其年龄修改为35 ⑥ 使用字符缓冲流将年龄修改为35
这一套操作太麻烦了,而现在我们有一种更加方便的方式来完成这个需求了,这种方式就是数据库!
1.2 数据库的介绍
- 用于存储和管理数据的仓库
- 英文单词为:DataBase,简称DB
- 它的存储空间很大,可以存放百万条、千万条、上一条数据。
- 使用一种统一的方式操作数据库——SQL
我们要学习的是MySQL数据库。
- MySQL是一个最流行的关系型数据库管理系统之一。由瑞典MySQL AB公司开发,后被Oracle公司收购。
- 关系型数据库是将数据保存在不同的数据表中,而不是将所有数据放在一个大仓库内,而且表与表之间还可以有关联关系。这样就提高了访问速度以及提高了灵活性。
- MySQL所使用的SQL语句是用于访问数据库最常用的标准化语言。
-
1.3 数据库的好处
可以持久化存储数据
- 方便存储和管理数据
- 使用了统一的方式操作数据库 — SQL
1.4 数据库安装(暂时略,没啥写的)
2. DDL操作数据库和数据表
2.1 数据库、数据表、数据的关系
- 数据库
- 用于存储和管理数据的仓库(MySQL服务器中可以创建多个数据库)
- 一个库中可以包含多个数据表
- 数据表
- 数据库最重要的组成部分之一
- 它由纵向的列和横向的行组成(类似excel表格)
- 可以指定列名、数据类型、约束等
- 一个表中可以存储多条数据
- 数据
- 想要永久化存储的数据
- 客户端通过数据库管理系统来操作MySQL数据库
2.2 SQL介绍
- SQL(Structured Query Language):结构化查询语言。其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式可能会存在一些不一样的地方,我们称为“方言”。
- 通用语法规则
- SQL 语句可以单行或多行书写,以分号结尾。
- 可使用空格和缩进来增强语句的可读性。
- MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
- 数据库的注释:
- 单行注释:— 注释内容 #注释内容(mysql特有)
- 多行注释:/ 注释内容 /
- SQL分类
- DDL(Data Definition Language)数据定义语言。用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
- DML(Data Manipulation Language)数据操作语言。用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
- DQL(Data Query Language)数据查询语言。用来查询数据库中表的记录(数据)。关键字:select, where 等
- DCL(Data Control Language)数据控制语言(了解)。用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等
2.3 DDL查询和创建数据库
# 查询所有数据库
SHOW DATABASES;
# 查询数据库的创建语句
SHOW CREATE DATABASE 数据库名称;
# 创建数据库
CREATE DATABASE 数据库名称;
# 创建数据库(判断,如果不存在则创建)
CREATE DATABASE IF NOT EXISTS 数据库名称;
# 创建数据库(指定字符集)
CREATE DATABASE 数据库名称 CHARACTER SET 字符集名称;
练习:创建db4数据库、如果不存在则创建,指定字符集为gbk
CREATE DATABASE IF NOT EXISTS db4 CHARACTER SET gbk;
练习:查看db4数据库的字符集
SHOW CREATE DATABASE db4;
2.4 DDL修改、删除、使用数据库
# 修改数据库(修改字符集)
ALTER DATABASE 数据库名称 CHARACTER SET 字符集名称;
# 删除数据库
DROP DATABASE 数据库名称;
# 删除数据库(判断,如果存在则删除)
DROP DATABASE IF EXISTS 数据库名称;
# 使用数据库
USE 数据库名称;
# 查看当前使用的数据库
SELECT DATABASE();
2.5 DDL查询数据表
# 查询所有的数据表
SHOW TABLES;
# 查询表结构
DESC 表名;
# 查询字符集
SHOW TABLE STATUS FROM 库名 LIKE '表名';
2.6 DDL创建数据表
# 创建数据表
CREATE TABLE 表名(
列名 数据类型 约束,
...
列名 数据类型 约束,
列名 数据类型 约束
);
# 常见数据类型
int:整数类型
double:小数类型
data:日期类型。包括年月日,格式yyyy-MM-dd
datetime:日期类型。包括年月日时分秒,格式yyyy-MM-dd HH:mm:ss
timestamp:时间戳类型。包含年月日时分秒,格式yyyy-MM-dd HH:mm:ss
* 如果不给该列赋值、或赋值为null,则默认使用当前系统时间自动赋值
varchar(长度):字符串类型
练习:创建一个product商品表(商品编号、商品名称、商品价格、商品库存、上架时间)
CREATE TABLE product(
id INT,
NAME VARCHAR(20),
price DOUBLE,
stock INT,
insert_time DATE
);
练习:查看product表详细结构
DESC product;
数据类型汇总
各数据类型及字节长度一览表:
数据类型 | 字节长度 | 范围或用法 |
---|---|---|
Bit | 1 | 无符号[0,255],有符号[-128,127],天缘博客备注:BIT和BOOL布尔型都占用1字节 |
TinyInt | 1 | 整数[0,255] |
SmallInt | 2 | 无符号[0,65535],有符号[-32768,32767] |
MediumInt | 3 | 无符号[0,2^24-1],有符号[-2^23,2^23-1]] |
Int | 4 | 无符号[0,2^32-1],有符号[-2^31,2^31-1] |
BigInt | 8 | 无符号[0,2^64-1],有符号[-2^63 ,2^63 -1] |
Float(M,D) | 4 | 单精度浮点数。天缘博客提醒这里的D是精度,如果D<=24则为默认的FLOAT,如果D>24则会自动被转换为DOUBLE型。 |
Double(M,D) | 8 | 双精度浮点。 |
Decimal(M,D) | M+1或M+2 | 未打包的浮点数,用法类似于FLOAT和DOUBLE,天缘博客提醒您如果在ASP中使用到Decimal数据类型,直接从数据库读出来的Decimal可能需要先转换成Float或Double类型后再进行运算。 |
Date | 3 | 以YYYY-MM-DD的格式显示,比如:2009-07-19 |
Date Time | 8 | 以YYYY-MM-DD HH:MM:SS的格式显示,比如:2009-07-19 11:22:30 |
TimeStamp | 4 | 以YYYY-MM-DD的格式显示,比如:2009-07-19 |
Time | 3 | 以HH:MM:SS的格式显示。比如:11:22:30 |
Year | 1 | 以YYYY的格式显示。比如:2009 |
Char(M) | M | 定长字符串。 |
VarChar(M) | M | 变长字符串,要求M<=255 |
Binary(M) | M | 类似Char的二进制存储,特点是插入定长不足补0 |
VarBinary(M) | M | 类似VarChar的变长二进制存储,特点是定长不补0 |
Tiny Text | Max:255 | 大小写不敏感 |
Text | Max:64K | 大小写不敏感 |
Medium Text | Max:16M | 大小写不敏感 |
Long Text | Max:4G | 大小写不敏感 |
TinyBlob | Max:255 | 大小写敏感 |
Blob | Max:64K | 大小写敏感 |
MediumBlob | Max:16M | 大小写敏感 |
LongBlob | Max:4G | 大小写敏感 |
Enum | 1或2 | 最大可达65535个不同的枚举值 |
Set | 可达8 | 最大可达64个不同的值 |
Geometry | ||
Point | ||
LineString | ||
Polygon | ||
MultiPoint | ||
MultiLineString | ||
MultiPolygon | ||
GeometryCollection |
|
2.7 DDL修改数据表(表结构的修改,非数据)
# 修改表名
ALTER TABLE 表名 RENAME TO 新表名;
# 修改表的字符集
ALTER TABLE 表名 CHARACTER SET 字符集名称;
# 单独添加一列
ALTER TABLE 表名 ADD 列名 数据类型;
# 修改某列的数据类型
ALTER TABLE 表名 MODIFY 列名 新数据类型;
# 修改列名和数据类型
ALTER TABLE 表名 CHARACTER 列名 新列名 新数据类型;
# 删除某一列
ALTER TABLE 列名 DROP 列名;
2.8 DDL删除数据表
# 删除数据表
DROP TABLE 表名;
# 删除数据表(判断,如果存在则删除)
DROP TABLE IF EXISTS 表名;
3. DML表数据的增删改
3.1 DML新增表数据
# 给指定列添加数据
INSERT INTO 表名(列名1,列名2,...) VALUES (值1,值2,...);
# 给全部列添加数据
INSERT INTO 表名 VALUES (值1,值2,...);
# 批量添加数据
INSERT INTO 表名(列名1,列名2,...) VALUES (值1,值2,...),(值1,值2,...),...;
INSERT INTO 表名 VALUES (值1,值2,...),(值1,值2,...),...;
列名和值的数量以及数据类型要对应,除了数字类型(如int,double),其他数据类型的数据都需要加引号(单引双引都行,推荐单引)
3.2 DML修改和删除表数据
#修改表中的数据
UPDATE 表名 SET 列名1=值1,列名2=值2,...[WHERE条件];
注意:修改语句中必须加条件,如果不加条件,则会将所有数据都修改。如:UPDATE product SET name='棒棒糖';
# 删除表中的数据
DELETE FROM 表名 [WHERE 条件];
注意:删除语句中必须加条件,如果不加条件,则会将所有数据都删除。如DELETE FROM product;
4. DQL表数据的查询
4.1 数据准备
-- 创建db1数据库
CREATE DATABASE db1;
-- 使用db1数据库
USE db1;
-- 创建数据表
CREATE TABLE product(
id INT, -- 商品编号
NAME VARCHAR(20), -- 商品名称
price DOUBLE, -- 商品价格
brand VARCHAR(10), -- 商品品牌
stock INT, -- 商品库存
insert_time DATE -- 添加时间
);
-- 添加数据
INSERT INTO product VALUES
(1,'华为手机',3999,'华为',23,'2088-03-10'),
(2,'小米手机',2999,'小米',30,'2088-05-15'),
(3,'苹果手机',5999,'苹果',18,'2088-08-20'),
(4,'华为电脑',6999,'华为',14,'2088-06-16'),
(5,'小米电脑',4999,'小米',26,'2088-07-08'),
(6,'苹果电脑',8999,'苹果',15,'2088-10-25'),
(7,'联想电脑',7999,'联想',NULL,'2088-11-11');
从上面我们可以看到:插入语句中除了数字类型外,其它都用单引号包裹!
4.2 查询语法
SELECT
字段列表
FROM
表名列表
WHERE
条件列表
GROUP BY
分组字段
HAVING
分组后的过滤条件
ORDER BY
排序
LIMIT
分页
4.3 查询全部
--查询全部的表数据
SELECT * FROM 表名;
# 查询指定字段的表数据
SELECT 列名,列名2,...FROM 表名;
# 去除重复查询
SELECT DISTINCT 列名1,列名2,...FROM 表名;
# 计算列的值(四则运算)
SELECT 列名1 运算符(+-*/) 列名2 FROM 表名;
# 起别名查询
SELECT 列名 AS 别名 FROM 表名;
练习:
/*
查询全部数据
标准语法:
SELECT * FROM 表名;
*/
-- 查询product表所有数据
SELECT * FROM product;
/*
查询指定列
标准语法:
SELECT 列名1,列名2,... FROM 表名;
*/
-- 查询名称、价格、品牌
SELECT NAME,price,brand FROM product;
/*
去除重复查询
标准语法:
SELECT DISTINCT 列名1,列名2,... FROM 表名;
*/
-- 查询品牌
SELECT brand FROM product;
-- 查询品牌,去除重复
SELECT DISTINCT brand FROM product;
/*
计算列的值
标准语法:
SELECT 列名1 运算符(+ - * /) 列名2 FROM 表名;
如果某一列为null,可以进行替换
ifnull(表达式1,表达式2)
表达式1:想替换的列
表达式2:想替换的值
*/
-- 查询商品名称和库存,库存数量在原有基础上加10
SELECT NAME,stock+10 FROM product;
-- 查询商品名称和库存,库存数量在原有基础上加10。进行null值判断
SELECT NAME,IFNULL(stock,0)+10 FROM product;
/*
起别名
标准语法:
SELECT 列名1,列名2,... AS 别名 FROM 表名;
*/
-- 查询商品名称和库存,库存数量在原有基础上加10。进行null值判断。起别名为getSum
SELECT NAME,IFNULL(stock,0)+10 AS getSum FROM product;
SELECT NAME,IFNULL(stock,0)+10 getSum FROM product;
4.4 条件查询
查询条件分类 | 符号 | 功能 | | —- | —- | | > | 大于 | | < | 小于 | | >= | 大于等于 | | <= | 小于等于 | | = | 等于 | | <> 或 != | 不等于 | | BETWEEN … AND … | 在某个范围之内(都包含) | | IN(…) | 多选一 | | LIKE 占位符 | 模糊查询 _单个任意字符 %多个任意字符 | | IS NULL | 是NULL | | IS NOT NULL | 不是NULL | | AND 或 && | 并且 | | OR 或 || | 或者 | | NOT 或 ! | 非,不是 |
查询条件语法
SELECT 列名列表 FROM 表名 WHERE 条件;
练习 ```sql /* 条件查询 标准语法:
SELECT 列名列表 FROM 表名 WHERE 条件;
/ — 查询库存大于20的商品信息 SELECT FROM product WHERE stock > 20;
— 查询品牌为华为的商品信息 SELECT * FROM product WHERE brand=’华为’;
— 查询金额在4000 ~ 6000之间的商品信息 SELECT FROM product WHERE price >= 4000 AND price <= 6000; SELECT FROM product WHERE price BETWEEN 4000 AND 6000;
— 查询库存为14、30、23的商品信息 SELECT FROM product WHERE stock=14 OR stock=30 OR stock=23; SELECT FROM product WHERE stock IN(14,30,23);
— 查询库存为null的商品信息 SELECT * FROM product WHERE stock IS NULL;
— 查询库存不为null的商品信息 SELECT * FROM product WHERE stock IS NOT NULL;
— 查询名称以小米为开头的商品信息 SELECT * FROM product WHERE NAME LIKE ‘小米%’;
— 查询名称第二个字是为的商品信息 SELECT * FROM product WHERE NAME LIKE ‘_为%’;
— 查询名称为四个字符的商品信息 SELECT * FROM product WHERE NAME LIKE ‘__‘;
— 查询名称中包含电脑的商品信息 SELECT * FROM product WHERE NAME LIKE ‘%电脑%’;
<a name="PHWg6"></a>
## 4.5 聚合函数查询
- 聚集函数的介绍
将一列数据作为一个整体,进行纵向的计算。
- 聚合函数的分类
| **函数名** | **功能** |
| --- | --- |
| count(列名) | 统计数量(一般选用不为null的列) |
| max(列名) | 最大值 |
| min(列名) | 最小值 |
| sum(列名) | 求和 |
| avg(列名) | 平均值 |
- 聚合函数查询语法
```sql
SELECT 函数名(列名) FROM 表名 [WHERE 条件];
- 练习
```sql
/*
聚合函数
标准语法:
/ — 计算product表中总记录条数 SELECT COUNT() FROM product; — 我们这里为什么用,因为要求是选用不为null的列,如果是就是所有列,那么一般来说,应该一定有不为null的SELECT 函数名(列名) FROM 表名 [WHERE 条件];
— 获取最高价格 SELECT MAX(price) FROM product;
— 获取最低库存 SELECT MIN(stock) FROM product;
— 获取总库存数量 SELECT SUM(stock) FROM product;
— 获取品牌为苹果的总库存数量 SELECT SUM(stock) FROM product WHERE brand=’苹果’;
— 获取品牌为小米的平均商品价格 SELECT AVG(price) FROM product WHERE brand=’小米’;
<a name="e8KHh"></a>
## 4.6 排序查询
```sql
# 排序查询语法
SELECT 列名列表 FROM 表名 [WHERE 条件] ORDER BY 列名 排序方式,列名 排序方式,...;
# 排序方式:ASC-升序,DESC-降序
# 如果有多个排序条件,只有当前边的条件值一样时,才会判断第二条件。
- 练习
```sql
/*
排序查询
标准语法:
/ — 按照库存升序排序 SELECT FROM product ORDER BY stock ASC;SELECT 列名 FROM 表名 [WHERE 条件] ORDER BY 列名1 排序方式1,列名2 排序方式2;
— 查询名称中包含手机的商品信息。按照金额降序排序 SELECT * FROM product WHERE NAME LIKE ‘%手机%’ ORDER BY price DESC;
— 按照金额升序排序,如果金额相同,按照库存降序排列 SELECT * FROM product ORDER BY price ASC,stock DESC;
<a name="jcINj"></a>
## 4.7 分组查询
- 分组查询语法
```sql
-- 标准语法
SELECT 列名 FROM 表名 [WHERE 条件] GROUP BY 分组列名 [HAVING 分组后条件过滤] [ORDER BY 排序列名 排序方式];
- 练习
```sql
/*
分组查询
标准语法:
*/ — 按照品牌分组,获取每组商品的总金额 SELECT brand,SUM(price) FROM product GROUP BY brand;SELECT 列名 FROM 表名 [WHERE 条件] GROUP BY 分组列名 [HAVING 分组后条件过滤] [ORDER BY 排序列名 排序方式];
— 对金额大于4000元的商品,按照品牌分组,获取每组商品的总金额 SELECT brand,SUM(price) FROM product WHERE price > 4000 GROUP BY brand;
— 对金额大于4000元的商品,按照品牌分组,获取每组商品的总金额,只显示总金额大于7000元的 SELECT brand,SUM(price) getSum FROM product WHERE price > 4000 GROUP BY brand HAVING getSum > 7000;
— 对金额大于4000元的商品,按照品牌分组,获取每组商品的总金额,只显示总金额大于7000元的、并按照总金额的降序排列 SELECT brand,SUM(price) getSum FROM product WHERE price > 4000 GROUP BY brand HAVING getSum > 7000 ORDER BY getSum DESC;
<a name="GGcbY"></a>
## 4.8 分页查询
- 分页查询语法
```sql
-- 标准语法
SELECT 列名 FROM 表名 [WHERE 条件] GROUP BY 分组列名 [HAVING 分组后条件过滤] [ORDER BY 排序列名 排序方式] LIMIT 开始索引,每页显示条数;
-- 公式:开始索引 = (当前页码-1) * 每页显示的条数
-- 当前页码即你想要第几页,从第一页开始
练习 ```sql /* 分页查询 标准语法:
SELECT 列名 FROM 表名
[WHERE 条件]
[GROUP BY 分组列名]
[HAVING 分组后条件过滤]
[ORDER BY 排序列名 排序方式]
LIMIT 当前页数,每页显示的条数;
LIMIT 当前页数,每页显示的条数; 公式:当前页数 = (当前页数-1) 每页显示的条数 / — 每页显示3条数据
— 第1页 当前页数=(1-1) 3 SELECT FROM product LIMIT 0,3;
— 第2页 当前页数=(2-1) 3 SELECT FROM product LIMIT 3,3;
— 第3页 当前页数=(3-1) 3 SELECT FROM product LIMIT 6,3;
<a name="hZDX2"></a>
# 5. 约束
<a name="MwPhb"></a>
## 5.1 约束的介绍
- 什么是约束
表中数据进行限定,保证数据的正确性、有效性、完整性!
- 约束的分类
| **约束** | **说明** |
| --- | --- |
| PRIMARY KEY | 主键约束 |
| PRIMARY KEY AUTO_INCREMENT | 主键、自动增长 |
| UNIQUE | 唯一约束 |
| NOT NULL | 非空约束 |
| FOREIGN KEY | 外键约束 |
| FOREIGN KEY ON UPDATE CASCADE | 外键级联更新 |
| FOREIGN KEY ON DELETE CASCADE | 外键级联删除 |
<a name="SaP3s"></a>
## 5.2 主键约束
- 主键约束特点
- 主键约束包含:非空和唯一两个功能
- 一张表只能有一个列作为主键
- 主键一般用于表中数据的唯一标识
- 建表时添加主键约束
```sql
-- 标准语法
CREATE TABLE 表名(
列名 数据类型 PRIMARY KEY,
列名 数据类型,
...
);
-- 创建student表
CREATE TABLE student(
id INT PRIMARY KEY -- 给id添加主键约束
);
- 删除主键约束 ```sql — 标准语法 ALTER TABLE 表名 DROP PRIMARY KEY;
— 删除主键 ALTER TABLE student DROP PRIMARY KEY;
- 建表后单独添加主键约束
```sql
-- 标准语法
ALTER TABLE 表名 MODIFY 列名 数据类型 PRIMARY KEY;
-- 添加主键
ALTER TABLE student MODIFY id INT PRIMARY KEY;
5.3 主键自增约束
- 建表时添加主键自增约束(如果添加是NULL,则自增) ```sql — 标准语法 CREATE TABLE 表名( 列名 数据类型 PRIMARY KEY AUTO_INCREMENT, 列名 数据类型, … );
— 创建student2表 CREATE TABLE student2( id INT PRIMARY KEY AUTO_INCREMENT — 给id添加主键自增约束 );
— 添加null值,会自动增长 INSERT INTO student2 VALUES (NULL),(NULL);
- 删除自动增长
```sql
-- 标准语法
ALTER TABLE 表名 MODIFY 列名 数据类型;
-- 删除自动增长
ALTER TABLE student2 MODIFY id INT;
- 建表后单独添加自动增长 ```sql — 标准语法 ALTER TABLE 表名 MODIFY 列名 数据类型 AUTO_INCREMENT;
— 添加自动增长 ALTER TABLE student2 MODIFY id INT AUTO_INCREMENT;
注意:MySQL中的自增约束,必须配合键(**不一定是主键**)的约束一起使用!
<a name="VRnZd"></a>
## 5.4 唯一约束
- 建表时添加唯一约束
```sql
-- 标准语法
CREATE TABLE 表名(
列名 数据类型 UNIQUE,
列名 数据类型,
...
);
-- 创建student3表
CREATE TABLE student3(
id INT PRIMARY KEY AUTO_INCREMENT,
tel VARCHAR(20) UNIQUE -- 给tel列添加唯一约束
);
-- 添加数据
INSERT INTO student3 VALUES (NULL,'18888888888'),(NULL,'18666666666');
-- 添加重复数据,会报错
INSERT INTO student3 VALUES (NULL,'18666666666');
- 删除唯一约束 ```sql — 标准语法 ALTER TABLE 表名 DROP INDEX 列名;
— 删除唯一约束 ALTER TABLE student3 DROP INDEX tel;
- 建表后单独添加唯一约束
```sql
-- 标准语法
ALTER TABLE 表名 MODIFY 列名 数据类型 UNIQUE;
-- 添加唯一约束
ALTER TABLE student3 MODIFY tel VARCHAR(20) UNIQUE;
5.4 非空约束
- 建表时添加非空约束 ```sql — 标准语法 CREATE TABLE 表名( 列名 数据类型 NOT NULL, 列名 数据类型, … );
— 创建student4表 CREATE TABLE student4( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20) NOT NULL — 给name添加非空约束 );
— 添加数据 INSERT INTO student4 VALUES (NULL,’张三’),(NULL,’李四’); — 添加null值,会报错 INSERT INTO student4 VALUES (NULL,NULL);
- 删除非空约束
```sql
-- 标准语法
ALTER TABLE 表名 MODIFY 列名 数据类型;
-- 删除非空约束
ALTER TABLE student4 MODIFY NAME VARCHAR(20);
- 建表后单独添加非空约束 ```sql — 标准语法 ALTER TABLE 表名 MODIFY 列名 数据类型 NOT NULL;
— 添加非空约束 ALTER TABLE student4 MODIFY NAME VARCHAR(20) NOT NULL; ```
外键约束
请看下一章 进阶课程!