MySQL数据库基础

数据库的基本概念

  1. 数据库的英文:DataBase 简称:DB.

  2. 什么是数据库?

    ​ io 数据持久化 内存? txt

    用来存储和管理数据的有结构和组织的仓库。其本质就是一个文件夹

  3. 数据库的特点:

    ​ 1)可以进行数据的持久化操,其实数据库就是一个大的文件系统。

    ​ 2)方便统一管理和存储数据

    ​ 3)使用统一的方式进行数据库的操作和管理

  4. 常见的数据库

    ​ 1) MySQL 数据库,期初是Sun公司开发的产品,后期Oracle

    公司收够,是Oracle公司的产品,这款软件是开源。

    ​ MariaDB 完全免费

1
2
3
4
5
MySQL分社区版和商业版。社区版是免费的,商业版要收费。
1、MySQL Community Server 社区版本,开源免费,但不提供官方技术支持。
2、MySQL Enterprise Edition 企业版本,需付费,可以试用30天。
3、MySQL Cluster 集群版,开源免费。可将几个MySQL Server封装成一个Server。
4、MySQL Cluster CGE 高级集群版,需付费。

​ 2) Oracle 数据库,是闭源产品,市场占有率仅次于MySQL

​ 3) SQLServer数据库,是微软旗下的产品,同样是闭源产品主要应用在微软的整体解决方案中

​ 4)DB2数据库,IBM公司的产品,闭源,应用在IBM的整体解决方案中

安装MariaDB数据库

mysql的安装和卸载是比较繁琐的,对于初学者来讲,会带来很多不必要的麻烦!

安装MariaDB的原因:

  • 1.安装非常简单,傻瓜式操作;
  • 2.自带可视化工具,不需要借助第三方软件进行数据的操作。

安装过程中需要注意的点:

  1. 如果安装失败,需要通过控制面板进行卸载造成,完了继续双击安装包进行安装

  2. 安装过程中,需要设置自己的用户密码。第一个是密码填写,第二次是密码确定。因为用户名是默认的root,建议设置为:root

  3. 还需要勾选字符集:UTF8

  4. 注意下:mysql数据库的默认端口号是:3306

  5. 安装成功的标志:

    (1)看桌面上有没有HeidiSQL软件图标

    (2)打开开始,找到安装的Mariadb文件夹,找到MySQL Client5.5,打开之后在黑窗口面板上填写自己设置的密码:root,回车之后出现以下的内容表示安装成功!

    1
    2
    3
    4
    5
    6
    7
    8
    Enter password: ****
    Welcome to the MariaDB monitor. Commands end with ; or \g.
    Your MariaDB connection id is 2
    Server version: 5.5.67-MariaDB mariadb.org binary distribution
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

    MariaDB [(none)]>
  1. 登录mysql 的方式

    (1)点击开始,找到安装的Mariadb文件夹,找到MySQL Client5.5,打开之后在黑窗口面板上填写自己设置的密码:root

    (2)win+R ,调出的窗口中输入cmd。先将路径切换到MariaDB数据库的bin目录下

    cd D:

    cd 01-software/MariaDB 5.5/bin

    》 mysql -uroot -proot

    1
    2
    3
    4
    5
    6
    7
    8
    D:\01-software> cd MariaDB 5.5/bin
    D:\01-software\MariaDB 5.5\bin> mysql -uroot -proot
    Welcome to the MariaDB monitor. Commands end with ; or \g.
    Your MariaDB connection id is 3
    Server version: 5.5.67-MariaDB mariadb.org binary distribution
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    MariaDB [(none)]>

如果有会话链接失败的,或者在黑窗口不能够登录成功的,是应为mysql的服务端没有开启。下面开启服务端的步骤:

(1)第一种方式:

​ 点开开始,输入“服务”,跳出服务界面,打开之后寻找“MySQL”

​ 或者win+R 输入:services.msc,依旧会跳出服务界面。打开之后寻找“MySQL”

(2)第二种,使用命令进行启动和关闭

  • 启动:net start mysql

  • 终止:net stop mysql

    1
    2
    3
    4
    5
    6
    7
    C:\Windows\system32>net start mysql
    MySQL 服务正在启动 .
    MySQL 服务已经启动成功。

    C:\Windows\system32>net stop mysql
    MySQL 服务正在停止..
    MySQL 服务已成功停止。
  1. 退出Mysql:

    输入:exit 或者 quit

