目录
数据库管理系统、数据库和表的关系
数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中表内的数据
数据库管理程序(DBMS)可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。为保存应用中实体的数据,一般会在数据库创建多个表,以保存程序中实体的数据。数据库管理系统、数据库和表的关系如图所示:
先有数据库 → 再有表 → 再有数据
一个库包含多个表
SQL语句
SQL的概念
什么是SQL
结构化查询语言(Structured Query Language)简称SQL,SQL语句就是对数据库进行操作的一种语言。
SQL作用
通过SQL语句我们可以方便的操作数据库中的数据库、表、数据。
SQL是数据库管理系统都需要遵循的规范。不同的数据库生产厂商都支持SQL语句,但都有特有内容。
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等
SQL通用语法
- SQL语句可以单行或多行书写,以分号结尾。
- 可使用空格和缩进来增强语句的可读性。
- MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。
DDL语句
DDL(Data Definition Language)数据定义语言
用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter等
DDL操作数据库
- 直接创建数据库
CREATE DATABASE
数据库名;
- 判断是否存在并创建数据库
CREATE DATABASE IF NOT EXISTS
数据库名;
- 创建数据库并指定字符集(编码表)
CREATE DATABASE
数据库名 CHARACTER SET 字符集;
- 具体操作:
- 直接创建数据库db1
- CREATE
image-20200903093635240
- 判断是否存在并创建数据库db2
- CREATE
- 创建数据库并指定字符集为gbk
- CREATE
gbk
;
- 查看所有的数据库
SHOW DATABASES;
- 查看某个数据库的定义信息
SHOW CREATE DATABASE
数据库名;
修改数据库字符集格式
ALTER DATABASE 数据库名 DEFAULT CHARACTER SET 字符集;
具体操作:
- 将db3数据库的字符集改成utf8
- ALTER
utf8
;
DROP DATABASE 数据库名;
具体操作:
- 删除db2数据库
- DROP
- 查看正在使用的数据库
SELECT DATABASE();
- 使用/切换数据库
USE
数据库名;
具体操作:
- 查看正在使用的数据库
- SELECT
- 使用db1数据库
- USE
DDL操作表
>前提先使用某个数据库
表的结构与excel相似
语法:
CREATE TABLE 表名 (字段名1 字段类型1, 字段名2 字段类型2…);
关键字说明:
CREATE
-- 表示创建
TABLE
-- 表示创建一张表
建议写成如下格式:
CREATETABLE
表名
(
字段名
1字段类型
1,
字段名
2字段类型
2
);
MySQL数据类型
MySQL中的我们常使用的数据类型如下:
类型 | 描述 |
int | 整型 |
double | 浮点型 |
varchar | 字符串型 |
data | 日期类型:yyyy-MM-dd |
详细的数据类型如下(不建议详细阅读!)
分类 | 类型名称 | 说明 |
整数类型 | tinyInt | 很小的整数 |
smallint | 小的整数 | |
mediumint | 中等大小的整数 | |
int(integer) | 普通大小的整数 | |
小数类型 | float | 单精度浮点数 |
double | 双精度浮点数 | |
decimal(m,d) | 压缩严格的定点数 | |
日期类型 | year | YYYY 1901~2155 |
time | HH:MM:SS -838:59:59~838:59:59 | |
date | YYYY-MM-DD 1000-01-01~9999-12-3 | |
datetime | YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00~ 9999-12-31 23:59:59 | |
timestamp | YYYY-MM-DD HH:MM:SS 19700101 00:00:01 UTC~2038-01-19 03:14:07UTC | |
文本、二进制类型 | CHAR(M) | M为0~255之间的整数 |
VARCHAR(M) | M为0~65535之间的整数 | |
TINYBLOB | 允许长度0~255字节 | |
BLOB | 允许长度0~65535字节 | |
MEDIUMBLOB | 允许长度0~167772150字节 | |
LONGBLOB | 允许长度0~4294967295字节 | |
TINYTEXT | 允许长度0~255字节 | |
TEXT | 允许长度0~65535字节 | |
MEDIUMTEXT | 允许长度0~167772150字节 | |
LONGTEXT | 允许长度0~4294967295字节 | |
VARBINARY(M) | 允许长度0~M个字节的变长字节字符串 | |
BINARY(M) | 允许长度0~M个字节的定长字节字符串 |
具体操作:
创建student表包含id,name,birthday字段
CREATETABLE
student
(
id
INT,
name
VARCHAR(20),
birthday
DATE
);
- 查看某个数据库中的所有表
SHOW TABLES;
- 查看表结构
DESC
表名;
- 查看创建表的SQL语句
SHOW CREATE TABLE
表名;
CREATE TABLE 新表名 LIKE 旧表名;
具体操作:
- 创建s1表,s1表结构和student表结构相同
- CREATE
s1
LIKEstudent
;
- 直接删除表
DROP TABLE
表名;
- 判断表是否存在并删除表
DROP TABLE IF EXISTS
表名;
修改表结构使用不是很频繁,只需要了解,等需要使用的时候再回来查即可
- 添加表列
ALTER TABLE
表名 ADD 列名 类型;
具体操作:
-
- 为学生表添加一个新的字段remark,类型为varchar(20)
- ALTER
student
ADDremark
VARCHAR(20);
- 修改列类型
ALTER TABLE
表名 MODIFY列名 新的类型;
具体操作:- 将student表中的remark字段的改成varchar(100)
- ALTER
student
MODIFYremark
VARCHAR(100);
- 修改列名
ALTER TABLE
表名 CHANGE 旧列名 新列名 类型;
具体操作:- 将student表中的remark字段名改成intro,类型varchar(30)
- ALTER
student CHANGE remark intr
varchar(30);
- 删除列
ALTER TABLE
表名 DROP 列名;
具体操作:- 删除student表中的字段intro
- ALTER
student
DROPintr
;
- 修改表名
RENAME TABLE
表名 TO 新表名;
具体操作:- 将学生表student改名成student2
student
TOstudent2
;
- 修改字符集
ALTER TABLE
表名 character set 字符集;
具体操作:- 将sutden2表的编码修改成gbk
- ALTER
student2
character setgbk
;
DML语句
DML(Data Manipulation Language)数据操作语言
用来对数据库中表的数据进行增删改。关键字:insert, delete, update等
插入记录
- 关键字说明
- INSERT
表名 – 表示往哪张表中添加数据
- (
字段名
1,字段名
2,…
) - VALUES
值
1,值
2,…
); - 注意
- 值与字段必须对应,个数相同,类型相同
- 值的数据大小必须在字段的长度范围内
- 除了数值类型外,其它的字段类型的值必须使用引号引起。(建议单引号)
- 如果要插入空值,可以不写字段,或者插入null
- 所有的字段名都写出来
INSERT INTO
表名 (字段名1, 字段名2, 字段名3…) VALUES (值1, 值2, 值3);
- 不写字段名
INSERT INTO
表名 VALUES (值1, 值2, 值3…);
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);
没有添加数据的字段会使用NULL
具体操作:
创建db2数据库,并使用。
CREATEDATABASE
db2;
USE
db2;
创建完整学生信息表,包括学员的id,姓名,年龄,性别,家庭地址,电话号码,生日,数学成绩,英语成绩
CREATETABLE
student
(
id
int,
name
varchar(20),
age
int,
sex char
(1),
address
varchar(200),
phone
varchar(20),
birthday
date,
math
double,
english
double
);
- 插入部分数据,往学生表中添加 id, name, age, sex,address数据
INSERTINTO
student
(id
,name
,age
,sex
,address
)values(1,'张三',19,'男','北京市');
提示:使用SELECT * FROM 表名;测试是否插入成功
- 向表中插入所有字段
- 所有的字段名都写出来
student
(id
,name
,age
,sex
,address
,phone
,birthday
,math
,english
)values(2,'小美',18,'女','上海市','18888888888','2011-12-12',65.5,99.2);- 不写字段名
INSERTINTO
student
values(3,'小明',27,'男','深圳市','13333333333','2000-11-06',95.5,92);
什么是蠕虫复制:在已有的数据基础之上,将原来的数据进行复制,插入到对应的表中
语法格式:INSERT INTO 表名1 SELECT * FROM 表名2;
作用:将表名2
中的数据复制到表名1
中
具体操作:
- 创建student2表,student2结构和student表结构一样
CREATETABLE
student
LIKEstudent2
;
- 将student表中的数据添加到student2表中
INSERTINTO
student
SELECT*
FROM
student2
;
注意:如果只想复制student表中name,age字段数据到student2表中使用如下格式
INSERTINTO
student2
(name
,age
)SELECT
name
,age
FROMstudent
;
更新表记录
- 不带条件修改数据
UPDATE
表名 SET 字段名=值;
- 带条件修改数据
UPDATE
表名 SET 字段名=值 WHERE 字段名=值;
- 关键字说明
- UPDATE
: 修改数据
- SET
: 修改哪些字段
- WHERE
: 指定条件
- 具体操作:
- 不带条件修改数据,将所有的性别改成女
- UPDATE
student
SETsex
='女';
- 带条件修改数据,将id号为2的学生性别改成男
- UPDATE
student
SETsex
='男'id
=2;
- 一次修改多个列,把id为3的学生,年龄改成26岁,address改成北京
- UPDATE
student
SETage
=26,address
='北京'id
=3;
删除表记录
- 不带条件删除数据
DELETE FROM
表名;
- 带条件删除数据
DELETE FROM
表名 WHERE 字段名=值;
- 具体操作:
- 带条件删除数据,删除id为3的记录
- DELETE
student
WHEREid
=3;
- 不带条件删除数据,删除表中的所有数据
- DELETE
student
;
truncate删除表记录
`TRUNCATE TABLE 表名;`
truncate和delete的区别:
- delete是将表中的数据一条一条删除
- truncate是将整个表摧毁,重新创建一个新的表,新的表结构和原来表结构一模一样
DQL
DQL(Data Query Language)数据查询语言
用来查询数据库中表的记录(数据)。关键字:select, where等
>注意:查询不会对数据库中的数据进行修改.只是一种显示数据的方式
简单查询
- 使用*表示所有列
SELECT * FROM
表名;
具体操作:
SELECT*
FROM
student
;
- 写出查询每列的名称
SELECT
字段名1, 字段名2, 字段名3, ... FROM 表名;
具体操作:
SELECTid
,name
,age
,sex
,address
,phone
,birthday
,math
,english
FROMstudent
;
查询指定列的数据,多个列之间以逗号分隔SELECT
字段名1, 字段名2... FROM 表名;
具体操作:
查询student表中的name 和 age 列
SELECTNAME
,age
FROMstudent
;
- 查询时给列、表指定别名需要使用AS关键字
- 使用别名的好处是方便观看和处理查询到的数据
SELECT
字段名1 AS 别名, 字段名2 AS 别名... FROM 表名;
注意:AS可以省略不写 - 具体操作:
- 查询sudent表中name 和 age 列,name列的别名为”姓名”,age列的别名为”年龄”
- SELECT
NAME
AS姓名
,age
AS年龄
FROMstudent
;
- 查询指定列并且结果不出现重复数据
SELECT DISTINCT
字段名 FROM 表名;
- 某列数据和固定值运算
SELECT
列名1 + 固定值 FROM 表名;
- 某列数据和其他列数据参与运算
SELECT
列名1 + 列名2 FROM 表名;
注意: 参与运算的必须是数值类型
条件查询
前面我们的查询都是将所有数据都查询出来,但是有时候我们只想获取到满足条件
的数据
语法格式:SELECT 字段名 FROM 表名 WHERE 条件;
流程:取出表中的每条数据,满足条件的记录就返回,不满足条件的记录不返回
>
大于<
小于<=
小于等于>=
大于等于=
等于<>
、!=
不等于
SELECT
*
FROM hero
WHERE 条件判断语句
and
多个条件同时满足or
多个条件其中一个满足not
不满足
in关键字
语法格式:SELECT 字段名 FROM 表名 WHERE 字段 in (数据1, 数据2...);
in
里面的每个数据都会作为一次条件,只要满足条件的就会显示
BETWEEN 值1 AND 值2
表示从值1到值2范围,包头又包尾
比如:age BETWEEN 35 AND 70
相当于: age>=35 && age<=70
LIKE
表示模糊查询SELECT * FROM
表名 WHERE 字段名 LIKE '通配符字符串';
满足通配符字符串
规则的数据就会显示出来
MySQL通配符有两个:%
: 表示0个或多个字符(任意个字符)_
: 表示一个字符
通过ORDER BY
子句,可以将查询出的结果进行排序(排序只是显示方式,不会影响数据库中数据的顺序)
语法:SELECT 字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名 [ASC|DESC];
ASC: 升序, 默认是升序
DESC: 降序
单列排序就是使用一个字段排序
SELECT*
FROM
表名
ORDERBY
列名
ASC;
组合排序就是先按第一个字段进行排序,如果第一个字段相同,才按第二个字段进行排序,依次类推。
上面的例子中,年龄是有相同的。当年龄相同再使用其他字段进行排序SELECT
字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名1 [ASC|DESC], 字段名2 [ASC|DESC];
之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个结果值。另外聚合函数会忽略空值
五个聚合函数:count
: 统计指定列记录数,记录为NULL的不统计sum
: 计算指定列的数值和,如果不是数值类型,那么计算结果为0max
: 计算指定列的最大值min
: 计算指定列的最小值avg
: 计算指定列的平均值,如果不是数值类型,那么计算结果为0
聚合函数的使用:写在 SQL语句SELECT
后 字段名
的地方SELECT
字段名... FROM 表名;
SELECT COUNT(age) FROM
表名;
我们发现对于NULL的记录不会统计
只要使用全部字段作为衡量标准既不会有遗漏的错误统计出现
SELECTCOUNT(*)
FROM
表名
分组查询是指使用 GROUP BY
语句对查询信息进行分组,相同数据作为一组
SELECT
字段1,字段2... FROM 表名 GROUP BY 分组字段 [HAVING 条件];
GROUP BY怎么分组的?将分组字段结果中相同内容作为一组SELECT * FROM
表名GROUP BY 列名;
分组的目的就是为了统计,一般分组会跟聚合函数一起使用。
分组后聚合函数的作用?不是操作所有数据,而是操作一组数据。SELECT
聚合函数 FROM 表名 GROUP BY 列名
>注意: 若要对分组后的数据进行下一步筛选,对于分组后的条件需要使用having
子句
SELECT聚合函数
FROM表名
WHERE判断语句
GROUPBY
列名
HAVING判断语句
;
having与where的区别
- having是在分组后对数据进行过滤.
- where是在分组前对数据进行过滤
- having后面可以使用聚合函数
- where后面不可以使用聚合函数
LIMIT
是限制
的意思,所以LIMIT
的作用就是限制查询记录的条数。SELECT *|
字段列表 [as 别名] FROM 表名 [WHERE子句] [GROUP BY子句][HAVING子句][ORDER BY子句][LIMIT子句];
思考:limit子句为什么排在最后?
因为前面所有的限制条件都处理完了,只剩下显示多少条记录的问题了!
LIMIT语法格式:
SELECT
*
FROM
表名LIMIT offset,length; 或者limit length;
offset
是指偏移量,可以认为是跳过的记录数量,默认为0length
是指需要显示的总记录数
LIMIT的使用场景:分页
比如我们登录京东,淘宝,返回的商品信息可能有几万条,不是一次全部显示出来。是一页显示固定的条数。
假设我们一每页显示5条记录的方式来分页,SQL语句如下:
-- 每页显示5条
-- 第一页: LIMIT 0,5; 跳过0条,显示5条
-- 第二页: LIMIT 5,5; 跳过5条,显示5条
-- 第三页: LIMIT 10,5; 跳过10条,显示5条
SELECT*
FROM
hero
LIMIT0,5;
SELECT*
FROM
hero
LIMIT5,5;
SELECT*
FROM
hero
LIMIT10,5;
注意:
- 如果第一个参数是0可以简写:
SELECT * FROM student3 LIMIT 0,5;
SELECT * FROM student3 LIMIT 5;
- LIMIT 10,5; – 不够5条,有多少显示多少
数据库约束
对表中的数据进行进一步的限制,保证数据的正确性、有效性和完整性。
约束种类:
PRIMARY KEY
: 主键UNIQUE
: 唯一NOT NULL
: 非空DEFAULT
: 默认FOREIGN KEY
: 外键
主键
主键的作用
用来唯一标识一条记录,每个表都应该有一个主键,并且每个表只能有一个主键。
有些记录的 name,age,sex 字段的值都一样时,那么就没法区分这些数据,造成数据库的记录不唯一,这样就不方便管理数据
哪个字段应该作为表的主键?
通常不用业务字段作为主键,单独给每张表设计一个id的字段,把id作为主键。主键是给数据库和程序使用的,不是给最终的客户使用的。所以主键有没有含义没有关系,只要不重复,非空就行。
创建主键
主键:PRIMARY KEY
主键的特点:
- 主键必须包含唯一的值
- 主键列不能包含NULL值
创建主键方式:
在创建表的时候给字段添加主键字段名 字段类型 PRIMARY KEY
删除主键
ALTER TABLE 表名 DROP PRIMARY KEY;
具体操作:
- 删除hero1表的主键
ALTERTABLE
hero1
DROPPRIMARY
KEY;
主键自增
主键如果让我们自己添加很有可能重复,我们通常希望在每次插入新记录时,数据库自动生成主键字段的值AUTO_INCREMENT
表示自动增长(字段类型必须是整数类型)
扩展
默认地AUTO_INCREMENT 的开始值是1,如果希望修改起始值,请使用下列SQL语法ALTER TABLE
表名 AUTO_INCREMENT=起始值;
DELETE和TRUNCATE的区别
- DELETE 删除表中的数据,但不重置AUTO_INCREMENT的值。
- TRUNCATE 摧毁表,重建表,AUTO_INCREMENT重置为1
唯一
在这张表中这个字段的值不能重复
唯一约束的基本格式
字段名 字段类型 UNIQUE
注:NULL和NULL不相等
非空
这个字段必须设置值,不能是NULL
非空约束的基本语法格式
字段名 字段类型 NOT NULL
默认值
往表中添加数据时,如果不指定这个字段的数据,就使用默认值
默认值格式字段名 字段类型 DEFAULT 默认值