Java从入门到实战总结-4.1、数据库基础

Java从入门到实战总结-4.1、数据库基础


第一章 数据库简介

1.1 简介

数据库(DataBase,DB):指长期保存在计算机的存储设备上,按照一定规则组织起来,可以被各种用户或应用共享的数据集合。

数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。
用户通过数据库管理系统访问数据库中的数据。

数据库软件应该为数据库管理系统,数据库是通过数据库管理系统创建和操作的。

数据库:存储、维护和管理数据的集合。

1.2 常见数据库管理系统

  • Oracle:Oracle数据库被认为是业界目前比较成功的关系型数据库管理系统。Oracle数据库可以运行在UNIX、Windows等主流操作系统平台,完全支持所有的工业标准,并获得最高级别的ISO标准安全性
    认证。

  • MySQL:MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS
    (Relational Database Management System,关系数据库管理系统) 应用软件。

  • DB2:DB2是IBM公司的产品,DB2数据库系统采用多进程多线索体系结构,其功能足以满足大中公司的需要,并可灵活地服务于中小型电子商务解决方案。

  • Microsoft SQL Server:SQL Server 是Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点。

还有非关系型数据库,比如Redis,这个在后面我们专门总结。目前后续的数据库学习以mysql为主。

1.3 三大范式(规范)

什么是三大范式:

  • 第一范式:无重复的列。当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。

  • 第二范式:属性完全依赖于主键 [ 消除部分子函数依赖 ]。如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被唯一地区分。为实现区分通常需要为表加上
    一个列,以存储各个实例的唯一标识。这个唯一属性列被称为主关键字或主键、主码。

  • 第三范式:属性不依赖于其它非主属性 [ 消除传递依赖 ]。设R是一个满足第一范式条件的关系模式,X 是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF. 满足第三范式(3NF)必须先满足第二范式(2NF)。第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

注:关系实质上是一张二维表,其中每一行是一个元组,每一列是一个属性

第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于,2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。

1.4 MySQL安装和卸载

  • 安装和配置步骤(详见下发的资料)
    目前最新的使用版本:MYSQL8.0.24,一般我们会落后一般版本使用。
1.4.1 windows下安装

在这里插入图片描述

for mac或者for ubuntu Linux等:

在这里插入图片描述

没有账户的点击左下方:No thanks。

在这里插入图片描述

下载后解压,放在非C盘下,文件夹改名mysql
将解压文件夹下的bin路径添加到变量值中,前后以 ; 开头结尾

在这里插入图片描述

  • 步骤3:在mysql文件夹下找到my.ini或my-default.ini,如果没有.ini结尾的文件,直接创建该文件。新增
    内容为如下,注意basedir和datadir是我自己的路径位置,自定义。记得新增一个文件Data文件夹

在这里插入图片描述

[mysqld]
# 设置3306端口
port=3306
# 设置mysql的安装目录
basedir=D:\Program Files\mysql
# 设置mysql数据库的数据的存放目录
datadir=D:\Program Files\mysql\data
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_connect_errors=10
# 服务端使用的字符集默认为UTF8
character-set-server=utf8
# 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB 
# 默认使用mysql_native_password插件认证default_authentication_plugin=mysql_native_password [mysql] 
# 设置mysql客户端默认字符集 
default-character-set=utf8 [client] 
# 设置mysql客户端连接服务端时默认使用的端口 
port=3306 
default-character-set=utf8
  • 步骤4:安装mysql
    在mysql的安装目录中,打开bin文件夹,运行cmd.执行初始化数据库的指令:
mysqld --initialize --console

在这里插入图片描述

root用户的初始化密码:

在这里插入图片描述

要是你不小心关掉cmd,或者没记住,那也没事,删掉初始化的 datadir 目录,再执行一遍初始化命令,又会重新生成的。

  • 步骤5:安装服务
    在MySQL安装目录的 bin 目录下执行命令:
    mysqld --install [服务名] 这里的服务名默认是mysql,可以自定义

在这里插入图片描述

如果提示上述错误,需要关闭cmd,重新打开,使用管理员身份执行
在这里插入图片描述

安装完成之后

通过命令net start mysql8启动MySQL的服务了。
通过命令net stop mysql8停止服务。

在这里插入图片描述

注意:安装时,卸载其他版本的mysql数据库

  • 步骤6:链接数据库
mysql -u root -p

在这里插入图片描述

修改账户密码:

alter user 'root'@'localhost' identified with mysql_native_password BY '新密码';

示例:

alter user 'root'@'localhost' identified with mysql_native_password BY '123456';

修改密码,注意命令尾的分号一定要有,这是mysql的语法

在这里插入图片描述

退出数据库:

quit或者\q
1.4.2 卸载
  • 步骤1:使用管理员身份运行cmd,关闭mysql服务
  • 步骤2:删除mysql服务

命令:sc delete mysql8 或者 mysqld remove mysql8

  • 步骤3:刪除mysqlDB目录文件( 安裝mysql时my.ini指定的目录)
1.4.3 mac使用HomeBrew安装

iTerm下执行如下命令即可:

brew install mysql@8.0

在这里插入图片描述

启动mysql服务使用:

mysql.server start

第一次登陆时root没有密码:

mysql -uroot

可以使用

man mysql或者mysql --help

来获取帮助信息,ubuntu等Linux系统也类似。

第二章 SQL语言