SQL

  1. 什么是SQL?

    英文全称: Structured Query Language

    中文名称:结构化查询语言

    其实就是定义了 操作所有关系型数据库的规则,每一个数据库了操作的方式可以能是不一样的,存在一定差异化,类比于地方的方言。

  2. SQL通用用法

    ​ 1)SQL 是可以单行运行、也可以多行运行的,且结束符号是封号(英文状态)

    ​ 2)可以使用空格和缩进来增强SQL语句的可读性。

    ​ 3)MySQL数据库中,是不区分大小写的,关键字一般建议使用大写。 ​4)数据库中设计3中注释

    • 单行注释: -- 需要注释的内容

                         `#`   需要注释的内容(在mysql特有)
    • 多行注释:/* 需要注释的内容 */

  3. SQL的分类

    ​ (1)DDL(Date Definition Language)数据定义语言

    ​ 是用来定义数据库对象:数据库、数据表、列等

    ​ 关键字:create、drop、alter等

    ​ (2)DML(Date Manipulation Language)数据操作语言

    ​ 是用来对数据库中的表中的数据进行:增删改。

    ​ 关键字:insert、delete、 update等

​ (3)DQL(Date Query Language)数据库查询语言

​ 是用来查询数据库中表的记录(即指数据)。

​ 关键字:select、 where等

​ (4)DCL(Data Control Language) 数据控制语言

​ 是用来定义数据库的访问权限和安全级别。

​ 关键字:Grant、 Revoke等。

SQL 语句的应用

