字段属性
主键、唯一键、和自增长。
主键:
primary key ,主要的键。一张表只能有一个字段可以使用对应的键,用来唯一的约束改字段里面的数据,不能重复,这种称为主键。
一张表只能最多一个主键。
增加主键
sql操作中有很多种方式可以给表增加主键,大体分为三种。
方案1:在创建表的时候,直接在字段之后跟primary key 关键字。
方案2:在创建表的时候,在所有的字段之后,使用primary key(主键字段列表)来创建主键(如果有多个字段作为主键,可以是符合主键)
方案3:当表已经创建好之后,额外追加主键,可以通过修改表字段属性,也可以直接追加。
alter table 表名 add primary key(字段列表)
前提:表中字段对应的数据本身是独立的。(不重复)
主键约束
主键对应的字段中的数据不允许重复:一旦重复数据操作失败(增和改)
更新主键&删除主键
没有办法更新主键:主键必须先删除,才能增加。
alter table 表名 drop primary key;
自动增长
自增长:当对应的字段,不给值或者只给默认值或者给null的时候,会自动的被系统出发,
系统会从当前字段中已有的最大值再进行加1操作,得到一个新的在不同的字段。
自增长通常是跟主键搭配。
自增长特点:auto_increment
1.任何一个字段要做自增长必须前提是本身只有一个索引(key一栏有值)
2.自增长字段必须是数字(整型)
3.一张表最多只能有一个自增长
自增长使用
当自增长被指定的值为null或者默认值的时候会出发自动增长。
自增长如果对应的字段输入了值,那么自增长失效:但是下一次还是能够正确的自增长(从最大值+1)
修改自增长
自增长如果是涉及到字段改变:必须先删除自增长,后增加(一张表只能有一个自增长)
修改当前自增长已经存在的值:修改只能比当前已有的自增长的最大值打,不能小(小不能生效)
alter table 表名 auto_increment = 值;
删除自增长
自增长是字段的一个属性,可以通过modify来进行修改(保证字段没有auto_increment即可)
alter table 表名 modify 字段 类型;
唯一键
一张表中往往有很多字段需要具有唯一性,数据不能重复,但是一张表中只能有一个主键,
唯一键(unique key)就可以解决表中多个字段需要的唯一性的问题。
唯一键的本质与主键差不多,唯一键默认的允许为空,而且可以多个为空(空字段不参与唯一性比较)
增加唯一键
基本与主键差不多:三种方案
方案1.在创建表的时候,字段之后直接跟unique/unique key
方案2.在所有的字段之后增加unique key(字段列表);--复合唯一键
方案3.在创建表之后增加唯一键
更新唯一键&删除唯一键
更新唯一键:先删除后新增(唯一键可以有多个:可以不删)
alter table 表名 drop unique key;(错误,唯一键有多个)
alter table 表名 drop index 索引名字;
索引
几乎所有的索引都是建立在字段之上。
索引:系统根据某种算法,将已有的数据(未来可能新增的数据),单独建立一个文件,文件能够实现快速的匹配数据,
并且能够快速的找到对应表中的记录。
索引的意义
1.提升查询数据的效率
2.约束数据的有效性(唯一性等)
增加索引的前提条件:索引本身会产生索引文件(有时候有可能比数据文件还大),会非常耗费磁盘空间。
如果某个字段需要作为查询的条件经常时候用,那么可以使用索引(一定会想办法增加)
如果某个字段需要进行数据的有效性约束,也可能使用索引(主键,唯一键)
mysql中提供了多种索引
1.主键索引:primary key
2.唯一索引:unique key
3.全文索引:fulltext index
4.普通索引:index
全文索引:针对文章内容的关键字进行索引,
全文索引最大的问题:在于如何确定关键字
关系
将实体与实体的关系,反应到最终数据库表的设计上来,将关系分成三种,一对一,一对多(多对一),多对多。
所有的关系都是指的表与表之间的关系。
一对一
一对一:一张表的一条记录,一定只能与领一张表的一条记录进行对应,反之亦然。
学生表:姓名、性别、年龄、身高、体重、婚姻状况、籍贯、家庭住址、紧急联系人
将常用的和不常用的信息分离存储,分成两张表
不常用信息:保证不常用信息与常用信息一定能够对应上:找到一个具有唯一性(确定记录)
一个常用表中的一条记录:永远只能在一张补偿用表中匹配一条记录;反过来一个不常用表中的一条记录
在常用表中也只能匹配一条记录。一对一关系。
一对多
一对多:一张表中有一条记录可以对应另一张表中的多条记录,但是反过来,领一张表的一条记录只能对应第一张表的记录,
这种关系就是一堆多或者多对一。
孩子与母亲的关系:母亲、孩子两个实体。
妈妈表
孩子表
以上关系:一个妈妈可以在孩子表中找到多条记录(也有可能是一条),但是一个孩子只能找到一个妈妈
是一种典型的一对多的关系。
但是以上设计,解决了实体的设计表问题,但是没有解决关系问题,孩子找不到妈,妈也找不到孩子。
解决方案:在某一张表中增加一个字段,能够中找到另外一张表中的记录,应该在孩子表中增加一个字段指向妈妈表:
因为孩子表的记录只能匹配到一条妈妈表的记录。
多对多
多对多:一张表中(A)的一条记录能够对应另一张表(B)中的多条记录,同时B表中的一条记录也能对应A表中的多条记录:
多对多的关系。
老师教学:老师和学生
老师表
学生表
以上设计方案:实现了实体的设计,但是没有维护实体关系,一个老师教过多个学生,一个学生也被多个老师教过。
解决方案:不管在哪张表中增加字段,都会出现一个问题,该字段要保存多个数据。而且是与其他表有关系的字段,不符合表设计规范
增加一张新表,专门维护两张表之间的关系。
中间关系表:老师与学生的关系
增加中间表之后:中间表与老师表形成了一堆多的关系,而且中间表示多表,维护了能够唯一找到一表的关系。
同样的,学生表与中间表也是一个一对多的关系。一对多的关系可以匹配到关联表之间的数据
范式
范式:Normal Format,是一种离散数学中的知识,是为了解决一种数据的存储与优化的问题。
保存数据的存储之后,凡是能够通过关系寻找出来的数据,坚决不再重复存储:终极目标是为了减少数据的冗余。
范式:是一种分层结构的规范,分为六层:每一层都比上一层更加严格:若要满足下一层范式,前提是满足上一层。
六层范式:1NF,2NF,3NF...6NF,1NF是最底层,要求最低6NF最高层,要求最严格。
mysql属于关系型数据库:有空间浪费,也是致力于节省存储空间,与范式所有解决的问题不谋而合,在设计数据库的时候,
会利用到范式来指导设计。但是数据库不单是要解决空间问题,要保证效率问题,范式职位解决空间问题,
所以数据库的设计又不可能完全按照范式的要求实现,一般情况下,只有前三种范式需要满足。
范式数据库的设计当中是有指导意义:但是不是强制规范。
1NF
属性不可再分,字段保证原子性
2NF
第二范式:在数据表设计的过程中,如果有复合主键(多字段主键),且表中有字段并不是由整个主键来确定
而是依赖主键中的某个字段(主键的部分),如果存在字段依赖主键的部分问题,称之为部分依赖,第二范式就是
解决表设计不允许出现部分依赖。
解决方案:只要没有复合主键就复合第二范式
3NF
要满足第三范式,必须满足第一第二范式
第三范式:理论上讲,应该一张表中的所有字段都应该直接依赖主键(逻辑主键:代表的是业务主键),
如果表设计中存在一个字段,并不是直接依赖主键,而是通过某个非主键字段依赖,最终实现依赖主键,
把这种不是直接依赖主键而是依赖非主键字段的依赖关系称之为传递依赖,第三范式就是要解决传递依赖的问题。
讲师带课表
以上设计方案中:性别依赖讲师存在,讲师依赖主键,教室依赖班级,班级依赖主键,性别和教室都存在传递关系。
解决方案:将存在传递依赖的字段,以及依赖的字段本身单独取出,形成一个单独的表,然后再需要对应的信息的时候,
使用对应的尸体表的主键加进来
讲师带课表
讲师表 班级表
讲师表: ID = 讲师 班级表中:ID = 班级
数据高级操作
数据操作:增删改查
新增数据
insert 表名【(字段列表)】 values(值列表);
在数据插入的时候,假设主键对应的值已经存在:插入一定会失败。
主键冲突
当主键存在冲突的时候(Dupliccate key),可以选择性的进行处理
主键冲突:更新操作
insert into 表名{(字段列表,包含主键)}values(值列表)on duplicate key update 字段 = 新值;
主键冲突:替换
replace into 表名{(字段列表,包含主键)}values(值列表);
蠕虫复制
蠕虫复制:从已有的数据中去获取数据,然后将数据又进行新增操作,数据城北的增加
表创建高级操作:从已有表创建新表(复制表结构)
create table 表名 like 数据库表名;
蠕虫复制:先查出数据,然后将查出的数据新增一遍
insert into 表名{(字段列表)} select 字段列表 /* from 数据库表名
蠕虫复制的意义:
1.从已有表拷贝数据到新表中
2.可以迅速的让表中的数据膨胀,到一定的数量级,测试表的压力以及效率。
更新数据
基本语法:update 表名 set 字段 = 值{where 条件}
高级新增语法:update 表名 set 字段 = 值{where 条件} {limit 更新数量};
删除数据
与更新类似:可以通过limit来限制数量
delete from 表名 【where 条件】【limit 数量】
清空表重置自增长: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,0代表false,1代表true
判断条件:运算符:>,=,<=,!=,<>,=,like,between,and,in,not in
逻辑运算符:&&(and),||(or),!(not)
where原理:where是唯一一个直接从磁盘获取数据的时候开始判断的条件,从磁盘取出一条记录梦开始进行where判断,
判断的结果如果成立保存到内存,如果判断失败直接放弃。
group by 子句
group by:分组的意思,根据某个字段进行分组(相同的放一组,不同的分到不同的组)
基本语法:group by 字段名
分组的意思:是为了统计数据(按组统计,按分组字段进行数据统计)
sql提供了一系列统计函数:
count():统计分组后的记录数,每一组有多少记录
max():统计每组中最大的值
avg():统计平均值
sum():统计和
count函数:里面可以使用两种参数:*代表统计记录,字段名代表统计对应的字段(null不统计)
having 子句
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起始位置、长度;
主要用来实现数据的分页,为用户节省时间,提升服务器的相应效率,减少资源浪费。