夜鹰教程网-程序员的加油站
 当前位置:文章中心 >> sql2016_sql2012_sql2015_sql2008
关系模型和对象模型的究竟匹配还是不匹配?
夜鹰教程网 来源:www.yyjcw.com 日期:2016-11-7 23:19:56
震惊的只是三大范式和我们现在遵循ORM的原则去设计数据库的方式如出一辙!我简单摘要书中内容如下: 
在过去的很多年,我以为关系模型就是传统的企业应用当中DBA设计的那些无数冗余字段,多个模型合并到一个表里面的数据库设计方式,这种数据库设计非常适合复杂的OLAP类型的查询,他可以有效的消除多表联合查询,而我们大家都知道,大表的复杂关联查询是性能杀手,一旦无法有效利用索引,导致了全表扫描,等待你的只有数据库服务器硬盘灯的狂闪不止,和无数进程阻塞在IO WAIT状态的无奈。

我前几个月订购了一本人邮图灵出版的《MySQL 5 权威指南》第三版中文版,买这本书只是因为有人送我China-Pub的优惠券,我就顺手买本MySQL的书,用来管理JavaEye服务器的时候备查的。其实这本书内容很一般,他说的东西我都知道了,所以这本书我拿过来随手翻了翻就感觉到买的不值得。但是当我随手翻到第8章第5节第138页介绍什么是三大范式的时候,我终于知道我错了。

从138页到142页,作者深入浅出举例说明了三大范式,我被震了,就这几页让我觉得买这本书值了。对于我这个不是计算机科班出身的人来说,到现在才知道什么是三大范式不算可耻。我震惊的只是三大范式和我们现在遵循ORM的原则去设计数据库的方式如出一辙!我简单摘要书中内容如下:

引用
第一范式:
1、内容相似的数据列必须消除(消除的办法就是再创建一个数据表来存放他们,建立关联关系)
2、必须为每一组相关数据分别创建一个表
3、每条数据记录必须用一个主键来标示

第二范式:
1、只要数据列里面的内容出现重复,就意味着应该把表拆分为多个表
2、拆分形成的表必须用外键关联起来。

第三范式:
1、与主键没有直接关系的数据列必须消除(消除的办法就是再创建一个表来存放他们)


这三大范式就像给ORM的人如何设计数据库写的指南:
引用
第一范式:
1、每个持久对象映射一张表
2、每个持久对象必须有一个主键

第二范式:
1、持久对象要有内聚性,冗余的内容拿出去,单独创建持久对象
2、持久对象之间的关系用外键关联

第三范式:
1、持久对象要有内聚性,无关的内容拿出去,单独创建持久对象


关系模型和对象模型是不是在存储概念上一致,就不用多说废话了。

说关系模型和对象模型“阻抗不匹配”,当然是有不匹配的地方,比方说对象模型当中特有的“继承”,“组合”,“聚合”,“依赖”的概念在关系模型当中是不存在的,但是这种模型的“阻抗不匹配”最终在存储模型是还是能够统一起来的,这就是ORM的作用:

1、对象的继承关系可以表达为三种不同的关系存储模型:整个继承数一张表;每个继承层次一张表;每个对象一张表

2、对象的组合和聚合可以用主外键关联的表来存储,它可以表达1:n,n:1和n:m的关系

3、对象的依赖关系和存储无关,所以不需要ORM做什么。

所以结论就是这样:

关系模型和对象模型存在概念上的阻抗不匹配,但是在关系数据库的存储模型上是一致的,无论你从关系模型的三大范式理论出发,还是从对象模型的ORM理论出发,最终一定会得到一致的数据库表设计。

这里值得我们反思的一个问题是:为什么传统的数据库应用人们这样漠视和违反三大范式?在很多所谓的金融、电信等超级大项目当中,连主键都没有的表比比皆是,一张表上百个字段,字段之间没有什么逻辑关系的情况比比皆是?

我想答案在于:传统的数据库应用软件开发,程序员很难从符合三大范式的数据模型当中获得有效的查询性能。符合三大范式就意味着数据库表会拆分的很细,表间关联很多,统计分析查询就不可避免的导致n张表的联合查询,在没有有效的应用层缓存的情况下,这种查询无可避免的性能低下。这使得程序员宁肯违背三大范式,而选择查询性能优先的数据库设计。

但是我们现在不一样了,有了良好的ORM框架和应用层的对象缓存机制,我们可以做到:让比较简单的查询根本不打扰数据库,让比较复杂的查询尽量少的扫描表记录,其最终达到的效果在OLTP类型的应用上面效果远远超过传统的方式。

