mysql学习之旅_1

Mysql

php阶段将数据库分为三个阶
基础阶段:
mysql数据库的基本操作(增删改查),以及一些高级操作(视图,触发器,函数,存储过程等),PHP操作没有sql数据库。
优化阶段:
如何提高数据库效率,如索引,分表等。
部署阶段:
如何搭建真实的系统环境,如服务集群,负载均衡。

数据库基础
什么是数据库:
数据库:database ,存储数据的仓库(高效的存储和处理数据库的介质如磁盘、内存)
数据库分类:
1,关系型数据库:(sql型)
2,非关系型数据库(nomysql型)not only
不同数据卡产品:
关系型数据库:大型:Oracle ,DB2
中型:SQLserver,Mysql
小型:access
非关系型数据库:mencahed,moogodb,redis2
数据库的区别->两种阵营
关系型database:安全(保存在磁盘,不会丢失),浪费空间。
非关系型数据库:效率高(不够安全)
关系型数据库:
1,什么是关系型数据库:
建立在关系模型上的数据库(数学模式)
关系模型:建立在关系上的模型,三个方面。
1,数据结构:数据存储问题,二维表的行列结构
2,Sql指令集合:sql语句。
3,完整性约束:表内数据约束,表与表之间的约束。
2,关系型数据库的设计:
关系型数据库:从需要存储的数据需求分析,如果是一类数据(实体)->设计成二维表->表头(字段名field)和数据部分(实际存储单元);
二维表:行与列,
例:
表头 字段1 字段2 字段3
数据单元 数据1 数据2 数据3

实际案例:教师负责讲学,教学生,在教室。
1,找出实体。教师表,学生表,教室表。
2,找出实体数据信息: (教师)姓名,性别,年龄,工资
(学生)姓名,性别,年龄,学号
(班级)班级编号,教室号
3,关系型数据库:维护实体内部、实体与实体之间的联系。
1,实体内部的联系:每个学生都有姓名、性别、学科、学号。

               学生表

姓名 性别 学号 学科 班名
张三 男 001 软件工程 软件工程001
小强 女 001 机械工程 机械工程001

第二行所有字段:都是在描述张三这个学生(内部联系)第二列只能是性别(内部约束)。

关系型数据库特点之一:如果表对应的某个字段没有值(数据),但是系统依然要分配存储空间;关系型数据库比较浪费空间。

实体与实体之间的联系:每个学生肯定属于某个班级,每个班级肯定有多个学生。
班名 教室编号
软件工程001 001
机械工程001 002

班级实体与学生实体之间的联系:实体与实体之间的联系

3,关键字说明:
数据库:database
数据库系统:DBS (database system):虚拟系统,将多种内容关联起来的称呼
DBS=DBMS+DB
DBMS:database mangerment system数据库管理系统,专门管理数据库。
DBA:database Administrator 数据库管理员。

行/记录:row/record本质是一个东西->表中的一个记录,行是从结构角度出发,记录从数据角度出发。
列/字段 column/filed,本质是一个东西。

SQL:
Structured Query language(结构化查询语言)数据库以查询为主,98%都是查询操作。
SQL分为三个部分:
DDL:data Definition Language 数据定义语言–>用来维护存储数据的结构(数据库,表)
代表指令:create ,drop ,alter
DML:data manipulation Language 数据库操作语言–>用来对数据进行操作(数据表中的内容)
代表指令:insert delete updata等其中DML内部又进行分类:DQL(database Query Language)数据查询语言,如select。
DCL:data contral Language 数据控制语言–>主要负责权限的管理(用户)
代表指令:grant ,revoke等。

SQL简介:
Sql是关系型数据库的操作指令
Sql是一种约束,但不强制(类似玩w3c组织)如Oracle,mysql内部有细微的区别。

Mysql:
Mysql数据库是一种c/s结构,客户端/服务端若想要访问服务器必须通过客户端(服务器一直运行,客户端在需要的时候运行),

