java学习笔记(二十四) - MySQL数据库
java学习笔记(二十四) - MySQL数据库
执笔数据库
基本指令
1 | net start mysql //启动mysql服务 |
数据库三层结构
- 所谓的安装Mysql数据库,就是在主机安装一个数据库管理系统(DBMS:database manager system),这个管理程序可以管理多个数据库
- 一个数据库中可以创建多个表,以保存数据(信息)
- 普通表的本质仍然是文件
数据库的范式
- 第一范式:列不可再分
- 第二范式:一张表只表达一层含义(只描述一件事情)
- 第三范式:表中的每一列和主键都是直接依赖关系,而不是间接依赖
数据库设计的范式和数据库的查询性能很多时候是相悖的,我们需要根据实际的业务情况做一个选择:
- 查询频次不高的情况下,我们更倾向于提高数据库的设计范式,从而提高存储效率
- 查询频次较高的情形,我们更倾向于牺牲数据库的规范度,降低数据库设计的范式,允许特定的冗余,从而提高查询的性能
存储方式
- 表的一行称为一条记录,在Java程序中,一行记录往往用对象表示
SQL语句的分类
- DDL:数据定义语句[create表,库.….]
- DML:数据操作语句[增加insert,修改update,删除delete]
- DQL:数据查询语句[select ]
- DCL:数据控制语句[管理数据库:比如用户权限 grant revoke ]
数据库操作
创建数据库
- CHARACTER SET:指定数据库采用的字符集,默认utf8
- COLLATE:指定数据库字符集的校对规则(通常采用utf8_bin[区分大小写]、utf8_general_ci[不区分大小写],默认是utf8_general_ci)
- 规避关键字可以用反引号(`)
1 | CREATE DATABASE db01;//创建db01数据库 |
查看、删除数据库
1 | SHOW DATABASES;//显示数据库 |
备份和恢复数据库
备份数据库
- 在dos下执行
1 | mysqldump -u 用户名 -p -B 数据库1 数据库2 数据库n > 文件名.sql |
恢复数据库
- 进入SQLyog再执行
1 | Source 文件名.sql |
表
创建表
备份和回复表
1 | //备份数据库的表 |
修改表
1 | //修改表名 |
1 | // 修改job列,使其长度为60 |
表复制
- 自我复制数据(蠕虫复制)
1 | -- 表复制(蠕虫复制) |
显示表结构
1 | //显示表结构 可以查看表所有的列 |
Mysql常用的数据类型(列类型)
整数类型
- 在满足需求的情况下,尽量选者占用空间小的数据类型
1 | //定义无符号的整数 |
位类型
- bit字段显示时,按照位的方式显示
- 查询的时候仍然可以使用添加的数值
1 | //基本使用 |
小数
1 | FLOAT/DOUBLE[UNSIGNED]//float 单精度,double 双精度 |
字符串
1 | CHAR(size)//固定长度字符串,最大255字符 |
数据库crud
insert 添加数据
1 | //案例 |
update 修改数据
1 | //案例 |
delete 删除数据
1 | //案例 |
select 查询数据
1 | //案例 |
使用表达式对查询的列进行运算
1 | select name,(math + chinese + english) from students; |
给列取别名
1 | select name as '名字' from students; |
where 选择查询
比较运算符 | > < <= >= = <> != | 大于、小于、大于(小于)等于、不等于 |
---|---|---|
between…and… | 显示某一区间的值 | |
in(set) | 显示在in列表中的值,in(100,200) | |
like ‘张pattern’ not like | 模糊查询 | |
is null | 判断是否为空 | |
逻辑运算符 | and | 多个条件同时成立 |
or | 多个条件任一条件成立 | |
not | 不成立 |
order by 排序查询
1 | //案例 |
count 合计函数
1 | //案例 |
sum 求和
1 | // 统计一个班级语文、英语、数学各科的总成绩 |
AVG 平均值
1 | // 求一个班级总分平均分 |
Max/Min 最大/最小值
1 | // Max Min 函数的使用 |
group by 分组
1 | // 显示平均工资低于2000的部门号和它的平均工资//别名 |
- 使用having子句对分组后的结果进行过滤
1 | // 2. 显示平均工资低于2000的部门号和它的平均工资 |
字符串相关函数
CHARSET(str) | 返回字串字符集 |
---|---|
CONCAT(string2 [,….]) | 连接字符串 |
INSERT(string , substring) | 返回substring在string中出现的位置,没有就返回0 |
UCASE(string2) | 转换成大写 |
LCASE(string2) | 转换成小写 |
LEFT(string2, length) | 从string2中的左边起取length个字符 |
LENGTH(string) | string长度[按照字节] |
REPLACE(str , search_str, replace_str) | 在str中用replace_str替换search_str |
STRCMP(string1, string2) | 逐字符比较两个字符串 |
SUBSTRING(str, position [,length]) | 从str的position开始[从1开始计算], 取length个字符 |
LTRIM(string2)RTRIM(string2)trim | 去除前端空格或后端空格 |
1 | -- 字符串相关的函数的使用 |
数学相关函数
ABS(num) | 绝对值 |
---|---|
BIN(decimal_number) | 十进制转二进制 |
CEILING(number2) | 向上取整,得到比num2大的最小整数 |
CONV(number2, from_base, to_base) | 进制转换 |
FLOOR(number2) | 向下取整,得到比num2小的最大整数 |
FORMAT(number, decimal_place) | 保留小数位数 |
HEX(DecimalNumber) | 转十六进制 |
LEAST(number, number2[,….]) | 求最小值 |
MOD(numberator, denominator) | 求余 |
RAND([seed]) | 返回一个随机浮点值v,范围0≤v≤1.0**;诺已指定一个整数N,则它被用作种子值,用来产生重复序列** |
1 | -- 数学相关函数 |
时间日期相关函数
CURRENT_DATE() | 当前时间 |
---|---|
CURRENT_TIME() | 当前日期 |
CURRENT_TIMESTAMP() | 当前时间戳 |
DATE(datetime) | 返回datetime的日期部分 |
DATE_ADD(date2, INTERVAL d_value d_type) | 在data2中加上日期或时间 |
DATE_SUB(date2, INTERVAL d_value d_type) | 在data2中减去日期或时间 |
DATEDIFF(date1, date2) | 两个日期时间差(结果是多少天) |
TIMEDIFF(date1, date2) | 两个时间差(多少小时多少分钟多少秒) |
NOW() | 当前时间 |
YEAR、Month、DATE(datetime)、FROM_UNIXTIME() | 年月日 |
1 | -- 日期时间相关函数的使用 |
加密和系统函数
USER() | 查询用户 |
---|---|
DATABASE() | 数据库名称 |
MD5(str) | 为字符串算出一个MD5 32位的字符串, (用户密码)加密 |
PASSWORD(str) | 从原文密码str计算并返回密码字符串,通常用于对mysql数据库的用户密码加密 |
1 | -- 加密和系统函数使用 |
流程控制函数
IF(expr1, expr2, expr3) | 如果expr1为true,则返回expr2否则返回expr3 |
---|---|
IFNULL(expr1, expr2) | 如果expr1不为空,则返回expr1,否则返回expr2 |
SELECT CASE WHERE expr1 THEN expr2 WHERE expr3 THEN expr4 ELSE expr5 END;[类似多重分支] | 如果expr1为true,则返回expr2,如果expr2为true,返回expr4,否则返回expr5 |
1 | -- 流程控制语句 |
单表查询
- 即单张表查询
1 | -- 查询加强 |
limit分页查询
1 | -- 公式 |
1 | -- 按照雇员的empno号降序取出 每页显示5条记录 分别显示第3页 第5页对应的sql语句 |
数据分组
1 | -- 请统计各个部门的平均工资,并且是大于1000的,并且按照平均工资从高到纸排序, |
多表查询
- 基于多个表进行查询
笛卡尔集
在默认情况下,当两个表查询时,规则:
从第一张表中取出一行和第二张表中的每一行进行组合,返回结果[含有两张表的所有列]
一共返回的记录数第一张表行数 * 第二张表的行数
多表默查询返回的结果,称为笛卡尔集
解决方案:
- 添加过滤条件where
1 | SELECT ename, sal, dname,emp.deptno |
自连接
- 指在同一张表的连接查询[将一张表看做两张表]
1 | -- 多表查询 自连接 |
子查询
- 指嵌入在其他sql语句中的select语句,也叫嵌套查询
单行子查询
- 指只返回一行数据的子查询语句
1 | -- 子查询使用 嵌套查询 |
多行子查询
- 返回多行数据的子查询 使用关键字in
1 | -- 多行子查询 |
临时表查询
- 将子查询当做一张临时表
1 | SELECT temp.ename, emp.empno |
all操作符
1 | -- all |
any操作符
1 | -- 显示工资比部门30的其中一个高员工的工资高的员工姓名、工资和部门号 |
多列子查询
- 返回多个列数据
1 | -- 多列子查询 |
合并查询
union all
- 用于取得两个结果集的并集,使用该操作符时,不会取消重复行
1 | -- union all 将两个查询结果合并 不会去重 |
union
- 用于取得两个结果集的并集,使用该操作符时,会取消重复行
1 | -- union 将两个查询结果合并 会去重 |
外连接
左外连接
- 左侧的表完全显示
1 | -- 左外连接 |
右外连接
- 右侧的表完全显示
1 | -- 右外连接(显示所有成绩 如果没有名字匹配 显示空) |
Mysql约束
- 约束用于确保数据库满足特定的商业规则
primary key(主键)
一张表的主键一般情况下设计原则:与业务无关,无实际意义,使用自增链 AUOT_INCREMENT
- 用于唯一标示表行的数据,当定义主键约束后,该列不能重复,且不能为null
- 一张表最多只能有一个主键,但是可以有多个复合主键
- 主键的指定方式:
- 直接在字段名后指定:字段名 primary key
- 在表定义最后写:primary key(列名);
- 使用desc 表名 可以查看primary key 的情况
1 | CREATE TABLE t17 |
not null(非空)
- 列上定义了not null 表示插入数据时,必须为列提供数据
1 | create table student ( |
unique(唯一)
- 当该列定义了唯一约束,该列值不能重复
- 如果没有指定not null,则unique字段可以有多个null
- 一张表可以有多个unique字段
1 | CREATE TABLE t22 |
foreign key(外键)
- 用于定义主表和从表之间的关系:外键约束要定义在从表上,主表则必须具有主键约束或是unique约束,当定义外键约束后,要求外键列数据必须在主表的主键列存在或是为null
1 | -- foreign key 外键 |
check
- 用于强制行数据必须满足的条件
- mysql5.7目前还不支持check,只做语法校验,不会生效
1 | -- check 的使用 |
自增长
- 从1开始自动增长的整数
1 | //添加自增长方式 |
1 | -- 自增长 |
索引
- 添加索引可提高查询速率
原理
类型
- 主键索引(primary key):主键自动的为主索引
- 唯一索引(unique)
- 普通索引(indext)
- 全文索引(fulltext):适用于MyISAM,一般情况下不适用mysql自带的全文索引,而是使用全文搜索Solr和ElasticSearch(ES)
1 | -- mysql的索引使用 |
事务
- 用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败
事务和锁
- 当执行事务操作时(dml语句),mysql会在表上加锁,防止其它用户改表的数据.这对用户来讲是非常重要的
1 | //mysql数据库控制台事务的几个重要操作 |
1 | -- 事务操作 |
1 | //细节 |
1 | -- 事务细节 |
隔离级别
多个连接开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个连接在获取数据时的准确性。如果不考虑隔离性,可能会引发如下问题:脏读、不可重复读、幻读
脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读
- 不可重复读(nonrepeatable read):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生不可重复读。
- 幻读(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻读。
1 | -- mysql事务 隔离级别 |
- 全局修改
1 | //修改mysql.ini配置文件,在最后加上 |
acid特性
原子性(Atomicity)
- 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
一致性(Consistency)
- 事务必须使数据库从一个一致性状态变换到另外一个一致性状态
隔离性(lsolation)
- 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离
持久性(Durability)
- 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
表类型和存储引擎
介绍
- MySQL的表类型由存储引擎(Storage Engines)决定,主要包括MylSANinnoDB、Memory等。
- MySQL数据表主要支持六种类型,分别是:CSV、Memory、ARCHIVE、MRG MYISAM、MYISAM、 InnoBDB。
- 这六种又分为两类,一类是”事务安全型”(transaction-safe),比如:InnoDB;其余都属于第二类,称为”非事务安全型”(non-transaction-safe)[mysiam 和memory].
1 | //显示当前数据库支持的 存储引擎 |
特点
特点 | Myisam | Innodb | Memory | Archive |
---|---|---|---|---|
批量插入的速度 | 高 | 低 | 高 | 非常高 |
事务安全 | 支持 | |||
全文索引 | 支持 | |||
锁机制 | 表锁 | 行锁 | 表锁 | 行锁 |
存储限制 | 没有 | 64TB | 有 | 没有 |
B树索引 | 支持 | 支持 | 支持 | |
哈希索引 | 支持 | 支持 | ||
集群索引 | 支持 | |||
数据缓存 | 支持 | 支持 | ||
索引缓存 | 支持 | 支持 | 支持 | |
数据可压缩 | 支持 | 支持 | ||
空间使用 | 低 | 高 | N/A | 非常低 |
内存使用 | 低 | 高 | 中等 | 低 |
支持外键 | 支持 |
MyISAM不支持事务、也不支持外键,但其访问速度快,对事务完整性没有要求
InnoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是比起MylSAM存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。
MEMORY存储引擎使用存在内存中的内容来创建表。每个MEMORY表只实际对应一个磁盘文件。MEMORY类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用HASH索引。但是一旦服务关闭,表中的数据就会丢失掉,表的结构还在。
1 | -- 显示所有引擎 |
选择
- 如果你的应用不需要事务,处理的只是基本的CRUD操作,那么MylSAM是不二选择,速度快
- 如果需要支持事务,选择lnnoDB
- Memory存储引擎就是将数据存储在内存中,由于没有磁盘I./O的等待,速度极快。但由于是内存存储引擎,所做的任何修改在服务器重启后都将消失。(经典用法用户的在线状态().)
视图
- 视图是一个虚拟表,其内容由查询定义,视图包含列,其数据来自对应的基表
视图和基表的关系
基本使用
1 | //基本使用 |
细节
创建视图后,查询数据库文件,视图只有一个结构文件(形式:视图名.frm)
视图的数据变化会影响到基表,基表的数据变化也会影响到视图
- 视图中可以在使用视图
特点
- 安全。一些数据表有着重要的信息。有些字段是保密的,不能让用户直接看到。这时就可以创建一个视图,在这张视图中只保留一部分字段。这样,用户就可以查询自己需要的字段,不能查看保密的字段。
- 性能。关系数据库的数据常常会分表存储,使用外键建立这些表的之间关系。这时,数据库查询通常会用到连接(JOIN)。这样做不但麻烦,效率相对也比较低。如果建立一个视图,将相关的表和字段组合在一起,就可以避免使用JOIN查询数据。
- 灵活。如果系统中有一张旧的表,这张表由于设计的问题,即将被废弃。然而,很多应用都是基于这张表,不易修改。这时就可以建立一张视图,视图中的数据直接映射到新建的表。这样,就可以少做很多改动,也达到了升级数据表的目的。
Mysql管理
- mysql中的用户,都存储在系统数据库mysql中user表中
- host:允许登入的地址,localhost表示该用户只允许本机登入,也可以指定ip地址登入如:192.168.1.100
- user:用户名
- authentication_string:密码,是通过mysql的password()函数加密之后的密码
操作
1 | //创建用户 同时指定密码 |
mysql权限
给用户授权
语法
1 | grant 权限列表 on 库.对象名to'用户名'@'登录位置'[identified by'密码'] |
说明
1 | //1. 权限列表,多个权限用逗号分开 |
回收用户授权
1 | revoke 权限列表 on 库.对象名 from '用户名'@'登入位置'; |
权限生效指令
1 | FLUSH PRIVILEGES; |
细节
- 在创建用户的时候,如果不指定Host,则为%,%表示表示所有IP都有连接权限create user xxX
- 你也可以这样指定create user ‘xxx’ @’192.168.1.%’表示xxx用户在192.168.1.*的ip可以登录mysql
- 在删除用户的时候,如果host 不是%需要明确指定‘用户’@’host值’
案例
1 | -- 设学校环境如下:一个系有若干个专业,每个专业一年只招一个班,每个班有若干个学生。 |
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果