关系
将实体与实体的关系,反应到最终数据表的设计上来,将关系分为三种,一对多,多对多,多对多。
所有关系都是表与表之间的关系。
一对一:
一张表的一条记录一定只对应另外一张表的一条记录,反之亦然。
例
Id |
姓名 |
性别 |
年龄 |
电话号码 |
1 |
张三 |
男 |
23 |
13320848263 |
一对多
一张表中有一条记录,对应另一张表多条记录但是反过来,另一张表的一条记录只能对应这张表的一条记录。
例母亲与孩子的关系
多对多
一张表中的一条记录对应另外一张表的多条记录,同时另一张表的一条记录对应另外一张表的多条记录。
范式
Normal format
是一找种离散型数学中的知识,为解决数据存储的与优化问题,
数据保存以后,凡是能够通过关系找出来的数据,坚决不在重复存储:终极目标是减少数据的冗余。
范式是一种分层的结构规范,分为六层,每一层都比上一层严。若要满足下一范式,前提是满足上一层范式。
六层范式:1NF,2NF,3NF.4NF,5NF,6NF最高
Mysql属于关系型数据库有空间浪费:致力于节省存储空间,与范式所解决的问题不谋而活:在设计数据库,会利用范式来指导设计,但是数据不单是解决空间问题,要保护效率问题,范式只为解决空间问题,所以数据库的设计又不可能完全按照范式要求实现,一般只有前三种范式需求满足。
范式在数据库中有指导意义:但是不强制规范。
第一范式:1NF
在设计表存储数据的时候,如果表中设计的字段存储的数据,再取出来的使用之前还需要额外的处理(拆分)那么说表的设计不满足第一范式=>第一范式要求字段的数据具有原子性=>不可再分。
第二范式:2NF
再数据表设计过程中,如果有复合主键(多字段主键),且表中有字段并不是由整个主键来确定,而是依靠主键的某个字段(主键的一部分)=>存在字段约束主键的部分问题,称之为部分依赖=>第二范式就是要解决表中不允许出现部分依赖。
取消复合主键,使用逻辑主键。
第三范式:3NF
要满足第三范式,必须满足第二范式。
第三范式:理论上讲,y应该一张表中所有字段都应该有直接依赖主键(逻辑主键代表业务主键),如果表设计中存在一个字段,并不直接依赖主键而是通过某个非主键字段依赖,最终实现依赖主键。把这种不是直接依赖主键而是依赖非主键字段的依赖关系称之为依赖传递
逆规范化
磁盘利用率与效率的对抗,有时候再设计表的时候如果一张表中有就几个字段需要从别的表中去获取信息,理论上讲的确可以获得想要的数据,但是效率低一点,会刻意的在某些表中,不去保存外表的主键(逻辑主键)而是直接保存想要的数据信息这样一来在查询数据的时候,一张表可以直接提供数据,而不需要多表查询(效率低)。
数据的高级操作:
数据的操作:增删查改。
高级新增数据
Insert into 表名(字段列表) values (值列表);
在数据插入的时候,假设主键对应的值已经存在,插入一定会失败。
主键冲突:
当主键存在冲突的时候(Duplicate key)
可以选择性进行处理:更新和替换
高级操作更新:
Insert into 表名 [field主键] values (值列表) on duplicate key update 字段=新值;
主键冲突例子:insert into my_sql values (‘php’,’B101’);
更新:insert into my_sql values (‘php’,B101’) on duplicate key update room =’B102’;
替换
Replace into 表名[字段主键] values (值列表)
例:replace into my_sql values (‘Java’,’102’);
蠕虫复制:
蠕虫复制:从已有的数据表中获取数据,然后将数据又进行新增操作,数据成部的增加。
表创建高级操作:从已有表创建新表(复制表结构)
Create table 表名 like 数据库.表名;
蠕虫复制:先查出数据,然后再将查出的数据新增n遍
Insert into 表名(字段) select 字段列表/* from 数据表名;;
蠕虫复制的意义:
1,从已有表拷贝数据到新表中
2,可以迅速让表中数据膨胀到一定的数量级;测试表的压极效率;
高级更新数据
Update
Update 表名 set 字段 =值[where条件];
高级新增语法
Update 表名 set 字段 =值[where条件][limit 更新数量];
例:update my_copy set name =’c’ where name =’a’ limit =3;
删除数据与更新类似
Delete from表名 [where条件][limit 数量];
例:delete from my_copy where name =’a’ limit=3;
删除:如果表中存在主键自增长,那么当删除之后自增长不会还原。
思路:数据的删除是不会改变表结构,只能删除表后重建
Truncate 表名; 先删除改变后新增改变
清空表,重置自增长。
查询数据
Select 字段列表/* from表名 [where条件];
完整语法:
Select [select选项] 字段列表 [字段别名] /* from数据源 [where条件子句] [group by 子句] [ having 子句] [order by 子句] [limit 子句];
select选项
Select对查询出来的结果处理方式
All:默认的保留所有结果。
Distinct:去重,查出来的结果,将重复的结构去除(所有字段相同)。
字段别名
当数据查询出来以后,有时候名字不一定就满足需求(多表查询的时候,会有同名的字段)
就需要对字段名进行重命名:别名:字段名 [as] 别名;
数据源
数据源:数据的来源,关系型数据库的来源都是数据表,本质上可以保证数据类似二维表,最终都可以作为数据源,
数据源分为多种:单标数据源,多表数据源,查询语句。
单标数据源
Select * from 表名;
多表数据源
Select *from 表名1,表名2.......;
从一张表中取出一条记录,去另外一张表中匹配所有记录,而且全部保留(记录数和字段数),将这种结果称之为笛卡尔积(交叉连接)
笛卡尔积没什么用,应该尽量避免。
子查询
数据的来源是一条查询语句(查询语句结果是二维表)
Select * from (select 语句) as 表名;
Where 子句
Where 子句,用来判断数据,筛选数据,
Where子句会返回结果:0/1;true/false
判断条件:运算符:<,>,<=,>=,!=,<>,like between and ,notin/in
逻辑运算符:&&(and),or
where原理
Where 是唯一一个直接从磁盘读取数据的时候就开始判断的条件,从磁盘取出一条记录,开始进行where 判断,成立保存到内存,失败则放弃
条件查询
要求找:
Group by 子句
分组
根据某个字段分组(同为一组)
基本语法:group by 字段名
意义:统计数据(按分组字段进行数组统计)
SQL提供了一系列统计函数
Count(c):统计分组后记录数,每组多少记录。
Max():最大值
MIn():最小值
Avg():平均数
Sum():求和
Count函数:里面可以使用两种参数,*代表统计记录
字段名代表统计对应字段(null不统计)
分组会自动排序,根据分组字段:默认排序
Group by 字段[desc/asc] ;多分组结果然后合并之后的整个结果进行排序;
多字段分组:先根据一个字段进行分组,然后对分组厚度结果按照其他字段进行分组。
有一个函数:可以对分组结果中的某个字段进行字符串连接(保留该字段所有的字段):
Group _concat(字段)
回溯统计:with rollup :任何一个分组后都会有一个小组,最后都需要向上级分组进行汇报统计:根据当前分组字段,回溯统计的时候会将分组字段置空
多字段回溯:考虑第一层分组会有此回溯:第二次分组要看第一层分组的组数,组数是多少回溯就是多少,然后加上第一层
Having子句
与where 子句一样;进行条件判断的,where是对磁盘数据进行判断,进入到内存以后经常分组操作,分组结果就需要having 来处理。
Having 能做where能做的几乎所有事情,但是where不能做having能做的很多事情。
1) 分组统计的结果就是或者是说统计函数都只有having 能够使用
2) Having 能够使用做的别名,where不能=>where是从磁盘读取数据,而名字可能是字段进入到内存后产生的。
Order by子句
Order by子句:排序,根据某个字段进行升序或者降序,排序依赖校对集。
基本语法:order by 字段名 [asc/desc]
Asc:是升序(默认的)
Desc:降序
排序可以进行多字段排序:先根据某个字段进行排序然后排序好内部。再按照某个数据进行排序。
Limit子句
Limit 子句是限制结果的语句,限制数量
Limit有两种使用方式
方案1:只用来限制长度(数据量)
Limit 数据量;
方案2:
限制起始位置,限制数量:limit 起始位置,长度
主要用来实现数据的分页:为当前用户节省时间提高服务器的响应效率,减少资源的浪费。
对于用户来讲:可以点击的分页按钮1,2,3,4
对于服务器来讲:根据用户选择的页码来获取不同的数据:limit offset,
Length;
Length:每页显示的数据量,基本不变;
Offset: offset=(页码-1)*每页显示量。
原文地址:https://www.cnblogs.com/lqh969696/p/9693785.html