仓酷云

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

[学习教程] MYSQL编程:对MYSQL查询中有疑问的数据举行编码

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

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

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

x
不可否认,MySQL也是一个很好的关系型数据库,或许在技术上它与其他领先的关系数据库相差并不大,或不具有劣势。但是,对于一些企业环境来说,MySQL显然不具有优势。6.8其他主题
本节包含几个主题,这些主题不完整合适于本章从client1到client5的开辟中的任一大节的内容:
■在利用了局集元数据匡助考证这些数据合适于盘算以后,利用了局集数据盘算了局。
■怎样处置很难拔出到查询中的数据。
■怎样处置图形数据。
■怎样取得表布局的信息。
■罕见的MySQL程序计划毛病及怎样制止。
6.8.1在了局集上实行盘算
迄今为止,我们会合而次要地利用了却果集元数据来打印行数据,但很分明,除打印以外,另有必要利用数据做其他事变的时分。比方,盘算基于数据值的统计信息,使用元数据确保数据合适它们要满意的需求。哪一种范例的需求?关于启动程序来讲,大概要校验一下正
要实行数字盘算的列实践上是不是包括着数字!
上面的列表显现了一个复杂函数summary_stats(),它猎取了局集和列索引,并发生列值的汇总统计。该函数还列有缺多数值的数目,它是经由过程反省NULL来检测的。这些盘算包含两个数据所必需满意的需求,summary_stats()用了局集元数据来校验:
■指定的列必需存在(也就是说,列索引必需在了局集列值的局限内)。
■此列必需包含数字值。
假如这些前提不满意,则summary_stats()只打印堕落误动静并前往。代码以下:



请注重在mysql_fetch_row()轮回后面挪用的mysql_data_seek()。为取得一样的了局集,它同意屡次挪用summary_stats()(假定要盘算几列的统计值的话)。每次挪用summary_stats()都要“从头回到”到了局集的入手下手(这里假定mysql_store_result()创立了局集,假如用mysql_use_result()创立了局集就只能按按次处置行,并且只能处置一次)。summary_stats()是个绝对复杂的函数,但它给我们一个提醒,就是怎样编写一个对照庞大的盘算程序,如两个列的最小二乘回回大概尺度统计,如t-查验。
6.8.2对查询中有疑问的数据举行编码
包含引号、空值和反斜线的数据值,假如把它们拔出到查询中,在实行查询时就会发生一些成绩。上面的会商叙述了这些难点,并先容懂得决的举措。假定要制作一个SELECT查询,它基于由name指向的空闭幕串的内容:

 假如name的值相似于“0’Malley,Brian”,这时候举行的查询就长短法的,由于引号在援用的字符串里呈现:

必要出格注重这个引号,以便使服务器不将它注释为name的开头。一种办法是在字符串内利用双引号,这就是ANSISQL商定。SQL撑持这个商定,也同意引号在反斜线后利用:

另外一个有成绩的地方是查询中恣意二进制数据的利用,比方,在把图形存储到数据库如许的使用程序中会产生这类情形。由于二进制数值含有一些字符,把它放到查询中是不平安的。为懂得决这个成绩,可以使用mysql_escape_string(),它能够对特别字符举行编码,使其在援用的字符串中可使用。mysql_escape_string()以为的特别字符是指空字符、单引号、双引号、反斜线、换行符、回车符和Control-Z(最初一个在Windows言语情况中呈现)。甚么时分利用mysql_escape_string()呢?最保险的回覆是“一直”。但是,假如确信数据的情势而且晓得它是准确的―大概由于事后实行了确认反省―就不用编码了。比方,假如处置德律风号码的字符串,它完整由数字和短线构成,那末就不用挪用mysql_escape_string()了,不然仍是要挪用。
mysql_escape_string()对有成绩的字符举行编码是将它们转换为以反斜线开首的2个字符的序列。比方,空字符转换为‘’,这里的0是可打印的ASCII码0,而不是空。反斜线、单引号和双引号分离转换为‘’、‘’’和‘”’。挪用mysql_escape_string()的历程以下:

mysql_escape_string()对from_str举行编码,并把了局写进to_str中,还增加了空闭幕值,如许很便利,由于能够使用像strcpy()和strlen()如许的函数利用该了局串。from_str指向包含将要编码的字符串的char缓冲区,这个字符串大概包括任何内容,个中包含二进制数据。to_str指向一个存在的char缓冲区,在这个缓冲区里,能够写进编码的字符串;不要传送未初始化的指针或NULL指针,但愿由mysql_escape_string()分派空间。由to_str指向的缓冲区的长度最少是(from_len*2)+1个字节(极可能from_str中的每一个字符都必要用2个字符来编码;分外的字节是空闭幕值)。
from_len和to_len都是unsignedint值,from_len暗示from_str中数据的长度;供应这个长度长短常需要的,由于from_str大概包括空值字节,不克不及把它看成空闭幕串。从mysql_escape_string()前往的to_len值是作为了局的编码字符串的实践长度,没有对空闭幕值举行计数。
当mysql_escape_string()前往时,to_str中编码的了局便可看做是空闭幕串,由于from_str中的空值都被编码为‘’。
为了从头编写机关SELECT的代码,使称号的值即便包括引号也能事情,我们举行上面的操纵:

  6.8.3图象数据的处置
  mysql_escape_string()的基础功效之一就是把图象数据加载到一个表中。本节先容怎样举行这项事情(这个会商也合用于二进制数据的其他情势)。假定想从文件中读取图象,并将它们连同独一的标识符存储到表中。BLOB范例对二进制数据来说是个很好的选择,因而可使用上面的表申明:

实践上,要想从文件中猎取图象并放进images表,使用上面的函数load_image()能够完成,给出一个标识标记码和一个指向包含这个图象数据的翻开文件的指针:

load_image()不会分派十分年夜的查询缓冲区(100K),因而它只能处置绝对较小的图形。
在实践的使用程序中,能够依据图形文件的巨细静态地分派缓冲区。处置从数据库中恢复的图形数据(或任何二进制数据)其实不像入手下手把它放进时那样成绩重重,由于在变量MYSQL_ROW中数据值的原始情势是无效的,经由过程挪用mysql_fetch_length(),这个长度也是无效的。必需将值看做是计数串,而不是空闭幕串。
6.8.4猎取表信息
MySQL同意利用上面的查询猎取有关表布局的信息(上面二者是等价的):

与SELECT相相似,两个语句都前往了局集。为了在表中找出有关列,所需做的就是处置了局会合的行,从中猎取有效的信息。比方,假如从mysql客户机上公布DESCRIBEimages语句,就会前往如许的信息:

 假如从本人的客户机上实行一样的查询,能够失掉不异的信息(没有边框)。假如只想要单个列的信息,则利用以下这个查询:
 SHOWFIELDSFROMtbl_nameLIKE“col_name”
 此查询会前往不异的列,但只是一行(假如列不存在就不前往行)。
 6.8.5必要制止的客户机程序计划毛病
 本节会商一些罕见的MySQLCAPI程序计划毛病,和怎样制止其产生(这些成绩在MySQL邮件清单中会周期性地俄然呈现)。
 1.毛病1――利用未初始化的毗连处置程序指针在本章的样例中,我们已经由过程传送NULL参数挪用了mysql_init(),这就是让它分派而且初始化MYSQL布局,然后前往一个指针。别的一种办法是将指针传送到一个已有的MYSQL布局中。在这类情形下,mysql_init()会将布局初始化并前往一个指针,而不用本人分派布局。假如要利用第二种办法,则要当心会呈现一些奇妙的成绩。上面的会商指出了必要注重的一些成绩。假如将一个指针传送给mysql_init(),它应当实践指向某些器材。看上面的代码段:

这个成绩是,mysql_init()失掉了一个指针,但指针没有指向所知的任何中央。conn是一个部分变量,因而在main()入手下手实行时它是一个能指向任何中央的未初始化的存储器,这就是说mysql_init()将利用指针,并可在内存的一些恣意地区滥写。假如侥幸的话,conn将指向您的程序地点空间的内部,如许,体系将当即停止,使您能尽早意想到代码中呈现的成绩。
假如不幸的话,conn将指向程序中今后才利用的一些数据的外部,直到再次利用谁人数据时才发明成绩。因而实践呈现成绩的中央远比实行程序时呈现的成绩多,也更难捕获到。上面是一段有成绩的代码:

 此时,conn是一个全局变量,因而在程序启动前,将它初始化为0(就是NULL)。mysql_init()碰到NULL参数,因而初始化并分派一个新的毗连处置程序。只需将conn传送给必要非NULL毗连处置程序的MySQLCAPI函数,体系就会溃散。这些代码段的修正就是确保conn有一个可知的值。比方,能够将它初始化到已分派的MYSQL布局地点中往:

但是,保举的(较简单的!)办理计划仅仅是将NULL显式地传送给mysql_init(),让该函数分派MYSQL布局,并将前往值赋值给conn:

不管怎样不要健忘查验mysql_init()的前往值,以确保它不是NULL。
2.毛病2――无效了局集查验的失利
请记着反省但愿失掉的了局集的挪用形态。上面的代码没有做到这一点:

不幸地是,假如mysql_store_result()失利,res_set为NULL,while轮回也不实行了,应测试前往了局集函数的前往值,以确保实践上在举行事情。
3.毛病3――NULL列值引发的失利
不要健忘反省mysql_fetch_row()前往的数组MYSQL_ROW中列值是不是为NULL指针。假如row为NULL,则在一些呆板上,上面的代码就会引发溃散:

该毛病伤害最年夜的部分是,有些printf()的版本很宽大地对NULL指针输入了“(null)”,这就使毛病很简单逃走而没有把毛病定位。假如把程序给了伴侣,而他只要不太宽大printf()版本,程序就会溃散,您的伴侣会以为您是个无用的程序员。轮回应当写成上面如许:

不必要反省列值是不是为NULL的唯一一次是当已从列信息布局断定IS_NOT_NULL()为真时。
4.毛病4――传送偶然义的了局缓冲区
必要您供应缓冲区的客户机库函数一般要使这些缓冲区真正存在,上面的代码违背了这个划定规矩:

成绩是甚么呢?to_str必需指向一个存在的缓冲区,而在这个样例中没有,因而,它指向了随便的地位。不要向mysql_escape_string传送偶然义的指针作为to_str参数,不然它会任意踩踏内存。
平台即服务PaaS、基础设施即服务IaaS、软件即服务SaaS都是我们比较熟悉的MySQL学习教程,现在又出现了数据库即服务DBaaS,以基于云的方式存储结构化数据。
第二个灵魂 该用户已被删除
沙发
发表于 2015-1-19 10:55:33 | 只看该作者
比如,MicrosoftSQLServer2008的某一个版本可以满足现在的这个业务的需要,而且价格还比Oracle11g要便宜,那么这一产品就是适合的。
莫相离 该用户已被删除
板凳
发表于 2015-1-28 06:10:15 | 只看该作者
但是随着数据量的增大,这种成本差距会逐渐减小,趋于相等。(500万数量级只相差10%左右)
admin 该用户已被删除
地板
发表于 2015-2-5 19:14:10 | 只看该作者
是要和操作系统进行Socket通讯的场景。否则建议慎重!
若天明 该用户已被删除
5#
发表于 2015-2-13 07:15:09 | 只看该作者
同样会为索引视图等应用带来麻烦。看看行级和事务级的快照数据放在tempdb中,就能感觉到目前架构的尴尬。
愤怒的大鸟 该用户已被删除
6#
发表于 2015-3-3 19:12:11 | 只看该作者
sqlserver的痛苦之处在于有用文档的匮乏,很多只是表明的东西
灵魂腐蚀 该用户已被删除
7#
发表于 2015-3-11 12:51:22 | 只看该作者
对一张百万级别的表建游标,同时又没有什么过滤条件,取得游标效率是如果直接SQL查询百万条数据;如果再对每条记录做处理,耗时将更长。
不帅 该用户已被删除
8#
发表于 2015-3-18 19:44:32 | 只看该作者
习惯敲命令行的朋友可能会爽一些。但是功能有限。适合机器跑不动SQLServerManagementStudio的朋友使用。
深爱那片海 该用户已被删除
9#
发表于 2015-3-26 14:53:34 | 只看该作者
也可谈一下你是怎么优化存储过程的?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-1 09:30

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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