DDL : 数据库定义语言 -- 数据库、数据表

  1. 操作数据库: CRUD

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    1. C:Create 创建
    -- 创建数据库
    create database 数据库名称;
    -- 创建数据库并判断是否存在
    create database if not exists 数据库名称;
    -- 创建数据库的同时可以设置字符集
    create database 数据库名称 character set 字符集; 【uft8、gbk】
    # 练习:创建一个名为db1的数据库
    # 创建一个名为db2的数据库,并判断
    # 创建一个名为db3的数据库,并判断的同时设置字符集为utf8
    create database db1;
    create database if not exists db2;
    create database if not exists db3 character set utf8;

    MariaDB [(none)]> create database db1;
    Query OK, 1 row affected (0.00 sec)

    MariaDB [(none)]> create database if not exists db2;
    Query OK, 1 row affected (0.00 sec)

    MariaDB [(none)]> create database if not exists db3 character set utf8;
    Query OK, 1 row affected (0.00 sec)


    2.R:Retrieve 查询
    -- 查询数据库
    show databases;
    -- 查询某个数据库的字符集:查询某个数据库的创建语句就可以查询到字符集
    show create database 数据库名称;

    MariaDB [(none)]> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | db1 |
    | db2 |
    | db3 |
    | mysql |
    | performance_schema |
    +--------------------+
    6 rows in set (0.00 sec)

    MariaDB [(none)]> show create database db1;
    +----------+--------------------------------------------------------------+
    | Database | Create Database |
    +----------+--------------------------------------------------------------+
    | db1 | CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8 */ |
    +----------+--------------------------------------------------------------+
    1 row in set (0.00 sec)

    3.U: Update 修改
    -- 修改数据库的字符集
    alter database 数据库名称 character set 字符集名称;

    # 修改db3数据库的默认字符集为gbk
    alter database db3 character set gbk;

    MariaDB [(none)]> alter database db3 character set gbk;
    Query OK, 1 row affected (0.00 sec)

    MariaDB [(none)]> show create database db3;
    +----------+-------------------------------------------------------------+
    | Database | Create Database |
    +----------+-------------------------------------------------------------+
    | db3 | CREATE DATABASE `db3` /*!40100 DEFAULT CHARACTER SET gbk */ |
    +----------+-------------------------------------------------------------+
    1 row in set (0.00 sec)

    4. D: Delete 删除
    -- 删除数据库
    drop database 数据库名称;
    -- 判断数据库是否存在,存在则删除
    drop database if exists 数据库名称;
    # 删除db3数据库

    drop database if exists db3;

    MariaDB [(none)]> drop database if exists db3;
    Query OK, 0 rows affected (0.00 sec)

    MariaDB [(none)]> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | db1 |
    | db2 |
    | mysql |
    | performance_schema |
    +--------------------+
    5 rows in set (0.00 sec)

  2. 操作数据表 (CRUD)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    C:Create 创建
    -- 创建数据库表
    # 创建表的标准语法:
    create table 表名称(
    类名称1 数据类型1,
    列名称2 数据类型2,
    ...
    变量名称n 数据类型n
    );
    # 注意使用: 最后一列的数据,是不需要添加逗号的
    数据类型:
    1.int 整数类型 id int(18)
    2.double 小数类型 sal double(10, 2) 数据的最大长度是10,小数点精确到后2位
    3.varchar 字符串类型 name varchar(10) "zhangsan" / "张三"
    4.date 日期类型 只包含了年月日, yyyy-MM-dd
    datetime 包含了年月日时分秒,yyyy-MM-dd HH:mm:ss
    timestamp 叫时间戳,包含了年月日时分秒,yyyy-MM-dd HH:mm:ss
    -- 特点在于,不给其赋值时,默认会填写当前系统所在的时间,完成自动赋值。

    -- 创建数据表

    create table user(
    id int(5),
    name varchar(32),
    score double(3, 2),
    birthday datetime,
    create_table_time timestamp
    );

    MariaDB [(none)]> use db2;
    Database changed
    MariaDB [db2]> create table student(
    -> id int(5),
    -> name varchar(32),
    -> score double(3, 2),
    -> birthday datetime,
    -> create_table_time timestamp
    -> );
    Query OK, 0 rows affected (0.01 sec)

    # 练习: 创建一张名为user的数据表,包含字段:年龄、性别、名字、生日、工资、表创建的时间


    R:Retrieve 查询
    -- 查询表
    show tables;
    -- 查询表的结构
    desc 数据表名称;
    MariaDB [db2]> show tables;
    +---------------+
    | Tables_in_db2 |
    +---------------+
    | student |
    | user |
    +---------------+
    2 rows in set (0.00 sec)

    MariaDB [db2]> desc user;
    +-------------------+-------------+------+-----+-------------------+-----------------------------+
    | Field | Type | Null | Key | Default | Extra |
    +-------------------+-------------+------+-----+-------------------+-----------------------------+
    | id | int(5) | YES | | NULL | |
    | name | varchar(32) | YES | | NULL | |
    | score | double(3,2) | YES | | NULL | |
    | birthday | datetime | YES | | NULL | |
    | create_table_time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
    +-------------------+-------------+------+-----+-------------------+-----------------------------+
    5 rows in set (0.01 sec)

    U: Update 修改
    -- 修改表名称
    alter table 旧的表名称 rename to 新的表名称;
    -- 修改表的字符集
    alter table 表名称 character set 字符集;
    -- 增加一列
    alter table 表名称 add 列名称 数据类型;
    -- 修改列的名称
    alter table 表名称 change 列名称 新列名称 数据类型;
    alter table 表名称 modify 列名称 新的数据类型;
    -- 删除列
    alter table 表名称 drop 列名称;


    D: Delete 删除
    -- 删除整张表
    drop table 表名称;
    drop table if exists 表名称;

    MariaDB [db2]> drop table if exists user1;
    Query OK, 0 rows affected (0.00 sec)

    MariaDB [db2]> show tables;
    +---------------+
    | Tables_in_db2 |
    +---------------+
    | student |
    +---------------+
    1 row in set (0.00 sec)

DML:数据操作语言

  1. 向表中添加数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
语法结构:
insert into 表名称(列名称1, 列名称2,列名称3,... 列名称n)values(值1,值,值3...值n);
注意事项:
1. 列名称和值要做到一一对应!
2. 如果表名称后面不定义列名,则默认是给所有的列进行赋值
insert into 表名称 values(值1,值,值3...值n);
3. 除了数字类型,其他的类型需要使用引号(单双引号都是可以的)
# 举例
-- 创建表
create table person(id int(3),name varchar(32))charset=utf8;
-- 插入数据
方式一:
INSERT INTO person(id,name)VALUES(100,'张三');
方式二:
INSERT INTO person VALUES(200,'李四');
方式三:
INSERT INTO person VALUES(300,'王五'),(400,'马六'),(500,'田七');
  1. 将表中数据删除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
