猿进化系列11——一文快速学会MYSQL

2020-07-28 16:45:36 浏览数 (1)

看完上一个章节,相信你已经掌握了JSPJSTLSERVLET相关技术的基础知识和用法,已经初步具备了制作动态网页的实力,今天我们来开启一门新的知识——数据库。

之前我们有提到网页提供的数据是动态的,我们的数据大多数是从数据库中存取的。数据库就是我们存取数据的一种工具,可以暂时理解为我们存取数据的一个仓库。一般来讲,在互联网行业MYSQL是最流行的数据库,没有之一。

结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。

SQL有以下特点:

1)SQL是一种关系型数据库的查询语言,所有的关系型数据库都支持,SQL可以在不同的数据库中使用。

2) 由于数据库厂商不同,不同的数据库厂商的数据库有本地方言,SQL在不同的数据库中的写法有一些差别。

SQL语句通常可以分为以下几类:

1)DDL(Data Definition Language数据定义语言) 比如建库,建表 (CREATE DATABSET CREAT TABLE)等等。

2)DML(Data Manipulation Language DML 数据操纵语言),比如对表中的记录进行增删改等操作(INSERT UPDATE DELETE)。

3)DQL(Data Query Language数据查询语言),比如对表中的查询操作(SELECT)

4)DCL(DCL Data Control Language数据控制语言),比如对用户的数据访问权限进行授权(GRANT INVOKE)。

作为一只开发猿,攻城狮,使用得最多的是DQL和DML,DDL和DCL的执行权限往往在DBA(数据库管理员)手中。

我们来看看怎么创建数据库:

CREATE DATABASE 数据库名 DEFAULT CHARACTER SET字符集名; (注意空格,字符集名 建议使用'utf8')

例子:

CREATE DATABASE test01 DEFAULT CHARACTER SET 'utf8'; (注意字符集名的单引号,utf8能比较好的支持中文)

创建数据库前可以判断下数据库是否存在

CREATE DATABASE IF NOT EXISTS test01 DEFAULT CHARACTER SET 'utf8';

想知道怎么查看数据库创建时的信息吗?

SHOW CREATE DATABASE 数据库名;(可以查询数据库创建时的信息)

例子:

SHOW CREATE DATABASE test01;

你还可以对数据库进行修改

ALERT DATABASE 数据库名 要修改的内容;

比如修改字符集

ALERT DATABASE test01 DEFAULT CHARACTER SET 'gbk'; (将数据库字符集转换为gbk)

注意:修改字符集这种事情,在实际工作中的线上程序中几乎不可能发生,字符集这种事情,大家应该先确定好,直接修改数据风险极大,大家了解即可。

如何使用一个数据库?使用数据库,代表当前要对哪个数据库做操作。

USE DATABASE 数据库名;

例子:

USE DATABASE test01;

查看当前正在使用的数据库:

SELECT DATABSE();

怎样删除一个数据库?

DROP DATABASE 数据库名;

例子:

DROP DATABASE test01;

注意:删除数据库作为语法掌握即可,数据库删除后,数据就没有了,大家了解即可!

相信大家都见过表格吧?有表头,有行数据。比如下面这个东西:姓名、年龄、性别、备注就是列名,通过这种方式,我们能直观的知道张三,胖虎,如花的信息,胖虎 19 男 胖胖哒,就是行数据,一行数据代表了一个人的信息。

姓名

年龄

性别

备注

二丫

19

漂亮

胖虎

20

胖胖哒

如花

21

难看

我们通常使用数据库的表(TABLE)来存放数据,TABALE也是有行列的,和表格类似,只是我们常常将表头叫做字段名。

我们怎样才能使用数据库建立数据表呢?在这之前,你得先了解数据库的数据类型。

比如1,2,3,这样的数字,我们通常称为整数,3.1415926这样的数字我们通常称为小数,2019-10-01 10:00:00这样的数据我们通常称为时间。我们在数据库中存放数据,也需要对数据进行分类。数据类型就是对数据的一个分类。下表是MYSQL数据库中的数据类型(不用刻意去记忆,用得多了就熟悉了)。

数据类型

