一、 数据库的操作
1.1 显示当前的数据库
大小写都可以!
show databases;
会返回一个默认的数据库,你们新安装的可能和我不一样,我的新建的有数据库;
1.2 创建数据库
主要使用:
create database [数据库名];
还有一个详细版:
CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] …]
create_specification:
[DEFAULT] CHARACTER SET charset_name
[DEFAULT] COLLATE collation_name
说明:
- [ ]是可选项
- 大写的表示关键字
- CHARACTER SET: 指定数据库采用的字符集 (ASCII码表 GBK…)
- COLLATE: 指定数据库字符集的校验规则
IF NOT EXISTSt
:如果数据库不存在就创建,如果数据库存在就什么都不干
MySQL要求,同一个MySQL服务器上,每个数据库的名字不可以重复~
如果一个数据库的名字已经存在,你再尝试创建一个同名数据库,就会报错~
加上IF NOT EXISTSt
即使同名也不会报错.
那么这玩意有没有用呢?
当然,虽然我们现在是一条条SQL语句,一个个写,但是在以后的工作中,更常见的是把一些SQL写到一个文件中,然后批量执行。
在批量执行的过程中如果个别SQL语句报错,后面的SQL就不能继续执行了
。
示列:
- 创建名为
test
的数据库
1.3 使用数据库
语法:
use 数据库名;
当前可能会有许多数据库,要想具体操作,就需要先选中一个数据库,然后再操作~
1.4 删除数据库
语法:
DROP DATABASE [IF EXISTS] db_name;
示例:
说明:
- 数据库删除以后,内部看不到对应的数据库,里边的表和数据全部被删除
课外话:
删除操作十分危险,在实际工作中,不应该使用drop命令来删除任何数据库!!!
一般测试数据库,删除问题不大,最多被领导骂一顿
如果你删除的是线上数据库问题可能非常严重!!! 极端情况可能要进去
二、 常用数据类型
2.1 数值类型:
分为整形和浮点型:
数据类型 | 大小 | 说明 | 对于java类型 |
---|---|---|---|
BIT[ (M) ] | M指定位数,默认为1 | 二进制数,M范围从1到64,存储数值范围从0到2^M-1 | 常用Boolean对应BIT,此时默认是1位,即只能存0和1 |
TINYINT | 1字节 | Byte | |
SMALLINT | 2字节 | Short | |
INT | 4字节 | Integer | |
BIGINT | 8字节 | Long | |
FLOAT(M, D) | 4字节 | 单精度,M指定长度,D指定小数位数。会发生精度丢失 | Float |
DOUBLE(M,D) | 8字节 | Double | |
DECIMAL(M,D) | M/D最大值+2 | 双精度,M指定长度,D表示小数点位数。精确数值 | BigDecimal |
NUMERIC(M,D | M/D最大值+2 | 和DECIMAL一样 | BigDecimal |
扩展资料:
数值类型可以指定为无符号(unsigned),表示不取负数。
但是官方文档上面已经明确写了,不建议这样使用.unsigned已被标记为“即将弃用”的状态。
为什么呢? 因为无符号容易溢出
1U - 2U => 变成一个非常大的整数…
介绍一下 FLOAT(M, D)的M 和 D是啥意思
M:有效数的长度
D:指小数位数
实例:
FLOAT(3, 1)
45.6 : 有效数3位 ,小数位一位
插入 4.56非法,插入456也非法~
介绍一下DECIMAL(M,D)
IEEE 754 标准 约定了float和double具体咋存的,导致了有些小数是不能精确表示.
由于这是一个二进制的科学计数法,只能精确表示如:0.5,0.25,0.125,0.375…这类能够精确表示
但是如果通过float或者double表示“钱‘’ 那么可能会遇见 19.99999999998 , 35.0000000002这些数字.
deimal 类型:
优势:能够更精确的表示小数
劣势:付出很多的时间和空间的代价
要是算钱更好的办法使用int
代替decimal 或者 double
因为钱一般都是精确到小数点后两位(分)
就直接使用int就行,钱的单位就是分。
2.2 字符串类型
数据类型 | 大小 | 说明 | 对应类型 |
---|---|---|---|
VARCHAR (SIZE) | 0-65,535字节 | 可变长度字符串 | String |
TEXT | 0-65,535字节 | 长文本数据 | String |
MEDIUMTEXT | 0-16 777 215字节 | 中等长度文本数据 | String |
BLOB | 0-65,535字节 | 二进制形式的长文本数据 | byte[] |
varchar(size):
size 表示这个字符串的最大长度 单位是字符(不是字节)
varchar(20),此时这个字段里面最大长度就是20个字符
汉字,一个汉字是一个字符 , 但是不一定是一个字节。
TEXT
:
没有参数 不是用户指定一个长度,会根据用户插入的数据来动态确定占用空间
MEDIUMTEXT :
和上面差不多,大小变大了
BLOB
一些典型的:图片 mp3 ,视频等格式,这些都属于二进制数据。
如果想把图片保存mysql 可以考虑使用blob类型~
blob类型能表示最大的是64kb.
那么图片肯定会超过64kb,如果真的要保存,一般是把图片以文件的形式放到硬盘上,然后在数据库中记录这个图片的路径。
2.3 日期类型
数据类型 | 大小 | 说明 | 对应类型 |
---|---|---|---|
DATATIME | 8字节 | 范围从1000到9999年,不会进行时区的检索及转换 | java.util.Date、java.sql.Timestamp |
TIMESTAMP | 4字节 | 范围从1970到2038年,自动检索当前时 | java.util.Date、java.sql.Timestamp |
这个两个类型也是都是非常常用的类型。用来表示时间日期(年月日时分秒)
timestamp
时间戳:
2021年11月21日 17:17:00 日常生活使用一个这样的字符串表示时间日期~~
计算机这样表示吗,非常不方便(占用更多空间,不方便时间/日期的换算)
时间戳:以1970年1月1日0时0分0秒为基准时刻~
有个小知识点:我们这个时间戳类型大小是4个字节,4个字节的表述数据范围是 -21亿 -> +21亿
可以去百度看一下当前时间戳是16亿多,也就是说 2038年这个timetamp类型就使用不了了,
现在我们使用时间戳尽量使用8个字节的版本,不要使用个字节的!!
三、表的操作
需要操作数据库中的表时,需要先使用该数据库:
use 数据库名;
3.1创建表
语法:
create table [表名] (列名1 列类型,列名2 列类型);
使用括号,把若干个列给包裹起来,表名列名随便取,但是要注意不可以和SQL中的关键字冲,比如create,table,drop,show…这些都是具有特殊含义关键字
如果非要使用表名列名为关键字的话,可以通过反引号链接: ``
e:要先选中数据库
可以看见我们创建了一个 haha 表 里面的字段有 id, name
3.2查看表结构
这个可以查看一下你的表结构,比如某个字段是什么类型 等等等等
desc 表名;
示例: 先use 这个数据库 然后在操作,如果不知道怎么看表 使用 show tables; 即可
上面就是 goods表的一个结构;
3.3 删除表
语法:
drop table [表名]
例:
– 删除 stu_test 表
drop table stu_test;
– 如果存在 stu_test 表,则删除 stu_test 表
drop table if exists stu_test;
删表和危险 大家要小心使用!!!
四、表的增删改查(基础)
4.1 CRUD
CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Delete)四个单词的首字母缩写
大家以后不要老是嫌弃公司的CRUD,这个是最基本的,我们还是要掌握的~~
4.2 新增(Create)
[ ] : 可有可无
语法:
INSERT [INTO] table_name [(column [, column] …)] VALUES (value_list) [, (value_list)] …
(1)单行数据 – 全列插入
案例:
为什么叫单行,是因为 省略了表名后面的列 ,但是插入的数据要有多少列插入多少数据
括号里面的数据要和列名一 一对应,列的数目要一致,类型要匹配, 上面的 1 是id,zahngsan是name, SQL中 单引号和双引号都是字符串。
如果插入中文报错请看这个篇文章:
(2)多行数据 – 全列插入
多行是指数目? 来看看下面的操作吧!
语法:
– 插入两条记录,value_list
数量必须和指定列数量及顺序一致
INSERT INTO student (id, sn, name) VALUES
(102, 20001, ‘曹孟德’),(103, 20002, ‘孙仲谋’);
当我们指定了插入具体的列,如果数量不对应,就会发生报错
一一对应才可以成功:
那么没有插入的位置是什么数据呢?
这里id默认是null,所以里面是null
上面是一个语句可以插入多个数据,那我们可不可以使用多个sql插入呢?答案是可以的。
但是咱们一般认为,一条语句,一次插入多个记录,效率要比多个语句每个插入一条记录要高很多。
课外话:
- 因为mysql是一个“客户端” “服务器”结构的程序 .用户在客户端输入的sql都会通过网络传输给服务器,由服务器来进行具操作~~
多个sql语句就会占用资源,越来越慢所以就是这个原因
4.3 查询(Retrieve)
4.3.1 全列查询
语法:查找所有的数据(所有的行和列)
查询语句有点多先讲最基本的
select * from 表名
案例:
这里可以看见刚刚使用插入语句也已经插入进去了
要注意:这个查询的结果是一个类似于"表"这样的结构,但是这这个表,是一个“临时表”,这个表仅仅是在内存里存了一下,接下来就打印,打印完了就没有了,不会持久化存储。
这个操作,如果在生产环境中,一定要注意使用,因为有可能数据太大了,拖慢服务器。
如果这些操作执行了,可以使用ctrl+c 终止操作~~
4.3.2 指定列查询
语法:
select [列名], [列名] from [表名];
案列:
这个比上面的那种要 好一点 ,但是还是架不住数据太大,所以要看下面的
4.3.3 查询字段为表达式
比如我们要查上面表的一个所有数据
语法:
– 表达式不包含字段
SELECT id, name, 10 FROM exam_result;
– 表达式包含一个字段
SELECT id, name, english + 10 FROM exam_result;
– 表达式包含多个字段
SELECT id, name, chinese + math + english FROM exam_result;
select name, chinese+math+english from exam_result;
结果就是三列相加,每一行的三个列相加~相加的结果不会影响到原来的结果。以上是针对列的操作。
4.3.4 别名
为查询结果中的列指定别名,表示返回的结果集中,以别名作为该列的名称,语法:
select [列名] [ as ] [ 别名] from 表名
案列:
也可以省略 as
4.3.5 去重:DISTINCT
针对某个指定的列,把相同的值的记录给去重~
– 98 分重复了 2个98
SELECT math FROM exam_result;
±-------+
| math |
±-------+
| 98 |
| 78 |
| 98 |
| 84 |
| 85 |
| 73 |
| 65 |
±-------+
7 rows in set (0.00 sec)
加上去重:
只有一个98.0
去重操作也可以针对多个列来去重。
不过要去重多个列的时候,要保证他们都一样
select distinct math,english from exam_result;
可以看见这个上面没有去重因为英语那一列不一样。
4.3.6 排序:ORDER BY
语法:
– ASC 为升序(从小到大)
– DESC 为降序(从大到小)
– 默认为 ASC
select … from 表名 order by 列名 【desc】;
1.没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序
- 什么意思呢?比如你查一下id 发现是 1 ,2 ,3 ,4 ,5 你认为他顺序的对的,是升序,但是不一定,如果后面进行了修改表,可能顺序就变了。
- NULL 数据排序,视为比任何值都小,升序出现在最上面,降序出现在最下面
3. 使用表达式及别名排序
查询同学及总分,由高到低
语句一:
SELECT name, chinese + english + math FROM exam_result
ORDER BY chinese + english + math DESC;
语句二:
SELECT name, chinese + english + math total FROM exam_result
ORDER BY total DESC;
4.可以对多个字段进行排序,排序优先级随书写顺序
查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
SELECT name, math, english, chinese FROM exam_result
ORDER BY math DESC, english, chinese;
4.3.7 条件查询:WHERE
条件查询适用范围非常广,一个SQL语句可以使用where 找到满意的结果。
where 后面跟上一些条件表达式,相当于一个“筛选的过程”
比较运算符:
运算符 | 说明 |
---|---|
>, >=, <, <= | 大于,大于等于,小于,小于等于 |
= | 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL |
<=> | 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1) |
!=, <> | 不等于 |
between a0 and a1 | 范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1) |
IN (option, …) | 如果是 option 中的任意一个,返回 TRUE(1) |
IS NULL | NULL |
IS NOT NULL | 不是 NULL |
LIKE | 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字 |
逻辑运算符:
运算符 | 说明 |
---|---|
AND | 多个条件必须都为 TRUE(1),结果才是 TRUE(1) |
OR | 任意一个条件为 TRUE(1), 结果为 TRUE(1) |
NOT | 条件为 TRUE(1),结果为 FALSE(0) |
注:
- WHERE条件可以使用表达式,但不能使用别名。
- AND的优先级高于OR,在同时使用时,需要使用小括号()包裹优先执行的部分
案列:
1. 查询英语不及格的同学及英语成绩 ( < 60 )
注意体会执行过程:执行select的时候就会先尝试遍历表中的每一条记录~ 遍历的时候会把当前的记录带入到比较条件中,来看看条件是否成立(true成立 false 不成立)放到结果的临时表里,不成立的直接pass
2. 查询语文成绩好于英语成绩的同学
SELECT name, chinese, english FROM exam_result WHERE chinese > english;
条件查询是很方便的进行列和列之间的比较的~(同一行数据)
3. 查询总分在 200 分以下的同学
where后面不可以使用as
4. 查询语文成绩大于80分,且英语成绩大于80分的同学
SELECT * FROM exam_result WHERE chinese > 80 and english > 80;
5. 查询语文成绩大于80分,或英语成绩大于80分的同学
SELECT * FROM exam_result WHERE chinese > 80 or english > 80;
注意:and 比 or 优先级高一点
范围查询:
BETWEEN … AND …
-
查询语文成绩在 [80, 90] 分的同学及语文成绩
使用大于小于也可以 效果一样
有人会想,既然可以搞,为什么要between and ,因为这个是一个高频的操作,我们要想SQL引擎可以很好的优化
IN
-
查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);
模糊查询:LIKE
% 匹配任意 多个(包括 0 个)字符
SELECT name FROM exam_result WHERE name LIKE ‘孙%’;-- 匹配到孙悟空、孙权
_ 匹配严格的 一个任意字符
SELECT name FROM exam_result WHERE name LIKE ‘孙_’;-- 匹配到孙权
如果匹配的是数值类型 也可以的 like ’ 9 %’
NULL 的查询:IS [NOT] NULL
– 查询 qq_mail 已知的同学姓名
SELECT name, qq_mail FROM student WHERE qq_mail IS NOT NULL;
– 查询 qq_mail 未知的同学姓名
SELECT name, qq_mail FROM student WHERE qq_mail IS NULL;
条件查询 不一定只在select出现 ,update delete都会出现
4.3.8 分页查询:LIMIT
查询结果比较多的时候,把结果分成许多“页”
如果一下子查出来,其实开销是很大
1.数据库服务器磁盘io
2.数据库客户端到数据库服务器的网络io
我们来看一下,下一个查询语句的意思
这个就是查看前3个的内容,下标是从0开始。
还可以使用
还可以这些简写
不过还是建议使用 offset 这样的,因为下面的这样不好区分什么是偏移量什么是页数
语法:
– 起始下标为 0
– 从 0 开始,筛选 n 条结果
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT n;
– 从 s 开始,筛选 n 条结果
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT s, n;
– 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT n OFFSET s;
4.4. 修改(Update)
语法:
update 表名 set 列名 = 值 ,列名 =值 where 条件;
update 会修改数据库服务器的硬盘的数据,update会把所有的符号条件修改
- 将孙悟空同学的数学成绩变更为 80 分
UPDATE exam_result SET math = 80 WHERE name = ‘孙悟空’;
2.将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
UPDATE exam_result SET math = 60, chinese = 70 WHERE name = ‘曹孟德’;
3.将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
UPDATE exam_result SET math = math + 30 ORDER BY chinese + math + english LIMIT
4.将所有同学的语文成绩更新为原来的 2 倍
UPDATE exam_result SET chinese = chinese * 2;
以上案例看看即可最基本
4.5. 删除(Delete)
语法:
delete from 表名 where 条件;
案列:
- 删除孙悟空同学的考试成绩
DELETE FROM exam_result WHERE name = ‘孙悟空’;
- 删除整张表数据 (如果不加条件就是删除整张表)
delete from 表名