数据库表操作

目录

一、表设计三范式

一、范式三约定

1、第一范式:确保每列保持原子性

2、第二范式:确保每行的唯一性

3、第三范式:确保每列都和主键列直接相关,而不是间接相关

二、范式应用举例分析

三、School数据库举例

二、主键约束和外键约束

一、关于完整性约束

二、主键约束

三、外键约束

三、其他约束

一、自增长

二、唯一约束

三、非空约束

四、检查约束

五、默认值约束

一、表设计三范式

关系数据库中的关系必须满足一定的要求,即满足不同的范式(Normal Format, 简单NF)。范式为设计数据库中表内关系,表与表之间的关系提供了规范和标准,任何按照范式设计的表结构将是最优结构,同时也可以避免数据冗余,减少数据库的存储空间,减轻维护数据完整性的麻烦。

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、第四范式(4NF)、第五范式(5NF)、第六范式(6NF)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。

一、范式三约定
1、第一范式:确保每列保持原子性

第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。

第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算 满足了数据库的第一范式

2、第二范式:确保每行的唯一性

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。即要求每个实体都必须具有主键进行区分。

要求实体的属性完全依赖于主关键字,不是依赖部分关键字

image-20210401150857228

这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。

下述表结构实现了第二范式要求:

image-20210401161706190

3、第三范式:确保每列都和主键列直接相关,而不是间接相关

第三范式需要确保数据表除外键外,其他非主键属性不得重复出现在第二张表上。

比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。

image-20210401152728590

二、范式应用举例分析

下面以一个学校的学生系统为例分析说明,这几个范式的应用:

  1. 第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。

    这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。在当前的任何关系数据库管理系统(DBMS)中,傻瓜也不可能做出不符合第一范式的数据库,因为这些DBMS不允许你把数据库表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的。

    首先我们确定一下要设计的内容包括那些。学号、姓名、年龄、性别、课程名称、课程学分、系别、学科成绩,系办地址、系办电话等信息。为了简单我们暂时只考虑这些字段信息。对于这些信息,关心的问题有如下几个方面:学生有那些基本信息?学生选了那些课,成绩是什么?每个课的学分是多少?学生属于那个系,系的基本信息是什么?

  2. 第二范式(2NF)实例分析:

    首先我们考虑,把所有这些信息放到一个表中(学号,姓名、年龄、性别、课程名称、课程学分、系别、学科成绩,系办地址、系办电话),互相存在如下的依赖关系:(学号) → (姓名,年龄,性别,系别,系办地址、系办电话)

    (课程名称) → (学分)

    (学号,课程) → (学科成绩)

    问题分析:

    因此不满足第二范式的要求,会产生如下问题数据冗余:同一门课程由n个学生选修,”学分”就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。

    更新异常:

    1. 若调整了某门课程的学分,数据表中所有行的”学分”值都要更新,否则会出现同一门课程学分不同的情况。

    2. 假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有”学号”关键字,课程名称和学分也无法记录入数据库。

    3. 删除异常:假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。

      解决方案:

      把选课关系表StudentCourse改为如下三个表:

      学生:Student (学号,姓名, 年龄,性别,系别,系办地址、系办电话)

      课程:Course (课程名称, 学分)

      选课关系:Score (学号, 课程名称, 成绩)

  3. 第三范式(3NF)实例分析:

    接着看上面的学生表Student(学号,姓名, 年龄,性别,系别,系办地址、系办电话),关键字为单一关键字”学号”,因为存在如下决定关系:

    (学号)→ (姓名,年龄,性别,系别,系办地址、系办电话)

    但是还存在下面的决定关系

    (学号)→ (所在学院)→(学院地点,学院电话)

    即存在非关键字段”学院地点”、”学院电话”对关键字段”学号”的传递函数依赖。它也会存在数据冗余、更新异常、插入异常和删除异常的情况。根据第三范式把学生关系表分为如下两个表就可以满足第三范式了:

    学生:Student (学号,姓名,年龄,性别,系别)

    系别:Dept (系别,系办地址、系办电话)。

    上面的数据库表就是符合I,II,III范式的,消除了数据冗余、更新异常、插入异常和删除异常。

三、School数据库举例

1、学生表

编号学号姓名年龄学历班级编号
1WN001靳小杰23大专T03
2WN002刘小畅24本科T03
3WN003姜小泊25大专T03
4WN004毛小东22本科T03
5WN005王小鹏21大专T03
6WN006文小玉25本科T03
7WN007周小钊23本科T02
8WN008王小杰26大专T02
9WN009何小松30本科T02
10WN010杨小宁28本科T02

2、学生详细信息表

编号学号身份证地址毕业院校
1WN0011111西安交大
2WN002222宝鸡科大
3WN003333汉中电大
4WN004444榆林农大
5WN005555延安林大