存储空间

数据范围(含负数)

数据范围(不含负数)

用途

TINYINT

1 字节

(-128,127)

(0,255)

小整数值,一般用于存储状态啊,性别一类的数据,就几个值不用太变化,比如1表示男2表示女

SMALLINT

2 字节

(-32 768,32 767)

(0,65 535)

大整数值,不常用

MEDIUMINT

3 字节

(-8 388 608,8 388 607)

(0,16 777 215)

大整数值

INT或INTEGER

4 字节

(-2 147 483 648,2 147 483 647)

(0,4 294 967 295)

大整数值,视数据情况而定,需要考虑数据大小是否够用

BIGINT

8 字节

(-9,223,372,036,854,775,808,9 223 372 036 854 775 807)

(0,18 446 744 073 709 551 615)

极大整数值,如果用作主键对于整型数据,推荐使用BIGINT,INT太小不够用

FLOAT

4 字节

(-3.402 823 466 E 38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E 38)

0,(1.175 494 351 E-38,3.402 823 466 E 38)

单精度

DOUBLE

8 字节

(-1.797 693 134 862 315 7 E 308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E 308)

0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E 308)

双精度

DECIMAL

对DECIMAL(M,D) ,如果M>D,为M 2否则为D 2

依赖于M和D的值

依赖于M和D的值

小数值,推荐使用,数据较大,小数位可掌控

DATE

3

1000-01-01/9999-12-31

YYYY-MM-DD

日期值 没有时分秒

DATETIME

8

1000-01-01 00:00:00/9999-12-31 23:59:59

YYYY-MM-DD HH:MM:SS

精确到秒

TIMESTAMP

4

结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07

YYYYMMDD HHMMSS

精确到毫秒 对时间有要求时推荐使用

CHAR

0-255字节

定长字符串

VARCHAR

0-65535 字节

变长字符串,常用,存储空间较为灵活

TINYBLOB

0-255字节

不超过 255 个字符的二进制字符串

TINYTEXT

0-255字节

短文本字符串

BLOB

0-65 535字节

二进制形式的长文本数据

TEXT

0-65 535字节

长文本数据

MEDIUMBLOB

0-16 777 215字节

二进制形式的中等长度文本数据

MEDIUMTEXT

0-16 777 215字节

中等长度文本数据

LONGBLOB

0-4 294 967 295字节

二进制形式的极大文本数据

LONGTEXT

0-4 294 967 295字节

极大文本数据

注意:[]的部分为可选部分,在创建表的时候可以不写,NOT NULL的含义是,是否允许为空,如果一个字段被设置为NOT NULL那么,这个字段必须有值。

PRIMARY KEY的意思是主键,所谓主键,就是指一张表里,一行记录的唯一标识,在一张表里主键是不允许重复的。

接下来打开你的SQLyog,我们来建立一张表,我们用一行数据来表示学生的基本信息:

编号,姓名,性别,年龄,入学时间备注:

CREATE TABLE `test01`.`student`(

`ID` BIGINT(21) NOT NULL AUTO_INCREMENT COMMENT '编号,主键',

`name` VARCHAR(50) COMMENT '姓名',

`sex` TINYINT(4) COMMENT '性别(1男2女)',

`age` TINYINT(4) COMMENT '年龄',

`admission_date` TIMESTAMP COMMENT '入学时间',

`remark` VARCHAR(200) COMMENT '备注',

PRIMARY KEY (`ID`)

) ENGINE=INNODB CHARSET=utf8;

注意:

COMMENT 后面是字段的备注,往往代表字段的说明,说明字段的真实含义,建议在建表的时候加上便于维护。

PRIMARY KEY (`ID`) 指定了ID作为主键

AUTO_INCREMENT代表自增,每次写入数据时,不写该字段,该字段默认加1.

ENGINE=INNODB CHARSET=utf8; 指定表的存储引擎为INNODB 字符集为utf8. (存储引擎:数据库存储数据的方式,暂时不提)

语句准备好了,直接执行就好。

如何查询建表语句?

SHOW CREATE TABLE 表名;

查看表结构:DESC 表名;