语法规则:
delete from 表名称 [where 条件];
注意事项:
1. 如果删除语句不添加任何的条件,则删除的是整张表的数据。
2. 如果我们要删除表中的所有数据:
(1)delete from 表名称; 【占空间的,好比于删除了文件,该文件还是放在了回收站中(回滚)】
(2)truncate table 表名称; 【删除的数据是永久 shift+del 】
注意以上的两个sql删除的都是表中的数据,并非删除的是表结构。
如果要删除标本身:drop table 表名称;
# 举例
DELETE FROM person WHERE id=100;
DELETE FROM person WHERE name='李四';
DELETE FROM person WHERE id=300 and name='李四';
TRUNCATE TABLE person;-- 删除的是表中的数据
DELETE FROM person;-- 删除的是表中的数据
DROP TABLE person; -- 删除的是整个表的结构

  1. 把表中的数据修改
1
2
3
4
5
6
7
8
语法结构:
update 表名称 set 列名称1 = 值1,列名称2=值2,...,列名称n=值n [ where 条件];
注意事项:
(1)如果更新操作不添加任何的条件,那么修改的是整张表中的数据。
# 举例
UPDATE person SET id=101,NAME='zahngsan' WHERE id=500
UPDATE person SET id=102,NAME='lisi' WHERE id=300 AND NAME='李四';
UPDATE person SET id=103,NAME='wangwu' ;-- 整张表的数据被更新

练习作业

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1. 创建mydb1和mydb2数据库,字符集第一个utf8和第二个gbk
create database mydb1 ....
2. 查询所有数据库检查是否创建成功

3. 分别查询两个数据库的字符集是否正确
4. 先使用mydb1再使用mydb2
5. 删除两个数据库
6. 创建数据库:mydb3 字符集utf8并使用
7. 创建员工表emp字段:名字 字符集utf8
8. 添加表字段: 最后添加job,最前面添加id, job前面添加工资salary
9. 删除:job字段
10. 修改表名为:e
11. 删除表:emp
12. 删除数据库:mybd3
13. 创建数据库mydb4 字符集utf8并使用
14. 创建汽车car表,字段有: id ,name, type(类型的意思字符串),生产日期(包含年月日)
15. 插入以下数据:
(1)五菱宏光 面包车,(2)保时捷911 跑车, (3)蔚来ES8 SUV,(4)小鹏p7 纯电轿车
16. 修改五菱宏光为:火车
17. 给表添加字段:价格money
18. 修改id小于3的价格为10000
19. 修改:蔚来es8 为纯电SUV
20. 修改保时捷911价格为20000
21. 删除:id等于4的数据
22. 修改:所有车的价格为888
23. 修改表名为:cars
24. 删除:money字段
25. 删除所有数据
26. 删除表
27. 删除数据库

DQL:数据查询语言

应用数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
-- 只需要将以下的数据复制到可视化窗口,选中运行即可。或者粘贴到黑窗口回车运行!

# 创建表
CREATE TABLE student(
id int, -- 编号
name varchar(20), -- 姓名
age int, -- 年龄
sex varchar(5), -- 性别
address varchar(100), -- 地址
chinese int, -- 语文
math int, -- 数学
english int -- 英语
);
# 插入数据
INSERT INTO student(
id, name, age, sex, address, chinese, math, english
)VALUES

(1,'唐僧',55,'女','大唐',88,66,78),
(2,'孙悟空',45,'男','水帘洞',90,98,87),
(3,'猪八戒',39,'男','高老庄',66,56,77),
(4,'沙和尚',40,'男','流沙河',64,76,65),
(5,'牛魔王',45,'男','翠云山',60,86,58),
(6,'铁扇公主',38,'女','火焰山',61,81,71),
(7,'红孩儿',12,'男','火云洞',55,99,65),
(8,'如来佛',99,'男','西天',99,99,99),
(9,'观世音',98,'女','西天',98,98,98),
(10,'白骨精',28,'女','妖界',59,56,NULL);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
一、基础查询
1.语法结构:
select 列名1,列名2,列名3,..,列名n from 表名称
# 举例:
select id,name,age,sex from student;
2.注意事项:
(1)select命令可以读取一行或者多行数据
(2)如果要查询表中所有的列,则可以使用 * 代替
SELECT * FROM student;
(3)还可以添加条件进行查询,添加条件之后,返回的是所有符合条件的内容
SELECT * FROM student WHERE id<=5;

3.(*)对于查询到的数据结果,如果有重复数据体现,在某些情况下需要对其去重操作。则:
使用关键字: distinct
select distinct sex from student; -- 查表结果中的性别数据