2.1 概述

SQL:Structure Query Language(结构化查询语言),SQL被美国国家标准局(ANSI)确定为关型数据库语言的美国标准,后来被国际化标准组织(ISO)采纳为关系数据库语言的国际标准。

各数据库厂商都支持ISO的SQL标准,普通话
各数据库厂商在标准的基础上做了自己的扩展,方言

SQL 是一种标准化的语言,它允许你在数据库上执行操作,如创建项目,查询内容,更新内容,并删除条目等操作。

Create, Read, Update, and Delete 通常称为CRUD操作。

2.2 SQL语句分类

  • DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等。
  • DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据)增删改。
  • DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别。
  • DQL(Data Query Language):数据查询语言,用来查询记录(数据)查询。

注意:sql语句以;结尾
mysql中的关键字不区分大小写

2.3 DDL操作数据库

2.3.1 创建

CREATE DATABASE语句用于创建新的数据库:

编码方式:gb2312,utf-8,gbk,iso-8859-1

CREATE DATABASE db1;

在这里插入图片描述

再比如:

//create database 数据库名 
CREATE DATABASE mydb1;
//create database 数据库名 character set 编码方式 
CREATE DATABASE mydb2 character SET GBK; 
//create database 数据库名 set 编码方式 collate 排序规则 
CREATE DATABASE mydb3 character SET GBK COLLATE gbk_chinese_ci;
2.3.2 查看数据库

查看当前数据库服务器中的所有数据库

show databases;

在这里插入图片描述

查看我们创建数据库的定义信息:

show CREATE DATABASE xxx;

在这里插入图片描述

2.3.3 修改数据库
alter database 数据库名 character set 编码方式

查看服务器中的数据库,并把db1的字符集修改为utf8;

alter database db1 character set utf8;

在这里插入图片描述

2.3.4 删除数据库
drop database 数据库名

在这里插入图片描述

2.3.5 其他语句

查看当前使用的数据库

Select database();

切换数据库: use 数据库名

USE mydb2;

在这里插入图片描述

2.4 DDL操作表

2.4.1 概述

CREATE TABLE语句用于创建新表。

语法:

CREATE TABLE 表名(
    列名1 数据类型 [约束],
    列名2 数据类型 [约束],
    列名n 数据类型 [约束]
);

说明:表名,列名是自定义,多列之间使用逗号间隔,最后一列的逗号不能写

[约束] 表示可有可无

示例:

CREATE TABLE Employees(
    id INT,
    age INT,
    first VARCHAR(255),
    last VARCHAR(255)
);

常用数据类型:
int:整型
double:浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值为
999.99;默认支持四舍五入
char:固定长度字符串类型; char(10) 'aaa ’ 占10位
varchar:可变长度字符串类型; varchar(10) ‘aaa’ 占3位
text:字符串类型,比如小说信息;
blob:字节类型,保存文件信息(视频,音频,图片);
date:日期类型,格式为:yyyy-MM-dd;
time:时间类型,格式为:hh:mm:ss
timestamp:时间戳类型 yyyy-MM-dd hh:mm:ss 会自动赋值
datetime:日期时间类型 yyyy-MM-dd hh:mm:ss

2.4.2 其他表操作

删除表:
drop table 表名;
当前数据库中的所有表
show tables;
查看表的字段信息
desc 表名;
增加列:在上面员工表的基本上增加一个image列。
alter table 表名 add 新列名 新的数据类型
修改job列,使其长度为60。
alter table 表名 change 旧列名 新列名 新的数据类型
列名name修改为username
删除image列,一次只能删一列。
alter table 表名 drop 列名
修改表名,表名改为user。
alter table 旧表名 rename 新表名;
查看表格的创建细节
show create table 表名;
修改表的字符集为gbk
alter table 表名 character set 编码方式

2.4.3 练习

表名 card(会员卡表)
列名 数据类型
cardid int
cardnum varchar(20)
regDate date
需求:
(1)创建该表
(2)将card表名修改为CardInfo
(3)添加delDate(注销时间) 列到表中
(4)将cardnum改为varchar(30)
(5)删除regDate列
(6)删除cardInfo表

在这里插入图片描述

2.5 DML操作

DML是对表中的数据进行增、删、改的操作。不要与DDL混淆了。

主要包括:INSERT 、UPDATE、 DELETE

小知识:
在mysql中,字符串类型和日期类型都要用单引号括起来。
空值:null

2.5.1 插入操作:INSERT
insert into 表名(列名) values(数据值);
  • 注意:
    1.多列和多个列值之间使用逗号隔开
    2.列名要和列值一一对应

  • 非数值的列值两侧需要加单引号
    常见错误: Data too long for column ‘stusex’ at row 1

  • 添加数据的时候可以将列名省略->当给所有列添加数据的时候

  • 此时列值的顺序按照数据表中列的顺序执行

insert into student values('李四',12,'1111',189.98,'2000-1-1','男','2007-1-1');
ALTER TABLE user CHARACTER SET gbk;
insert into student(stuname,stuage,stusex,birthday) values('张三1',18,'a','2000- 1-1');
  • 同时添加多行
insert into 表名(列名) values(第一行数据),(第二行数据),(),();
insert into student(stuname,stuage,stusex,birthday) values('张三3',18,'a','2000-1-1'), ('张三4',18,'a','2000-1-1'), ('张三5',18,'a','2000-1-1'), ('张三6',18,'a','2000-1-1'), ('张三7',18,'a','2000-1-1'), ('张三8',18,'a','2000-1-1');