3、班级表

编号班级编号班级名称班主任
1T01一期班李小华
2T02二期班秦小超
3T03三期班王小斌
4T04四期班张小三
5T05五期班周小四

4、课程表

编号课程编号课程名称任课老师
1C01外语李小华
2C02数学秦小超
3C03语文王小斌
4C04编程张小三
5C05艺术周小四
6C06体育王小五
7C07历史赵小六

5、成绩表

编号学号课程编号成绩选课日期
1WN002C01702018
2WN002C03752017
3WN002C04902019
4WN005C02702018
5WN005C01752017
6WN008C03902019
7WN008C04702017

小结

  1. 数据库表设计时,需要遵从“范式三约定”

  2. 第一范式:列具有原子性,不可再分;

  3. 第二范式:遵循第一范式基础上,表中的列必须要与主键相关;

  4. 第三范式:遵循第一,二范式基础上,表中的列必须要与主键直接相关,不能间接相关。间接相关的,应该分到其它表,使用外键建立关系维护

二、主键约束和外键约束

所谓约束:就是指我们在创建表的过程中,给表的字段添加一些条件!在这些条件的配合下,可以保证数据的唯一性,完整性。有的约束针对整行有效 ,有的约束只针对某一列有效。

一、关于完整性约束

img

img

  1. 域完整性:限制数据类型、外键约束、默认值、非空约束。

  2. 实体完整性:唯一约束、主键约束、自增列。

  3. 参照完整性:主外键关联。

  4. 自定义完整性:规则、存储过程、触发器。

二、主键约束

表中有一列或几列组合的值能用来唯一地标识表中的每一行,这样的一列或者多列的组合叫做表的主键。如:学号可以作为学生表的主键,课程号可以作为课程表的主键,(学号,课程号)作为成绩表的主键(组合键)。

一个表只能有一个主键,主键约束确保了表中的行是唯一的。

表中可以没有主键,但是通常情况下应当为表设置一个主键。

主键选择原则:

  1. 最少性:尽量选择一个键作为主键

  2. 稳定性:尽量选择数值更新少的值作为主键

  3. 去业务性:尽量不选择具备业务含义的列作为主键,例如:身份证,电话号码……

创建主键的3种方式:

  1. 直接在字段定义后面声明主键

      create table student_info (id bigint primary key,                           student_name varchar(20),                           
      age tinyint,                           
      gender tinyint,                           
      telphone varchar(11),                           
      study_direction varchar(20)) 
      engine=innodb character set = utf8mb4;

    id bigint primary key 直接在id列后面,添加主键约束

  2. 用constraint声明主键

      create table student_info (id bigint,                           
      student_name varchar(20),                           
      age tinyint,                          
      gender tinyint,                          
      telphone varchar(11),                          
      study_direction varchar(20),                          
      CONSTRAINT pk_student_info primary key (id)) engine=innodb character set = utf8mb4;     
      # pk_student_info    规范:pk_表名 或者: 
      create table student_info (id bigint,                          
      student_name varchar(20),                           
      age tinyint,                           
      gender tinyint,                           
      telphone varchar(11),                           
      study_direction varchar(20),                          
      PRIMARY KEY (student_name, telphone)) engine=innodb character set = utf8mb4; # 复合主键
  3. 用ALTER语句补充声明主键

      create table student_info (
      id bigint,                           
      student_name varchar(20),                           
      age tinyint,                           
      gender tinyint,                           
      telphone varchar(11),                           
      study_direction varchar(20)) 
      engine=innodb character set = utf8mb4;  
      ALTER TABLE student_info add CONSTRAINT pk_student_info PRIMARY KEY (id);

删除主键的方式:

 ALTER TABLE student_info DROP PRIMARY KEY;
三、外键约束

什么是外键:简单地说,就是“子表”中对应于“主表”的列,在子表中称为外键或者引用键。

它的值要求与主表的主键或者唯一键相对应,外键用来强制引用完整性。例如在成绩表中,学号为外键。一个表可以有多个外键。

image-20210406160902906

创建学生表:

 create table student_info (
 id bigint primary key,                          
 student_name varchar(20),                          
 age tinyint,                          
 gender tinyint,                          
 telphone varchar(11),                          
 study_direction varchar(20)) 
 engine=innodb character set = utf8mb4;

创建课程表:

 create table course_info (
 id bigint primary key,                          
 course_name varchar(20)) 
 engine=innodb character set = utf8mb4;

