数据库设计及应用

目录

数据库几种范式

1NF,即第一范式,是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。第一范式的模式要求属性值不可再分裂成更小部分,即属性项不能是属性组合或由组属性组成。

简而言之,第一范式就是无重复的列。例如,由“职工号”“姓名”和“电话号码”组成的表(一个人可能有一个办公电话和一个移动电话),这时将其规范化为1NF可以将电话号码分为“办公电话”和“移动电话”两个属性,即职工表(职工号、姓名、办公电话和移动电话)。

2NF,即第二范式,是在第一范式(INF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。

第二范式(2NF)要求数据库表中的每个实例或行必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。如果关系模式R为第一范式,并且R中每一个非主属性完全函数依赖于R的某个候选键,则称R为第二范式模式。(如果A是关系模式R的候选键的一个属性,则称A是R的主属性,否则称A是R的非主属性)例如,在选课关系表(学号、课程号、成绩和学分)中,关键字为组合关键字(学号、课程号),但由于非主属性学分仅依赖于课程号,对关键字(学号、课程号)只是部分依赖,而不是完全依赖,所以,此种方式会导致数据冗余以及更新异常等问题,解决办法是将其分为两个关系模式:学生表(学号、课程号和分数)和课程表(课程号、学分)新关系通过学生表中的外关键字课程号联系,在需要时进行连接。

3NF,即第三范式,如果关系模式R是第二范式,且每个非主属性都不传递依赖于R的候选键,则称R是第三范式的模式。例如,学生表(学号、姓名、课程号和成绩),其中,学生姓名无重名,所以,该表有两个候选码(学号、课程号)和(姓名、课程号),则存在函数依赖:学号→姓名,(学号、课程号)→成绩,(姓名、课程号)→成绩,唯一的非主属性成绩对码不存在部分依赖,也不存在传递依赖,所以,它属于第三范式

BCNF构建在第三范式的基础上,如果关系模式R是第一范式,且每个属性都不传递依赖于R的候选键,那么称R为BCNF范式的模式。假设仓库管理关系表(仓库号、存储物品号、管理员号和数量),满足一个管理员只在一个仓库工作,一个仓库可以存储多种物品,则存在如下关系:

  • (仓库号、存储物品号)→(管理员号、数量)
  • (管理员号、存储物品号)→(仓库号、数量)

即存在关键字段决定关键字段的情况,所以,其不符合BCNF范式。把仓库管理关系表分解为两个关系表:仓库管理表(仓库号、管理员号)和仓库表(仓库号、存储物品号和数量),这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。

4NF,即第四范式,设R是一个关系模式,D是R上的多值依赖集合。如果D中成立非平凡多值依赖X→Y时,X必是R的超键,那么称R是第四范式的模式。例如,职工表(职工编号、职工孩子姓名和职工选修课程),在这个表中,同一个职工也可能会有多个职工孩子姓名,同样,同一个职工也可能会有多个职工选修课程,即这里存在着多值事实,不符合第四范式。如果要符合第四范式,只需要将此表分为两个表,使它们只有一个多值事实,例如:职工表一(职工编号、职工孩子姓名)和职工表二(职工编号、职工选修课程),两个表都只有一个多值事实,所以,符合第四范式。

1 定义有表结构如下所示:

(1)表名: g_cardapply

字段(字段名/类型长度):g_applyno varchar 8:申请单号(关键字);g_applydate bigint 8:申请日期;g_state varchar 2:申请状态

(2)表名: g_cardapplydetail

字段(字段名/类型/长度):g_applyno varchar 8:申请单号(关键字);g_name varchar 30:申请人姓名;g_idcard varchar 18:申请人身份证号;g_state varchar2:申请状态

其中,两个表的关联字段为申请单号,题目:

1)查询身份证号码为612301430103082的申请日期          2)查询同一个身份证号码有两条以上记录的身份证号码及记录个数

3)将身份证号码为612301430103082的记录在两个表中的申请状态均改为15          4)删除g_cardapplydetail表中所有姓张的记录

解题分析:

1) 主要思路为:从g_cardapplydetail中找到身份证号对应的 g_applyno,然后根据g_applyno在表g_cardapply中找出申请日期即可,下面给出两种写法:

select tl g_applydate from g_cardapply tl, g_cardapplydetail t2 where t2.g_idcard = '612301430103082' and tl.g_applyno= t2.g applyno

select g_applydate from g_cardapply where g_idcard in (select g_idcard from g_cardapplydetail where g_idcard = '612301430103082')

2)本题的主要思路为:首先按身份证号码进行分组,然后统计每个身份证出现的次数,最后把出现次数大于或等于2的信息查询出来,SQL语句如下:

select g_idcard, count(g_idcard) as num from g_cardapplydetail group by g_idcard having count(g_idcard) > 1

3)更新记录需要使用update语句,可以使用两条SOL语句分别更新两张表

UPDATE g_cardapplydetailset g_state='15' WHERE g_idcard='612301430103082'

