本节目标
我们平常使用文件就可以保存数据了,为什么还要整个数据库呢?
那就要说到文件存储数据的缺点了:
文件存储和数据库存储数据的存储介质是磁盘和内存中,但是数据能够更加有效的管理数据,数据库可以提供远程服务,即提供远程连接来使用数据库,因此也称为数据库服务器.
数据库大体可以分为 关系型数据库 和 非关系型数据库
是指采用了关系模型来组织数据的数据库. 简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织 , 基于标准的SQL,只是内部一些实现有区别。常用的关系型数据库如:
- Oracle:甲骨文产品,适合大型项目,适用于做复杂的业务逻辑,如ERP、OA等企业信息系
统。收费。- MySQL:属于甲骨文,不适合做复杂的业务。开源免费。
- SQL Server:微软的产品,安装部署在windows server上,适用于中大型项目。收费
不规定基于SQL实现。现在更多是指NoSQL数据库,如 :
- 基于键值对(Key-Value):如 memcached、redis
- 基于文档型:如 mongodb
- 基于列族:如 hbase
- 基于图型:如 neo4j
关系型数据库与非关系型数据库的 区别:
关系数据库 | 非关系数据库 | |
---|---|---|
使用SQL | 是 | 不强制要求,一般不基于SQL实现 |
事务支持 | 支持 | 不支持 |
复杂操作 | 支持 | 不支持 |
海量读写操作 | 效率低 | 效率高 |
基本结构 | 基于表和列,结构固定 | 灵活性比较高 |
使用场景 | 业务方面的OLTP系统 | 用于数据的缓存,或基于统计分析的OLAP系统 |
注:OLTP(On-Line Transaction Processing)是指联机事务处理,OLAP(On-Line Analytical Processing)是指联机分析处理。
当我们安装配置好数据库后,MySql默认只允许本机服务器,使用root账户访问,如果要设置为任意ip都可以访问,按照下面操作进行
// 1.在本地服务器命令行中输入
mysql -u root -p
//2.如果有密码则输入后回车进入
//3.使用数据库
use mysql
//4.更新用户表的root账户,设置为任意ip都可以访问,密码修改为原root密码
update user set host="%",authentication_string=password('root') where user="root";
//5.刷新权限
flush privileges;
//6.退出
quit
代表指令: create, drop, alter
代表指令: insert,delete,update
DML中又单独分了一个DQL,数据查询语言,代表指令: select
DCL数据控制语言,主要负责权限管理和事务
代表指令: grant,revoke,commit
一. MySQL分为客户端和服务器
客户端和服务器之间是通过网络进行通信,那么有一个问题,现在一台服务器和客户端都在同一机器上,但是该机器没有联网,为什么客户端还可以访问服务器呢?
因为网卡和操作系统虚拟出来一个特殊的网卡,“环形网卡”,所以可以访问自己的主机上的服务器,只不过由于没有网络,访问不到其他主机.
二. MySQL内部组织数据结构
show databases;
create database 数据库名;
use 数据库名;
drop database 数据库名;
数据类型 | 大小 | 说明 | 对应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 |
Decimal | M/D最大值+2 | BigDecimal |
相关资料:
1字节(byte) = 8bit
对应整型范围:
2.1 有符号范围:-2^(类型字节数*8 - 1) ~2^(类型字节数 *8 - 1) - 1;比如int为4字节,范围为-2^31 ~ 2^31 -1
2.2 无符号范围:0到2 ^(类型字节数* 8)-1,如int就是2^32-1
SQL语言比Java早诞生,那时候编程界对类型的命名没有一个统计的约束.
浮点数按照IEEE754标准,规定浮点数如何存储.例如计算0.3+0.2结果不是0.5
Decimal相当于通过字符串的方式来表示浮点数,优势能够精确表示,精确计算;但是劣势是计算消耗时间更多,存储的空间也更多,所以是特别需要才使用它.
数据类型不区分大小写.
数据类型 | 大小 | 说明 | 对应java类型 |
---|---|---|---|
varchar(size) | 0-65,535字节 | 可变长度字符串 | String |
text | 0-65,535字节 | 长文本数据 | String |
mediumtext | 0-16 777 215字节 | 中等长度文本数据 | String |
blob | 0-65,535字节 | 二进制形式的长文本数据 | byte[] |
相关资料:
数据类型 | 大小 | 说明 | 对应Java类型 |
---|---|---|---|
datatime | 8字节 | 范围从1000到9999年,不会进行时区的 检索及转换 | java.util.Date、 java.sql.Timestamp |
timestamp | 4字节 | 范围从1970到2038年,自动检索当前时 区并进行转换。 | java.util.Date、 java.sql.Timestamp |
在创建表时,需要指明在哪一个数据库中创建,使用要使用:
use 数据库名;
接下来就是创建表:
create table 表名 (列名 类型, 列名 类型 ...)
注意:
例使用关键字show:
处理方法,加反引号:
show create table 表名;
查看当前数据库中有那些表:
show tables;
查看这个表里面的列和类型
desc 表名;
drop table 表名;
所谓的增删查改就是CRUD : Create(增加), Retrieve(查询),Update(更新),Delete(删除).
insert into 表名 values (值, 值, ...);
insert into 表名 (列名) values (值);
注意: 其他没有指定的列,其值为默认值;
insert into 表名 values (值, 值..);
注意: value_list 数量必须和定义表的列的数量及顺序一致
insert into 表名(列名,列名..) values (值, 值..);
注意:
--创建表
create table exam_result (
id int,
name varchar(20),
chinese decimal(3.1),
math decimal(3,1),
english decimal(3,1)
);
--插入测试数据
insert into exam_result (id, name, chinese, math, english) values
(1,'唐三藏', 67.0, 98.0, 56.0),
(2,'孙悟空', 87.5, 78.0, 77.0),
(3,'猪悟能', 88.0, 98.5, 90.0),
(4,'曹孟德', 82.0, 84.0, 67.0),
(5,'刘玄德', 55.5, 85.0, 45.0),
(6,'孙权', 70.0, 73.0, 78.5),
(7,'宋公明', 75.0, 65.0, 30.0);
select * from 表名;
注:
select 列名,列名... from 表名;
注:
在查询的时候带有表达式,让查询结果进行一些计算.
-- 表达式不包含字段
select id, name, 10 from exam_result;
注意事项:
当10输入进去是sql会在数据库中查询列名为10的列,有则输出,没有也会输出10,因为10本来就是一个表达式
-- 表达式包含一个字段
select name, chinese + 10 from exam_result;
-- 表达式包含多个字段
select name, chinese + math + english from exam_result;
注意事项:
2.2 可以使用
show warnings; 查看警告信息
--由于表达式的名称太复杂,所以可以使用起一个别名来表示它
select name, chinese + math + english as total from exam_result;
这里有两个数学成绩相同的:
--这时候就可以去重查询,会把查询结果相同的合并为一行
select distinct 列名 from 表名;
distinct后面可以指定多个列,那么此时只有列结果全部相同时,才会去重;
现在插入一段相同数据
insert into exam_result values (8, '唐三藏',67.0,98.0, 56.0);
然后多条件去重;
select distinct name, math from exam_result;
在查询过程中,对查询的结果进行排序;
select 列名 from 表名 order by 列名;
-- asc 为升序 (从小到大)
-- desc 为降序(从大到小)
-- 默认比较asc
注意事项:
1.使用表达式及别名排序
1.1 不使用别名版
1.2 使用别名版
1.1 null数据排序,视为比任何值都小,升序出现在最上面,降序出现在最下面
1.2 在表达式求值并排序时,任何数据与其结果是null
这里的math三个人相同,然后按照chinese降序比较(不行默认为降序).
比较运算符:
运算符 | 说明 |
---|---|
>, >=, <, <= | 大于,大于等于,小于,小于等于 |
= | 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL,相当于false |
<=> | 等于,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) |
案例:
-- 查询英语不及格的同学及英语成绩 ( < 60 )
select name, english from exam_result where english < 60;
-- 查询语文成绩好于英语成绩的同学
select name, chinese, english from exam_result where chinese > english;
-- 查询总分在 200 分以下的同学
select name, chinese+math+english as total from exam_result where chinese + math + english < 200;
注:where中可以使用表达式,不可以使用别名.
-- 查询语文成绩大于80分,且英语成绩大于80分的同学
select name, chinese,english from exam_result where chinese > 80 and english > 80;
-- 查询语文成绩大于80分,或英语成绩大于80分的同学
select name, chinese,english from exam_result where chinese > 80 or english > 80;
-- and 和 or 的优先级
select * from exam_result where chinese > 80 or math > 70 and english > 70;
结论: and的优先级比or高, 也就是说在表达式中优先判断and,如果不满足则判断or的另一个条件
-- 加() 后改变运算顺序
select * from exam_result where( chinese > 80 or math > 70) and english > 70;
范围查询
-- 查询语文成绩在 [80, 90] 分的同学及语文成绩
select name, chinese from exam_result where chinese between 80 and 90;
-- 也可以使用and实现
select name, chinese from exam_result where chinese >= 80 and chinese <= 90;
注:between…and… 是闭区间
-- 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
select * from exam_result where math in (58, 59, 98, 90);
-- 使用 OR 也可以实现
select * from exam_result where math = 58 or math = 59 or math = 98 or math = 90;
-- % 匹配任意多个(包括 0 个)字符
select name from exam_result where name like '孙%';
类似的: %孙 -> 匹配以孙结尾的数据; %孙% -> 匹配包含孙的数据; % -> 匹配所有数据.
-- _ 匹配严格的一个任意字符
select name from exam_result where name like '孙_';
类似的: 孙_ -> 匹配一个任意字符; 孙__ -> 匹配两个任意字符
-- 查询语文成绩为null
-- = 是不能够正确筛选
select * from exam_result where chinese = null;
-- <=> 可以正确筛选
select * from exam_result where chinese <=> null;
-- 也可以用 is null 来正确筛选
select * from exam_result where chinese is null;
-- 起始下标是0, offset是偏移量,相对于起始位置的偏移量. limit限制返回的结果条数
-- 从 0 开始,筛选 n 条结果
select 列名 from 表名 limit n;
-- 从 m 开始,筛选 n 条结果 ,建议使用写法1 更直观
写法1: select 列名 from 表名 limit n offset m;
写法2: select 列名 from 表名 limit m, n;
limit可以可where,order by等子句搭配使用,查询总成绩前4位
语法:
update 表名 set 列名 = 值 , 列名 = 值...where 子句 order by 子句 limit 子句
-- 将孙悟空同学的数学成绩变更为 80 分
update exam_result set math = 80 where name = '孙悟空';
-- 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
update exam_result set math = 80, chinese = 70 where name = '曹孟德';
-- 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
修改前:
注:
-- 将所有同学的语文成绩更新为原来的 0 倍
update exam_result set chinese = 0;
delete from 表名 where 条件;
-- 删除孙悟空同学的考试成绩
delete from exam_result where name = '孙悟空';
-- 删除整张表,只是数据清空
delete from exam_result;