【狂神学习笔记】数据库
文章目录
- 关于外键
- DQL
- 联表查询
- 排序和分页
- 聚合函数
- 事务
- 索引
- 规范数据库设计
- 为什么需要数据库设计
- 三大范式
- JDBC(重点)
- statement对象
- PreparedStatement
- 事务
- 数据库连接池
- 对SELECT语句的理解
- 结合Excel生成重复性SQL语句
- 字符集使用:Database charset:utf8mb4 Database collation:utf8mb4_bin
- SQL中大小写不敏感,因此命名规则不再使用驼峰式命名,而使用增加下划线来进行分隔。
- SQL语句中表名和字段名通常使用``(Tab上)来包裹起来。
关于外键
关于外键。以前我设计数据库很喜欢定义外键,认为这就是数据库的分类思想,一个大表由一堆外键和小表关联起来的。今天听了狂神这节课,深有感触外键。在此总结。
我们在数据库定义的外键为物理级别的外键,引入外键是逻辑上可说清楚了。但是会带来很多麻烦。
主从表删除麻烦,我们在定义外键的时候就要去选择那些例如RESTRICT、NO ACTION等选项的意思和含义。
如果设置外键,会使得表之间的耦合性增大,后期工程删除、维护时考虑的问题就多了。
所以关于外键。我的看法是数据库就纯粹的存储数据即可,不需要(很少)关注逻辑,逻辑交给代码处理就行,做到心中有外键表中无外键。
DQL
DQL(Data Query Language:数据查询语言)
SELECT语法
SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
FROM table_name [as table_alias][left | right | inner join table_name2] -- 联合查询[WHERE ...] -- 指定结果需满足的条件[GROUP BY ...] -- 指定结果按照哪几个字段来分组[HAVING] -- 过滤分组的记录必须满足的次要条件[ORDER BY ...] -- 指定查询记录按一个或多个条件排序[LIMIT {[offset,]row_count | row_countOFFSET offset}];-- 指定查询的记录从哪条至哪条
注意 : [ ] 括号代表可选的 , { }括号代表必选得。顺序严格要求。
联表查询
-- 查询 数据库结构-1 的所有考试结果(学号 学生姓名 科目名称 成绩)
SELECT s.studentno,studentname,subjectname,StudentResult
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
WHERE subjectname='数据库结构-1'
SELECT 哪些字段名 FROM 哪个表,这句话就定了你结果显示的那张表是什么样的(表头出来了)。
INNER JOIN: 取交集,交的是符合on后面条件的内容,其他内容select有啥输出啥。
LEFT JOIN:即使右表中没有匹配的,也从左表中返回所有的行(SELECT中的)。
RIGHT JOIN:即使左表中没有匹配,也从右表中返回所有的行(SELECT中的)。
排序和分页
/*============== 排序 ================
语法 : ORDER BYORDER BY 语句用于根据指定的列对结果集进行排序。ORDER BY 语句默认按照ASC升序对记录进行排序。如果您希望按照降序对记录进行排序,可以使用 DESC 关键字。*/-- 查询 数据库结构-1 的所有考试结果(学号 学生姓名 科目名称 成绩)
-- 按成绩降序排序
SELECT s.studentno,studentname,subjectname,StudentResult
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
WHERE subjectname='数据库结构-1'
ORDER BY StudentResult DESC
/*============== 分页 ================
语法 : SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
好处 : (用户体验,网络传输,查询压力)推导:第一页 : limit 0,5第二页 : limit 5,5第三页 : limit 10,5......第N页 : limit (pageNo-1)*pageSzie,pageSzie[pageNo:页码,pageSize:单页面显示条数]*/-- 每页显示5条数据
SELECT s.studentno,studentname,subjectname,StudentResult
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
WHERE subjectname='数据库结构-1'
ORDER BY StudentResult DESC , studentno
LIMIT 0,5
聚合函数
函数名称 | 描述 |
---|---|
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;
-- 查询不同课程的平均分,最高分,最低分-- 前提:根据不同的课程进行分组SELECT subjectname,AVG(studentresult) AS 平均分,MAX(StudentResult) AS 最高分,MIN(StudentResult) AS 最低分FROM result AS rINNER JOIN `subject` AS sON r.subjectno = s.subjectnoGROUP BY r.subjectnoHAVING 平均分>80;/*where写在group by前面.要是放在分组后面的筛选要使用HAVING..因为having是从前面筛选的字段再筛选,而where是从数据表中的>字段直接进行的筛选的*/
SELECT后面不仅是表头,而且还是可以使用聚合函数让下面的每一列都是上面的形式。
事务
什么是事务
要么都成功,要么都失败
索引
索引(Index)是帮助MySQL高效获取数据的数据结构。
索引数据结构
https://blog.codinglabs.org/articles/theory-of-mysql-index.html
规范数据库设计
为什么需要数据库设计
当数据库比较复杂时我们需要设计数据库
糟糕的数据库设计 :
- 数据冗余,存储空间浪费
- 数据更新和插入的异常
- 程序性能差
良好的数据库设计 :
- 节省数据的存储空间
- 能够保证数据的完整性
- 方便进行数据库应用系统的开发
软件项目开发周期中数据库设计 :
- 需求分析阶段: 分析客户的业务和数据处理需求
- 概要设计阶段:设计数据库的E-R模型图 , 确认需求信息的正确和完整.
设计数据库步骤
收集信息
- 与该系统有关人员进行交流 , 座谈 , 充分了解用户需求 , 理解数据库需要完成的任务.
标识实体[Entity]
- 标识数据库要管理的关键对象或实体,实体一般是名词
- 标识每个实体需要存储的详细信息[Attribute]
标识实体之间的关系[Relationship]
三大范式
问题 : 为什么需要数据规范化?
不合规范的表设计会导致的问题:
信息重复
更新异常
插入异常
- 无法正确表示信息
删除异常
- 丢失有效信息
三大范式
第一范式 (1st NF)
第一范式的目标是确保每列的原子性,如果每列都是不可再分的最小数据单元,则满足第一范式(每一列原子性,不可再分)
第二范式(2nd NF)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
第二范式要求每个表只描述一件事情(属性完全依赖于主键;一个表只说明一个事物)
第三范式(3rd NF)
如果一个关系满足第二范式,并且除了主键以外的其他列都不传递依赖于主键列,则满足第三范式.
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。(属性不依赖于其他非主属性;每列都与主键有直接关系,不存在传递依赖。)
规范化和性能的关系
为满足某种商业目标 , 数据库性能比规范化数据库更重要
在数据规范化的同时 , 要综合考虑数据库的性能
通过在给定的表中添加额外的字段,以大量减少需要从中搜索信息所需的时间
通过在给定的表中插入计算列,以方便查询
JDBC(重点)
数据库驱动
驱动:声卡、显卡、数据库。刚买的显卡直接按上去使用不了,需要更新一下才能发挥它的作用。
我们的应用程序不能直接访问相关数据库,两者语言都不通,这时候就需要数据库驱动了。数据库驱动由数据库厂商提供,MySQL提供MySQL数据库的驱动,Oracle提供Oracle数据库的驱动。你可以看做成一堆API。
JDBC
多个数据库厂商可能有不同的驱动,兼容性差,要记好多。这样不统一,SUN公司为了简化开发人员(对数据库的统一)操作,提供一个(JAVA操作数据库的)规范,俗称JDBC,这些规范的实现由具体的厂商去做。
对于开发人员来说,我们只需要掌握JDBC接口的操作即可。
JDBC是一套规范,开发者使用这个进行数据库开发,数据库厂商遵守这个规范写相应的操作接口。
导入相关包。
statement对象
JDBC中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送相关的增删改查语句即可。
Statement的executeUpdate()方法,用于数据库增删改,其返回值返回一个整数。(即增删改语句导致了数据库几行数据发生了改变)
Statement的executeQuery方法用于数据库查询语句,其返回值是ResultSet对象。
PreparedStatement
预编译。用?当占位符。
把传递进来的参数当作字符,假设其中存在转义字符,比如说单引号''
会被直接转义,所以不会出现SQL注入。
事务
ACID
原子性:要么全部完成,要么都不完成
一致性:总数不变
隔离性:多个进程互不干扰
持久性:一旦提交不可逆,数据持久化到数据库了
隔离性问题:
脏读:一个事务读取了另一个没有提交的事务
不可重复读:在同一个事物内,重复读取表的数据,表数据发生了改变
虚读(幻读):在一个事务内,读取到了别人插入的数据,导致前后读出来结果不一致
Connection connection = ...;
PrepareStatement ps = ...;
Result rs = ...;try {//关闭数据库的自动提交功能connection.setAutoCommit(false);//开启事务String sql1 = "update account set money = money-100 where name='A'";ps = connection.prepareStatement(sql1);ps.executeUpdate();String sql2 = "update account set money = money+100 where name='B'";ps = connection.prepareStatement(sql2);ps.executeUpdate();//业务完毕,提交事务connection.commit();} catch (Exception e) { // 这里可能出现获取数据库连接的异常以及业务代码的异常,只要捕获到都需要进行事务回滚try {connection.rollback();} catch (SQLException throwables) {throwables.printStackTrace();}e.printStackTrace();} finally {//释放资源}
数据库连接池
数据库连接资源和释放资源是十分浪费系统资源的。
准备一些预先的资源,过来就用预先准备好的。拿来即用,用完归还。
和线程池一样。
开源数据源实现
DBCP
C3P0
Druid:阿里巴巴
使用这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了。
对SELECT语句的理解
select语句主体
SELECT (查出来形成新表的列名,强烈建议用as写好新表的列名) FROM (从哪几张表,建议也用as起别名,方便区分是哪一个表的列) WHERE (条件,不加就会变成笛卡尔积的形式)
写Select语句就先写主体,SELECT … FROM … WHERE,然后根据需求去填充。(建议别名用as明示,别只写个空格)
select s.id as sid,s.name as sname,s.teacher_id as tid,t.name as tnamefrom student as s,teacher as t where s.teacher_id = t.id
联表查询的SQL语句就很好写和分析了。上面的SQL语句代表从student表(别名为s)和teacher表(别名为t),形成结果新表sid列是student表的id;新表sname列是student表的name;新表tid列是student表的teacher_id;新表tname是teacher表的name;条件为student表的teacher_id与teacher表的id相等。
起别名的原因是:经过select查询形成的新表的新列名就是按照别名走的,如果没设置就按源表走;同时设置了别名,mybtatis写参数也就按照新表走了。
面试高频
- Mysql引擎
- InnoDB底层原理
- 索引
- 索引优化!
结合Excel生成重复性SQL语句
对于重复性的SQL语句,我们其实可以借助Excel的公式来做是十分有效的,写生成SQL语句脚本。别把计算机最简单的办公软件给忘了呀。
例如,我在工程中遇到的写出中文和译文,再确定键值。然后生成插入中英译文脚本和查重脚本。
如图:
这些都是第一行写上脚本语句后,下面的所有只是复制粘贴操作,这样大大提高了效率。
插入中文SQL脚本
="INSERT INTO SYS_LOCALE (P_KEY, L_KEY, MIDDLE_DESC, DESC_DEF, MODIFY_DATE, ID, TYPE) VALUES('"&B2&"', 'ZH_CN', '"&A2&"', 'M', sysdate, (SELECT max(id)+1 FROM sys_locale), 'CONTENT');"
插入译文脚本
="INSERT INTO SYS_LOCALE (P_KEY, L_KEY, MIDDLE_DESC, DESC_DEF, MODIFY_DATE, ID, TYPE) VALUES('"&B2&"', 'EN', '"&D2&"', 'M', sysdate, (SELECT max(id)+1 FROM sys_locale), 'CONTENT');"
查重脚本
="SELECT * FROM SYS_LOCALE l WHERE l.MIDDLE_DESC = '"&A2&"' OR l.P_KEY LIKE '"&B2&"';"
【狂神学习笔记】数据库相关推荐
- JavaWeb(引用-->狂神学习笔记)2021-08
狂神学习笔记 1.基本概念(①) 1.1 前言 web开发: web,网页的意思,www.baidu.com· 静态web html,css 提供给所有人看的数据始终不会发生变化! 动态web 淘宝, ...
- Spring5(引用-->狂神学习笔记)2021-08
狂神学习笔记 Spring5 1.Spring 1.1 简介 2002,首次推出Spring框架的雏形;interface21框架 Spring框架以interface21框架为基础,2004年发布1 ...
- SpringMVC(狂神学习笔记)2021-10-5
注意:本笔记是在学习狂神的视频教程的记录 1.回顾MVC 1.1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务逻辑. ...
- Spring5 详解 B站 狂神 学习笔记
目录 1. Spring 1.简介 2.优点 3.组成 4.拓展 2.IOC理论推导 IOC本质 3.HelloSpring 思考问题? 4.IOC创建对象的方式 5.Spring配置 1.别名 2. ...
- MySQL狂神说笔记数据库笔记详解
1.初始MySQL javaEE:企业级java开发 Web 前端(页面:展示,数据!) 后台(连接点:连接数据库JDBC,连接前端(控制,控制视图跳转,和给前端传递数据)) 数据库(存数据,Txt, ...
- Android-入门学习笔记-数据库基础
5 如果你还没有 CourtCounter 应用,可以在此处下载该应用. 7 计算机内存和硬盘存储空间之间的区别 注意: 在"测量单位 (Units of Measurement)" ...
- MYSQL个人学习笔记——数据库介绍、mysql安装配置、数据库操作指令、备份恢复、mysql函数、例题分享
数据库 一.数据库概述 数据库(DataBase,简称DB):长期存储数据的仓库 数据库分类:层次式数据库.网络式数据库.关系型数据库 数据库特点: 1.实现数据共享,减少数据冗余 2.采用特定的数据 ...
- django学习笔记--数据库中的多表操作
1.Django数据库----多表的新增操作 1.一对一模式下新增 创建一个详情对象,把这个对象赋值给创建的新的user对象 author_detail = models.AuthorDetail.o ...
- C#学习笔记——数据库篇(1)
1 C#的数据连接分同样分三步走 2 1.连接语句 3 string str_conn = "sever = localhost;database = smaple;usid = sa;pw ...
最新文章
- php如何实现省市,PHP简单实现正则匹配省市区的方法
- 微信小程序 基础1【本页面窗口配置、组件、布局】
- 网络编程--sockaddr 与 sockaddr_in
- 动态改变_Excel中如何动态改变可编辑区域?
- 信息学奥赛一本通(1104:计算书费)
- 微信版花呗“分付”要来了!花呗,白条你们怎么看?
- cpu线程测试软件,CPU多线程测试:wPrime/国际象棋
- embedding与pytorch中squeeze()和unsqueeze()函数介绍
- 试凑法整定PID参数
- robotium 代码
- Cyclone IV系列FPGA串口远程烧写详解
- p2v之clonezilla(1)再生龙启动u盘制作
- 最流行的前端框架vue基础
- 深入浅出scala之函数(匿名函数)(P41-45)
- 使用OpenCV实现Halcon算法(1)亚像素提取边缘,Sub-Pixel Edge Detector
- 2020-08-09 我来邀请码
- Win7通过无线网卡共享本地网络,开启WiFi热点以及关闭WiFi热点
- Altium Designer——PCB绘制
- 20181021模拟赛(暴力+暴力+优先队列二分)
- O准备如何苟进复赛圈?华为软挑开挂指南(附赛题预测)
热门文章
- python方式对接AWS的kinesis
- gPhone体验和思考(一)
- 收购汇源是可口可乐的失败
- 杭州计算机学校2018年招生,杭州市财经职业学校2018年提前自主招生“3+2”、“五年一贯制”拟录取名单公示...
- html 页面设置离顶部距离,设置table距离顶部位置
- STM32F407 两个SPI互相通信,SPI1与SPI2通信实验
- gcc生成动态链接库
- 天津理工大学 计算机网络综合实验,天津理工大学计算机网络实验二.pdf
- 唯鲲论坛-你不得不知的外汇市场上的各种角色
- 广工2016校赛决赛