以JavaEye网站为例:JavaEye使用了Rails的ActiveRecord ORM,表设计符合三大范式,所有页面都是动态页面,要对数据库发送大量查询,很多Web页面至少要向数据库发送50条以上的SQL语句。根据对数据库和Memcached Server的统计数据表明:JavaEye网站平均每秒向数据库发送140条SQL语句,平均每秒向Memcached Server发送250次缓存查询,缓存命中率大概为85%,也就是说缓存服务器要比数据库服务器繁忙将近一倍,而Ruby应用程序的数据有60%是来自Memcached Server,而只有40%是直接来自MySQL的。

为了加深大家印象,再给大家一个数据,目前JavaEye的Web服务器CPU负载在40-60%左右,而JavaEye的数据库服务器CPU负载只有20%-30%,IO WAIT几乎没有。所以良好的遵循三大范式,利用好ORM和对象缓存,可以取得非常棒的应用性能,还可以让你的数据库更加轻松。
最后,我的结论就是对象模型和关系模型在数据库存储上不存在阻抗不匹配,面向对象的程序设计和面向数据库的程序设计应该是一致的,而不应该是对立和冲突的,请不要把面向对象和面向数据库对立起来,不是他们对立,而是你不了解什么才是真正良好的设计。
复制链接 网友评论 收藏本文 关闭此页
上一条: 用java编程时,怎么用它和数据库相…  下一条: 关系数据库设计之基本规则--范式
夜鹰教程网成立于2008年,目前已经运营了将近 13 年,发布了大量关于 html5/css3/C#/asp.net/java/python/nodejs/mongodb/sql server/android/javascript/mysql/mvc/easyui/vue/echarts原创教程。 我们一直都在坚持的是:认证负责、一丝不苟、以工匠的精神来打磨每一套教程,让读者感受到作者的用心。我们默默投入的时间,确保每一套教程都是一件作品,而不是呆板的文字和视频! 目前我们推出在线辅导班试运营,模式为一对一辅导,教学工具为QQ。我们的辅导学科包括 java 、android原生开发、webapp开发、商城开发、C#和asp.net开发,winform和物联网开发、web前端开发,但不仅限于此。 普通班针对的是国内学员,例如想打好基础的大学生、想转行的有志青年、想深入学习的程序员、想开发软件的初学者或者业余爱好者等。 就业办针对即将毕业上岗的大四学生,或者打算转行的初级开发工程师。 留学生班针对的是在欧美、加拿大、澳洲、日本、韩国、新加坡等地留学的中国学子,目的是让大家熟练地掌握编程技能,按时完成老师布置的作业,并能顺利地通过考试。 详细咨询QQ:1416759661   夜鹰教程网  基于角色的权限管理系统(c-s/b-s)。
  夜鹰教程网  基于nodejs的聊天室开发视频教程
  夜鹰教程网  Git分布式版本管理视频教程
  夜鹰教程网  MVC+EasyUI视频教程
  夜鹰教程网  在线考试系统视频教程
  夜鹰教程网  MongoDB视频教程。
  夜鹰教程网 Canvas视频教程
  夜鹰教程网 报表开发视频教程
  热点推荐
牛人是怎样处理海量数据的
MYSQL与MSSQL UPDATE两表更新语法…
SQL SERVER常用日期函数的详解
随机查询ORDER BY NEWID()
批量插入数据 延时 SQL
用sql转换汉字为拼音
定时同步服务器上的数据
SQL Server 2008与SQL Server 200…
在XP下安装SQL Server2000 清除安…
SQL触发器实例
Mssql触发器学习例子之UPDATE触发…
两表连接的SQL语句
写一个HTML代码或C++代码分析器是…
分页存储过程!
普通行列转换 SQL(1)
  最近更新
SQL命令:增加字段、修改字段、修…
sql 中的 indexOf 与 lastIndexOf…
SQL中使用正则表达式提取或者过滤…
什么是BI?
Mongodb是一种比较常见的NOSQL数据…
SQL2008 提示评估期已过的解决方法…
存在属性(Directory, Compressed)…
属性不匹配directory,archive
sql2012安装图解教程
一条sql语句批量插入多条记录
sql2016下载
sql server2008 r2 密钥
sql2016安装密钥
sql2016安装图解教程
sql server 2012提示评估期已过的…

关于我们 | 网站建设 | 技术辅导 | 常见问题 | 联系我们 | 友情链接

夜鹰教程网 版权所有 www.yyjcw.com All rights reserved 备案号:蜀ICP备08011740号3