MySQL

 

 

 

1.初识MySQL

javaEE:企业级java开发 Web

前端 (页面 :展示,数据! )

后台( 连接点:连接数据库JDBC ,链接前端(控制试图跳转,和给前端传递数据))

数据库( 存数据,Txt ,Excel ,word)

 

离散数学 ,数字电路 ,体系结构 ,编译原理 。


1.2为什么学习数据库

1.岗位需求

2.大数据时代 ,得数据者得天下

3.被迫需求:存数据

4.数据库是所有软件体系中最核心的存在 DBA


 

1.3 什么是数据库

数据库(DB DataBase)

概念:数据仓库,软件,安装在操作系统(window,linux,mac,……) 之上!SQL,可以存储大量的数据,500万!

作用:存储数据,管理数据

DB(数据库 )

DBMS(数据库管理系统)


1.4数据库分类

关系型数据库:(SQL)

  • MySQL ,Oracle ,Sql Server, DB2, SQLlite

  • 通过表和表之间,行和列之间的关系进行数据的存储,学员信息表,……

 

非关系型数据库: (NO SQL) Not Only SQL

  • Redis , Mong DB

  • 非关系型数据库,对象存储,通过对象的自身的属性来决定。


 

DBMS(数据库管理系统)

  • 数据库的管理软件,科学有效的管理我们的数据.维护和获取数据:

  • MySQL,数据库管理系统


1.5 MySQL 简介

MySQL是一个 关系型数据库管理系统 ,

前世: 由瑞典MySQL AB 公司开发

今生:Oracle 旗下产品。

MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。

开源的数据库软件

体积小,速度快,总体拥有成本低,招人成本比较低,所有人必须会~

中小型网站,或者大型网站,集群

https://www.mysql.com


1.6 安装MySQL

1.解压

2.把这个包放到自己的电脑环境目录下~

3.配置环境变量

4.新建MySQL配置文件ini

[mysqld]
basedir=C:\Program Files\Java\mysql-8.0.25\
datadir=C:\Program Files\Java\mysql-8.0.25\data\
port=3306
skip-grant-tables

5.启动管理员

………………

1.7 安装SQLyog

1.安装

2.注册

3.打开链接数据库

4.新建一个数据库 renren-fast

 

 

 

 

 

5.新建一个表

 

 

 

 

字段 : id . name .age

 

 

 

 

命令行
MySQL  
show databases;    --查看所有的数据库

mysql> use renren-fost  --切换数据库中所用的表
describe student;  --显示数据库中所有的表信息

crezte database westos; -- 创建一个数据库

exit ; --提出链接

--单行注释(sql 的 注释)
/*
多行注释
*/

 

数据库 xxx语言 CRUD 增删改查 !

 

DDL 定义

DML 操作

DQL 查询

DCL 控制

2.操作数据库

2.1操作数据库(了解)

1.创建数据

create database if not exists renren-fost
创建     数据库         存在       数据库名称

2.删除数据库

drop database if exists renren-fost
除名                      

3.使用数据库

---tab 上面 , 如果 你的表名或者字段名是一个特殊字符,就需要带``
use renren-fost

4.查看数据库

show database

2.2数据库的列类型

数值

  • tinyint 十分小的数据 1个字节

  • smalint 较小的数据 2个字节

  • mediumint 中等大小的数值 3个字节

  • int 标准的整数 4个字节

  • bigint 较大的数据 8个字节

  • float 浮点数 4个字节

  • double 浮点数 8个字节(精度问题!)

  • decimal 字符串形式的浮点数 金融计算的时候,一般是使用decimal

字符串

  • char 字符串固定大小的 0~255

  • varcher 可变字符串 0~65535 常用的变量 String

  • tinytext 微型文本 2^8 -1

  • text 文本串 2^16 -1 保存文本

时间日期

java.util.Date

 

  • date YYY-MM-DD, 日期格式

  • time HH: mm: ss: 时间格式

  • datetime YYYY-MM-DD HH: mm: ss 最常用的时间格式

  • timestamp 时间戳 , 1970.1.1 到现在的毫秒数! 也较为常用!

  • yeear 年份表示

null

  • 没有值 ,

  • 注意,不要使用NULL进行运算,结果为NULL

2.3数据库的字段属性(重点)

Unsigned :

  • 无符号的整数

  • 声明该列不能声明为负数

 

zerofill:

  • 0填充的

  • 不足的位置,使用0来填充, int(3), 1 --001

 

自增: AUTO_INCREMENT

  • 通常理解为自增,自动在一条记录的基础上+1 (默认)

  • 通常用来设计唯一的主键~ index , 必须整数类型

  • 可以自定义设计主键自增的起始值和步长

 

非空 null not null

  • 假设设置为 not null ,如果不给它赋值,就会报错!

  • null ,如果不填写值,默认就是null

 

默认:DEFAULT

  • 设置默认值!

  • sex,默认值 为男,如果不指定该列的值,则会有默认的值!

注释:comment

/*
每个表,都必须存在一下五个字段! 未来做项目用的,表示一个记录存在意义!

id 主键
version 乐观锁
is_delete伪删除
gmt_create 创建时间
gmt_update 修改时间
*/

2.4创建数据库(重点)

--目标:创建一个数据库
/*
创建一个学生表(列,字段)使用SQL 创建
学号int 登录密码varcher(20) 姓名,性别varcher(2), 出生日期(datatime),家庭地址 ,email

注意点 使用英文() ,表的名称 和 字段 尽量使用 `` 括起来
字符串使用单引号括起来!
所有语句后面加, (英文的),最后一个不用加
*/

