MySQL (三)-- 字段属性、索引、关系、范式、逆规范化
1 字段属性
- 主键、唯一键和自增长。
1.1 主键
- 主键:primary key,一张表中只能有一个字段可以使用对应的键,用来唯一的约束该字段里面的数据,不能重复。
- 一张表只能有最多一个主键。
1.1.1 增加主键
- 在SQL操作中欧有多种方式可以给表增加主键,大体分为三种:
- 方案1:在创建表的时候,直接在字段之后,跟primary key关键字(主键本身不能为空)。
-- 增加主键 create table my_pri( id int primary key, name ) not null comment '姓名' )charset utf8;
- 优点:非常直接;缺点:只能使用一个字段作为主键。
- 方案2:在创建表的时候,在所有的字段之后,使用primary key(主键字段列表)来创建主键,如果有多个字段作为主键,可以是复合主键。
create table my_pri2( ) comment '学号', course ) comment '课程代码:3901+0000', score comment '成绩', -- 增加主键限制:学号和课程代码应该是唯一的 primary key (number,course) )charset utf8;
- 方案3:当表已经创建好之后,额外追加主键:可以通过修改表字段属性,也可以直接追加。
alter table 表名 add primary key (字段列表);
- 前提:表中字段对应的数据本身是独立的(不重复)。
1.1.2 主键约束
- 主键对应的字段中的数据不允许重复,一旦重复,数据操作失败(增和该)。
1.1.3 主键更新 & 删除主键
- 没有办法更新主键:主键必须先删除,才能增加。
drop table 表名 drop primary key;
1.1.4 主键分类
- 在实际创建表的过程中,很少使用真实业务数据作为主键字段(业务主键,如学号、课程号)。
- 大部分的时候,是使用逻辑性的字段(字段没有业务含义,值是什么都没有关系),将这种字段主键称为逻辑主键。
1.2 自动增长
- 自增长:当对应的字段,不给值,或者给默认值,或者给null的时候,会自动的被系统触发,系统会从当前字段中的已有的最大值+1操作,得到一个新的不同的字段。
- 通常自动增长和主键搭配。
1.2.1 新增自增长
- 自增长特点:auto_increment
- 任何一个字段要做自增长必须前提是本身是一个索引(key一栏有值)。
- 自增长必须是数字。
- 一张表最多只能有一个自增长。
1.2.2 自增长使用
- 当自增长被给定的值为null或者默认值的时候,会触发自动增长。
1.2.3 修改自增长
- 自增长如果是涉及到字段改变:必须先删除自增长,后增加(一张薄只能有一个自增长)。
- 修改当前自增长已经存在的值:修改只能比当前已有的自增长的最大值大,不能小(小不生效)。
-- 修改表选项的值 alter table 表名 auto_increment = 值;
- 思考:为什么自增长是从1开始?为什么每次都是自增1呢?
- 所有系统的变现(如字符集、校对集)都是系统内部的变量进行控制的。
- 查看自增长对应的变量:show variables like 'auto_increment%';
- 可以修改变量实现不同的效果,但是修改是针对整个数据库的修改,而不是单张表,不建议修改。
-- 不建议修改 ;
1.2.4 删除自增长
- 自增长是字段的一个属性:可以通过modify来进行修改(保证字段没有auto_increment即可)
alter table 表名 modify 字段 类型;
1.3 唯一键
- 一张表往往有很多字段需要具有唯一性,数据不能重复;但是一张表中只能有一个主键,所以唯一键就可以解决表中有多个字段需要唯一性的约束。
- 唯一键的本质和主键差不多,唯一键默认的允许自动为空,而且可以多个为空。
1.3.1 增加唯一键
- 基本上和主键差不多:三种方案。
- 方案一:在创建表的时候,字段之后直接跟unique/unque key。
- 方案二:在所有的字段之后增加unique key(字段列表);--复合唯一键
- 方案三:在创建表之后增加唯一键。
1.3.2 唯一键约束
- 唯一键与主键本质相同,唯一的区别就是唯一键默认允许为控控,而且是多个为空。
- 如果唯一键也不允许为空,那么与主键的约束作用是一致的。
1.3.3 更新唯一键&删除唯一键
- 更新唯一键:先删除唯一键,再增加唯一键。
- 删除唯一键,默认使用字段名作为索引名字
alter table 表名 drop index 索引名字;
2 索引
- 几乎所有的索引都是建立在字段之上。
- 系统根据某种算法,将已有的数据(未来可能新增的数据),单独建立一个文件:文件能够实现快速的匹配数据,并且能够快速的找到对应表中的记录。
- 索引的意义:
- 提升查询数据的效率。
- 约束数据的有效性(唯一性等)。
- 增加索引的前提条件:索引本身会产生索引文件(有时候可能比数据文件还打),会非常消耗磁盘空间。
- 如果某个字段需要作为查询条件经常使用,那么可以使用索引。
- 如果某个字段需要进行数据的有效性约束,也可以使用索引(主键、唯一键)。
- MySQL中提供了多种索引。
- 主键索引 primary key
- 唯一索引 unique key
- 全文索引 fulltext index
- 普通索引 index
- 全文索引:针对文章内部的关键字进行索引。
- 全文索引最大的问题在于如何确定关键字。
3 关系
- 将实体与实体的关系,反应到最终数据库表的设计上来。将关系分成三种:一对一,一对多和多对多。
3.1 一对一
- 一对一:一张表的一条记录一定只能和另一张表的一条记录进行对应;反之亦然。
- 学生表:姓名、性别、年龄、身高、体重、婚姻、籍贯、家庭住址、紧急联系人。
id | 姓名 | 性别 | 年龄 | 身高 | 体重 | 籍贯 | 家庭住址 | 紧急联系人 | 婚姻 |
- 表设计成以上这种形式,是符合要求的。其中姓名、性别、年龄、身高、体重是常用数据,但是婚姻、籍贯、住址和紧急联系人属于不常用数据。如果每次查询都是查询所有数据,不常用的数据就会影响效率,实际又不用。
- 解决方案:将常用的和不常用的信息分离存储,分成两张表。
- 学生常用信息表
id | 姓名 | 性别 | 年龄 | 身高 | 体重 |
- 学生不常用信息表
籍贯 | 家庭住址 | 紧急联系人 | 婚姻 |
- 但是如果我有时候又需要使用不常用信息怎么办?
- 为了保证不常用信息和常用信息一定能够对应上,我们唯有找到一个具有唯一性的字段来共同连接两张表。--主键字段
- 所以,学习不常用信息表修改如下
id | 婚姻 | 籍贯 | 家庭住址 | 紧急联系人 |
- 综上所述,一个常用表中的一条记录,永远只能在一张不常用表中匹配一条记录;反过来,一个不常用表中的一条记录在常用表中也只能匹配一条记录。
3.2 一对多
- 一对多:一张表中的一条记录可以对应另外一张表中的多条记录,反过来,另一张表的一条记录只能对应第一张表的一条记录,这种关系就是一对多或多对一。
- 学生和班级的关系:
- 学生表
id | 姓名 | 年龄 | 性别 |
- 班级表
id | 班级名字 |
- 我们知道,一个学生只能属于一个班级,而一个班级却有多个学生,一对多。
- 但是以上设计:解决了实体的设计表问题,但是没有解决关系问题:学生找不到班级,班级没有学生。
- 解决方案:在某一张表中增加一个字段,能够找到另一张表中的记录。如何做到呢?在学生表中增加一个字段指向班级表,因为学生表的记录只能匹配到一个班级的记录。
- 学生表
id | 姓名 | 性别 | 年龄 | 班级id |
班级主键 | ||||
班级主键 |
3.3 多对多
- 多对多:一张表(A)的一条记录能够对应另外一张表(B)的多条记录;同时B表中的一条记录也能对应A表中的多条记录。
- 老师教学:;老师和学生
- 老师表
t_id | 姓名 | 性别 | 工资 |
1 | A | 男 | 6000 |
2 | B | 女 | 8000 |
- 学生表
s_id | 姓名 | 性别 | 分数 |
1 | 张三 | 男 | 59 |
2 | 李四 | 男 | 95 |
- 以上设计方案:实现了实体的设计,但是没有维护实体的关系。
- 一个老师教过多个学生,一个学生也被多个老师教多。
- 解决方案:不管在那张表中增加字段,都会出现问题:该字段要保存多个数据,而且是与其它表有关系的字段,不符合表的设计规范,增加一张新表,专门维护两张表之间的关系。
- 中间关系表:老师与学生的关系
T_ID | S_ID |
1 | 1 |
1 | 2 |
2 | 1 |
2 | 2 |
- 增加了中间表之后:中间表与老师表形成了一对多的关系,而且中间表是多表,维护了能够唯一找到一表的关系。
4 范式
- 范式:是离散数学中的知识,是为了解决一种数据的存储与优化的问题(保存数据的存储之后,凡是能够通过关系寻找出来的数据,坚决不再重复存储,起终极目标是为了减少数据冗余)。
- 范式:是一种分层结构的规范,分为6层:每一层都比上一层更加严格。
- 六层范式:1NF、2NF、3NF、4NF、5NF和6NF,其中1NF要求最低,6NF要求最高。
- MySQL属于关系型数据库:有空间浪费,而范式致力于节省存储空间。所以,在设计数据库的时候,会利用范式来指导设计。但是数据库不单是解决空间问题,还要保证效率;而范式只为解决空间问题,所以数据库的设计不可能完全按照范式的要求实现,所以一般情况下,只有前三种范式需要满足。
- 范式在数据库的设计当中是有指导意义,但是不是强制规范。
4.1 第一范式 1NF
- 第一范式:在设计表存储数据的时候,如果表中设计的字段存储的数据,在取出来使用之前还需要额外的处理(拆分),那么就说表的设计不满足第一范式。
- 第一范式:属性不可再分,字段保证原子性。
- 讲师代课表
讲师 | 性别 | 班级 | 教室 | 代课时间 | 代课时间(开始时间、结束时间) |
朱元璋 | 男 | java001班 | B23 | 30天 | 2014-02-17 2014-05-05 |
朱元璋 | 男 | java002班 | C15 | 30天 | 2014-05-05 2014-05-30 |
李世民 | 男 | Linux003班 | C15 | 15天 | 2016-02-21 2014-06-20 |
- 上表的设计不存在问题,但是如果需求是将数据查出来之后,要求一个老师从什么时候开始上课,到什么时候结束课程,此时需要将代课时间进行拆分,不符合第一范式,因为数据不具有原子性,可以再拆分。
- 解决方案::将代课时间拆成两个字段就可以了。
4.2 第二范式 2NF
- 第二范式:在数据表设计的过程中,如果有复合主键,且表中有字段并不是由整个主键来确定,而是依赖主键的某个字段(主键的部分),存在字段依赖主键部分的问题,称之为部分依赖。第二范式就是要解决表设计不允许出现部分依赖。
姓名 | 性别 | 班级 | 教室 | 代课时间 | 开始时间 | 结束时间 |
朱元璋 | 男 | java001班 | C01 | 30天 | 2014-02-27 | 2014-05-05 |
朱元璋 | 男 | java002班 | B23 | 30天 | 2014-03-21 | 2014-05-30 |
李世民 | 男 | Linux003班 | A15 | 15天 | 2014-06-01 | 2014-06-20 |
- 在上面的表中:因为讲师没有办法作为独立主键,需要结合班级才能作为主键(复合主键:一个老师在一个班永远只带一个阶段的课)。代课时间、开始时间和结束时间字段都与当前的代课主键(讲师和班级):但是性别并不依赖班级,教室不依赖讲师,性别只依赖讲师,教室只依赖班级,出现了性别和教室依赖主键的一部分:即部分依赖。
- 解决方案:取消复合主键,使用逻辑主键。
4.3 第三范式 3NF
- 要满足第三范式,必须满足第二范式。
- 第三范式:理论上讲,一张表中的所有字段都应该直接依赖主键(逻辑主键除外),如果表设计中存在一个字段,并不直接依赖主键,而是通过某个非主键依赖,最终实现依赖主键,把这种不是直接依赖主键,而是依赖非初见字段的依赖关系称之为传递依赖。第三范式就是解决传递依赖的问题。
- 讲师代课表
id | 讲师 | 性别 | 班级 | 教室 | 代课时间 | 开始时间 | 结束时间 |
1 | 朱元璋 | 男 | java01班 | A03 | 30天 | 2014-02-27 | 2014-05-05 |
2 | 朱元璋 | 男 | Linux02班 | B23 | 30天 | 2014-03-21 | 2014-05-30 |
3 | 李世民 | 男 | java001班 | A03 | 30天 | 2014-06-01 | 2014-06-20 |
- 以上设计方案中,性别依赖讲师存在,讲师依赖主键;教室依赖班级,班级依赖主键;性别和教室都存在传递依赖。
- 解决方案:将存在传递依赖的字段,一级依赖的字段本身单独取出,形成一个单独的表,然后在需要对应的信息的时候,使用对应的实体表的主键加起来。
id | 讲师id | 班级id | 代课时间 | 开始时间 | 结束时间 |
1 | 1 | 10 | 30天 | 2014-02-27 | 2014-05-05 |
2 | 1 | 12 | 30天 | 2014-03-21 | 2014-05-30 |
3 | 2 | 12 | 30天 | 2014-06-01 | 2014-06-20 |
id | 讲师 | 性别 |
1 | 朱元璋 | 男 |
2 | 李世民 | 男 |
id | 班级 | 教室 |
10 | java01班 | A03 |
12 | Linux02班 | B23 |
5 逆规范化
- 有的时候,在设计表的时候,如果一张表中有几个字段是需要从另外的表中去获取信息。理论上讲,的确可以获取到想要的数据,但是就是效率低一点。所以我们会刻意在某些表中,不去保存另外表的主键(逻辑主键),而是直接保存想要的数据信息,这样一来,在查询数据的时候,一张表可以直接提供数据,而不需要多表查询(效率低),但是会导致数据冗余增加。
MySQL (三)-- 字段属性、索引、关系、范式、逆规范化的更多相关文章
- mysql 排序字段与索引有关系吗?
mysql 排序字段与索引有关系吗?答案与否需要你explain一下你的sql脚本 另外记住:date_add()方法会影响Index_modify_time索引(即:时间字段索引) 一般遇到这样的 ...
- MySQL的字段属性+SQLyog查看建表语句
MySQL的字段属性 写在前面:数据库就是单纯的表,用来存储数据,只有行和列.行代表数据,列代表字段(id.name.age这种就叫字段) 1.长度 2.默认 3.主键 4.非空 5.Unsigned ...
- 总结: MySQL(基础,字段约束,索引,外键,存储过程,事务)操作语法
1. 显示数据库列表 show databases; # 查看当前所有数据库 show databases \G #以行的方式显示 2. 在命令行中,执行sql语句 mysql -e 'show ...
- MySQL给字段唯一索引的三种方法
建表时添加 DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `stu_id` ) NOT NULL AUTO_INCREMENT, ` ...
- mysql多字段唯一索引
项目中需要用到联合唯一索引: 例如:有以下需求:每个人每一天只有可能产生一条记录:处了程序约定之外,数据库本身也可以设定: 例如:user表中有userID,userName两个字段,如果不希望有2条 ...
- MySQL之字段数据类型和列属性
数据类型: 对数据进行统一的分类,从系统的角度出发,为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中将数据类型分成了三大类:数值类型.字符串类型.时间日期类型. 数值型: 数值型数据: ...
- mysql的数据类型和字段属性
本文内容: 数据类型 数值类型 整数型 浮点型 定点型 日期时间类型 字符串类型 补充: 显示宽度与zerofll 记录长度 字段属性 空\不为空值:NULL.NOT NULL 主键:primary ...
- 2-16 MySQL字段约束-索引-外键
一:字段修饰符 1:null和not null修饰符 我们通过这个例子来看看 mysql> create table worker(id int not null,name varchar(8) ...
- mysql字段约束-索引-外键---3
本节所讲内容: 字段修饰符 清空表记录 索引 外键 视图 一:字段修饰符 (约束) 1:null和not null修饰符 我们通过这个例子来看看 mysql> create table wo ...
随机推荐
- Code Complete
一.<代码大全>优先阅读参考顺序: 自学编程人:第07章 高质量的子程序 低年级学生:第11章 变量命名的力量 高年级学生:第08章 防御式编程 初级程序员:第18章 表驱动法 高级程序员 ...
- vc操作电脑之常用命令
1.重启计算机: ExitWindowsEx(EWX_REBOOT,0); 2.关机: ExitWindowsEx(EWX_SHUTDOWN,0); 3.注销: ExitWindowsEx(EWX_L ...
- NYOJ--513--A+B Problem IV(大数)
A+B Problem IV 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这 ...
- CronJobs
一.概念 CronJobs提供了在特定的时间或者间隔内处理业务逻辑的方法.一般创建一个Cronjob有两种方式,第一种是定义Java类,由Hybris生成脚本并加入数据库.第二种是直接编写gr ...
- iOS tableview group时头尾视图间隔大小
解决: 一,当使用tableview的格式为group时 1.先设置 tableview.sectionHeaderHeight = 0.00001; tableview.sectionFooterH ...
- js实现轮播图动画
在网页浏览中,可以看到轮播图是无处不在的,这是一个前端工程最基本的技巧.首先看看几个网页的呈现的效果. QQ音乐: 网易云音乐: 天猫: 接下来将从简到难总结几种实现轮播图的方法. 1.样式一:鼠标滑 ...
- 【转载】初识google test
一.前言 本篇将介绍一些gtest的基本使用,包括下载,安装,编译,建立我们第一个测试Demo工程,以及编写一个最简单的测试案例. 二.下载 如果不记得网址, 直接在google里搜gtest,第一个 ...
- WEB的进击之路-第一章 HTML基本标签(1)
一.HTML简介 超文本标记语言,标准通用标记语言下的一个应用. "超文本"就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素. 超文本标记语言的结构包括"头&q ...
- 微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)
微信小程序智能生活小秘书开发详解 >>>>>>>>>>>>>>>>>>>>> ...
- Writing A Threadpool in Rust
文 Akisann@CNblogs / zhaihj@Github 本篇文章同时发布在Github上:https://zhaihj.github.io/writing-a-threadpool-in- ...