注意:

  • 列名与列值的类型、个数、顺序要一一对应。
  • 参数值不要超出列定义的长度。
  • 如果插入空值,请使用null
  • 插入的日期和字符一样,都使用引号括起来。

示例:

create table emp(
    id int primary key,
    name varchar(100) not null,
    gender varchar(10) not null,
    birthday date, salary float(10,2),
    entry_date date, resume text
);

INSERT INTO emp(id,name,gender,birthday,salary,entry_date,resume)
    VALUES(1,'zhangsan','female','1990-5-10',10000,'2015-5-5-','goodgirl');
    
INSERT INTO emp(id,name,gender,birthday,salary,entry_date,resume) 
    VALUES(2,'lisi','male','1995-5-10',10000,'2015-5-5','good boy');
    
INSERT INTO emp(id,name,gender,birthday,salary,entry_date,resume)
    VALUES(3,'你好','male','1995-5-10',10000,'2015-5-5','good boy');
2.5.2 sql中的运算符
  • (1)算术运算符:+,-,*,/(除法),求余(%)
    示例:
    5/2
    5%2
    2/5
    2%5

-(2)赋值运算符:=
注:赋值方向:从右往左赋值
示例: name=‘张三’

  • (3) 逻辑运算符:
    and(并且),or(或者),not(取非)
    作用:用于连接多个条件时使用

  • (4) 关系运算符:

>,<,>=,<=,!=(不等于),=(等于),<>(不等于)

补充:查询所有数据:select * from 表名

在这里插入图片描述

2.5.3 修改(更新)操作:UPDATE

语法:UPDATE 表名 SET 列名1=列值1,列名2=列值2 … WHERE 列名=值

练习:
将所有员工薪水修改为5000元。 将姓名为zhangsan的员工薪水修改为3000元。 将姓名为lisi的员工薪水修改为4000元,resume改为normal。 将你好的薪水在原有基础上增加1000元。

update emp set salary=5000;
update emp set salary=3000 where name = 'zhangsan';
update emp set salary=4000,resume='normal' where name='lisi';
update emp set salary=salary+1000 where name='你好';

在这里插入图片描述

2.5.4 删除操作:DELETE

语法 : DELETE from 表名 【WHERE 列名=值】

练习 :
删除表中名称为zhangsan的记录。
删除表中所有记录。
使用truncate删除表中记录。
TRUNCATE TABLE emp;

  • DELETE 删除表中的数据,表结构还在;删除后的数据可以找回
  • TRUNCATE 删除是把表直接DROP掉,然后再创建一个同样的新表。删除的数据不能找回。执行速度比DELETE快。
delete from emp where name='lisi';
delete from emp;
truncate table emp;
2.5.5 练习题

Manager(管理员表):
mid 编号 int (主键)
mname 名字 varchar(20)
age 年龄 int
sex 性别 char(2)
password 密码 varchar(20)
address 地址 varchar(20)
phone 电话 varchar(20)
数据:
1 王子 18 男 123 北京 110
2 公主 20 女 456 上海 220
3 太子 23 男 789 南京 330
需求:
(1)创建表
(2)将数据插入到表中
(3)将王子的年龄修改为24
(4)将地址是南京的管理员改为天津
(5)将性别是女,并且年龄大于30的用户密码改为888888
(6)将所有用户的密码恢复最初设置111111
(7)将员工的电话中不是110的电话号码改为7654321
(8)将王子的年龄改为18,地址改为承德,性别改为女
(9)删除王子的信息
(10)删除地址在南京并且年龄大于60的员工信息
(11)删除不在北京的员工信息
(12)删除地址在北京或上海的员工信息
(13)删除电话号码是空的员工信息

create table Manager(
    mid int,
    mname varchar(20),
    age int,
    sex char(2),
    address varchar(20),
    phone varchar(20)
);

insert into manager values (1, '王子', 18, '男', '123', '北京', '110');
insert into manager values (2, '公主', 20, '女', '456', '上海', '220');
insert into manager values (3, '太子', 23, '男', '789', '南京', '330');

update manager age=24 where name='王子';
update manager set address='天津' where address='南京';
update manager set password='888888' where sex='女' and age>30;
update manager set password='111111';
update manager set phone='7654321' where phone!='110';
update manager set age=18,address='承德',sex='女' where mname='王子';

delete from manager where mname='王子';
delete from manager where address='南京' and age>60;
delete from manager where address!='北京';
delete from manager where address='北京' or address='上海';
delete from manager where phone is null;
2.5.6 小结

为空的条件:列名 is null or 列名=’’
注:两个单引号表示空字符串

日期类型值的区别:
date:yyyy-MM-dd (年月日)
time:hh:mm:ss (时分秒)
datetime:yyyy-MM-dd hh:mm:ss (年月日时分秒)

获取当前系统时间:now()

select now();

2.6 DCL

2.6.1 创建用户

create user 用户名@指定ip identified by 密码;

create user test123@localhost IDENTIFIED by 'test123'

create user 用户名@客户端ip identified by 密码; 指定IP才能登陆

create user test456@10.4.10.18 IDENTIFIED by 'test456'
2.6.2 用户授权
grant 权限1,权限2,........,权限n on 数据库名.* to 用户名@IP;