4.(*)当null参与运算时,得到的结果还是null。对null就行处理时,
使用关键字:ifnull
SELECT id,NAME,ifnull(chinese,0)+ifnull(math,0)+ifnull(english,0) FROM student;
注意: ifnull(表达式1,表达式2)。
第一个表达式判断如果是null,则可以使用表达式2的值代替表达式1的值。

5.(*)可以给列起别名,使用到的关键字 AS,这个AS是可以省略掉的,但一定要打至少一个的空格
SELECT ifnull(chinese,0)+ifnull(math,0)+ifnull(english,0) AS '总分' FROM student;
SELECT id '序号', NAME '名字' FROM student;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
二、条件查询
1.where 字句后面是查询条件
2.运算符:
(1)比较运算符
>、 <、 >=、 <=、 !=和<>(表示不等于)、 =
between...and...
in(集合)
like: 模糊查询
# mysql的占位符:
_: 单个任意的字符
%: 多个任意的字符
is null
(2)逻辑运算符
and: 表示与的关系 或者可以使用: &&
or: 表示或的关系 或者可以使用: ||
not: 表示非的关系 或者可以使用: !
语法结构:
select
字段列表
from
表名称
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定

DQL条件查询练习(1):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- 1.查询年龄小于等于28的

-- 2.查询年龄大于90的

-- 3.查询年龄不等于45

-- 4.查询年龄大于20岁,小于等于50的

-- 5.查询年龄是 12岁,45岁,98岁的

-- 6.查询英语成绩是 null

-- 7.查询英语成绩不是null

-- 8.查询姓名中是4字的人

-- 9.查询姓名中包含'八'字的人

-- 10.查询姓名中第二个字是'八'的人

-- 11.查询姓名是以'红'开头的人

-- 12.查询姓名中以 "佛" 结尾的人

参考答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
-- 1.查询年龄小于等于28的
SELECT * FROM student WHERE age <=28;

-- 2.查询年龄大于90的
SELECT * FROM student WHERE age >90;

-- 3.查询年龄不等于45
SELECT * FROM student WHERE age != 45;
SELECT * FROM student WHERE age <>45;

-- 4.查询年龄大于20岁,小于等于50的
SELECT * FROM student WHERE age >20 && age <=50;
SELECT * FROM student WHERE age >20 AND age <=50;
SELECT * FROM student WHERE age BETWEEN 20 AND 50;

-- 5.查询年龄是 12岁,45岁,98岁的
SELECT * FROM student WHERE age =12 || age=45 || age=98;
SELECT * FROM student WHERE age =12 or age=45 or age=98;
SELECT * FROM student WHERE age =12 || age=45 or age=98;
SELECT * FROM student WHERE age in(12,45,98);

-- 6.查询英语成绩是 null
# SELECT * FROM student WHERE english=NULL; -- 判断值是否是null,是不可以使用==或者!=
正确的是:
SELECT * FROM student WHERE english IS NULL ;

-- 7.查询英语成绩不是null
SELECT * FROM student WHERE english IS NOT NULL ;

-- 8.查询姓名中是4字的人
SELECT * FROM student WHERE NAME LIKE '____' ;
-- 9.查询姓名中包含'八'字的人
# SELECT * FROM student WHERE NAME LIKE "%八_" ; -- 表示查询姓名倒数第二个字符是八的人
正确的是:
SELECT * FROM student WHERE NAME LIKE "%八%" ;

-- 10.查询姓名中第二个字是'八'的人
SELECT * FROM student WHERE NAME LIKE "_八%" ;

-- 11.查询姓名是以'红'开头的人
SELECT * FROM student WHERE NAME LIKE "红%" ;

-- 12.查询姓名中以 "佛" 结尾的人
SELECT * FROM student WHERE NAME LIKE "%佛" ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
三、排序查询
1. 语法:
select
字段列表
from
表名称
order by
排序字段1 排序方式1,排序字段2 排序方式2.. ;
# 例子

SELECT * FROM student ORDER BY math ASC ;-- asc 表示升序排序
SELECT * FROM student ORDER BY math DESC ;-- desc 表示降序排序
注意:
如果有多个排序的条件同时存在,则当前边的条件值相同时,才会依据第二个条件进行判断,如果当第二个条件还是相同时,就会以第三个条件作为判断升降序,依次类推下去。