create TABLE if NOT exists `student`(
`id`INT(10) NOT NULL AUTO_INCREMENT COMMENT'学号',
`NAME` VARCHAR(10) NOT NULL DEFAULT '匿名' COMMENT'姓名',
`pwd`INT(10) NOT NULL DEFAULT(123456) COMMENT'密码',
`sex`VARCHAR(2) NOT NULL DEFAULT'男' COMMENT'性别',
`birthday` DATETIME DEFAULT NULL COMMENT'出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT'家庭地址',
`email` VARCHAR(50) DEFAULT NULL COMMENT'邮箱',
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

格式:

create TABLE [if NOT exists] `student`(
   '字段名' 列类型 [属性] [索引] [注释]
  ………………
  ……
   )

常用命令

 show  create database 表明   --查看创建数据库的语句
show  create table 表名 -- 查看表数据表的定义语句
desc   表名    --显示表的结构

2.5数据库的类型

-- 关于数据库引擎 
/*
INNODB 默认使用~
MYISAM 早些年使用
*/

 

 MYISMINNODB
事物支持 不支持 支持
数据行锁定 不支持 支持
外键约束 不支持 支持
全文索引 支持 不支持
表空间的大小 较小 较大,约2倍

常规使用操作:

  • MYISM 节约空间,速度较快

  • INNODB 安全性高 ,事物的处理,多表多用户操作

     

在物理空间存在的位置

所有的数据库文件都存在 data目录下

本质还是文件的存储!

MySQL 引擎在物理文件上的区别

  • INNODB在数据库表中只有一个*.frm文件,以及上级目录下的 ibdata1文件

  • MYISAM 对应文件

    • *.frm 表结构的定义文件

    • *.MYD 数据文件(data)

    • *.MYI 索引文件(idex)


 

设置数据库表的字符集编码

 

1.CHARSET=utf8

不设置的话,会是mysql 默认的字符集编码~(不支持中文!)

MySQL默认编码是Latin1,不支持中文

在my.ini中配置默认的编码

character-set-server=utf8

2.6修改和删除表

 

修改

--修改表名: ALTER TABLE  旧表名  rename AS 新表名
ALTER TABLE student rename AS student1
奥特    
--增加表的字段: ALTER TABLE 表名 ADD 字段名 列属性
ALTER TABLE student ADD age INT(3)

--修改表的字段(重命名,修改约束!)
--ALTER TABLE 表名 MODIFY 字段名 列属性 []
ALTER TABLE student MODIFY age varchar(11)  --修改约束

--ALTER TABLE 表名 change 旧名字 新名字 列属性[]
ALTER TABLE student change age age1 int(1)--字段重命名

--删除表的字段 :ALTER TABLE 表名 DROP 字段名
ALTER TABLE student DROP age1

 

删除

--删除表(如果表纯在在删除)
drop table if exists student1

3Mysql 数据管理

 

3.1 外键(了解即可)

方式一 : 在创建表的时候,增加约束(比较麻烦)

create table grade(
`gradeid` int(10) not null auto_increment comment'年级id',
`gradename` varchar(5) not null comment'年级名称',
PRIMARY KEY (`gradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*
学生表的gradeid 字段 要去引用年级表的 gradeid
定义外键key
给这个外键添加约束(执行引用) references引用
*/

CREATE TABLE if not exists `student` (
 `id` int(10) NOT NULL auto_increment  COMMENT 'id',
 `NAME` varchar(10) NOT NULL DEFAULT '匿名' COMMENT '姓名',
 `pwd` int(10) NOT NULL DEFAULT (123456) COMMENT '密码',
 `sex` varchar(2) NOT NULL DEFAULT '男' COMMENT '性别',
 `birthday` datetime DEFAULT NULL COMMENT '出生日期',
 `address` varchar(100) DEFAULT NULL COMMENT '家庭地址',
 `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
 PRIMARY KEY (`id`),
key `fk_gradeid` (`gradeid`),
constraint `fk_gradeid` foreign key (`gradeid`) references `grade`(`gradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

删除有外键关系的表的时候,必须要先删除引用别人的表(从表),在删除被引用的表(主表)

方法二:创建表成功后,添加外键约束

--创建表的时候没有外键关系
ALTER TABLE 'student'
ADD constraint `fk_gradeid` foreign key (`gradeid`) references `grade`(`gradeid`)

--alte table 表 add constraint 约束名 foreign key (作为外键的列) references 那个表(那个字段)

3.2DML语言(全部背下来)

数据库意义:数据存储,数据管理

DML语言:数据操作语言

  • insert

  • upadte

  • delete

3.3添加

insent

/*
插入语句(添加)
insert int 表名([字段名1 ,字段2,字段3])values('值1')('值2')('值3')
*/

insert into `grade`(`gradename`) values('大2')

/*
点击一下运行一下啊
由于主键自增 我们可以省略(如果不写表的字段 ,他就会一一匹配)
一般写插入的语句,我们一定要数据和字段一一对应 !

插入多个字段
*/

insert into `grade`(`gradename`) values ('大二')('大一')


insert into `student`(NAME`) values ('大一')

insert into `student`(`name`,`pwd`,`sex`) VALUES ('张三','aaaa','男')

insert into `student`(`name`,`pwd`,`sex`) values ('李四','AAAAA','男')

语法 : insert into 表名 ([字段名1, 字段2, 字段3]) values ('值1'),('值2'),('值3',.......)

注意事项

  • 字段和字段之间使用英文逗号隔离

  • 字段是可以省略的, 但是后面的值必须要一一对应,不能少

  • 可以同时插入 多条数据,values后面的值,需要使用 , 隔开即可 values (),(),..............

3.4修改

update 修改谁 (条件) set 原来的值=新值

/*
修改学员的 名字 ,
*/
update `student` set `name`='小儿子' where id= 1;

/*
不指定的情况下,会改变所有的表
*/

update `student` set `name`='小儿子'

/*
修改多个属性,逗号隔开
*/

update `student` set `name`='小儿子',`email`='257105791@qq.com',`birthday`='2000-02-01' where id= 1;

/*
语法
update 表名 set colnum_name =value ,[colnum_name=value.....] where [条件]
*/

条件 :where 子句 运算符 id 等于 某个值,大于某个值,在某个区间内修改......

操作符会返回 布尔值

操作符含义范围结果
= 等于   false
<>或!= 不等于   true
>      
<      
>=      
<=      
between 在某个范围内    
and 我和你 &&    
o'r 我或你 ||    
/*
通过多个条件锁定
*/

update `student` set `name` ='小儿子' where `name`='大儿子' and sex='男'

注意 :

  • colnm_name 是数据库的列 ,尽量带上``

  • 条件,筛选的条件 ,如果没有指定,则会修改所有的列

  • value ,是一个具体的值 ,也可以是一个变量

  • 多个设置的属性之间,使用英文 逗号隔开

3.5删除

delete 命令

语法: delete from 表名 [where 条件]

/*
删除数据(避免这样写,会全部删除)
*/

delete from `student`

-- 删除 指定 数据

delete  from `student` where id=1;

 

truncate 命令

作用:完全清空一个数据库,表的结构和索引约束不会变,

-- 清空 student 表
truncate `student`

delete 和 truncate 的区别

  • 相同点:都能删除数据, 都不会删除表结构

  • 不同

    • trunctae 重新设置自增列 计数器会归零

    • turncate 不会影响事物


了解即可

delete 删除问题,重启数据库,现象

innodb 自增列会重1开始 (存在内存当中,断电丢失)

MyISAM 继续从上一个自增量开始 (存在文件中的,不会丢失)

4.DQL查询 数据(重点)

4.1DQL

(Data Query LANGUAGE:数据库查询语言)

  • 所有的查询操作都用他 Select

  • 简单的查询,复杂的查询它都能作到~

  • 数据库中核心的语言,最重要的语句

  • 使用频率最高的语句

 

 

 

 

4.2指定查询字段

--查询全部的学生 select 字段 from 表 
select * from student

--查询 指定的 字段    
select `Student`,`Student` from student

--别名, 给结果起一个名字 AS 可以给字段起别名 ,也可以给表起别名
Select `stedent` AS 学号, `StudentName` AS 学生姓名 from Student  

--函数 concat (a,b) 起到拼接的作用
Select concat('姓名',StudentName) AS 新名字 From Student

语法:select 字段 .... from 表

有的时候,列名字不是那么的见名之意,我们起别名 AS 字段名 AS 别名 表名 AS 别名

 

 

去重 distinct

作用 :去除select 查询出来的结果中重复的数据,重复的数据只显示一条

--查询 一下有哪些同学参加了考试,成级
select *from result  --查询全部的考试成绩
select `Studentno` from result --查询有哪些同学参加了考试
select distinct `studentno`from result --发现重复数据,去重

数据库的列(表达式)

select version() --查询版本
select 100*31-1 AS 计算结果 --用来技术(表达式)
select @@auto_increment_increment --查询自增的布长(变量)

--学员考试成绩  -1
select `studentno`,`studentresult`-1 AS '提分后'from sesult

数据库中的表达式:文本值,列 ,null,函数,计算表达式, 系统变量....

select 表达式 from 表

4.3where条件子句

作用:检索数据中的符合条件的值

搜索的条件由一个或者多个表达试组成!结果布尔值

逻辑运算符

运算符语法描述
and &&  
or ||  
not !=   取反
select studentno, `Student` from result

--查询考试成绩在  95--100之间
select studentno, `StudentResult` from result
where studentresult>=95 and studentresult<=100

--and &&
select studentno,'studentresult' from result
where studentresult>=95 && studentresult<=100

--模糊查询(区间)
select student , 'studentresult' from result
where studentresult between 95 and 100

--除了1000号学生之外的同学的成绩
select studentno, `studentresult` from reslut
where studentnNO !=1000;

-- != not
select studentno, ·`studentresult` from result
where not studentno =1000

模糊查询 :比较运算符

 

运算符语法描述
IS NULL a is null 如果操作符为null,结果为真
IS NOT NULL a is not null 如果操作符不为null,结果为真
BETWEEN a between b and c 若a在b 和c之间 ,结果为真
Like a like b SQL匹配,如果a匹配b,则结果为真
in a in (a1,a2,a3.....) 假设a在a1,或者a2...其中的某一个值中,结果为真
=============模糊查询=========
--查询姓刘的同学
--like结合 %(代表0到任意个字符) _(一个字符)
select `studentNO`,`studentname` from `student`
where studentname like '刘%'

--查询姓刘的同学,名字后面只有一个字的
select `studemtno`,`student` from `student`
where studentname like '刘_'

--查询姓刘的同学,名字后面只有两个字的
select `studemtno`,`student` from `student`
where studentname like '刘__'

--查询名字中间有嘉字的同学 %嘉%
select `studemtno`,`student` from `student`
where studentname like '%嘉%'

--in (具体的一个或多个值)=======
--查询 1001,1002,1003, 号学员
select `studemtno`,`student` from `student`
where studentname in (1001,1002,1003);

--查询在北京的同学
select `studemtno`,`student` from `student`
where `adderss` in('安徽',)--里面要填具体地址


--null not null ==

--查询地址为空的学生 null ''
select `studemtno`,`student` from `student`
wshere address='' or address is null

--查询有出生日期的同学 不为空
select `studemtno`,`student` from `student`
where `BornDate` IS not null

--查询没有出生日期的同学 为空
select `studemtno`,`student` from `student`
where `dorndate` is null

4.4 联表查询

JION

-- ==============  联表查询 jion ===========

-- 查询参加了考试 的同学(学号,姓名 ,科目编号 ,分数)

select * from result
select * from student

/*
思路
1.分析需求,分析查询的字段来自哪些表,(链接查询)
2.确定使用那种链接查询? 一共7种
确定交叉点(这两个表中那个数据是相同的)
判断的条件:学生表中的 studentNO = 成绩表 student No
*/

select s.studentNO,studentName,SubjectNo,StudentResult  -- 选择合并的项目
FROM student AS S
INNER JOIN result AS r      -- AS 给表重新命名
ON s.studentNO = r.studentNO

-- Right Jion
select s.studentNO,studentName,SubjectNo,StudentResult  
FROM student S
Right JOIN result r      -- 空格 也可以 给表重新命名
ON s.studentNO = r.studentNO

-- Left Jion
select s.studentNO,studentName,SubjectNo,StudentResult  
FROM student S
Right JOIN result r      
ON s.studentNO = r.studentNO
操作描述
inner join 如果表中至少有一个匹配,就返回行
left join 会从左表中返回所有的值,即使右表中没有匹配
right jion 会从右表中返回所有的值,即使左表中没有匹配
-- jion (连接的表) on (判断的条件) 链接查询 
-- where 等值查询

-- 查询缺考的同学

select s.studentNO,studentName,SubjectNo,StudentResult  
FROM student S
left JOIN result r      
ON s.studentNO = r.studentNO
where StudentResult is null

-- 查询参加了考试 的同学(学号,姓名 ,科目编号 ,分数)

select s.studentNO,studentName,SubjectNo,StudentResult  
FROM student S
right JOIN result r      
ON r.studentNO = s.studentNO
inner join 'student' A
ON r.studentNO = A.studentNO

/*
我们要查询那些数据 select ..
从那几个表中查 from 表 xxx join 链接的表 on 交叉条件
假设存在 一种多张表查询 ,先查询两张表然后在增加
*/

自链接

自己的表和自己的表链接,核心: 一张表拆为两张一样的表即可

 

 

 

 

 

 

 

 

 

 

 

 4.5 分页和排序

排序

-- 排序  : 升序 ASC , 降序  DESC
-- order by 通过哪个字段排序,怎么排
-- 查询的结果根据 成绩降序 排序
select s.'Studetno','StudentName','SubjectName','StudentRecult'
from student s
inner join 'result' r
ON s.StudentNo = r.StudentNO
inner Join 'subject' sub
ON r.'SubjectNo' = sub .'SubjectNO'
where subjectName ='数据库-1'
ORDER BY studentresult ASC

分页

 -- 好处 缓解数据库压力,给人的体验更好,    
-- 还有 一种是 瀑布流

-- 分页,每页只显示五条数据
-- 语法:limit 起始值,页面大小
-- 页面应用:当前,总的页数,页面的大小

-- limit 0,5 1~5
-- limit 1,5 2~6
-- limit 6,5  
select s.'Studetno','StudentName','SubjectName','StudentRecult'
from student s
inner join 'result' r
ON s.StudentNo = r.StudentNO
inner Join 'subject' sub
ON r.'SubjectNo' = sub .'SubjectNO'
where subjectName ='数据库-1'
ORDER BY studentresult ASC
limit 5,5

-- 第一页 limit 0,5 (1-1)*5
-- 第二页 limit 5,5 (2-1)*5
-- 第三页 limit 10-5 (3-1)*5
-- 第N页 limit 0,5 (n-1)*pageSize,pageSize
-- [Pagesize : 页面大小]
-- [(n-1)*pagesize:起始值]
-- [n : 当前页]
-- [数据总数/页面大小 =总页数]

4.6子查询

/*============== 子查询 ================
什么是子查询?
   在查询语句中的WHERE条件子句中,又嵌套了另一个查询语句
   嵌套查询可由多个子查询组成,求解的方式是由里及外;
   子查询返回的结果一般都是集合,故而建议使用IN关键字;
*/

-- 查询 数据库结构-1 的所有考试结果(学号,科目编号,成绩),并且成绩降序排列
-- 方法一:使用连接查询
SELECT studentno,r.subjectno,StudentResult
FROM result r
INNER JOIN `subject` sub
ON r.`SubjectNo`=sub.`SubjectNo`
WHERE subjectname '数据库结构-1'
ORDER BY studentresult DESC;

-- 方法二:使用子查询(执行顺序:由里及外)
SELECT studentno,subjectno,StudentResult
FROM result
WHERE subjectno=(
   SELECT subjectno FROM `subject`
   WHERE subjectname '数据库结构-1'
)
ORDER BY studentresult DESC;

-- 查询课程为 高等数学-2 且分数不小于80分的学生的学号和姓名
-- 方法一:使用连接查询
SELECT s.studentno,studentname
FROM student s
INNER JOIN result r
ON s.`StudentNo` = r.`StudentNo`
INNER JOIN `subject` sub
ON sub.`SubjectNo` = r.`SubjectNo`
WHERE subjectname '高等数学-2' AND StudentResult>=80

-- 方法二:使用连接查询+子查询
-- 分数不小于80分的学生的学号和姓名
SELECT r.studentno,studentname FROM student s
INNER JOIN result r ON s.`StudentNo`=r.`StudentNo`
WHERE StudentResult>=80

-- 在上面SQL基础上,添加需求:课程为 高等数学-2
SELECT r.studentno,studentname FROM student s
INNER JOIN result r ON s.`StudentNo`=r.`StudentNo`
WHERE StudentResult>=80 AND subjectno=(
   SELECT subjectno FROM `subject`
   WHERE subjectname '高等数学-2'
)

-- 方法三:使用子查询
-- 分步写简单sql语句,然后将其嵌套起来
SELECT studentno,studentname FROM student WHERE studentno IN(
   SELECT studentno FROM result WHERE StudentResult>=80 AND subjectno=(
       SELECT subjectno FROM `subject` WHERE subjectname '高等数学-2'
  )
)

/*
练习题目:
   查 C语言-1 的前5名学生的成绩信息(学号,姓名,分数)
   使用子查询,查询郭靖同学所在的年级名称
*/

4.7、分组和过滤

题目:

-- 查询不同课程的平均分,最高分,最低分 ,平均分大于80
-- 前提:根据不同的课程进行分组

SELECT subjectname,AVG(studentresult) AS 平均分,MAX(StudentResult) AS 最高分,MIN(StudentResult) AS 最低分
FROM result AS r
INNER JOIN `subject` AS s
ON r.subjectno = s.subjectno
GROUP BY r.subjectno
HAVING 平均分>80;

/*
where写在group by前面.
要是放在分组后面的筛选
要使用HAVING..
因为having是从前面筛选的字段再筛选,而where是从数据表中的>字段直接进行的筛选的
*/

4.8select总结

 

 

 

 

5.Mysql函数

5.1常见 函数

1.数据函数

 SELECT ABS(-8);  /*绝对值*/
SELECT CEILING(9.4); /*向上取整*/
SELECT FLOOR(9.4);   /*向下取整*/
SELECT RAND();  /*随机数,返回一个0-1之间的随机数*/
SELECT SIGN(0); /*符号函数: 负数返回-1,正数返回1,0返回0*/

2.字符串函数

 SELECT CHAR_LENGTH('狂神说坚持就能成功'); /*返回字符串包含的字符数*/
SELECT CONCAT('我','爱','程序');  /*合并字符串,参数可以有多个*/
SELECT INSERT('我爱编程helloworld',1,2,'超级热爱');  /*替换字符串,从某个位置开始替换某个长度*/
SELECT LOWER('KuangShen'); /*小写*/
SELECT UPPER('KuangShen'); /*大写*/
SELECT LEFT('hello,world',5);   /*从左边截取*/
SELECT RIGHT('hello,world',5);  /*从右边截取*/
SELECT REPLACE('狂神说坚持就能成功','坚持','努力');  /*替换字符串*/
SELECT SUBSTR('狂神说坚持就能成功',4,6); /*截取字符串,开始和长度*/
SELECT REVERSE('狂神说坚持就能成功'); /*反转

-- 查询姓周的同学,改成邹
SELECT REPLACE(studentname,'周','邹') AS 新名字
FROM student WHERE studentname LIKE '周%';

日期和时间函数

SELECT CURRENT_DATE();   /*获取当前日期*/
SELECT CURDATE();   /*获取当前日期*/
SELECT NOW();   /*获取当前日期和时间*/
SELECT LOCALTIME();   /*获取当前日期和时间*/
SELECT SYSDATE();   /*获取当前日期和时间*/

-- 获取年月日,时分秒
SELECT YEAR(NOW());
SELECT MONTH(NOW());
SELECT DAY(NOW());
SELECT HOUR(NOW());
SELECT MINUTE(NOW());
SELECT SECOND(NOW());

3.系统信息函数

 SELECT VERSION();  /*版本*/
SELECT USER();     /*用户*/

5.2聚合函数

 

函数名称描述
COUNT () 计数
SUM 求和
AVG 平均值
MAX 最大值
MIN 最小值

 


函数名称描述COUNT()返回满足Select条件的记录总和数,如 select count(*) 【不建议使用 *,效率低】SUM()返回数字字段或表达式列作统计,返回一列的总和。AVG()通常为数值字段或表达列作统计,返回一列的平均值MAX()可以为数值字段,字符字段或表达式列作统计,返回最大的值。MIN()可以为数值字段,字符字段或表达式列作统计,返回最小的值。 -- 聚合函数
/*COUNT:非空的*/
SELECT COUNT(studentname) FROM student;
SELECT COUNT(*) FROM student;
SELECT COUNT(1) FROM student;  /*推荐*/

-- 从含义上讲,count(1) 与 count(*) 都表示对全部数据行的查询。
-- count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即不统计字段为null 的记录。
-- count(*) 包括了所有的列,相当于行数,在统计结果的时候,包含字段为null 的记录;
-- count(1) 用1代表代码行,在统计结果的时候,包含字段为null 的记录 。
/*
很多人认为count(1)执行的效率会比count(*)高,原因是count(*)会存在全表扫描,而count(1)可以针对一个字段进行查询。其实不然,count(1)和count(*)都会对全表进行扫描,统计所有记录的条数,包括那些为null的记录,因此,它们的效率可以说是相差无几。而count(字段)则与前两者不同,它会统计该字段不为null的记录条数。

下面它们之间的一些对比:

1)在表没有主键时,count(1)比count(*)快
2)有主键时,主键作为计算条件,count(主键)效率最高;
3)若表格只有一个字段,则count(*)效率较高。
*/

SELECT SUM(StudentResult) AS 总和  FROM result;
SELECT AVG(StudentResult) AS 平均分 FROM result;
SELECT MAX(StudentResult) AS 最高分 FROM result;
SELECT MIN(StudentResult) AS 最低分 FROM result;

5.3数据库级别的MD5加密(扩展)

一、MD5简介

1.什么是MD5?

2.主要增强算法复杂和不可逆性

3.MD5不可逆,具体的值的 MD5是一样的

4.MD5 破解网站的原理 ,背后有一个字典,MD5加密后的值,加密前的值

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。

-- ========= 测试MD5 加密 =========
-- 新建一个表 testmd5

CREATE TABLE `testmd5` (
 `id` INT(4) NOT NULL,
 `name` VARCHAR(20) NOT NULL,
 `pwd` VARCHAR(50) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

插入一些数据
-- 明文密码
INSERT INTO testmd5 VALUES(1,'kuangshen','123456'),(2,'qinjiang','456789')

如果我们要对pwd这一列数据进行加密,语法是:

update testmd5 set pwd = md5(pwd);  -- 也可以 Where id 选则一个或几个进行加密

如果单独对某个用户(如kuangshen)的密码加密:

INSERT INTO testmd5 VALUES(3,'kuangshen2','123456')
update testmd5 set pwd = md5(pwd) where name = 'kuangshen2';

插入新的数据自动加密

INSERT INTO testmd5 VALUES(4,'kuangshen3',md5('123456'));

查询登录用户信息(md5对比使用,查看用户输入加密后的密码进行比对)

SELECT * FROM testmd5 WHERE `name`='kuangshen' AND pwd=MD5('123456');

5.4小结

 -- ================ 内置函数 ================
-- 数值函数
abs(x)            -- 绝对值 abs(-10.9) = 10
format(x, d)    -- 格式化千分位数值 format(1234567.456, 2) = 1,234,567.46
ceil(x)            -- 向上取整 ceil(10.1) = 11
floor(x)        -- 向下取整 floor (10.1) = 10
round(x)        -- 四舍五入去整
mod(m, n)        -- m%n m mod n 求余 10%3=1
pi()            -- 获得圆周率
pow(m, n)        -- m^n
sqrt(x)            -- 算术平方根
rand()            -- 随机数
truncate(x, d)    -- 截取d位小数

-- 时间日期函数
now(), current_timestamp();     -- 当前日期时间
current_date();                    -- 当前日期
current_time();                    -- 当前时间
date('yyyy-mm-dd hh:ii:ss');    -- 获取日期部分
time('yyyy-mm-dd hh:ii:ss');    -- 获取时间部分
date_format('yyyy-mm-dd hh:ii:ss', '%d %y %a %d %m %b %j');    -- 格式化时间
unix_timestamp();                -- 获得unix时间戳
from_unixtime();                -- 从时间戳获得时间

-- 字符串函数
length(string)            -- string长度,字节
char_length(string)        -- string的字符个数
substring(str, position [,length])        -- 从str的position开始,取length个字符
replace(str ,search_str ,replace_str)    -- 在str中用replace_str替换search_str
instr(string ,substring)    -- 返回substring首次在string中出现的位置
concat(string [,...])    -- 连接字串
charset(str)            -- 返回字串字符集
lcase(string)            -- 转换成小写
left(string, length)    -- 从string2中的左边起取length个字符
load_file(file_name)    -- 从文件读取内容
locate(substring, string [,start_position])    -- 同instr,但可指定开始位置
lpad(string, length, pad)    -- 重复用pad加在string开头,直到字串长度为length
ltrim(string)            -- 去除前端空格
repeat(string, count)    -- 重复count次
rpad(string, length, pad)    --在str后用pad补充,直到长度为length
rtrim(string)            -- 去除后端空格
strcmp(string1 ,string2)    -- 逐字符比较两字串大小

-- 聚合函数
count()
sum();
max();
min();
avg();
group_concat()

-- 其他常用函数
md5();
default();

6.事务

6.1什么是 事务

要么都成功要么都失败

事务原则:ADIC 原则 原子性,一致性 ,隔离性,持久性 (脏读 ,幻读……)

 

 

 

 

 

1.原子性(Atomicity)

要么都成功 , 要么都失败

2.一致性(consistency)

事物前后的数据完整性要保证一致,1000

3.持久性(Durability)--事物提交

事物一旦提交则不可逆,被持久化到数据库中!

4.隔离性(lsolation)

事物的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事物的操作数据所干涉事务之间要相互隔离

隔离所导致的一些问题

脏读

指一个事务读取了另一个事务未提交的数据

不可重复读

在一个事务内读取表中的某一行数据,多次读取结果不同.(这个不一定是错误,只是某些场合不对)

虚读(幻读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致.

执行事务

-- ======================  事务  =======================

-- mysql 是默认开启事务自动提交的
set autocommit = 0    -- 关闭  
set autocommit = 1    -- 开启 (默认的)

-- 手动处理事务
set autocommit = 0  -- 关闭自动提交 处理事务的第一布

-- 事务开启
start transation -- 标记一个事务的开始,从这个之后的sql 都在同一个事务内

insert xx
insert xx

-- 提交:持久化(成功!)
commit

-- 回滚:回到的原来的样子(失败!)
rollback

-- 事务结束
set autocommit = 1  -- 开启自动提交 结束时候开启

-- (常识)
savepoint 保存点名 -- 设置一个事务的保存点
rollback to saveepoint 保存点名 -- 回滚到保存点
release savepoint 保存点名 -- 撤销保存点

模拟转账情景

 -- 转账
CREATE DATABASE `shop`CHARACTER SET utf8 COLLATE utf8_general_ciUSE `shop`

CREATE TABLE `account` (
`id` INT(11NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32NOT NULL,
`money` DECIMAL(9,2NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO account (`name`,`money`)
VALUES('A',2000.00),('B',10000.00)

-- 转账实现
SET autocommit 0-- 关闭自动提交
START TRANSACTION;  -- 开始一个事务,标记事务的起始点
UPDATE account SET money=money-500 WHERE `name`='A';  
UPDATE account SET money=money+500 WHERE `name`='B';
COMMIT-- 提交事务
rollback;  -- 回滚
SET autocommit 1-- 恢复自动提交

7.索引

索引的作用: 1.提高查询速度 2.确保数据的唯一性 3.是帮助Mysql 高效获取数据的数据结构

提取句子主干,就可以得到索引的本质:索引是数据结构

7.1 索引的分类

在一个表中 ,主键索引只能 有一个,唯一索引可以有多个

  • 主键索引 (Primary Key)

    • 唯一的标识 ,主键不可重复,只能有一个列作为主键

  • 唯一索引 (Unique Key)

    • 避免重复的列出现, 唯一索引可以重复,多个列都可以标识 唯一索引

  • 常规索引 ( Index/key )

    • 默认的,index. key 关键字来设置

  • 全文索引 (FullText)

    • 在特定的数据库引擎下才有 , MyISAM

  • 快速定位数据

 

基础语法

-- 索引的使用
-- 1.在创建表的时候给字段增加索引
-- 2.创建完毕后, 添加索引

-- 显示所有的索引消息
SHOW INDEX from student

-- 增加一个全文索引 (索引名) 列名
alter table school.student ADD  fulltext index `studentName`(`studentName`);

-- Explain 分析sql 执行的状况

explain select * FROM student ;-- 非全文索引

explain select * from student WHERE match(studentName) AGAINST('李')

7.2 测试索引

索引在小数据量的时候,用户不大,但是在大数据的时候,区别十分明显~

7.3索引原则

  • 索引不是越多越好

  • 不要对进程 变动的数据 加索引

  • 小数据量的表不需要加索引

  • 索引一般加在常用来查询的字段上!

索引的数据结构

Hash 类型的索引

btree:innoDB 的默认数据结构~

 

 

 

 

 

 

8.权限管理和备份

8.1 用户管理

SQL yog 可视化管理

 

SQL 命令操作

用户表:mysql .user

本质 :读这张彪进行增删改查

-- 创建用户 CREATE USER 用户名 IDENTIFIED BY '密码'
create  user student IDENTIFIED '123456'

-- 修改密码 (修改当前用户密码)
SET  PASSWORD = password('123456')

-- 重命名 rename user 原来名字 TO 新的名字
RENAME USER student  to studentname

-- 用户授权 ALL privileges 全部的权限 ,库 , 表
-- ALL privileges 除了给别人授权,其他都能够干
grant all privileges on *.* to studentname

-- 查询权限
show grants for studentname -- 查看指定用户的权限
show grants for root@localhost

-- root 用户权限 : GRANT all PRIVILEGES ON *.* TO 'root'@ 'localhost' with grant option

-- 撤销权限 Revoke 哪些权限 ,在哪个库撤销 , 给谁撤销
PEVOKE ALL PRIVILEGES *.* FROM studentname

-- 删除用户
drop user stdent

8.2 MySQL 备份

为什么要备份:

  • 保证重要的数据不丢失

  • 数据转移

Mysql数据库备份的文件

  • 直接 拷贝物理文件

  • 在Sqlyog 这种可视化工具手动导出

    • 在想要导出的表或者库中,右键,选择备份或导出

    •  

       

命令行备份

 

9.规范数据库设计

9.1为什么需要设计

当数据库比较复杂的时候,我们就需要设计了

糟糕的数据库设计:

  • 数据多余,浪费空间

  • 数据库插入和删除都会麻烦,异常 [屏蔽使用物理外键 ]

  • 程序的性能差

良好的数据库设计

  • 节省内存空间

  • 保证数据库的完整性

  • 方便我们开发系统

软件开发中,关于数据库的设计

  • 分析需求:分析业务和需求处理的数据库的需求

  • 概要设计:设计关系图 E-R图

  •  

设计数据库的步骤;(个人博客)

  • 收集客户需求

    • 用户表

    • 分类表

    • 文章表

    • 评论表

    • ………………

  • 标识实体 (把需求落地到每个字段)

  • 标识实体 之间的关系

    • user --> blog

    • user --> category

    • user -->user

    • links

网站 : cm ELement Ant Design Pro

9.2 三大范式

为什么需要数据规范化?

  • 信息重复

  • 更新异常

  • 插入异常

    • 无法正常 显示

  • 删除异常

    • 丢失有效的信息

 

 

三大范式

第一范式(1NF)

原子性 :保证每一个列不可再分

第二范式(2NF)

前提:在满足第一范式的情况下

每张表只描述一件事情

第三范式(3NF)

前提:在满足第一范式和第二范式的情况下

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

 

(规范数据库的设计)

 

规范性 和 性能的问题

  • 关联查询的表不得超过三张表

  • 考虑商业化的需求和目标,(成本,用户体验 !)数据库的性能更加重要

  • 在规范性能的问题的时候,需要适当的考虑一些规范性!

  • 故意给某些表增加一些冗余的字段 (从多表查询中变为单表查询)

  • 故意增加一些计算列(从大数据量降低为小数据量的查询:索引)

10,JDBC(重点)

10.1,数据库驱动

驱动:声卡 显卡 数据库

 

 

 

我们的程序会通过数据库 驱动 和 数据库打交道

 

10.2 JDBC

SUN 公司为了 简化开发人员的(对数据库的统一)操作,提供了一个(Java操作数据库的)规范,俗称 JDBC 这些规范的实现由具体的厂商去做

开发人员 主要掌握对接的问题即可

 

 

 

 

 

还需要 导入一个 数据库驱动包 mysql -connector-java-5.1.47.jar

10.3 第一个JDBC 程序

测试数据可

创建测试数据库

CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;

USE jdbcStudy;

CREATE TABLE `users`(
id INT PRIMARY KEY,
NAME VARCHAR(40),
PASSWORD VARCHAR(40),
email VARCHAR(60),
birthday DATE
);

INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)
VALUES(1,zhansan,123456,zs@sina.com,1980-12-04),
(2,lisi,123456,lisi@sina.com,1981-12-04),
(3,wangwu,123456,wangwu@sina.com,1979-12-04)

1.创建一个普通的项目

2.导入数据库驱动

ctrl+c ctrl+v

 

 

3.编写测试代码

     import java.sql.*;

//我的第一个JDBC 程序  
public class JdbcFirstDemo{
   public static void main(String[]args) throws ClassNotFoundException,SQLException {
       
       // 1.加载驱动
       Class.forName("com.mysql.jdbc.Driver"); // 固定写法, 加载驱动
       
       //2.用户信息和url
       // useUnicode=true&charaterEncoding=utf8&useSSL=true
       String url ="Jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding=utf8&useSSL=true";
       String username ="root";
       String password = "123456"
       //3.连接成功,数据库对象 Connection 代表数据库
       Connection connection =DriverManager.getConnection(url, username , passworld);  
       
       //4.执行SQL 的对象 Statement 执行sql的对象
       Statemet statement = connection.createStatement();
       
       //5.执行SQL的对象 去 执行SQL, 可能存在结果, 查看返回结果
       String sql ="SELECT * FROM users"  //编写sql
           
        ResultSet resultset = statement.executeQuery(sql); //返回的结果集,结果集中封装了我们全部的查询出来的结果  
       
       While (resultSet.next()){
           System.out.println("id=" + resultSet.getObject("id"))
           System.out.println("name=" + resultSet.getObject("NAME"))
           System.out.println("pwd=" + resultSet.getObject("PASSWORD"))
           System.out.println("email=" + resultSet.getObject("email"))
           System.out.println("birth=" + resultSet.getObject("birthday"))
      }
       
       
       //6.释放链接
       resultSet.close();
       statement.close();
       connection.close();    
       
  }
}

步骤总结

1.加载驱动

2.链接数据库DriverManger

3.获得执行sql的对象 Statement

4.获取返回的结果集

5.释放链接

 

Driver Manager

 

//DriverManager.registerDriver(new com.mysql.jdbc.Driver);
Class.forName("com.mysql.jdbc.Driver"); // 固定写法, 加载驱动

Connection connection=DriverManager.getConnection(url,username,password);

//connection 代表数据库
//数据库设置自动提交
//事务提交
//事务回滚
connection.rollback();
connection.commit();
connection.setAutocommit();

 

URL

 String url ="Jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding=utf8&useSSL=true";

//mysql --3306
//协议 ; //主机地址;端口号/数据库名?参数1&参数2&

//orlce --1521
//jdbc:orlce:thin:@localhost:1521:sid

 

Staement 执行SQL 的对象 PrepareStatement 执行SQL的对象

   String sql ="SELECT * FROM users"  //编写sql
       
 statement.executeQuery();//查询操作返回 Resultset
 statement.execute();//执行任何SQL
 statement.executeUpdate();// 更新. 插入 . 删除 .都是用这个,返回一个受影响的行数

 

Result Set 查询的结果集; 封装了所用的查询结果

获得指定的数据类型

resultSet.getObject(); //在不知道列类型的情况下使用
// 如果知道列的类型就使用指定的类型
resultSet.getString();
resultSet.getint();
resultSet.getFloat();
resultSet.getDate();

遍历 ,指针

resultSet.beforeirst(); //移动到最前面
resultSet.afterLast();  //移动到最后面
resultSet.next();       //移动到下一个数据
resultSet.previous();   //移动到前一行
resultSet.absolute(row);   //移动到指定行

释放资源

resultSet.close();
statement.close();
connection.close(); // 耗资源,用完关闭!

10.4 statement对象

jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删该查语句即可.

Statement对象的executeUpdatefan方式,用于向数据库发送增.删.改的sql语句,executeUpdatefan执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)

Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResulSet对象

 

CRUD操作-create

使用executeUpdate(String sql)方法完成数据添加操作,

Statemt st =coon.createStatement();
String sql ="insert into user (...) values(....)";
int num =st.executeUpdate(sql)
if(num>0){
    System.out.println("插入成功!!");
}    

CRUD操作 - delent

使用executeUpdate(String sql)方法完成数据添加操作,

Statemt st =coon.createStatement();
String sql ="delete from user where id=1";
int num =st.executeUpdate(sql)
if(num>0){
    System.out.println("删除成功!!");
}    

CRUD 操作-update

使用executeUpdate(String sql)方法完成数据添加操作,

Statemt st =coon.createStatement();
String sql ="update user set name='' where name=''";
int num =st.executeUpdate(sql)
if(num>0){
    System.out.println("修改成功!!");
}  

CRUD操作-read

使用executeUpdate(String sql)方法完成数据添加操作,

Statemt st =coon.createStatement();
String sql ="select * from user where id=1";
ResultSet rs =st.executeUpdate(sql)
while(rs.next){
  //根据获取的数据类型,分别调用rs的相应方法映射到java对象中
}  

 

 

 

 

 

 

 

 

 

 

posted on 2021-09-11 22:55  小白jva  阅读(46)  评论(0编辑  收藏  举报

导航