给指定用户授予指定指定数据库指定权限

grant all on . to 用户名@IP

给指定用户授予所有数据库所有权限

2.6.3 用户权限查询
show grants for 用户名@IP;
2.6.4 撤销用户权限
revoke 权限1,权限2,........,权限n on 数据库名.* from 用户名@IP;
2.6.5 删除用户
drop user 用户名@IP;

第三章 DQL数据查询

3.1 DQL数据查询语言

数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端。

查询返回的结果集是一张虚拟表。

查询关键字:SELECT

语法:

SELECT 列名 FROM 表名 【WHERE --> BROUP BY–>HAVING–> ORDER BY】

* 表示所有列

SELECT 要查询的列名称
FROM 表名称
WHERE 限定条件 /*行条件*/
GROUP BY grouping_columns /*对结果分组*/
HAVING condition /*分组后的行条件*/
ORDER BY sorting_columns /*对结果分组*/
LIMIT offset_start, row_count /*结果限定*/

接下来创建三张表用于后续查询:

1>创建学生表并添加数据

#创建表stu 
CREATE TABLE stu (
    sid CHAR(6),
    sname VARCHAR(50),
    age INT, gender VARCHAR(50)
);

#添加数据 
INSERT INTO stu VALUES('S_1001', 'liuYi', 35, 'male'); 
INSERT INTO stu VALUES('S_1002', 'chenEr', 15, 'female');
INSERT INTO stu VALUES('S_1003', 'zhangSan', 95, 'male');
INSERT INTO stu VALUES('S_1004', 'liSi', 65, 'female');
INSERT INTO stu VALUES('S_1005', 'wangWu', 55, 'male');
INSERT INTO stu VALUES('S_1006', 'zhaoLiu', 75, 'female');
INSERT INTO stu VALUES('S_1007', 'sunQi', 25, 'male');
INSERT INTO stu VALUES('S_1008', 'zhouBa', 45, 'female');
INSERT INTO stu VALUES('S_1009', 'wuJiu', 85, 'male');
INSERT INTO stu VALUES('S_1010', 'zhengShi', 5, 'female');
INSERT INTO stu VALUES('S_1011', 'xxx', NULL, NULL);

2>创建雇员表并添加数据

#创建雇员表
CREATE TABLE emp2(
    empno INT,
    ename VARCHAR(50),
    job VARCHAR(50),
    mgr INT,
    hiredate DATE,
    sal DECIMAL(7,2),
    comm decimal(7,2),
    deptno INT
);

