仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1557|回复: 8
打印 上一主题 下一主题

[学习教程] MSSQL网页编程之数据库正轨化和计划技能

[复制链接]
飘飘悠悠 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:42:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
限制,如果WHERE子句的查询条件里有不等号(WHEREcoloum!=),MySQL将无法使用索引。类似地,如果WHERE子句的查询条件里使用了函数(WHEREDAY(column)=),MySQL也将无法使用索引。技能|计划|数据|数据库在静态网站的计划中,数据库计划的主要性不问可知。假如计划不妥,查询起来就十分费劲,程序的功能也会遭到影响。不管你利用的是mySQL大概Oracle数据库,经由过程举行正轨化的表格计划,能够令你的PHP代码更具可读性,更简单扩大,从而也会提拔使用的功能。  复杂说来,正轨化就是在表格计划时,打消冗余性和不和谐的附属干系。在本文中,我将经由过程五个渐进的历程来告知你在计划中应当懂得的正轨化技能。从而创建一个可行并且效力高的数据库。本文也会具体剖析一下能够使用的干系范例。
  这里假定我们要创建一个用户信息的表格,个中要存储用户的名字、公司、公司地点和一些团体的保藏夹或url。在入手下手时,你大概界说一个以下的表格布局:

零形态情势

usersnamecompanycompany_addressurl1url2JoeABC1WorkLaneabc.comxyz.comJillXYZ1JobStreetabc.comxyz.com

  因为没有举行任何的正轨化处置,我们将这类情势的表称为零形态情势的表。寄望个中的url1和url2字段---假如我们在使用中必要第三个url呢?如许你就要在表格中多加一列,很分明,这不是一个好举措。假如你要创立一个富有扩大性的体系,你就要思索利用第一个正轨化的情势,而且使用到该表格中。

第一级正轨化情势

1.打消每一个表格中反复的组2.为每套相干的数据创建一个自力的表格3.利用一个主键来标识每套相干的数据

  以上的表格分明违背了下面第一条的划定,那末第三条的主键又是甚么意义呢?很复杂,它只是在每一个纪录中到场一个独一的、主动增添的整型值。经由过程这个值,就能够将两个姓名一样的纪录辨别开来。经由过程使用第一级正轨化情势,我们失掉了以下的表格:

usersuserIdnamecompanycompany_addressurl1JoeABC1WorkLaneabc.com1JoeABC1WorkLanexyz.com2JillXYZ1JobStreetabc.com2JillXYZ1JobStreetxyz.com

  如今我们的表格能够说已处在第一级正轨化的情势了,它已办理了url字段的限定成绩,不外如许的处置后又带来了一个新的成绩。每次在user表中拔出一笔记录的时分,我们都必需反复一切的公司和用户数据。如许不但令数据库比之前年夜了,并且很简单堕落。因而还要经由第二级正轨化处置。第二级正轨化情势

1.为使用在多笔记录的字段创建自力的表格2.经由过程一个foreignkey来联系关系这些表格的值

  我们将url的值放在一个自力的表格中,如许我们就能够在今后到场更多的数据,而无需忧虑发生反复的值。我们还经由过程主键值来联系关系这些字段:

usersuserIdnamecompanycompany_address1JoeABC1WorkLane2JillXYZ1JobStreet

urlsurlIdrelUserIdurl11abc.com21xyz.com32abc.com42xyz.com

  如上所示,我们创立了自力的表格,users表中的主键userid如今与url表中的foreignkeyrelUserId联系关系。如今的情形好象已失掉了分明的改良。不外,假如我们要为ABC公司到场一个员工纪录呢?大概更多,200个?如许我们就必需反复利用公司名和地点,这分明不敷冗余。因而我们将使用第三级正轨化办法:

第三级正轨化情势

1.打消不依附于该键的字段

公司名及地点与UserId都是没有干系的,因而它们使用具有本人的公司Id:

usersuserIdnamerelCompId1Joe12Jill2

companiescompIdcompanycompany_address1ABC1WorkLane2XYZ1JobStreet

urlsurlIdrelUserIdurl11abc.com21xyz.com32abc.com42xyz.com

  如许我们就将companies表中的主键comId和users表中名字为relCompId的foreignkey联系关系起来,就算为ABC公司到场200个员工,在companies中也只要一笔记录。我们的users和urls表能够不休地扩展,而无需忧虑拔出不用要的数据。年夜部分的开辟者都以为经由三步的正轨化就充足了,这个数据库的计划已能够很便利地处置全部企业的包袱,此意见在年夜多半的情形下是准确的。

  我们能够寄望一下url的字段--你注重到数据的冗余了吗?假如给用户用户输出这些url数据的HTML页面是一个文本框,可恣意输出的话,这并没有成绩,两个用户输出一样保藏夹的几率较少,不外,假如是经由过程一个下拉式的菜单,只让用户选择两个url输出,大概更多一点。这类情形下,我们的数据库还能够举行下一级其余优化--第四步,关于年夜多半的开辟者来讲,这一步都是疏忽的,由于它要依附一个很出格的干系--一个多对多的干系,这在我们的使用中是还没有碰到过的。数据干系

  在界说第四个正轨化的情势前,我想起首提一下三种基础的数据干系:一对一,一对多和多对多。我们转头看一下经由第一个正轨化的users表。如果我们将url的字段放在一个自力的表中,每次在users表中拔出一个纪录,我们就会在urls表中拔出一行。我们将失掉一个一对一的干系:用户表中的每行,都将在urls表中找到响应的一行。关于我们的使用来讲,这既不有用也不尺度。

  然后看看第二个正轨化的例子。关于每一个用户纪录,我们的表格同意有多个urls的纪录与之联系关系。这是一个一对多的干系,这是一个很罕见的干系。

  关于多对多的干系来讲,就有点庞大了。在我们的第三个正轨化情势的例子中,我们的一个用户与良多的url有关,而我们想将该布局变成同意多个用户与多个的urls有关,如许我们就能够失掉一个多对多的布局。在会商前,我们先看看表格布局会有些甚么变更