指定外键更新或删除的行为:

  1. 如果子表试图创建一个在父表中不存在的外键值,InnoDB会拒绝任何INSERT或UPDATE操作

  2. 如果父表试图UPDATE或者DELETE任何子表中存在或匹配的外键值,最终动作取决于外键约束定义中的ON UPDATE和ON DELETE选项。InnoDB支持5种不同的动作,如果没有指定ON DELETE或者ON UPDATE,默认的动作为RESTRICT

  3. CASCADE: 从父表中删除或更新对应的行,同时自动的删除或更新自表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持

  4. SET NULL: 从父表中删除或更新对应的行,同时将子表中的外键列设为空。注意,这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持

  5. NO ACTION: InnoDB拒绝删除或者更新父表

  6. RESTRICT: 拒绝删除或者更新父表。指定RESTRICT(或者NO ACTION)和忽略ON DELETE或者ON UPDATE选项的效果是一样的

创建外键的2种方式:

  1. 直接在建表时使用foreign key来声明

      create table student_course_info (id bigint primary key,                           
      fk_student_id bigint,                           
      fk_course_id bigint,                           
      score int,                           
      choice_date date,                           
      foreign key (fk_student_id) references student_info(id) on delete cascade on update cascade,                           foreign key (fk_course_id) references course_info(id) on delete cascade on update cascade) 
      engine=innodb character set = utf8mb4;
  2. 通过CONSTRAINT添加外键

     create table student_course_info (id bigint primary key,                           
      fk_student_id bigint,                           
      fk_course_id bigint,                           
      score int,                           
      choice_date date) engine=innodb character set = utf8mb4; 
      ALTER TABLE student_course_info ADD CONSTRAINT fk_student_id FOREIGN KEY (fk_student_id) REFERENCES student_info (id) ON DELETE CASCADE ON UPDATE CASCADE; 
      ALTER TABLE student_course_info ADD CONSTRAINT fk_course_id FOREIGN KEY (fk_course_id) REFERENCES course_info (id) ON DELETE CASCADE ON UPDATE CASCADE;

删除外键的方式:

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称

小结

  1. 数据库中约束可分为:列/域完整性,实体完整性,参照完整性,自定义完整性。

  2. 列完整性,主要控制列的条件。而实例完整性,主要控制行的条件。参照完整性,主要描述表与表之间的相关性

  3. 主键约束的目的:主要保证行数据的完整性,以及唯一性

  4. 外键约束的目的:主要保证“子表”能根据外键,找到“主表”的数据

  5. 当然外键约束,可能存在一定的级联操作,特别是更新或删除数据时。

三、其他约束

一、自增长

自增长,也是一种约束。但是这种约束,只能定义在主键上,且一张表只能有1个自增长!

自增长约束的目的,让主键列可以实现自动变化,程序员减少对主键的生成性的操作。

image-20210406172546228

create table student_info (id bigint primary key auto_increment,                           
student_name varchar(20),                          
age tinyint,                          
gender tinyint,                          
telphone varchar(11),                          
study_direction varchar(20)) engine=innodb character set = utf8mb4;

但是:auto_increment 只针对数值类型有效,其他类型将无法使用!

二、唯一约束

唯一约束,同样也是保证数据行完整性的一种。

唯一约束的目的:保证某一列数据的唯一性,例如:身份证,电话号码…… ,如果重复添加,将抛出异常!

image-20210406194613612

create table student_info (id bigint primary key auto_increment,                           
student_name varchar(20),                          
age tinyint,                          
gender tinyint,                          
telphone varchar(11) unique,                          
study_direction varchar(20)) engine=innodb character set = utf8mb4;
三、非空约束

非空约束,主要保证某一列的值,一定要有值,不能为Null。

image-20210406195037585

create table student_info (
id bigint primary key auto_increment,                           
student_name varchar(20) not null,                          
age tinyint,                          
gender tinyint,                          
telphone varchar(11) unique,                          
study_direction varchar(20)) 
engine=innodb character set = utf8mb4;

默认情况下,如果列名后未加not null,该列数据是可以添加null数据的

四、检查约束

检查约束:检查某一个列的值,是否是自己规定的值,如果不是将抛出异常!

image-20210406195454713

create table student_info (
id bigint primary key auto_increment,                           
student_name varchar(20) not null,                          
age tinyint,                          
gender set('男','女'),                         
telphone varchar(11) unique,                          
study_direction varchar(20)) 
engine=innodb character set = utf8mb4;

或者
create table student_info (
id bigint primary key auto_increment,                           
student_name varchar(20) not null,                          
age tinyint,                          
gender enum('男','女'),                          
telphone varchar(11) unique,                          
study_direction varchar(20)) 
engine=innodb character set = utf8mb4;
五、默认值约束

默认值约束:主要为某一列进行默认值设置,当用户未录入数据时,就填充默认值!

image-20210406200355021

create table student_info (id bigint primary key auto_increment,                           
student_name varchar(20) not null,                          
age tinyint,                          
gender set('男','女'),                          
telphone varchar(11) unique,                          
study_direction varchar(20),                          
password varchar(32) default '123456') engine=innodb character set = utf8mb4;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值