#添加数据
INSERT INTO emp2 values(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp2 values(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp2 values(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp2 values(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp2 values(7654,'MARTIN','SALESMAN',7698,'1981-09- 28',1250,1400,30);
INSERT INTO emp2 values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO emp2 values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO emp2 values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO emp2 values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp2 values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO emp2 values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);

3>创建部门表并添加数据

CREATE TABLE dept(
    deptno INT,
    dname varchar(14),
    loc varchar(13)
);

#添加数据
INSERT INTO dept values(10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO dept values(20, 'RESEARCH', 'DALLAS'); 
INSERT INTO dept values(30, 'SALES', 'CHICAGO'); 
INSERT INTO dept values(40, 'OPERATIONS', 'BOSTON');

3.2 简单查询

查询所有列

SELECT * FROM stu;

查询指定列

SELECT sid, sname, age FROM stu;

3.3 条件查询

条件查询就是在查询时给出WHERE子句,在WHERE子句中可以使用如下运算符及关键字:
=、!=、<>、<、<=、>、>=; BETWEEN…AND; IN(set); IS NULL; AND;OR; NOT;

  • (1)查询性别为女,并且年龄50以内的记录
SELECT * FROM stu WHERE gender='female' AND age<50;
  • (2)查询学号为S_1001,或者姓名为liSi的记录
SELECT * FROM stu WHERE sid ='S_1001' OR sname='liSi';
  • (3)查询学号为S_1001,S_1002,S_1003的记录
    列名 in (列值1,列值2)
SELECT * FROM stu WHERE sid IN ('S_1001','S_1002','S_1003');
  • (4)查询学号不是S_1001,S_1002,S_1003的记录
SELECT * FROM stu WHERE sid NOT IN('S1001','S1002','S_1003');
  • (5)查询年龄为null的记录
SELECT * FROM stu WHERE age IS NULL;
  • (6) 查询年龄在20到40之间的学生记录
SELECT * FROM stu WHERE age>=20 AND age<=40;

或者:列名 between 开始值 and 结束值;//注意:1.开始值<结束值 2.包含临界值的

SELECT * FROM stu WHERE age BETWEEN 20 AND 40;
  • (7) 查询性别非男的学生记录
SELECT * FROM stu WHERE gender!='male';

或者

SELECT * FROM stu WHERE gender<>'male';

或者

SELECT * FROM stu WHERE NOT gender='male';
  • (8) 查询姓名不为null的学生记录
SELECT * FROM stu WHERE NOT sname IS NULL;

或者

SELECT * FROM stu WHERE sname IS NOT NULL;

3.4 模糊查询

当想查询姓名中包含a字母的学生时就需要使用模糊查询了。模糊查询需要使用关键字LIKE。

语法: 列名 like ‘表达式’ //表达式必须是字符串

通配符:

_(下划线): 任意一个字符
%:任意0~n个字符,‘张%’

  • (1)查询姓名由3个字构成的学生记录
SELECT * FROM stu WHERE sname LIKE '___';

模糊查询必须使用LIKE关键字。其中"“匹配任意一个字,3个”"表示3个任意字。

  • (2)查询姓名由5个字母构成,并且第5个字母为"i"的学生记录
SELECT * FROM stu WHERE sname LIKE '____i';
  • (3)查询姓名以"z"开头的学生记录
SELECT * FROM stu WHERE sname LIKE 'z%';

其中"%"匹配0~n个任何字母。

  • (4)查询姓名中第2个字母为"i"的学生记录
SELECT * FROM stu WHERE sname LIKE '_i%';
  • (5)查询姓名中包含"a"字母的学生记录
SELECT * FROM stu WHERE sname LIKE '%a%';

3.5 字段控制查询

  • (1)去除重复记录
    去除重复记录(两行或两行以上记录中系列的上的数据都相同),例如emp表中sal字段就存在相同的记录。当只查询emp表的sal字段时,那么会出现重复记录,那么想去除重复记录,需要使用DISTINCT:
SELECT DISTINCT sal FROM emp2;
  • (2)查看雇员的月薪与佣金之和
    因为sal和comm两列的类型都是数值类型,所以可以做加运算。如果sal或comm中有一个字段不是数值类型,那么会出错。
SELECT *,sal+comm FROM emp2;

comm列有很多记录的值为NULL,因为任何东西与NULL相加结果还是NULL,所以结算结果可能会出现NULL。下面使用了把NULL转换成数值0的函数IFNULL:

SELECT *,sal+IFNULL(comm,0) FROM emp2;
  • (3)给列名添加别名
    在上面查询中出现列名为sal+IFNULL(comm,0),这很不美观,现在我们给这一列给出一个别名,为total:
SELECT *, sal+IFNULL(comm,0) AS total FROM emp2;

给列起别名时,是可以省略AS关键字的:

SELECT *,sal+IFNULL(comm,0) total FROM emp2;

3.6 排序

语法: order by 列名 asc/desc
//asc 升序 desc 降序 默认不写的话是升序

  • (1) 查询所有学生记录,按年龄升序排序
SELECT * FROM stu ORDER BY age ASC;

或者

SELECT * FROM stu ORDER BY age;
  • (2) 查询所有学生记录,按年龄降序排序
SELECT * FROM stu ORDER BY age DESC;
  • (3) 查询所有雇员,按月薪降序排序,如果月薪相同时,按编号升序排序
    多列排序:当前面的列的值相同的时候,才会按照后面的列值进行排序
SELECT * FROM emp ORDER BY sal DESC,empno ASC;

3.7 聚合函数

聚合函数是用来做纵向运算的函数:

  • COUNT(列名):统计指定列不为NULL的记录行数;
  • MAX(列名):计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
  • MIN(列名):计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
  • SUM(列名):计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
  • AVG(列名):计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;
3.7.1 COUNT

当需要纵向统计时可以使用COUNT()。
查询emp表中记录数:

SELECT COUNT(*) AS cnt FROM emp;

查询emp表中有佣金的人数:

SELECT COUNT(comm) cnt FROM emp;

注意,因为count()函数中给出的是comm列,那么只统计comm列非NULL的行数。

查询emp表中月薪大于2500的人数:

SELECT COUNT(*) FROM emp WHERE sal > 2500;

统计月薪与佣金之和大于2500元的人数:

SELECT COUNT(*) AS cnt FROM empWHERE sal+IFNULL(comm,0) > 2500;

查询有佣金的人数,以及有领导的人数:

SELECT COUNT(comm), COUNT(mgr)FROM emp;
3.7.2 SUM和AVG

当需要纵向求和时使用sum()函数。

查询所有雇员月薪和:

SELECT SUM(sal) FROM emp2;

查询所有雇员月薪和,以及所有雇员佣金和:

SELECT SUM(sal), SUM(comm) FROM emp2;

查询所有雇员月薪+佣金和:

SELECT SUM(sal+IFNULL(comm,0)) FROM emp2;

统计所有员工平均工资:

SELECT AVG(sal) FROM emp2;
3.7.3 MAX和MIN

查询最高工资和最低工资:

SELECT MAX(sal), MIN(sal) FROM emp;

3.8 分组查询

当需要分组查询时需要使用GROUP BY子句,例如查询每个部门的工资和,这说明要使用部分来分组。

注意:如果查询语句中有分组操作,则select后面能添加的只能是聚合函数和被分组的列名

3.8.1 分组查询

查询每个部门的部门编号和每个部门的工资和:

SELECT deptno, SUM(sal) FROM emp2 GROUP BY deptno;

查询每个部门的部门编号以及每个部门的人数:

SELECT deptno,COUNT(*) FROM emp2 GROUP BY deptno;

查询每个部门的部门编号以及每个部门工资大于1500的人数:

SELECT deptno,COUNT(*) FROM emp2 WHERE sal>1500 GROUP BY deptno;
3.8.2 HAVING子句

查询工资总和大于9000的部门编号以及工资和:

SELECT deptno, SUM(sal) FROM emp2 GROUP BY deptno HAVING SUM(sal) > 9000;

注:having与where的区别:

  • 1.having是在分组后对数据进行过滤,where是在分组前对数据进行过滤
  • 2.having后面可以使用分组函数(统计函数)
    where后面不可以使用分组函数。

WHERE是对分组前记录的条件,如果某行记录没有满足WHERE子句的条件,那么这行记录不会参加分组;而HAVING是对分组后数据的约束。

3.9 LIMIT

LIMIT用来限定查询结果的起始行,以及总行数。

limit 开始下标,显示条数;//开始下标从0开始
limit 显示条数;//表示默认从0开始获取数据

  • 1.查询5行记录,起始行从0开始
SELECT * FROM emp2 LIMIT 0, 5;

注意,起始行从0开始,即第一行开始!

  • 2.查询10行记录,起始行从3开始
SELECT* FROM emp2 LIMIT 3, 10;
3.9.1 分页查询

如果一页记录为10条,希望查看第3页记录应该怎么查呢?

第一页记录起始行为0,一共查询10行; limit 0,10

第二页记录起始行为10,一共查询10行;limit 10,10

第三页记录起始行为20,一共查询10行; limit 20,10

pageIndex 页码值 pageSize 每页显示条数

limit (pageindex-1)*pagesize,pagesize;

查询语句书写顺序:select from where groupby having order by limit
查询语句执行顺序:from where group by having select order by limit

第四章 使用开发工具实现数据库操作

4.1 基于Navicat实现数据库操作

官方下载地址:

https://www.navicat.com.cn/download/navicat-premium

下载安装后进行数据库连接即可,可以保持创建的连接,之后打开数据库、表格等即可,其它的操作和普通软件一样:

在这里插入图片描述

你可以当成可视化操作数据库的软件,比手动在终端操作数据库要方便很多,当然不要忘记常用的终端操作,当你学了一些脚本可以尝试写一些脚本来自动化操作数据库。

Navicat是收费软件,所以在某些时候我们会找一些free版本替代,比如下面的SQLyog社区版。

4.2 基于SQLyog实现数据库操作

社区版下载地址GitHub:

https://github.com/webyog/sqlyog-community/wiki/Downloads

但很可惜它目前似乎还没有mac版本。

4.3 练习

下列练习我们使用navicat来进行练习以此熟悉工具操作和数据库操作。

练习1:
Manager(管理员表):
mid 编号 int (主键)
mname 名字 varchar(20)
age 年龄 int
sex 性别 char(2)
password 密码 varchar(20)
address 地址 varchar(20)
phone 电话 varchar(20)
数据:
1 王子 18 男 123 北京 110
2 公主 20 女 456 上海 220
3 太子 23 男 789 南京 330
(14)查询公主的所有信息
(15)查询年龄在18-30之间的管理员姓名
(16)查询表中所有的用户名和电话
(17)查询性别是男,名字是王子的个人信息
(18)查询出地址在北京和上海的员工信息

在这里插入图片描述

在这里插入图片描述

SELECT * FROM Manager WHERE mname = '公主';
SELECT * FROM Manager WHERE age > 18 and age < 30;
SELECT mname,phone FROM Manager;
SELECT * FROM Manager WHERE sex = '男' and mname = '王子';
SELECT * FROM Manager WHERE address='上海' OR address='北京';

练习2:
scores
stuid int 学生id
java int java成绩
mysql int mysql成绩
stuname varchar(20) 学生姓名
数据:
1 67 78 张三
2 87 55 李四
3 66 90 王五
4 98 78 赵六
5 80 88 田七
需求:
(1)对java成绩进行降序排序
(2)得到mysql成绩前三名
(3)得到java学生中最后一名的学生信息
(4)查询出两门成绩都优秀(>=80)的学生姓名
(5)查询出成绩在90分以上(>=90)的学生信息
(6)查询出每名学员的java,mysql,总成绩
(7)显示出每名学生的总分以及姓名

SELECT * FROM scores ORDER BY java DESC;
SELECT * FROM scores ORDER BY mysql DESC LIMIT 0,3;
SELECT * FROM scores ORDER BY java LIMIT 0,1;
SELECT stuname FROM scores WHERE mysql >= 80 AND java >= 80;
SELECT * FROM scores WHERE mysql >= 90 OR java >= 90;
SELECT java,mysql,java+mysql FROM scores;
SELECT stuname,mysql+java AS total_scores FROM scores;

练习3:
测试数据:
郭敬明 1371234567 北京 java S1101 89 1979-04-05
张三丰 1372839201 上海 数据库 S1102 67 1967-09-07
赵敏 1387839201 山东 mysql S1103 99 1987-09-07
Student2
stuname 姓名 varchar(20)
telphone 电话 varchar(20)
address 住址 varchar(20)
subject 科目 varchar(20)
stuNo 学号 varchar(20)
score 成绩 int
birthday 出生日期 date

1.要查询列 2.条件
a.查询住址为"山东"的学生姓名、电话、住址
b.查询名称中含有"数据库"字样科目信息
c.查询电话中以"1387"开头的学生信息
d.查询姓姜的,三个字的学生信息
e.查询学号为S1101的指定java,mysql科目考试成绩
f.查询出80后学员信息
g.查询出家庭住址在北上广的学生名字
h.显示成绩在第5-10名的学生名字和电话
i.查询分数在80-90之间并且在北京的学生

SELECT stuname,telphone,address from Student2 WHERE address = '山东';
SELECT subject FROM Student2 WHERE `subject` like '%数据库%';
SELECT * FROM Student2 WHERE telphone LIKE '1387%';
SELECT * FROM Student2 WHERE stuname LIKE '姜__';
SELECT score FROM Student2 WHERE stuNo = "S1101" AND `subject` = 'mysql' OR `subject` = 'java';
SELECT * FROM Student2 WHERE birthday like '198%';
SELECT stuname FROM Student2 WHERE address = '北京' OR address = '上海' OR address = '广州';
SELECT stuname,telphone FROM Student2 ORDER BY score DESC limit 4,5;
SELECT * FROM Student2 WHERE address = '北京' AND score BETWEEN 80 AND 90;

练习4:聚合函数练习
表:scores2
年级 grade varchar(10)
学号 stuno varchar(20)
考试时间 examDate date
科目 subject varchar(20)
成绩 score int
学期 xueqi int
数据:
S1 S1101 2015-02-03 C 89 1
S2 S1103 2015-03-03 JAVA 90 2
S3 S1102 2015-07-03 C 100 1
1.查询学生总人数
2.学号为S1101的学生第一学期考试总成绩,平均分
3.查询2013年3月22日科目"C"的最高分、最低分、平均分
4.查询2013年3月22日科目"C"及格学生的平均分
5.查询所有参加"C"科目考试的平均分
6.查看考java的人数

SELECT COUNT(*) FROM scores2;
SELECT SUM(score),AVG(score) FROM scores2 WHERE stuNo = 's1101' and xueqi = 1;
SELECT MAX(score),MIN(score),AVG(score) FROM scores2 WHERE examDate='2013-03-22' AND `subject` = "C";
SELECT AVG(score) FROM scores2 WHERE examDate='2013-03-22' AND `subject` = "C" AND score >= 60;
SELECT AVG(score) FROM scores2 WHERE `subject` = "C";
SELECT COUNT(*) FROM scores2 WHERE subject = "JAVA";

练习5:分组练习
表名:student
年级(grade) varchar(10)
学生姓名(name) varchar(10)
学时(xueshi) int --每人单个学时
参加考试(isexam) char(1) 是/否、
课程(subject) varchar(10)
分数(score) int
数据:
1 张三 10 是 java 99
1 李四 10 否 java 0
2 王五 20 是 mysql 88
2 赵六 20 是 mysql 77
2 王五 20 是 java 99
2 赵六 20 否 java 0
1 张三 10 是 mysql 88
练习:
a:查询每个年级的总学时数,并按照升序排列
b:查询每个参加考试的学员的平均分
c:查询每门课程的平均分,并按照降序排列

SELECT SUM(xueshi) FROM student GROUP BY grade;
SELECT AVG(score) FROM student GROUP BY name;
SELECT AVG(score) AS avgscore FROM student GROUP BY subject ORDER BY avgscore DESC;

练习6:综合练习
Student
科目名称 subjectName varchar(20)
学生姓名 stuname varchar(20)
学生地址 address varchar(20)
学生性别 sex char(2)
电子邮件 email varchar(30)
年级 grade varchar(10)
出生日期 birthday date
考试日期 examDate date
成绩 scores int
数据:
JAVA 张三 北京 男 123@qq.com S1 1990-03-04 2013-5-6 89
html 李四 上海 男 S2 1993-08-04 2014-5-6 87
html 王五 北京 男 123@qq.com S2 1990-03-04 2015-4-6 90
1.查询S2的科目名称
2.查询S2男同学的姓名和住址
3.查询无电子邮件的学生姓名和年级信息
4.查询出生日期在1993年之前的S2的学生姓名和年级信息
5.查询参加了日期为2014年5月6日的"HTML"科目考试的成绩信息

SELECT `subjectName` FROM Student WHERE grade = "S2";
SELECT stuname,address FROM Student WHERE grade = "S2" AND sex = '男';
SELECT stuname,grade FROM Student WHERE email = '';
SELECT stuname,grade FROM Student WHERE YEAR(birthday) < 1993 AND grade = 's2';
SELECT scores FROM Student WHERE DATE(examDate) = '2014-05-06' AND subjectName = 'html';

练习7:

新入职的程序员冯帅被公司安排去跟一个学生管理系统的项目,项目组长安排他去主要负责数据库部分
的所有操作,日常数据的维护和根据需求进行数据查询。可冯帅之前并没有接触过数据库,那就抓紧时间学
习一下数据库,把组长安排的 sql 补充一下吧!

  • 数据表: 年级表(grade):年级 id(主键-gradeid),年级名称(gname)
  • 成绩表(score):id(主键-scoreid),学员编号(stuno),科目 id(subjectid),分数(score),考试时间(examtime)
  • 学生表(student):学生编号(主键-stuid),学生姓(stuname),登录密码(password),性别(sex),年级 id(gid),电话(telphone),地址(address),出生日期(birthday),邮箱(email)
  • 科目表(subject):科目 id(主键-subjectid),科目名称(subjectname),学时(studycount),年级 id(gradeid)
DROP TABLE IF EXISTS `grade`;
CREATE TABLE `grade` (
  `gradeid` int DEFAULT NULL,
  `gname` varchar(255) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
  `scoreid` int DEFAULT NULL,
  `stuno` varchar(20) DEFAULT NULL,
  `subjectid` int DEFAULT NULL,
  `score` int DEFAULT NULL,
  `examtime` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `stuid` int DEFAULT NULL,
  `stuname` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `sex` varchar(255) DEFAULT NULL,
  `gid` int DEFAULT NULL,
  `telphone` varchar(255) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

DROP TABLE IF EXISTS `subject`;
CREATE TABLE `subject` (
  `subjectid` int DEFAULT NULL,
  `subjectname` varchar(255) DEFAULT NULL,
  `studycount` int DEFAULT NULL,
  `gradeid` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

需求:

1.grade 表增加一个阶段,“就业期”
2.将第三阶段的学生的 gradeid 改为就业期的 id
3.查询所有得了 100 分的学号
4.查询所有 1989 年出生的学生(1989-1-1~1990-1-1)
5.查询学生姓名为"金蝶"的全部信息
6.查询 subjectid 为 8 的科目考试未及格(60 分)的学号和成绩
7.查询第 3 阶段课时大于 50 的课程全部信息
8.查询 S1101001 学生的考试信息
9.查询所有第二阶段的女生信息
10."基于.NET 平台的软件系统分层开发"需要多少课时
11.查询"设计 MySchool 数据库"和"面向对象程序设计"的课时(使用 in)
12 查询所有地址在山东的学生信息
13 查询所有姓凌的单名同学
14.查询 gradeid 为 1 的学生信息,按出生日期升序排序
15.查询 subjectid 为 3 的考试的成绩信息,用降序排序
16.查询 gradeid 为 2 的课程中课时最多的课程信息
17.查询北京的学生有多少个
18.查询有多少个科目学时小于 50
19.查询 gradeid 为 2 的阶段总课时是多少
20.查询 subjectid 为 8 的课程学生平均分
21.查询 gradeid 为 3 的课程中最多的学时和最少的学时
22.查询每个科目有多少人次考试
23.每个阶段课程的平均课时
24.查询每个阶段的男生和女生个数(group by 两列)

use test_db;
-- 1. grade 表增加一个阶段,“就业期” 
insert into grade(gname) values('就业期');
-- 2.将第三阶段的学生的 gradeid 改为就业期的 id
update student set gid = (select gradeid from grade where gname="就业期") where gid = (select gradeid from grade where gname="第三阶段");
-- 3.查询所有得了 100 分的学号 
select stuno from score where score = 100;
-- 4.查询所有 1989 年出生的学生(1989-1-1~1990-1-1)
select * from student where YEAR(birthday)=1989;
-- 5.查询学生姓名为“金蝶”的全部信息
select * from student where stuname = "金蝶";
-- 6.查询 subjectid 为 8 的科目考试未及格(60 分)的学号和成绩
SELECT * from score where score>60 and subjectid=8; 
-- 7.查询第 3 阶段课时大于 50 的课程全部信息
SELECT * from subject where studycount>50 and gradeid=(select gradeid from grade where gname = "第三阶段");
-- 8.查询 S1101001 学生的考试信息
select * from score where stuno="S1101001";
-- 9.查询所有第二阶段的女生信息
select * from student where sex = "女" and gid=(select gradeid from grade where gname = "第二阶段");
-- 10.“基于.NET 平台的软件系统分层开发”需要多少课时
select sum(studycount) from subject where subjectname="基于.NET 平台的软件系统分层开发";
-- 11.查询“设计 MySchool 数据库”和“面向对象程序设计”的课时(使用 in)
select subjectname,sum(studycount) from subject where subjectname IN ('设计 MySchool 数据库','面向对象程序设计') GROUP BY subjectname;
-- 12 查询所有地址在山东的学生信息
select * from student where address ="山东";
-- 13 查询所有姓凌的单名同学
select * from student where stuname like "凌_";
-- 14.查询 gradeid 为 1 的学生信息,按出生日期升序排序
select * from student where gid = 1 order by birthday;
-- 15.查询 subjectid 为 3 的考试的成绩信息,用降序排序
select * from score WHERE subjectid = 3 ORDER BY score DESC;
-- 16.查询 gradeid 为 2 的课程中课时最多的课程信息
select * from subject where gradeid = 2 and studycount=(select max(studycount) from subject where gradeid = 2);
-- 17.查询北京的学生有多少个
select count(stuname) from student where address = "北京";
-- 18.查询有多少个科目学时小于 50
select count(*) from subject WHERE studycount <= 50;
-- 19.查询 gradeid 为 2 的阶段总课时是多少
SELECT sum(studycount) from subject WHERE gradeid = 2;
-- 20.查询 subjectid 为 8 的课程学生平均分   
select avg(score) from score where subjectid = 8;
-- 21.查询 gradeid 为 3 的课程中最多的学时和最少的学时
select max(studycount),min(studycount) from subject WHERE gradeid = 3;
-- 22.查询每个科目有多少人次考试
select subjectid,count(*) from score GROUP BY subjectid; 
-- 23.每个阶段课程的平均课时
select gradeid,avg(studycount) from subject GROUP BY gradeid;  
-- 24.查询每个阶段的男生和女生个数(group by两列)
select gid,sex,count(*) from student GROUP BY gid,sex;

可使用source命令在数据库中执行sql文件,即将上述sql命令保存到.sql文件中,然后使用source命令执行:

mysql> source $path/xxx.sql

在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称系统有问题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值