持久层设计与实施

原创 2015年07月07日 21:34:52

持久层设计与实施

系统工程=程序+文档,程序是由逻辑结构+数据构成,那么对于数据的处理就显得格外重要。一个程序中会用到很多数据,然而不是所有的数据都需要存入数据库。我们在设计系统的时候应该如何做出选择呢?

首先,我们可以逐条解析需求说明书,从中提取所有出现的数据,然后将数据按照处理方式分类:部分数据只是在处理逻辑中使用,那么它们只需要赋给变量,部分数据可以写入文档,那么它们可以存放在工程文件夹中,最终可能一起放入服务器中保存,剩下的数据,需要持久保存时,才考虑将其存入数据库。对于有必要存入数据库的数据,我们按照功能逻辑先做一个简单的分组。

为了使数据库更加合理,高效。我们需要用三范式来规范每个数据表的属性。三范式拆分原则如下:

l        第一范式:确保每列属性保持原子性,即不可拆分。原子性是相对的,根据实际需求而定,要考虑是否便于查询,是否用到某属性处理业务逻辑

l        第二范式:主键列与非主键列遵循完全函数依赖关系,即确保表中的每列非主属性都和每个主键属性相关。确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。只要数据列中出现数据重复,就要把表拆分开来。

l        第三范式:非主键列之间没有传递函数依赖关系,确保每列都和主键列直接相关,而不是间接相关

有时候不能死板地套用三范式,还要根据具体情况,考虑需求和性能,做出更合理的取舍。

当用三范式规范了表结构之后,我们该考虑各个数据表之间的关系了,表与表之间本来是没有关系的,为什么要考虑关系呢?因为业务逻辑的需要,因为要查询出不同数据表信息的组合,所以才建立表格之间的关系。那么我们就可以从多表连接查询入手,来探究表之间的关系。新建两张表:student表和course表

          

(实际开发中这两个表会有自己不同的主键。)

1.       外连接

外连接可分为:左连接、右连接、完全外连接。

l        左连接left join或left outer join

SQL语句:select * from student left join course onstudent.ID=course.ID
执行结果:

左外连接包含left join左表所有行,如果左表中某行在右表没有匹配,则结果中对应行右表的部分全部为空(NULL)。【此时我们不能说结果的行数等于左表数据的行数。当然此处查询结果的行数等于左表数据的行数,因为左右两表此时为一对一关系】

l        右连接right join或right outer join

SQL语句:select *from student right join course on student.ID=course.ID
执行结果:

右外连接包含right join右表所有行,如果左表中某行在右表没有匹配,则结果中对应左表的部分全部为空(NULL)。【同样此时我们不能说结果的行数等于右表的行数。当然此处查询结果的行数等于左表数据的行数,因为左右两表此时为一对一关系】。

l        完全外连接full join或full outer join

SQL语句:select * from student full join course onstudent.ID=course.ID
执行结果:

完全外连接包含full join左右两表中所有的行,如果右表中某行在左表中没有匹配,则结果中对应行右表的部分全部为空(NULL),如果左表中某行在右表中没有匹配,则结果中对应行左表的部分全部为空(NULL)。

2.     内连接join或inner join

SQL语句:select * from student inner join courseon student.ID=course.ID
执行结果:

inner join 是比较运算符,只返回符合条件的行。此时相当于:select * from student,course where student.ID=course.ID

3.     交叉连接cross join

没有 WHERE 子句的交叉联接将产生连接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。SQL语句:select * from student cross joincourse执行结果:

如果我们在此时给这条SQL加上WHERE子句的时候比如SQL:select* from student cross join course where student.ID=course.ID此时将返回符合条件的结果集,结果和inner join所示执行结果一样。

4.     两表关系为一对多,多对一或多对多时的连接语句

当然上面两表为一对一关系,那么如果表A和表B为一对多、多对一或多对多的时候,我们又该如何写连接SQL语句呢?其实两表一对多的SQL语句和一对一的SQL语句的写法都差不多,只是查询的结果不一样,当然两表也要略有改动。比如表1的列可以改为:Sno Name Cno。表2的列可以改为:Cno CName。这样两表就可以写一对多和多对一的SQL语句了,写法和上面的一对一SQL语句一样。下面介绍一下当两表为多对多[需要建立中间关系表]的时候我们该如何建表以及些SQL语句。新建三表:student 表,course表,和student_course表

                

一个学生可以选择多门课程,一门课程可以被多个学生选择,因此学生表student和课程表course之间是多对多的关系。当两表为多对多关系的时候,我们需要建立一个中间表student_course,中间表至少要有两表的主键,当然还可以有别的内容。SQL语句:select s.Name,C.Cname from student_course as sc left join student ass on s.Sno=sc.Sno left join course as c on c.Cno=sc.Cno执行结果:

此条SQL执行的结果是学生选课的情况。

通过上面各种表之间的连接的关系,我们就可以根据实际情况,考虑各个表之间的关系了。那么我们明确一下几个问题:

[1]一对一,一对多/多对一还是多对多?

答:根据一条记录实例来考虑这一问题.

[2]外键应该建在哪个表[如何区分主表,从表]?

答:若是一对一关系,那么只要存在相同属性值的属性列,外键甚至可以不建立,如果建立外键,那么外键任意建立在哪个表.根据实际情况,逻辑情况做出选择.

   若是一对多关系,那么外键应该放在多的一方.

[3]单向还是双向?

答:不论外键是如何建立,都可以通过左外链和右外链查询到结果

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

JAVA三层架构,持久层,业务层,表现层的理解

SSH:Struts(表示层 )+Spring(业务层)+Hibernate(持久层)Struts: Struts是一个表示层框架,主要作用是界面展示,接收请求,分发请求。在 MVC框架 中,...

鲁棒的持久层设计

  • 2008年01月08日 19:31
  • 484KB
  • 下载

持久层设计与资源管理模式笔记

持久层设计与资源管理模式  无论是怎样的应用系统,都无法脱离对资源的管理和使用。而对于持久层而言,资源的合理管理和调度则显得尤为重要。  在大多数应用系统中,80%以上的应用逻辑并不需要特别复...
  • liu93
  • liu93
  • 2014年11月08日 22:57
  • 246

OPLib对象持久层 (源码)

  • 2006年03月16日 00:00
  • 358KB
  • 下载

用Hibernate和Spring开发持久层

  • 2007年06月25日 12:40
  • 325KB
  • 下载

【持久层】java程序猿的JDBC知识点

声明:本文只是JDBC和数据库的一个知识路线图,只是给出了一个大概的学习结构,很多东西提到了但是没有细节,需要自行丰富。 一、基本操作     JDBC的基本操作,总结起来就是...

用 Hibernate 和 Spring 开发持久层

  • 2008年04月02日 12:51
  • 269KB
  • 下载

自定义持久层(dao)框架

2. 自定义持久层(dao)框架 更新案例:(insert/update/delete) 1.       加载驱动 2.       获取连接 3.       创建pstmt对象 4. ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:持久层设计与实施
举报原因:
原因补充:

(最多只允许输入30个字)