字符串
- char 字符串固定大小的 0-255
- varchar 可变字符串 0-65535 常用的变量:String
- tinytext 微型文本 2^8-1
- text 文本串 2^16-1 保存大文本
时间日期—java.util.Date
- date: YYYY-MM-DD,日期格式
- time: HH:MM:SS,时间格式
- datetime: YYYY-MM-DD HH:mm:ss,最常用的时间格式
- timestamp: 时间戳,,1970.1.1到现在的毫秒数
Null
- 没有值,未知
- 不要使用null进行运算,结果依旧为null
unsigned
- 无符号的整数
- 声明了该列不能声明为负数
zerofill
- 0填充的
- int(3) => 5 => 005
- 不足的位数使用0来填充
自增
- 自动在上一条记录的基础上+1
- 通常用来设计唯一的主键,必须是整数类型
- 可以自己设计主键自增起始值和步长
非空
- 假设设置为not null,如果不给他赋值就会报错!
- 加入设置为null,如果不填写数值,默认就是null
默认
- 设置默认的值!
- 例如设置sex 默认值为男
每个表要有的字段(挖坑以后拓展)
- id 主键
- version 乐观锁
- is_delete 伪删除
- gmt_create 创建时间
- gmt_update 修改时间
创建数据库表
CREATE TABLE IF NOT EXISTS `runoob_tbl`( `runoob_id` INT UNSIGNED AUTO_INCREMENT, `runoob_title` VARCHAR(100) NOT NULL, `runoob_author` VARCHAR(40) NOT NULL, `submission_date` DATE, PRIMARY KEY ( `runoob_id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
查询语句
show create database [数据库名];
--查看创建数据库语句show create table [数据表名];
--查看数据表定义语句desc [数据库表名];
--显示表的结构
编辑表语句
alter table 表名 rename as 新表名;
--表名重命名alter table [表名] add [字段名] [列属性];
--添加字段
alter table [表名] modify [字段名] [列属性];
--修改字段约束alter table [表名] change [字段名] [新字段名] [列属性];
--字段重命名
alter table [表名] drop [字段名];
--删除表字段alter table if exists [表名];
--删除表(如果表存在再删除)
操作数据库注意点
- 所有名称尽量用``包裹,避免使用到了关键字
- 注释格式:- -
- sql关键字大小写不敏感,建议写小写
- 所有符号用英文
外键
- 物理外键
- 逻辑外键
- 删除有外键关系的表时,必须先删除引用别人的表(从表),在删除被引用的表(主表)
- 尽量使用程序去实现
DML语言:数据库操作语言
添加
insert into [表名] ([字段名01],[字段名02])values('[字段值01]','[字段值02]');
--插入单个值insert into [表名] ([字段名01],[字段名02])values('[字段值01]','[字段值02]'),('[字段值01]','[字段值02]');
--插入多个值- 如果主键自增可以省略主键
- 如果不写表的字段名,字段值 就会默认按字段名一一匹配
- 写的时候要保证数据和字段一一对应
修改
update [表名] set [修改字段名]='[修改字段值]' where [修改字段行的的某一字段名]=[修改字段行的的某一字段名的字段值]
; --修改一个属性update [表名] set [修改字段名01]='[修改字段值01]' [修改字段名02]='[修改字段值02]' where [修改字段行的的某一字段名]=[修改字段行的的某一字段名的字段值];
--修改多个属性update [表名] set [修改字段名]='[修改字段值]'
--将整张表的相应字段都改了,谨慎使用!!!- 语法
update 表名 set colnum_name = value,[colum_name = value,....] where [条件]
- 条件:where 子句 运算符 id 等于某个值 大于某个值 在某个区间修改
- 操作值会返回布尔值
- 注意:
- colnum_name => 数据的列
- 条件:筛选的条件,如果没有指定,则会修改所有列
- value:是具体的一个值,也可以是变量(例如当前的时间
current_time
)- 多个属性之间,使用英文逗号隔开
操作符 | 含义 | 范围 | 结果 |
---|---|---|---|
= | 等于 | 5=6 | false |
<>或!= | 不等于 | 5!=6 | true |
< | 小于 | – | – |
< | 小于等于 | – | – |
> | 大于 | – | – |
> | 大于等于 | – | – |
between … and … | 在某个范围内 | […,…] | – |
and | 我和你 && | – | – |
or | 我或你 | – | – |
删除
delete from [表名] where [字段名] = [字段值];
--删除指定数据delete from [表名]
--删除所有数据,慎用!!!
truncate table [表名]
--完全清空一个表,表的结构和索引约束不会变
- delete和truncate区别
- 相同:都能删除数据,都不会删除表结构
- 不同:truncate会重新设置自增列,计数器归零,不会影响事务(后面会讲)
- delete删除问题,重启数据库现象:
- InnoDB:自增列会从1开始(存在内存当中,断电即失)
- MyISAM:继续从上一个自增量开始(存在文件中的,不会丢失)
DQL(Data Query LANGUAGE:数据查询语言)
查询所有字段
查询指定字段
别名:给结果起名字,可以给字段起,也可以给表起
函数:拼接字符串
去重:distinct
查询MySQL版本号
计算结果
模糊查询
某列字段 + 1
Where条件语句
模糊查询 : 比较运算符
分页和排序
子查询
常用函数
- 数学运算
- 绝对值:
select ABS(-98.6);
- 向上取整:
select CEILING(1.2);
- 向下取整:
select floor(1.2);
- 0~1随机数:
select rand();
- 判断一个数的符号:
select sign(10);
- 字符串运算
- 返回字符数:
select char_length('你好');
- 合并字符串:
select concat('你','好');
- 替换字符串:
select insert('你好你好hello',1,2,'插入');
- 大写转小写:
select lower('SDSHJhjsak');
- 小写转大写:
select upper('dasdJLK');
- 找字符的位置(索引):
select instr('nihao','h');
- 替换出现的指定字符串:
select instr('nihao','h');
- 截取字符串:
select substr('hello',1,3);
- 反转字符串:
select reverse('hello');
- 时间和日期函数
- 获取当前日期:
select current_date();
/select cudate();
- 获取当前日期+时间:
select now();
- 获取其本地时间:
select localtime();
- 获取系统时间:
select sysdate();
- 实例
聚合函数
分组
MD5加密
什么是事务?
- 一个数据库事务通常包含对数据库进行读或写的一个操作序列
- 当一个事务被提交给了DBMS(数据库管理系统),则DBMS需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态(要么全执行,要么全都不执行);同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行
ACID原则
- 原子性(Atomicity):整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节
- 一致性(Consistency):一个事务操作前和操作后数据完整性保持一致
- 隔离性(Isolation):针对多个用户同时操作,主要是排除其他事务对本次事务的影响
- 持久性(Durability):事务一旦提交了就不可逆,被持久化到数据库中
事务的隔离级别
- 脏读:一个事务读取了另一个事务未提交的数据
- 不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同
- 虚读:在一个事务内读取到了别的事务插入的数据,导致前后读取不一样
代码实现
Mysql默认事务自动提交
set autocommit = 0; --关闭事务自动提交
set autocommit = 1; --开启事务自动提交
start transaction; --开始事务
commit; --提交事务
rollback; --回滚
savepoint; --设置事务保存点
rollback to savepoint; --回滚到保存点
release savepoint; --删除保存点
索引分类
- 主键索引(PRIMARY KEY)
- 唯一的标识,主键不可以重复,只有唯一的列作为索引
- 唯一索引(UNIQUE KEY)
- 避免重复的列出现
- 可以重复,多个列都可以表示为唯一索引
- 常规索引(KEY/INDEX)
- 默认的
- 全文索引(FullText)
- 在特定的数据库引擎下才有
- 快速定位
相关代码
show index from [表名]; --显示所有索引信息
alter table [表名] add fulltext index [索引名]([列名]); --增加全文索引
测试索引
- 创建函数生成100万条数据
CREATE DEFINER=`root`@`localhost` FUNCTION `createData`() RETURNS int BEGIN declare num int default 1000000; declare i int default 0; while i<num do insert into suoyin(`name`,`age01`,`age02`,`age03`,`age04`,`age05`) values(CONCAT('用户',i),floor(rand()*100),floor(rand()*100),floor(rand()*100),floor(rand()*100),floor(rand()*100)); -- DELETE FROM suoyin WHERE `NO` = i+1; set i = i+1; end while; return i; RETURN 0; END
索引原则
- 索引不是越多越好
- 不对经常变动的数据加索引
- 小数据量的表不加索引
- 一般在常用于查询的数据上加索引
索引的数据结构(留坑)
- Hash
- Btree
- innodb默认底层数据结构
用户管理
- 创建用户
create user user01 identified by '123456'; --创建user01的用户,密码为123456
- 修改密码(MySQL8.0之后取消了password函数)
set password = password('123456'); --修改当前用户密码为123456
set password for user01 = password('123456'); --修改user01用户密码为123456
- 重命名
rename user user01 to user02; --将user01用户名修改为user02
- 授权
grant all privileges on *.* to user02; --为用户user02授予所有库所有表的所有权限
show grants for user02; --查看user02用户权限
- 撤销权限
revoke all privileges on *.* from user02; --撤销用户user02所有库所有表的所有权限
- 删除用户
drop user user02; --删除user02用户
数据库备份
- 物理文件拷贝备份
- 数据库可视化工具手动导出备份
- 使用命令行导出(
mysqldump
,source
)
为什么使用数据规范化
- 信息重复
- 更新异常
- 插入异常
- 无法正常显示信息
- 删除异常
- 丢失有效信息
三大范式
- 第一范式
- 原子性:要求数据库的每一列都是不可分割的原子数据项
- 第二范式
- 满足第一范式
- 需要确保数据库每一列都和组件相关,而不能只与主键的某一部分相关
- 每张表只描述一件事情
- 第三范式
- 满足第二范式
- 确保数据表中的每一列数据都和主键直接相关,而不是间接相关
性能和规范性不能兼得
数据库驱动
- 驱动:声卡,显卡,数据库
- 驱动是应用程序和数据库之间连接的桥梁
JDBC
Statement对象
- 用于JDBC向数据库发送SQL
- 增删改查示例代码:
import java.sql.*; public class index { public static void main(String[] args) { try { Class.forName("com.mysql.cj.jdbc.Driver"); //加载驱动 String url = "jdbc:mysql://localhost:3306/mysqltest?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true"; String username = "root"; String pwd = "d9130513"; try { Connection connection = DriverManager.getConnection(url,username,pwd); //连接数据库 Statement statement = connection.createStatement(); //获得执行sql的对象 String sql01 = "select * from info"; String sql02 = "insert into info (no,studentno,name,age,sex,totel)values(5,1005,'小刘',23,2,13267656473)"; String sql03 = "update info set name='小邓' where no = 5"; String sql04 = "delete from info where no=5"; ResultSet resultSet01 = statement.executeQuery(sql01); //查询 while(resultSet01.next()){ System.out.print("no:" + resultSet01.getObject("NO") + " "); System.out.print("studentno:" + resultSet01.getObject("StudentNo") + " "); System.out.print("name:" + resultSet01.getObject("name") + " "); System.out.print("age:" + resultSet01.getObject("age") + " "); System.out.print("sex:" + resultSet01.getObject("sex") + " "); System.out.println("totel:" + resultSet01.getObject("totel")); } int num02 = statement.executeUpdate(sql02); //增加 if(num02 > 0){ System.out.println("增加成功!"); } int num03 = statement.executeUpdate(sql03); //修改 if(num03 > 0){ System.out.println("修改成功!"); } int num04 = statement.executeUpdate(sql04); //删除 if(num04 > 0){ System.out.println("删除成功!"); } resultSet01.close(); //释放连接 statement.close(); connection.close(); } catch (SQLException throwables) { throwables.printStackTrace(); System.out.println("2"); } } catch (ClassNotFoundException e) { e.printStackTrace(); System.out.println("1"); } } }