usersuserIdnamerelCompId1Joe12Jill2

companiescompIdcompanycompany_address1ABC1WorkLane2XYZ1JobStreet

urlsurlIdurl1abc.com2xyz.com

url_relationsrelationIdrelatedUrlIdrelatedUserId111212321422

  为了进一步减低数据的冗余,我们使用第四级正轨化情势。我们创立了一个颇奇异的url_relations表,内里的字段均为主键大概foreignkey。经由过程这个表,我们就能够打消urls表中的反复项目。以下是第四个正轨化情势的详细请求:

第四个正轨化情势

1.在一个多对多的干系中,自力的实体不克不及寄存在统一个表格中

  因为它仅使用于多对多的干系,因而年夜多半的开辟者能够疏忽这条划定。不外在某些情形下,它长短常有用的,这个例子就是如许,我们经由过程将不异的实体分别出来,而且将干系移到它们本人的表格中,从而改善了urls表格。

为了令你更简单分明,我们举个详细的例子,以下将用一个SQL语句选择出一切属于joe的urls:

SELECTname,urlFROMusers,urls,url_relationsWHEREurl_relations.relatedUserId=1ANDusers.userId=1ANDurls.urlId=url_relations.relatedUrlId

假如我们想要遍历每一个人的团体信息和url信息,我们能够如许做:

SELECTname,urlFROMusers,urls,url_relationsWHEREusers.userId=url_relations.relatedUserIdANDurls.urlId=url_relations.relatedUrlId

第五级正轨化情势

另有一级正轨化的情势,它其实不罕见,有点深邃,而且在年夜部分的情形下都是不用要的。它的准绳是:

1.本来的表格必需能够经由过程由它分别进来的表格从头构建

  利用这个划定的优点是,你能够确保不会在分别的表格中引进过剩的列,一切你创立的表格布局都与它们的实践必要一样年夜。使用这条划定是一个好习气,不外除非你要处置一个十分年夜型的数据,不然你将不必要用到它。

  但愿这篇文章对你有效,而且能够匡助你在一切的项目中使用这些正轨化的划定。你大概想晓得这些办法是从哪来的,我能够告知你,后面三个正轨化的划定是1972年,Dr.E.F.Codd在他的论文“进一步正轨化数据库的干系模子中”提出的,其他的划定是经由厥后的汇合实际和干系数学家实际化的。批评:正所谓物级必反,将表格分得细致偶然其实不好,由于如许必要将各表举行各类的联系关系,这会令查询时变得庞大,并且效力也大概下降,这些正轨化的划定能够参考,在实践使用时,要依据项目标巨细,需要时能够举行一些测试,以计划出更公道的表格布局。
对于update操作,只需要把event中的旧行和新行值对调即可。
变相怪杰 该用户已被删除
沙发
发表于 2015-1-19 21:32:49 | 只看该作者
我们学到了什么?思考问题的时候从表的角度来思考问
admin 该用户已被删除
板凳
发表于 2015-1-26 09:57:09 | 只看该作者
数据库物理框架没有变动undo和redo都放在数据库得transaction中,个人感觉是个败笔。如果说我们在设计数据库的时候考虑分多个数据库,可能能在一定程度上避免I/O效率问题。
若相依 该用户已被删除
地板
发表于 2015-2-4 13:49:54 | 只看该作者
对一张百万级别的表建游标,同时又没有什么过滤条件,取得游标效率是如果直接SQL查询百万条数据;如果再对每条记录做处理,耗时将更长。
老尸 该用户已被删除
5#
发表于 2015-2-10 01:08:03 | 只看该作者
个人感觉没有case直观。而且默认的第三字段(还可能更多)作为groupby字段很容易造成新手的错误。
山那边是海 该用户已被删除
6#
发表于 2015-2-28 11:10:18 | 只看该作者
这就引发了对varchar和char效率讨论的老问题。到底如何分配varchar的数据,是否会出现大规模的碎片?
愤怒的大鸟 该用户已被删除
7#
发表于 2015-3-9 22:54:47 | 只看该作者
分区表效率问题肯定是大家关心的问题。在我的试验中,如果按照分区字段进行的查询(过滤)效率会高于未分区表的相同语句。但是如果按照非分区字段进行查询,效率会低于未分区表的相同语句。
8#
发表于 2015-3-17 03:07:51 | 只看该作者
原理很简单,对要求长时间计算某一时间点的报表生成和防用户操作错误很有帮助。但是比起Oracle10g的闪回技术还是细粒度不够。可惜!
金色的骷髅 该用户已被删除
9#
发表于 2015-3-23 17:33:40 | 只看该作者
另一个是把SQL语句写到服务器端,就是所谓的SP(存储过程);
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 13:45

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表