SELECT * FROM student ORDER BY math DESC, english ASC ;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
四、聚合函数
含义:
将一列数据作为一个整体进行纵向的计算。
1.count(): 计算个数
注意:计算整体个数的时候,(1)一般是会选择非空的列(主键);(2)count(*)

2.max(): 求最大值
3.min(): 求最小值
4.sum(): 求和
5.avg(): 求平均数

注意: 聚合函数的计算中,是排出null值的,如果在某场景null有使用到,使用ifnull函数处理。
# 举例
SELECT avg(english)FROM student; -- 77.55
SELECT avg(ifnull(english,0))FROM student;-- 69.8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
五、分组查询
1. 语法:
select
分组的字段、 聚合函数
from
表名称
group by
分组字段;
-- 按性别分组,求各组的数学平均分,语文的最高分,英语的最低分
select sex,avg(math),max(chinese),min(english) from student group by sex;

-- 按性别分组,求各组的数学平均分,数学分数低于65分的不参与分组
SELECT sex,AVG(math),COUNT(id)FROM student WHERE math>65 GROUP BY sex;

-- 按性别分组,求各组的数学平均分,数学分数低于65分的不参与分组, 分组之后,人数要求大于4个
SELECT sex,AVG(math),COUNT(id)FROM student WHERE math>65 GROUP BY sex HAVING COUNT(id)>4;

WHERE 和 HAVING之间的区别:
1. 位置不同: where是在分组之前,如果条件不满足,则不参与分组
having是在分组之后,如果不满足条件,则不会被查询出来
2. where后面条件不可以使用聚合函数,而having后面的条件是可以使用聚合函数的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
六、分页查询
1.语法结构:
select
字段列表
from
表名称
limit
开始的索引,每页显示的条数

-- 查询第一页数据,每页显示3条
SELECT * FROM student LIMIT 0,3;

-- 查询第二页数据,每页显示3条
SELECT * FROM student LIMIT 3,3;

-- 查询第三页数据,每页显示3条
SELECT * FROM student LIMIT 6,3;

-- 查询第四页数据,每页显示3条
SELECT * FROM student LIMIT 9,3;

通用公式:
开始的索引 = (当前页码 - 1)* 每页显示的条数

DQL语句查询练习(2):

1
2
3
4
5
6
7
8
9
10
11
12
13
-- 1.查询所有数据,使用年龄降序排序


-- 2.查询所有数据,在数学成绩降序排序的基础上,如果数学相同再以年龄升序排序


-- 3.按性别进行分组,查询下男生和女生各有多少人和英语成绩的平均分


-- 4.查询年龄大于等于40岁的人,按性别分组,统计每组的人数


-- 5.查询年龄大于30岁的人,按性别分组,统计每组的人数,并只显示性别人数大于4的数据

参考答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 查询所有数据,使用年龄降序排序
select * from student order by age desc;0

-- 查询所有数据,在数学成绩降序排序的基础上,如果数学相同再以年龄升序排序
select * from student math desc, age asc;

-- 按性别进行分组,查询下男生和女生各有多少人和英语成绩的平均分
select sex, count(*), avg(ifnull(english,0)) from student3 group by sex;

-- 查询年龄大于等于40岁的人,按性别分组,统计每组的人数
select sex, count(*) from student where age >=40 group by sex;
select sex, count(*) from student where age >40 || age=40 group by sex;
select sex, count(*) from student where age >40 OR age=40 group by sex;
select sex, count(*) from student where age >30 OR age in(30) group by sex;

-- 查询年龄大于30岁的人,按性别分组,统计每组的人数,并只显示性别人数大于4的数据
select sex, count(*) from student where age >30 group by sex having count(*)>4

数据库表的约束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
约束:
对表中数据进行限定,保证数据的正确性、有效性和完整性!
添加约束的方式可以在定义表时同步添加,也可以在定义表之后再进行添加。

1.约束类型:
(1)主键约束: primary key
(2)唯一约束: unique
(3)非空约束: not null
(4)外键约束: foregin key


2.唯一约束:
含义:存在的值不能重复!
结构:phone varchar(20) unique

-- 创建表时添加唯一约束 【推荐】
CREATE TABLE USER(
id INT(3),
username VARCHAR(32),
phone VARCHAR(20) unique
);