交互方式
1,客户端连接认证:连接服务器认证身份
2,发送sql指令
3,服务器接受服务器指令,处理sql指令返回操作结果。
4,客户端接受操作结果,显示结果。
5,断开连接(释放资源,服务器并发限制)。

Mysql服务器对象
没有办法完全理解服务器内部的内容:
只能粗略的分析数据库服务器内部结构
将mysql数据库分为四层:
系统(DBMS)->数据库(BD)->数据表(table)->字段(filed)

SQL基本操作:
基本操作:CRUD
将sql的基本操作根据对象分为三类
1,库操作2,表操作3,数据操作
库操作:
数据库的增删改查。
新增数据库:create database 库名 [库选项]

库选项:约束数据库,分为两个选项。
字符集的设定:charset /character set +具体字符集(数据存储的编码格式,一般两种格式GBK和utf8)
校对集设定:collate +具体校对集(数据库比较规则)
– 双中下划线注释(单行注释,也可以用#)
其中数据库不能用关键字(已经被使用的字符或保留字(将来可能会用到))。

查看数据库:
Show databases;

查看指定部分数据库:模糊查询
Show databases like ‘patten’;–paatten是匹配模式
%:表示是匹配模式
_:表示匹配单个字符;

查看数据库创建语句:
Show create database 数据库名[库选项];

更新数据库:
数据库名字不可以修改;
数据库的修改仅限于库选项:字符集和校对集(校对集依赖于字符集);
Alter database 数据库名 [库选项];
Charset /character set [=] 字符集;
Collate [=] 校对集;
删除数据库:
所有操作中删除最简单;
Drop database 数据库名;
当删除数据库语句执行以后发生了什么?
1,在数据库颞部看不见对呀数据库。
2,对应数据库存储文件夹内数据库名字对应的文件夹表也被删除。
注意:不要随便删除数据库

表操作:
表与字段(filed)密不可分
新增数据表:
Create table 表名(字段名1 数据类型1,
字段名1 数据类型1
)[表选项]
表选项:控制表的选项
字符集:sharacter set /character 具体字符集;
校对集:collate 具体校对集;
存储引擎:engine 具体的存储引擎(innodb和myisam);
进入数据库环境 use 数据库名称

当创建表的sql指令执行以后发生了什么?
1,数据库下存在相应的表,
2,在数据库对应的文件夹下会产生对应的表结构文件。
查看数据表:
数据库能查看的方式,表都能查看。
查看所有表:
Show tables:
查看部分表:
模糊匹配:show tables like ‘patten’;
查看表的创建语句:
Show create table 表名;
查看表结构:
Desc class;
Describe class;
Show colums from class;
修改数据表:
俩部分,修改表本身,修改字段
Rename table 老表名 to 新表名;
修改表选项:字符集
Alter table 表名,表选项 值;

修改字段:
字段的操作很多新增、修改、修改、重名、删除。
新增字段:
Alter table 表名 add 字段名 数据类型 [列熟悉][位置];
位置:字段名可以存放在表中任何位置
First:第一位置。
Alter:在哪个字段之后,alter 字段名;默认在最后一个字段。

修改字段:
通常是修改属性或数据类型
Alter table 表名 modify 字段名 数据类型[属性][位置];
重命名字段:
Alter table 表名 change 旧字段 新字段 数据类型 [属性][位置];
删除字段:
Alter table 表名 drop 字段名;
删除数据表:
Drop table 表名1 表2–一次性多张

当删除数据表指令以后发生了什么?
1,表空间没有指定表(数据没有了);
2,数据库对应的文件夹下对应的文件(与存储引擎有关)也会被删除
注意:删除有风险,操作不可逆。
数据操作:
新增数据(两种)
方案1------给全字段插入数据,不需要指定列表:需要数据的值与表中设计字段出现顺序一致
Insert into 表名 values();
方案2------给部分字段插入数据,需要选定字段列表,字段列表顺序与字段顺序一致;
但是值列表顺序必须与选定字段顺序一致
Insert into 表名 (字段列表) values ([值列表], [值列表]);
查看数据
Select */字段列表 from 表名[while 条件];
更新数据
Update 表名 set 字段 =值[while 条件];
删除数据:不可逆
Delete from表名 [while 条件]
中文数据问题:
中文数据问题本质就说字符集问题,
计算机只识别二进制,人类识别符号;需要友谊个二进制与字符对应关系(字符集)。
报错:服务器没有识别对应的四个字节。
服务器认为的数据是utf—8,一个汉字有三个字节,读取三个字节转换成汉字(失败),剩余的再读三个字节,最终失败!

所有数据库服务器认为(表现)的一些特征都是通过服务器端的变量来存储,系统先读取自己的变量,看看应该怎么表现。
Show viriables like ‘character_set %’;(查看字符集);对外处理默认字符集

基本上服务器是万能的,什么字符集都能识别。问题的根源:客户端只能识别GBK而服务器是utf-8,矛盾产生。
解决方案1:
改变服务器。默认字符集为GBK
Set character_set_client =GBK;
注意:数据的来源是服务器,解析数据是客户端(客户端只识别GBK;两个字节一个汉字);但服务器给的数据却是utf8,三个字节一个汉字,乱码!!!!!!
解决方案2:
修改服务器给客户端的数据数据集为GBK
Set character_set_result=GBK;
Set 变量=值 ;修改只会是会话级别(当前客户端:当次连接有效:关闭失效)
快捷方式:
设置服务器对客户端的字符集的认识:
Set names 字符集;
例:set names gbk;
==>cheracter_set_client
==>character_set_result;
==>character_set_connection;
Connection: 连接层;字符集中间者统一了效率更高:
校对集问题:
校对集:数据比较的方式(三种方式)
_bin:binary;二进制比较取出二进制位,一位一位进行比较,区分大小写。
_ci:case sensitive; 大小写敏感,区分大小写;
_ci:case insensitive; 大小写不敏感。不区分大小写。
检查数据库支持的校对集
Show collation;
对比:使用utf_8的_bin和_ci来验证不同校对集的效果。
校对集:必须在没有数据之间声明好。
Web乱码问题:
动态网站:部分构成;
浏览器:appache 服务器(php)数据库服务器
三个部分都有自己的字符集;数据在三个部分之间传递很容易产生乱码;
如何解决乱码问题:
统一编码(三码合一);
事实上不可能:浏览器用户管路(不能控制)
但是必须解决这些问题

回顾
数据库基本知识:关系型数据库与非关系型数据库
关系型数据库:安全(磁盘)
非关系型数据库:高效(内存)
关系型数据库:建立在关系模型上的数据库,
数据结构:二维表(浪费空间)
数据库操作指令:sql(DDL,DML,DCL)
完整性约束:表内和表之间(实体)
Mysql关系型数据库:
C/S结构(直接认证发送sql指令,服务器处理指令返回结果,客户端接受结果,分析结果)
Mysql服务器对象:DBMS----->DATABASE------->TABLE------>FIELD
数据库基本操作:库操作,表操作和数据操作。
字符集问题:
中文数据问题
1,改变服务器接受数据字符集character_set_client
2,改变服务器返回数据字符集character_set_result
3,快捷方式:set names 字符集;
乱码问题:
浏览器解析:php处理
数据库处理
校对集问题:
比较规则:_bin二进制,_cs,_ci大小写
算法:快速排序。
数据类型:
列类型:
所谓数据类型:对数据进行统一分类
从系统数据角度出发就是为了使用统一方式进行管理
更好的利用有限的空间
Sql将数据类型分为三类:
数值类型,字符串类型,时间日期型。

数值型:
数值型数据:都是数据,系统将数据分为整数型和小数型
整数型:
存放的都是数据
在sql因为要考虑节省磁盘
Tingint :迷你整型,使用一个存储字节(常用),最多状态有256种
Smallint: 小整型,使用俩个字节,表示状态最多有65535种
Mediunint:中整型,使用三个字节存储
Int:表准整型,使用四个字节存储(常用)
Bigint :大整型,使用八个字节存储。

在sql中数据库全部都是默认有符号的;分正负,使用无符号数据:给约定的数据类型限定
Int unsigned --无符号,从零开始。
查看表结构的时候,发现每个字段的数据类型之后都会带一个括号,里面有指定数值
显示宽度:数据最终显示的位数(包含符号)如-123是四位,253是三位,
显示宽度:没什么特别意义只是默认告诉用户显示的形式而已。实际上用户可以控制,不会改变数据的实际大小。
显示宽度的意义:在于当数据不够显示宽度的时候,会自动让数据变成对应的显示宽度:
通常需要搭配一个前导0来增加宽度,不改变值的大小:zerofill(零填充)
零填充的意义(显示宽度):保证数据格式。
小数型:
带小数点或者范围超过整型的数值类型。
Sql中将小数型分为俩种:浮点型和定点型
浮点型:小数点浮动,精度有限,会丢失精度。
定点型:小数点固定,精度有限,不会丢失精度。

浮点型:
浮点型数据是一种精度型数据:因为超出规定范围之后会丢失精度(四舍五入)。
浮点型分为俩种:float:单精度,占用四个字节存储数据,大概七位。
Double:双精度,占用八个字节存储数据,大概十五位左右。
创建浮点数表:浮点的使用方式:直接float。
表示没有小数部分;float(M,D)M表示总长度,D表示小数部分长度,整数部分长度为(M-1)。 浮点型数据的插入:整数部分不能超过长度,但是小数部分可以超过长度(系统会自动四舍五入)结果:浮点数一定会进行四舍五入(超出精度范围)。
浮点数如果是因为系统进位导致整数部分超出指定长度:那么系统也会允许成立。

定点型:
绝对的保持整数部分不会被四舍五入(不会丢失精度),小数部分有可能丢失(理论上小数部分也不会丢失精度)

浮点数如果进位导致长度溢出,没有问题。但是定点数不行、

时间日期型:
Datetime:时间日期,格式是YYYY-MM-DD HH:ii:ss
Date :日期就是datetime的date部分
Time:时间段,指定某个区间之间,时间到时间
Timestamp:时间戳,是从1970开始的格式与datatime一致,
Year:年份,两种格式,year(2)。
插入数据:
时间time可以说负数,year可以使用2位数插入,也可以使用四位数。
Timestamp字段:只要是当前所在记录别更新,该字段一定会自动更新成当前时间。

网站以php位实现主要操作对象,php有非常强大的日期处理函数:date,只需要一个时间戳就可以转换成任意类型函数的时间:以php为主的时候,都是在数据库使用时间戳(整型)来存储时间。
字符串类型:
在sql中将字符串分为了6类
Char ,varchar,text,blob,set和enum
Char:定长字符串
定长字符串。磁盘在定义结果的时候就已经确定了最终数据的存储长度。
Char[L]:L代表length,可以存储长度,单位为字符最大长度值为255
例:char[4]在utf8环境下需要43=12个字节
Varchar:变长字符串
Varchar在分配空间长度的时候,按照最大空间分配,但是实际上最终用了多少是根据具体的数据来确定,
Varchar(L):L代表字符长度理论上长度65536个字符
但是会多1到2个字节来确定存储的实际长度
例:varchar(10)确实存了十个汉字,在utf8的环境下10
3+1=31字节

如何选择定长还是变成字符串?
定长的磁盘空间比较浪费空间,但是效率高;
变长的磁盘空间比较节省但是,效率低;
如果数据基本上确定长度一样,就是定长如果数据不能确定长度(不同数据有变化)

文本字符串:
如果数据量特别大,通常超过255个字符,就会使用文本字符串,文本字符串会根据存储数据的格式进行分类:text(文字存储)和blob(二进制数据,二进制存储路径)
枚举字符串:enum
枚举:enum,事先将可能出现的结构都设计好,实际上就是存储数据必须是规定好的数据中的一个。
枚举使用方式
定义:enum(可能出现的元素列表)
如:enum(‘女’,’男’,’人妖’,’保密’,);
使用:存储数据,只能存储上面定义好的数据
例:创建枚举表,create table my_enum(
Gender enum(‘男’,’女’,’人妖’) character utf8
加入数据;作用之一就是规范数据格式
数据只能是规定数据中的一个
Insert into my_enum values(‘男’),(‘人妖’);
作用之二节省空间(枚举 别名 单选框)(存储的是数值)

在mysql中系统也是自动转换数据格式的,
证明字段存储的是数值:将取出来的+0
就可以判断出原来的数据到底是字符串还是数值,如果是字符串结果为0,否则为其他值。
例:select gender+0,gender from My_enum;
找出枚举元素的规律,按照元素出现顺序从1开始编写
枚举原理:枚举在进行数据规范的时候,系统会自动建立一个数值与枚举元素的对应关系(关系放在日志中)然后在进行数据插入的时候,系统自动将字符串转换成对应的数字存储,然后进行数据提取的时候,系统自动将数值转换成对应的字符串显示。
集合字符串:
集合跟枚举很类似:实际存储的是数值而不是字符串(集合是多选)
例:create table my_set (hobby set (‘篮球’,’足球’,’乒乓球’))charset utf8;
插入数据:可以使用多元素字符串进行组合,也可以数值。
例:insert into my_set values (‘足球’)
Insert into my_set values(2)

集合中:每一个元素对应一个二进制位,被选中为一,没有则为零,最后方向反过来
例:110------>011=3
Select hobby +0 ,hobby from my_set;
集合元素的顺序没有关系,最终系统会匹配顺序;
集合的强大功能在于能够规范数据和节省空间。
Php也可以规范数据但是对于php来说效率优先;而且数据的维护可以通过数值进行增加php的维护成本;php根本没有办法判断数据在数据库的形式。

MySql记录长度
Mysql规定:任何一条记录最长不能超过65535个字节(varchar永远达不到理论值)
Varchar实际存储长度能达到多少呢,看字符集
在utf8下varchar的实际顶配varchar(21844)21844个字符-----218443+2=65532+2=65534
Gbk下实际顶配varchar(32766)32766个字符 ------32766
2+2=65532+2=65534
Mysql记录中如果任何一个字段允许为空,那么系统会自动从整个记录中保留一个字节存储在null(若想释放null所占用的字节,必须保证所有字段不为空)

Mysql中text文本字符串,不占用记录长度;额外存储,但是text文本字符串也是记录的一部分一定需要占据部分长度:10字节(保留数据的地址以及长度)
列属性:
列属性:真正约束字段的是数据类型,但是数据类型的约束很单一,需要一些额外的约束来保证数据的完整性

列属性:null/not null
Default
Primary key
Unque key
Auto_increment
Comment
空属性:null
Null(默认的和not null不为空)虽然是默认的,数据基本上都是字段为空,但是实际上真正开发的时候,尽肯能地保证所有的数据都不为空;空数据没有意义,空数据不能参加运算。
列描述:comment
没有实际意义,专门用来描述字段,会根据表的创建语句保存(用来给dba)了解的。
例:comment’姓名’;

默认值:default
某种数据会经常出现在某个具体的值
想要使用某个默认值,可以不一定指定列表,不使用字段列表,可以使用default关键字代替值
例:insert into my_default values(‘张三’,18,default);
回顾
字段类型(列类型):数值型,时间日期型,字符串类型
数值型:整型,小数型(浮点与定点)
时间日期型:datetime,time,datetimestamp,year
字符串类型:定长,变成,
文本字符串(text和blob)
枚举与集合
Mysql记录长度:65535个字节
Null占一个字节
text文本不占用记录长度,本身十个字节
字段属性:空属性,列描述,默认值
字段属性:
主键,唯一键,自增长。
主键:
Primary key 主要的键,一张表只能有一个字段能使用对应的键,用来唯一约束该字段里面的数据不能重复,称之为主见。
一张表最多只有一个主键。
增加主键:
Sql操作当中有很多方式给表增加主键,大体上有三种
方案一:
创建表的时候,直接加在字段之后跟primary key
例:name varcahr(20) primary key;
方案二:
复合主键
方案三:
当表已经创建好之后,再次额外追加主键,通过修改表字段的属性,也可以直接追加
Alter table 表名 add primary key (字段列表) ;
前提是:字段名不重复;
主键约束:
主键定义的字段中不允许重复;一旦重复数据操作失败(改,增)
更改主键&删除主键
Alter table 表名 drop primary
主键分类:
在实际创建表的过程中,很少使用真业务数据作为主键字段(业务主键)
大部分使用逻辑性字段(字段没有业务含义)将这种字段称之为逻辑主键。
自动增长:
自增长:
定义字段给的是默认值,不给值为null,会自动被系统触发,系统会从以前字段已有的最大值进行+1操作得到行的不同的字段。
自增长通常与主键搭配
特点:
auto_increment
1,任何一个字段要做自增长必须前提是本身是一个索引(key一栏有值)
2,自增长字段必须死数字(int 整型)
3,一张表最多只有一个自增长。
例:ID int primary key auto_increment comment’自动增长’;
自增长得使用
当自增长被给定的值为null 或者默认值的时候会自动增长
自增长如果对应的字段输入了值,那么自增长失效
下一次还是能够正确的自增长(最大值+1)
修改自增长:
自增长如果涉及到字段改变,必须先删除自增长(一张表只能有一个自增长)。
修改当前自增长已经存在的值,修改只能比当前已有的自增长的最大值大,不能为null。
Alter table 表名 atuo_increment=值
思考?为什么自增长都是从一开始为什么每次都是自增长一呢
所有系统的实现(如字符集,校对集)都是由系统内部变量控制的,查看自增长对应的变量
Show variables like ‘auto_increment’;

可以修改变量实现不同的效果;修改是对整个数据而不是单张表(修改只是会话级)
Set auto_incretment_increment=值—自增值
删除自增长:
自增长是字段的属性,通过modify来进行修改(保证字段没有auto_increment)
Alter table 表名 modify 字段类型;
唯一键:
一张表往往有很多字段需要具有唯一性,数据不能重复;但是一张表只能有一个主键。唯一键(unque key)就可以解决表中有很多字段需要唯一性约束。
本质与主键一致,唯一键允许自动为空(空字段不参与唯一性比较)
增加唯一键(三种)
方案一:
在创建表的时候字段后直接跟unque/unque key
例:name char(10) unque;
方案二:
在所有字段之后自动增加unque key(字段列表)—复合唯一键
Unque key (name);
方案三:
在创建表之后增加唯一键
Alter table 表名 add unque key (字段);
唯一键约束
唯一键与主键本质相同,唯一键区别就是唯一键默认允许为空,而且是多个为空
更新唯一键和删除唯一键:
先删除后新增(唯一键可以有多个)
Alter table 表名 drop index 索引名字
索引:
几乎所有的索引都建立在字段之上。
索引:系统根据某种算法将已有的数据(未来可能增加的数据),单独建立一个文件,文件能够实现快速匹配数据并且能够快速地找到对应表中的记录
意义:
1,提升查询数据的效率
2,约束数据的有效性(唯一性等)
增加索引的前提条件:索引本身会产生索引文件(有时候可能比数据文件还大)会非常耗费磁盘空间
如果某个字段作为查询条件经常使用你们可以使用索引(一定会想办法增加)
Mysql中提供了多种索引:
1、主键索引
2、唯一索引
3、全文索引
4、普通索引
全文索引:
针对文章内部关键字进行索引,
全文索引最大的问题:在于如何确定关键字
英文很容易:英文单词与单词之间有空格,中文很难,没有空格,而中文可以多种随意组合(分词:spinx)
关系
将实体与实体的关系,反应到最终数据表的设计上来,将关系分为三种,一对多,多对多,多对多。
所有关系都是表与表之间的关系。
一对一:
一张表的一条记录一定只对应另外一张表的一条记录,反之亦然。

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©:统计分组后记录数,每组多少记录。
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)*每页显示量。

posted @ 2018-09-23 21:11  清华大咖  阅读(114)  评论(0编辑  收藏  举报