UPDATE g_cardapply SET g_state='15' WHERE g_applyno IN (SELECT g_applyno FROM g_cardappdetail WHERE g_idcard='612301430103082)

当然也可以把这两个SQL语句写到一个存储过程里面,存储过程的参数为身份证号码。为了保持数据库中数据的一致性,最好把这两条 update语句放到一个事务中。

4)本题考察的是对like子句模糊查询的理解,SQL语句如下

DELETE FROM g_cardapplydetail WHERE g_name LIKE '张%'

2 论坛系统数据库设计

一个简单的论坛系统中数据库扮演着非常重要的角色,假设数据库需要存储如下的一些数据:用户名、 email、主页、电话、联系地址、发帖标题、发帖内容、回复标题以及回复内容。每天论坛的访问量达400万左右,更新帖子达10万左右。请给出数据库表结构设计并结合范式简要说明设计思路

解题分析:

(1)分析

在论坛系统中,最重要的对象就是用户与帖子。显然,可以给用户单独设计一张表,由于帖子对象比较特殊,每个帖子都会有回复帖,而回复帖也会有回复帖,如此递归。由于论坛中会有大量的帖子,因此,对帖子表的设计是非常重要的。为了提高査询效率,在设计的时候可以把主题帖与回复帖分开为两张表;对于回复帖的回复帖,可以考虑在回复帖的表中增加一个额外的字段(回复帖子的id)。

(2)E-R图设计

通过以上分析可知,这个简单的论坛系统主要有3个实体:用户 t_user、主题帖 t_mainPost和回复帖 t_replayPost。它们之间有如下关系

1)一个用户可以发0个或多个主题帖,因此, t_user与 t_mainPost的关系为一对多的关系。

2)一个用户可以有0个或多个回复帖,因此, t_user与 t_replayPost的关系为一对多的关系。

3)一个主题帖可以有0个或多个回复帖,因此, t_mainPost与 t_replayPost的关系也是对多的关系。

通过以上分析,数据库设计的E-R图如下图所示

 

 (3)E-R图转关系模型

当把E-R图转换为表的时候需要考虑如下规则:每一个实体可以转换为一张表,实体的属性就是表的列。实体关系的转换需要遵循下面的规则:

1)一个1:1的关系可以有如下两种转换方式:

①创建单独的关系表,则这个表中的主要内容为1:1关系的两个表的主键。

②两个实体合并为一张表,把两个表的属性合并,创建一张表。

2)一个1:n的关系可以有如下两种转换方式:

①创建单独的关系表,则这个表中的主要内容为1n关系的两个表的主键。

②通过在n端的表中引入一列(1端表的主键)作为外键,一般采用这种方式来减少表的个数,从而提高查询效率。

3)一个m:n关系转换为一个关系模式。只能创建单独的关系表,关系表中的主要内容为两个表的主键。

上面设计的E-R图只有1:n的关系,通过在n端引入1端实体的主键,得到数据库表结构为:

1) t_user表

 

2) t_mainPost表

3) t_replayPost表

 (4)结论

1)显然,表中每个字段不可再分,因此满足1NF

2)表中的每一行都可以唯一地用id区分,且不存在部分依赖,因此,满足2NF。

3) t_replaypost表存在传递依赖(rid→ r_paient_id, r_paient_id→mid),因此,这个设计不满足3NF。

数据库的范式主要目的是防止数据冗余、更新异常、插入异常和删除异常,范式越高,冗余越少。但是高的范式可能会带来处理速度缓慢和处理逻辑复杂的问题。因此,并不是范式越高越好,在实际设计的时候,需要权衡范式与效率,而不能盲目地追求高范式而忽视效率。对于本题而言, t_replaypost被设计为不满足3NF,虽然增加了冗余,但是能明显地提高效率。

社区身份设计

 一个人在社区中会有各种各样的身份,和不同的人相处会有不同的关系。请自行设计数据库(表结构,个数不限),保存一个人的名字、关系(包括父亲,朋友们),并尽可能少的时间空间开销组织好每个人和其他人的关系,组织好后尝试取出一个人的关系结构。请详细写出其中涉及的SQL语句、数据结构和数据组织,代码可以用伪代码或你熟悉的任何代码

解题分析:

这道题要求存储三类信息:用户信息、关系信息以及用户之间的关系信息
(1)用户表:存储用户基本信息
# 这个主键可以使用数据库自增的方式来实现,不同的数据库定义的方法有所不同)
CREATE TABLE user_info(user_id INT PRIMARY KEY,user_name VARCHAR(30) ,user_age INT);

 

 (2)用户关系定义表:主要存储用户之间所有可能的关系

CREATE TABLE relation_ define(relation_id INT PRIMARY KEY, relation_name varchar2(32));

 

(3)用户关系信息表:存储用户关系信息

CREATE TABLE user_relation(user_id INT, rel_user_id INT,relation_id INT );

-- 查询用户1的社会关系
SELECT a.user_name, b.relation_name FROM user_info a, relation_define b, 
-- 把这一部分查询结果定义为C
(SELECT user_id,relation_id FROM user_relation 
    WHERE rel_user_id =1 UNION SELECT rel_user_id AS user_id,relation_id FROM user_relation WHERE user_id =1) c 
    
WHERE a.user id=c er id AND b.relation id=c.relation id

0

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值