INSERT INTO user VALUES(1,'张三','11122223333');

-- 删除唯一约束 (索引约束)
# ALTER TABLE user MODIFY phone VARCHAR(20); -- 删除不成功
ALTER TABLE user DROP INDEX phone; -- 删除索引成功

-- 再给user表添加唯一约束
注意:在创建表之后添加唯一约束,需要保证表中指定列数据没有重复的
ALTER TABLE user MODIFY phone VARCHAR(20) UNIQUE;

注意在MySQL中,唯一约束限定是运行列的有多个 null 存在!

3.非空约束 not null
含义:列的值不能为null
结构:phone VARCHAR(20) not null
-- 创建表的同时,添加约束
CREATE TABLE USER(
id INT(3),
username VARCHAR(32),
phone VARCHAR(20) not null
);

INSERT INTO user VALUES(2,'李四',null); -- 跳窗报错,phone字段的值不能为null

-- 删除非空约束
ALTER TABLE user MODIFY phone VARCHAR(20);

-- 在创建user表之后,给指定列设置非空约束
ALTER TABLE user MODIFY phone VARCHAR(20) NOT NULL;



4.主键约束
含义: 非空且唯一(列的值不能是null,或者不能重复)
特点:在一张表中,只能有一个主键
结构: phone varchar(20) primary key

-- 创建表是添加主键约束
db1CREATE TABLE USER(
id INT(3) primary key,
username VARCHAR(32),
phone VARCHAR(20)
);

-- 插入数据
INSERT INTO user VALUES(4,'zhansan','13011112222')

-- 删除主键
# 删除失败 ALTER TABLE user MODIFY id INT(3);
ALTER TABLE user DROP PRIMARY KEY;

-- 添加主键
ALTER TABLE user add PRIMARY KEY(id);-- 【推荐使用第一种】
ALTER TABLE user MODIFY id INT(3)PRIMARY KEY;


4.1 主键自增:

-- 创建表是添加主键自增:auto_increment 注意主键自增是添加在int类型的字段上的!
CREATE TABLE USER(
id INT(3)PRIMARY KEY AUTO_INCREMENT , -- 1 2 3 1001 1002 1003
username VARCHAR(32),
phone VARCHAR(20)
);
-- 创建表的同时也是可以设置主键的起始值的,默认是从1开始
CREATE TABLE USER(
id INT(3)PRIMARY KEY AUTO_INCREMENT , -- 1 2 3 1001 1002 1003
username VARCHAR(32),
phone VARCHAR(20)
) AUTO_INCREMENT=1000; -- 表示主键从1000开始自增

INSERT INTO user VALUES(100, '张三','1100');
INSERT INTO user VALUES(200, '李三','1101');
INSERT INTO user VALUES(300, '王三','1102');
-- 插入数据方式:
INSERT INTO user VALUES(null, '王三','1102'); -- 因为前面的最大id是300,所以插入此数据之后,该条数据的id应该为:301,也就是在前面最大id值基础之上+1.

INSERT INTO user (username,phone) VALUES('小强','258');
INSERT INTO user (username,phone) VALUES('大强','369');
-- 删除主键自增
-- 特点:需要先删除自增:auto_increment 然后删除主键:primary key
ALTER TABLE user MODIFY id INT(3);
ALTER TABLE user DROP PRIMARY KEY;

-- 在建表之后添加主键自增 【以下设置主键自增失败】
ALTER TABLE user ADD PRIMARY KEY(id); # 一般一张表中的主键是给id的。
ALTER TABLE user AUTO_INCREMEN=400; # 建表之后,已经插入了数据,那么设置自增需要指定初始值,auto_increment 的默认值是 1,

# 添加主键自增
ALTER TABLE user MODIFY id INT(3)PRIMARY KEY auto_increment;
# 自定义主键起始值
ALTER TABLE user AUTO_INCREMENT=200; -- 实现了自增主键的起始值自定义


# delete 和 truncate 删除表数据对自增主键的影响
# 删除表数据
DELETE FROM user;
TRUNCATE TABLE user;
区别:
delete 删除表数据之后,自增主键值没有受任何影响。
truncate 删除表数据之后,自增主键又从默认的1开始。