注意:在实际工作中,字段类型确定了轻易不会从一种类型转换到另一种类型,倒是可能扩展字段长度,大家在设计表的时候要考虑充分。真正的生产系统是轻易不会drop字段的,了解语法就好。

插入数据:

INSERT INTO 表名 (字段名1, 字段名2, 字段名3…) VALUES (值1, 值2, 值3);

值1,值2,值3分别对应字段名1 字段名2 字段名3的数据。

例子:

INSERT INTO student (name,sex,age,admission_date,remark) VALUES('张三',1,18,'2019-09-01','高个子');

再来一条:

INSERT INTO student (name,sex,age,admission_date,remark) VALUES('李四',1,18,NOW(),'矮个子');

NOW()时一个数据库函数,代表当前的时间,如果要取当前时间可以用NOW()函数。

注意:字符类型的数据再需要单引号。

ID时自增的主键,所以不用在插入的时候写入数值,数据库会自动给它加一,书写字段名或值时多个字段或值用英文半角逗号分隔,最后一个字段名后是没有逗号的。

修改数据

UPDATE TABLE 表名 SET 字段1=新的值,字段2=新的值… [where 限定条件]

例子:

UPDATE student SET NAME='王五' ,sex=2,age=19 ,admission_date=NOW(),remark='妹子' WHERE ID=1;

注意:

UPDATE 语句使用时往往要加上限定语句 where 字段名=值,如果不加,修改的是全表数据,当然,如果你需要修改全部数据,不加也行。

删除数据

DELETE FROM TABLE 表名 [where 限定条件]

例子:

DELETE FROM student WHERE ID=1;

注意:

DELETE语句使用时往往要加上限定语句 where 字段名=值,如果不加,修改的是全表数据,当然,如果你需要修改全部数据,不加也行。

清空表:

TUNCATE TABLE 表名

注意:相当于drop一张表并创建一张新表,快速的清空一张表的记录,实际使用很少,一旦误操作,数据会丢失而且慎用。大家了解语法和作用就好。

查询一张表所有记录:

SELECT * FROM 表名;比如:

SELECT * FROM student;

查询部分字段:

SELECT 字段名1,字段名2,字段名3,…FROM 表名;

例子:

SELECT name,sex,age,admission_date,remark FROM student

改变显示的列名:

SELECT 字段名1 as 新名字,字段名2 as 新名字,字段名3 as 新名字,…FROM 表名;

SELECT name as xingming,sex as xingbie,age as nianling,admission_date as ruxueshijian,remark as beizhu FROM student

统计表里的记录条数:

SELECT COUNT(*) FROM student

count 时mysql 提供的函数,用于统计满足条件的记录数量。

看过了上面的查询语句,你已经有了简单的认知,接下来我们看看查询语句的写法:

SELECT [DISTINCT] 字段1 [AS 别名], ..., 字段N [AS 别名] FROM [库名.]表名

[

WHERE 约束条件

GROUP BY 分组依据

HAVING 过滤条件

ORDER BY 排序的字段

LIMIT 限制显示的条数

];

为了方便理解我们往student表中再增加几条记录

INSERT INTO student (name,sex,age,admission_date,remark) VALUES('赵二',1,18,NOW(),'矮个子');

INSERT INTO student (name,sex,age,admission_date,remark) VALUES('钱一',2,18,NOW(),'矮个子');

INSERT INTO student (name,sex,age,admission_date,remark) VALUES('孙六',1,20,NOW(),'矮个子');

增加后数据库里总共5条记录。

下面我们就语法结构做下讲解:

[]内的是非必须的语句,WHERE 我们之前已经用到了,用于限定符合条件的记录,where ID=1 表示ID等于1的记录,如果有多个限定条件可以用AND 或者是 or 连接,表示and同时满足的意思,or表示满足其中一个就好。

例子:

SELECT * FROM student WHERE id=2

SELECT * FROM student WHERE id=2 and sex=1 and age=18(注意空格)

SELECT * FROM student WHERE id=2 and sex=1 and age=19(注意空格)

and 表示同时满足,如果有一个条件不满足,则找不到记录!

