仓酷云

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

[学习教程] MYSQL编程:MYSQL办理计划漫笔

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

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

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

x
“MySQL实际上是一个数据库家族,你可以从选择一个并将其配置成可以满足你的大多数情况,”开源顾问公司Ethiqa的总裁如此表示,“因此,你可以在开始的时候选择一个小巧的版本产品,以后再根据需要来对其进行性能或大小上的扩展。”
3.8办理计划漫笔
本节内容相称杂;先容了如何编写办理各类成绩的查询。多半内容是在邮件清单上看到的办理成绩的计划(感谢清单上的那些伴侣,他们为办理计划作了良多事情)。
3.8.1将子选择编写为毗连
MySQL自3.24版本以来才具有子选择功效。这项功效的短少是MySQL中一件经常使人可惜的事,但有一件事良多人仿佛没有熟悉到,那就是用子选择编写的查询一般能够用毗连来编写。实事上,即便MySQL具有了子查询,反省用子选择编写的查询也是一件苦差事;用毗连而不是用子选择来编写会更加无效。
1.从头编写选择婚配值的子选择
上面是一个包括一个子选择查询的样例,它从score表当选择一切测试的学分(即,疏忽检验的学分):

可经由过程将其转换为一个复杂的毗连,不必子选择也能够编写出不异的查询,以下所示:

上面的例子为选择女先生的学分:

可将其转换为毗连,以下所示:

这里是一个形式,子选择查询以下情势:

如许的查询可转换为以下情势的毗连:

2.从头编写选择非婚配值的子选择查询
另外一种经常使用的子选择查询是查找一个表中有的而另外一个表中没有的值。正如之前所看到的那样,“那些未给出的值”这一类的成绩是LEFTJOIN大概有效的一个线索。上面的查询包括一个子选择(它寻觅那些全勤的先生):


3.8.2反省表中未给出的值
我们已在3.6节“检索纪录”中看到,在要想晓得一个表中哪些值不呈现在另外一表中时,可对两个表利用LEFTJOIN并查找那些从第二个表当选中NULL的行。并用以下两个表举例:

如今让我们来思索一种更加坚苦的情形,“缺了哪些值”。关于第1章中提到的学分保留计划中,有一个列出先生的student表,一个列出已呈现过的学分事务的event表,和列出每一个先生的每次学分事务学分的一个score表。可是,假如一个先生在某个测试或检验的统一天病了,那末score表中将不会有这个先生的该事务的学分,因而,要举行检验或测试的补考。我们如何查找这些短少了的纪录,以便能包管让这些先生举行补考?成绩是要对一切的学分事务断定哪些先生没有某个学分事务的学分。换个说法,就是我们但愿晓得先生和事务的哪些组合不呈现在学分表中。这就是我们但愿LEFTJOIN所做的事。这个毗连不像前例中那样复杂,由于我们不单单要查找不呈现在单列中的值;还必要查找两列的组合。
我们想要的这类组合是一切先生/事务的组合,它们由student表与event表的叉积发生:
FROMstudent,event
 然后我们掏出此毗连的了局,与score表实行一个LEFTJOIN语句找出婚配者:
FROMstudent,event
LEFTJOINscoreONstudent.student_id=score.student.id
ANDevent.event_id=score.event_id
请注重,ON子句使得score表中的行依据分歧表中的婚配者举行毗连。这是办理本成绩的关头。LEFTJOIN强迫为由student和event表的叉毗连天生的每行发生一个行,即便没有响应的score表纪录也是如许。这些短少的学分纪录的了局行可经由过程一个现实来辨认,就是来自score表的列将满是NULL的。我们可在WHERE子句当选出这些纪录。来自score表的任何列都是如许,但由于我们查找的是短少的学分,测试score列从观点上大概最为明晰:
WHEREscore.scoreISNULL
可使用ORDERBY子句对了局举行排序。两种最公道的排序分离是按先生和按事务举行,我们选择第一种:
ORDERBYstudent.student_id,event.event_id
如今必要做的就是定名我们但愿在输入了局中看到的列。终极的查询以下:
SELECT
student.name,student.student_id,
event.date,event,event_id,event.type
FROM
student,event
LEFTJOINscoreONstudent.student_id=score.student_id
ANDevent.event_id=score.event_id
WHERE
score.scoreISNULL
ORDERBY
student.student_id,event.event_id
运转此查询得出以下了局:

这里有一个成绩要引发注重。此输入列出了先生的ID和事务的ID。student_id列呈现在student和score表中,因而,入手下手您大概会以为选择列表能够给出student.student_id或score.student_id。但实践不是如许,由于可以找到感乐趣纪录的基本是一切学分表字段前往NULL。选择score.student_id将只在输入中发生NULL值的列。相似的推理可使用到event_id列,它也呈现在event和score表中。
3.8.3实行UNION操纵
假如想经由过程从具有不异布局的多个表中创建一个了局集,可在某些数据库体系中利用某种UNION语句来完成。MySQL没有UNION(最少直到3.24版还没有),但有很多举措来办理这个成绩,上面是两种可行的计划:
■实行多个SELECT查询,每一个表实行一个。假如不体贴所选出行的序次,如许做就好了。
■将每一个表中的行选进一个一时存储表,然后选择该表的内容。如许可对行按所需的序次举行排序。在MySQL3.23版及今后的版本中,可经由过程同意服务器创立存储表来办理这个成绩。并且,还可使该表为一时表,以便在您与服务器的会话停止时,主动删除该表。
鄙人面的代码中,我们明白地删除该表使服务器开释与其有关的资本。假如客户时机话将持续实行进一步的查询,如许做很有优点。为了取到更好的功能,还能够使用HEAP(在内存中)表。

关于3.23版本,除必需本人明白界说hold_tbl表中的列外,其设法是相似的,并且开头处的DROPTABLE是强迫性的,用来避免在以下客户时机话性命周期以后持续存在:

3.8.4增添序列号列
假如用ALTERTABLE增添AUTO_INCREMENT列,则该列用序列号主动地添补。上面这组mysql会话中的语句示出了如何创立一个表,在个中寄存数据,然后增添一个AUTO_INCREMENT列:

 3.8.5对某个已有的列举行排序
 假如有一个数值列,可对其按以下举行排序(或对其重排序,假如已对其排过序,但删除行而且想要对值从头排序使其一连):
 ALTERTABLEtMODIFYiINTNULL
 UPDATEtSETi=NULL
 ALTERTABLEtMODIFYiINTUNSIGNEDAUTO_INCREMENTNOTNULLPRIMARYKEY
 可是有一种更简单的办法,那就是删除该列,然后再作为一个AUTO_INCREMENT列追加它。ALTERTABLE同意指定多个举动,因而,上述事情可在单个语句中完成:
ALTERTABLEt
DROPi,
ADDiINTUNSIGNEDAUTO_INCREMENTNOTNULLPRIMARYKEY
3.8.6非一般序次的串
假设有一个暗示体育机构职员的表,如橄榄球队,假如按职员职位举行排序,以便以特别的按次暗示它,如:锻练、锻练助理、四分卫、活动后卫、接球员、巡查员等。可将列界说为ENUM并按但愿呈现的按次界说列举元素。对该列的排序将会以所指定的按次主动举行。
3.8.7创建计数表
在第2章的“利用序列”大节中,我们先容了如何使用LAST_INSERT_ID(expr)天生一个序列。谁人例子申明了如何使用单列的表举行计数。那样做关于只必要单个计数器的情况可以满意必要,可是,假如必要几个计数器,该办法将会引发不用要的表反复。假设有一个Web站点而且想要在几个页面上安排“此页面已被会见nnn次”如许的计数器。那末为每一个具有一个计数器的页面创建一个独自的表就有些过剩了。制止创立多个计数器表的一种办法是创建一个两列的表。个中一列寄存计数值;另外一列寄存计数器名。这时候仍旧可使用LAST_INSERT_ID()函数,但可用计数器名来决意用哪一行。这个表以下所示:
CREATETABLEcounter
(
countINTUNSIGNED,
namevarchar(255)NOTNULLPRIMARYKEY
)
个中计数器名为一个串,从而能够挪用任何想要的计数器,我们将其界说为PRIMARYKEY以避免称号反复。这里假定利用这个表的使用程序晓得他们将利用的称号。关于后面所说的Web计数器,可经由过程使用文件树中每一个页面的路径名作为其计数器名的办法,包管计数器名的独一性。比方,要为站点的主页创建一个新计数器,可实行以下语句:
INSERTINTOcounter(name)VALUES("index.html")
它用零值初始化称为“index.html”的计数器。为了天生序列中的下一个值,增添表中响应行的计数值,然后用LAST_INSERT_ID()检索它:
UPDATEcounter
SETcount=LAST_INSERT_ID(count+1)
WHEREname="index.html"
SELECTLAST_INSERT_ID()
另外一种办法是不必LAST_INSERT_ID()增添计数器的值,以下所示:
UPDATEcounterSETcount=count+1WHEREname="index.html"
SELECTcountFROMcounterWHEREname="index.html"
但是,假如另外一个客户在您公布UPDATE语句与SELECT语句之间增添了该计数器的值,则这类办法事情不一般。不外可在此两条语句的前后分离安排LOCKTABLES和UNLOCKTABLES,在您利用该计数器时堵塞其他客户,以办理上述成绩。但用LAST_INSERT_ID()办法完成一样的事情更加简单一些。由于它的值是客户公用的,您总能失掉本人拔出的值,而不是其他客户拔出的值,并且不用堵塞其他客户使代码庞大化。
3.8.8反省表是不是存在
在使用程序外部晓得一个表是不是存在偶然很有效。为了做到这一点,可以使用以下任一条语句:
SELECTCOUNT(*)FROMtb1_name
SELECT*FROMtb1_nameWHERE1=0
假如指定的表存在,则上述两条语句都将实行乐成,假如不存在,则都失利。它们是这类测试的很好的查询。它们实行速率快,以是不会费太多的工夫。这类办法最合适您本人编写的使用程序,由于您能够测试查询的乐成与失利并接纳响应的措施。但在从mysql运转的批量剧本中不出格有效,由于产生毛病时除停止运转外不成能做任何事(大概能够疏忽响应的毛病,可是明显没法再运转该查询了)。


与数据库相关的流程的逐渐标准化,使得解决方案提供商能以更便捷的方式提供服务、部署应用程序、规划容量和管理资源。DBaaS模式还有助于减少数据和数据库的冗余度并提升整体服务质量。
海妖 该用户已被删除
沙发
发表于 2015-1-19 10:18:51 | 只看该作者
外键的级联更能扩展可能大部分的同行在设计OLTP系统的时候都不愿意建立外键,都是通过程序来控制父子数据的完整性。
因胸联盟 该用户已被删除
板凳
发表于 2015-1-28 06:07:19 | 只看该作者
光写几个SQL实在叫无知。
蒙在股里 该用户已被删除
地板
发表于 2015-2-5 19:05:42 | 只看该作者
SP4是一个累积性的ServicePack,包含自以前的ServicePack发布以来所有的修补程序(包括MS03-031安全公告)。
兰色精灵 该用户已被删除
5#
发表于 2015-2-13 06:54:26 | 只看该作者
原来的计算字段其实和虚拟字段很像。只是管理方面好了而已,性能方面提高不多。但是SQL2005提供了计算字段的持久化,这就提高了查询的性能,但是会加重insert和update的负担。OLTP慎用。OLAP可以大规模使用。
只想知道 该用户已被删除
6#
发表于 2015-3-3 18:49:58 | 只看该作者
从项目平台的选择上讲,我们关心的,应该是一款产品能不能满足任务需求,而不是网上怎么说。
飘飘悠悠 该用户已被删除
7#
发表于 2015-3-11 12:46:11 | 只看该作者
你觉得我的非分区索引无法对起子分区,你可以提醒我一下呀!没有任何的提醒,直接就变成了非分区表。不知道这算不算一个bug。大家也可以试试。
第二个灵魂 该用户已被删除
8#
发表于 2015-3-18 19:12:26 | 只看该作者
理解了存储结构,再阅读下性能优化的章节基本上会对sqlserver有个清晰地认识
深爱那片海 该用户已被删除
9#
发表于 2015-3-26 14:41:28 | 只看该作者
换言之,只有在不断的失败中尝试成功,而关于失败的总结却是很少的
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-12-23 12:48

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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