5.外键约束
含义:foreign key
让表与表之间建立强连接关系,从而保证数据的一致性、安全性和完整性
结构:
-- (1)在创建表时,添加外键
create table dept(
.....,
constraint 外键名称 foreign key(外键列名称) references 主表名称(主表列名称)
);
-- 删除外键
格式: ALTER TABLE 表名称 DROP FOREIGN KEY 外键名称;
# 举例
ALTER TABLE emp DROP FOREIGN KEY emp_dept_fk;

-- 创建表之后,添加外键
alter table emp add constraint 外键名称 foreign key(外键列名称) references 主表名称(主表列名称)
# 举例
ALTER TABLE emp add CONSTRAINT emp_dept_fk FOREIGN KEY(dept_id) REFERENCES dept(id);
注意:在添加外键之前要确保从表中的数据是合理,比如从表中有部分编号1、2,但是在主表中中的
部门id只有2,那么在这种情况下添加外键是不成功的,需要将从表部门编号统一为2后再插入。

-- 级联操作
(1) ON UPDATE CASCADE
(2) ON DELETE CASCADE
需要注意的是在设置外键的同时进行设置级联操作,更新和删除级联操作可以同时设置,也可以分开设
置,具体按实际的应用场景决定。
# 结构:
alter table emp add constraint 外键名称 foreign key(外键列名称) references 主表名称(主表列名称)
# 举例
ALTER TABLE emp add CONSTRAINT emp_dept_fk FOREIGN KEY(dept_id) REFERENCES dept(id) ON UPDATE CASCADE ON DELETE CASCADE;


  • 外键约束:数据表

    一张表数据冗余度高,内存占用率高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30),
age INT,
dept_name VARCHAR(30), -- 部门名称
dept_loc VARCHAR(30) -- 部门地址
);
-- 添加数据
INSERT INTO emp (NAME, age, dept_name, dept_loc) VALUES ('张三', 22, '研发部', '福州');
INSERT INTO emp (NAME, age, dept_name, dept_loc) VALUES ('李四', 20, '研发部', '福州');
INSERT INTO emp (NAME, age, dept_name, dept_loc) VALUES ('王五', 25, '研发部', '福州');
INSERT INTO emp (NAME, age, dept_name, dept_loc) VALUES ('赵六', 18, '销售部', '厦门');
INSERT INTO emp (NAME, age, dept_name, dept_loc) VALUES ('田七', 22, '销售部', '厦门');
INSERT INTO emp (NAME, age, dept_name, dept_loc) VALUES ('黄八', 20, '销售部', '厦门');
  • 外键约束:解决方案

    多表外联,表结构简单,表关系清晰。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- 创建部门表(id,dept_name,dept_loc)
create table dept(
id int primary key auto_increment,
dept_name varchar(20),
dept_loc varchar(20)
);
-- 创建员工表(id,name,age,dept_id)
create table emp(
id int primary key auto_increment,
name varchar(20),
age int,
dept_id int
)
-- 添加 2 个部门
insert into dept values(null, '研发部','福州'),(null, '销售部', '厦门');

-- 添加员工, dept_id 表示员工所在的部门
INSERT INTO emp (NAME, age, dept_id) VALUES ('张三', 22, 1);
INSERT INTO emp (NAME, age, dept_id) VALUES ('李四', 20, 1);
INSERT INTO emp (NAME, age, dept_id) VALUES ('王五', 25, 1);
INSERT INTO emp (NAME, age, dept_id) VALUES ('赵六', 18, 2);
INSERT INTO emp (NAME, age, dept_id) VALUES ('田七', 22, 2);
INSERT INTO emp (NAME, age, dept_id) VALUES ('黄八', 20, 2);

数据库的设计

好的数据库表设计,不仅减小数据的冗余度,还能够使得数据查询效率提高!

  • 一对一【1-1】

    锁和钥匙、人和身份证

    解释:一个人只能有有一个身份证,一个身份证对应一个人

    实现:一对一的关系中,可以在任意一张表添加外键(唯一)指向另一张表的主键

  • 一对多(多对一)【1-n 或(n-1)】

    父亲和子女、部门和员工

    解释:一个父亲可以有多个子女,每个子女都有一个父亲

    实现:在多的一张表创建外键,指另一张表的主键

  • 多对多【n-n】

    学生和课程

    解释:一个学生可以选择多门课程,每门可以被多个学生选择

    实现:多对多的关系表中,需要借助第三张表来实现,第三张表也称为中间表,中间表至少包含两个字段,这两个字段分别指向另外两种表的主键