SELECT * FROM student WHERE id=2 OR sex=1 OR age=19 (注意空格)

OR 表示或许的意思 只要一个条件满足就好

where语句后可以出现的条件符号:

> 、< 、<= 、>= 、= 、<>(含义同数学中的含义)

例子:查询年龄大于18岁的同学。

SELECT * FROM student WHERE age>18(其余符号,大家可以自主在SQLYog中练习)

BETWEEN...AND (表示一个数值范围)

例子:查询年龄18到20岁之间的同学。

SELECT * FROM student WHERE age BETWEEN 18 AND 20

IN( 集合)

例子:查询编号为2,3,4的同学

SELECT * FROM student WHERE ID IN(2,3,4)

图片里故意写了一个1,1的记录不存在,则不会查询出来,同样,如果2,3,4不存在也不会展示出来。

LIKE:模糊查询

例子

查询姓李的同学

SELECT * FROM student WHERE NAME LIKE'李%'

%表示通配符,李%表示‘李’开头的数据

查询备注中有“个子的同学”

SELECT * FROM student WHERE remark LIKE'%个子%'

两个%%中间表示只要包含某个特定字符就满足条件。

DISTINCT

查询年龄,按年龄去重

SELECT DISTINCT age FROM student

DISTINCT是按某个列名去重,如果加了其他数据不同的列名,达不到效果

GROUP BY 分组条件:

查询性别和名字,按性别分组:

SELECT sex,name FROM student GROUP BY sex

如果有多个分组条件用逗号分隔,查询性别和姓名,按性别和姓名分组

SELECT sex,name FROM student GROUP BY sex,name

HAVING:

对数据做过滤条件,如果语句中有group by 出现,则必须跟在group by后面,否则会有语法错误。

当语句里没有 group by时,和where 含义差不多,只是很少这样写。

查询性别和姓名,按性别和姓名分组后,并且要求sex=1(男性)的数据

SELECT sex,name from student group by sex , name having sex=1

ORDER BY

排序的意思,默认是升序(ASC),也可以指明是降序(DESC)

例子:

查询性别和姓名,按性别和姓名分组后,并且要求sex=1(男性)的数据,按姓名升序排列

SELECT sex,NAME FROM student GROUP BY sex,NAME HAVING sex=1 ORDER BY NAME

或者

SELECT sex,NAME FROM student GROUP BY sex,NAME HAVING sex=1 ORDER BY NAME ASC

查询性别和姓名,按性别和姓名分组后,并且要求sex=1(男性)的数据,按姓名降序排列

SELECT sex,NAME FROM student GROUP BY sex,NAME HAVING sex=1 ORDER BY NAME DESC

Limit

限制条件:

表示需要多少条数据

注意当limit条件后跟随1个数字时,表示最多返回满足条件的多少条数据。

当limit条件后跟随2个数字(数字间用逗号分隔),表示从满足条件的第几条数据开始,一共最多返回多少条数据。

特别注意:满足条件的记录条数0,代表第一条记录。

例子:

查询性别和姓名,按性别和姓名分组后,并且要求sex=1(男性)的数据,按姓名降序排列,只返回第一条数据

SELECT sex,NAME FROM student GROUP BY sex,NAME HAVING sex=1 ORDER BY NAME DESC LIMIT 1

查询性别和姓名,按性别和姓名分组后,并且要求sex=1(男性)的数据,按姓名降序排列,从第一条数据开始,返回两条数据

接下来我们讲解多表查询
准备工作

我们先建立两张表课程表

CREATE TABLE `test01`.`CLASS`(

`ID` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '课程编号',

`C_NAME` VARCHAR(50) NOT NULL COMMENT '课程名称',

PRIMARY KEY (`ID`)

) ENGINE=INNODB CHARSET=utf8;

给课程表增加记录

INSERT INTO CLASS (C_NAME) VALUES('MYSQL基础');

INSERT INTO CLASS (C_NAME) VALUES('JAVA基础');

INSERT INTO CLASS (C_NAME) VALUES('HTML基础');

学生选课表 用于表示学生和课程之间的选学关系

CREATE TABLE `student_class` (

`ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '学生课程表ID,主键',

`S_ID` bigint(20) DEFAULT NULL COMMENT '学生编号',

`C_ID` bigint(20) DEFAULT NULL COMMENT '课程编号',

PRIMARY KEY (`ID`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

注意:STUDENT_CLASS 表中的C_ID的值和CLASS表的ID对应

STUDENT_CLASS 表中的S_ID的值student表的ID对应

增加记录

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(2,1);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(2,2);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(2,3);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(3,2);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(3,3);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(4,3);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(5,1);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(5,2);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(5,3);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(6,2);

多表连接查询:当某次查询结果需要用到多个表的数据的时候,就需要用到多表连接查询。

最简单的表连接查询为内连接查询。

内连接语法 :

select 需要查询的字段名 from 表1 INNER JOIN 表2 ON 表1.字段名=表2.字段名 INNER JOIN 表三 ON

表1.字段名=表3.字段名(或者是表2.字段名=表3.字段名)

[

WHERE 约束条件

GROUP BY 分组依据

HAVING 过滤条件

ORDER BY 排序的字段

LIMIT 限制显示的条数

];

注意:按需求去做表连接查询,有几个连接就写几个连接,内连接会返回连接两边都同时满足的记录。

下面就是使用内连接查询的例子:

1. 查询每个学生的基本信息和选课情况。

例子:

SELECT s.*,c.* FROM student s INNER JOIN student_class cs ON s.id =cs.s_id INNER JOIN class c ON cs.c_id=c.id

内连接也可以用=号代替推荐第二中写法,较为简洁。

SELECT s.*,c.* FROM student s, class c, student_class cs WHERE s.ID=CS.S_ID AND CS.C_ID= c.ID

2. 查询编号为2的学生的基本信息和选课情况

SELECT s.*,c.* FROM student s, class c, student_class cs WHERE s.ID=CS.S_ID AND CS.C_ID= c.ID AND s.id= 2

LEFT JOIN (左外连接)

数据准备:往学生选课表中插入三条学生表中不存在的记录

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(7,1);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(7,2);

INSERT INTO STUDENT_CLASS (S_ID,C_ID) VALUES(7,3);

使用左外连接查询学生的选课情况:

SELECT c.* ,s.*,cs.* FROM student_class cs LEFT JOIN student s ON s.id =cs.s_id LEFT JOIN class c ON cs.c_id=c.id

左外连接:以写在JOIN关键字左边的表为基准,和JOIN关键字右边的表做关联,如果JOIN关键字左边表里的数据存在,则会作为一条记录存在,如果右边的表里不存在相关联的数据,则用NULL值补充。

右外连接

使用右外连接查询学生的选课情况:

SELECT c.* ,s.*,cs.* FROM student s RIGHT JOIN student_class cs ON s.id =cs.s_id RIGHT JOIN class c ON cs.c_id=c.id

右外连接:以写在JOIN关键字右边的表为基准,和JOIN关键字左边的表做关联,如果JOIN关键字右边表里的数据存在,则会作为一条记录存在,如果左边的表里不存在相关联的数据,则用NULL值补充。

注意:LEFT JOIN 和RIGHT JOIN的写法是看顺序的,大家看例子的时候要注意语句的例子的写法。

子查询
IN 子查询

SELECT 字段名 FROM 表名 where 字段名 IN(SELECT 字段名 FROM 表名)

例子:

查询已经选课的学生基本信息

SELECT * FROM student WHERE id IN(SELECT s_id FROM STUDENT_CLASS)

小作业

1. 查询编号为2的学生基本信息。

2. 查询姓王的学生基本信息。

3. 统计每个学生的名字和选择了几门课程。(小提示:内连接,分组)

4. 统计选择了两门课以上的学生姓名和选择的课程数量。(小提示:内连接,分组,having)

5. 统计选择了两门课以上的学生姓名和选择的课程数量,按选课数量倒排返回2条记录。(小提示:内连接,分组,having,limit)

6. 统计选择了两门课以上的学生姓名和选择的课程数量,按选课数量倒排从第一条记录开始返回2条记录。(小提示:内连接,分组,having,limit)

0 人点赞