您好,欢迎来到花图问答。
搜索
您的当前位置:首页二级MySQL数据库程序设计复习全书

二级MySQL数据库程序设计复习全书

来源:花图问答


目 录

第一部分 备考指南 ........................................................................................................................................................... 2

第1章 考试概述 ....................................................................................................................................................... 2 第2章 复习技巧 ....................................................................................................................................................... 8 第二部分 核心讲义 ......................................................................................................................................................... 10

【公共基础知识】 ..................................................................................................................................................... 10

第1章 数据结构与算法 ................................................................................................................................. 10 第2章 程序设计基础 ..................................................................................................................................... 20 第3章 软件工程基础 ..................................................................................................................................... 25 第4章 数据库设计基础 ................................................................................................................................. 41 【MySQL数据库程序设计】 ................................................................................................................................... 53

第1章 数据库技术的基本概念与方法 ......................................................................................................... 53 第2章 MySQL概述 ....................................................................................................................................... 62 第3章 数据库和表 ......................................................................................................................................... 74 第4章 表数据的基本操作 ............................................................................................................................. 87 第5章 数据库的查询 ..................................................................................................................................... 92 第6章 索 引 ............................................................................................................................................... 107 第7章 视 图 ............................................................................................................................................... 113 第8章 数据完整性约束与表维护语句 ....................................................................................................... 118 第9章 触发器 ............................................................................................................................................... 125 第10章 事 件 ............................................................................................................................................. 128 第11章 存储过程与存储函数 ..................................................................................................................... 131 第12章 访问控制与安全管理 ..................................................................................................................... 140 第13章 备份与恢复 ..................................................................................................................................... 147 第14章 PHP的MySQL数据库编程 ......................................................................................................... 154 第15章 开发实例 ......................................................................................................................................... 162

第三部分 历年真题及详解 ........................................................................................................................................... 176

全国计算机等级考试《二级MySQL数据库程序设计》真题精选(一) ........................................................ 176 全国计算机等级考试《二级MySQL数据库程序设计》真题精选(二) ........................................................ 180 第四部分 模拟试题及详解 ........................................................................................................................................... 184

全国计算机等级考试《二级MySQL数据库程序设计》模拟试题及详解(一) ............................................ 184 全国计算机等级考试《二级MySQL数据库程序设计》模拟试题及详解(二) ............................................ 188

第一部分 备考指南

第1章 考试概述

一、考试简介

全国计算机等级考试(National Computer Rank Examination,简称NCRE),是经原国家教育委员会(现教育部)批准,由教育部考试中心主办,面向社会,用于考查应试人员计算机应用知识与技能的全国性计算机水平考试体系。

计算机技术的应用在我国各个领域发展迅速,为了适应知识经济和信息社会发展的需要,操作和应用计算机已成为人们必须掌握的一种基本技能。许多单位、部门已把掌握一定的计算机知识和应用技能作为人员聘用、职务晋升、职称评定、上岗资格的重要依据之一。鉴于社会的客观需求,经原国家教委批准,原国家教委考试中心于1994年面向社会推出了NCRE,其目的在于以考促学,向社会推广和普及计算机知识,也为用人部门录用和考核工作人员提供一个统一、客观、公正的标准。

二、考试科目

级别 一级 科目名称 计算机基础及WPS Office应用 计算机基础及MS Office应用 计算机基础及Photoshop应用 C语言程序设计 VB语言程序设计 VFP数据库程序设计 Java语言程序设计 二级 Access数据库程序设计 C++语言程序设计 MySQL数据库程序设计 Web程序设计 MS Office高级应用 网络技术 数据库技术 三级 软件测试技术 信息安全技术 嵌入式系统开发技术 网络工程师 数据库工程师 四级 软件测试工程师 信息安全工程师 嵌入式系统开发工程师 科目代码 14 15 16 24 26 27 28 29 61 63 64 65 35 36 37 38 39 41 42 43 44 45 考试时间 90分钟 90分钟 90分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 120分钟 90分钟 90分钟 90分钟 90分钟 90分钟 考核课程代码 114 115 116 201、224 201、226 201、227 201、228 201、229 201、261 201、263 201、264 201、265 335 336 337 338 339 401、403 404、405 401、405 401、403 401、402 说明: 同次考试考生可报考多个级别或科目,但不允许重复报考同一个科目,具体要求请向所在省级承办机构进行咨询。

报考多个科目时需咨询考点,避免考场安排时冲突。如:考生同时报考了二级C、三级网络技术、四级网络工程师三个科目,结果通过了三级网络技术、四级网络工程师考试,但没有通过二级C考试,将不颁发任何证书,三级网络技术、四级网络工程师两个科目成绩,自考试结束之日起可保留半年(按月计算)。下一次考试考生报考二级C并通过,将一次获得三个级别的证书;若没有通过二级C,将不能获得任何证书。同时,三级网络技术、四级网络工程师两个科目成绩自动失效。

三、报考条件

1.考生不受年龄、职业、学历等背景的限制,任何人均可根据自己学习和使用计算机的实际情况,选考不同等级的考试。考生一次只能报考一个科目的考试。考生一次考试只能在一个考点报名。考生可以不参加考前培训,直接报名参加考试。

2.每次考试报名的具体时间由各省(自治区、直辖市)级承办机构规定。考生按照有关规定到就近考点报名。上次考试的笔试和上机考试仅其中一项成绩合格的,下次考试报名时应出具上次考试成绩单,成绩合格项可以免考,只参加未通过项的考试。

3.特殊人员报考条件:

现役军人可使用军官证报考NCRE考试,在其军官证号码前后各加入识别码,此办法也适用于没有身份证的未成年人,识别码的编码有统一格式,前6位后4位。国务院和中央军事委员会联合下发的510号令,已经公布《现役军人和人民武装警察居民身份证申领发放办法》,该办法自2008年1月1日起实施,现役军人可以通过团以上单位集中向地方公安机关申请居民身份证。

无身份证的学生可携带户口本参加报名,身份证丢失者凭公安机关开具的身份证明,外籍人员凭护照参加报名。

四、报考方式

分为考点现场报名与网上报名。

考生在考点现场报名时,需出示身份证以及缴纳相关的考试费。考生一定要亲自到场,不能由任何单位、个人代劳。考生按要求进行信息采集,并逐一核实报名表上的个人信息:姓名、身份证号、照片、报考科目、报考类别(是否补考)等,发现信息不一致要立刻更改。报名完成后请妥善保管“考生报名登记表”防止阻碍准考证的领取。

考生采取网上报名方式,需先在所在省份的网上报名系统注册并填报相关基本信息、上传正面免冠电子近照,然后网上缴费或至指定地点缴费并确认身份信息,完成报名。

一般情况下,每次考试每个考生只能在一个考点完成报名。

考生报名时缴纳的考试费的具体金额由各省级承办机构根据考试需要和当地物价水平确定,并报当地物价部门核准。考点不得擅自加收费用。

注:报名时依据的身份证明包括:居民身份证、军人的证件、护照、户口本等。

五、报考时间 考试安排 报名时间 第一场 12月开始 第二场 5月开始 第三场 11月10日以后 注:各地的报名时间由考生报考所在地的当地考试机构决定。

六、考试时间

NCRE以往每年开考两次,从2014年开始每年开考次数由两次增为三次。

2016年NCRE安排三次考试,考试时间分别为3月21日~24日、9月19日~22日、12月12日~13日,其中3月和9月考试开考全部级别全部科目,12月只开考一级和二级,由各省级承办机构根据实际情况确定是否开考12月的考试。

七、各级别考试介绍

一级 科目 考试环境 考试软件 一级WPS Office 一级MS Office 一级Photoshop Photoshop CS5 (典型方式安装) 1.单项选择题,55题,55分(含计算机基础知识部分20分) 2.Photoshop操作题,45分 NCRE一级上机考试环境为Windows 7简体中文版 WPS Office 2012办公软件 1.单项选择题,20题,20分 2.Windows操作系统的使用,10分 3.WPS文字的操作,25分 4.WPS表格的操作,20分 5.WPS演示软件的操作,15MS Office 2010 1.单项选择题,20题,20分 2.Windows操作系统的使用,10分 3.Word操作,25分 4.Excel操作,20分 5.PowerPoint操作,15分 题型及分值比例

分 6.浏览器(IE)的简单使用和电子邮件收发,10分 6.浏览器(IE)的简单使用和电子邮件收发,10分 考核内容 1.考核内容包括计算机基础知识和操作技能两部分。 2.各科目对基础知识的要求相同,以考查应知应会为主,题型为选择题,分数占全卷的20%(20分)。 3.办公软件类考试,操作技能部分包括汉字录入、Windows系统使用、文字排版、电子表格、演示文稿、IE的简单应用及电子邮件收发。 3.Photoshop考试,要求了解数字图像的基本知识,熟悉Photoshop的界面与基本操作方法,掌握并熟练运用绘图工具进行图像的绘制、编辑、修饰,会使用图层蒙版、样式以及文字工具。 完全采取上机考试形式,各科上机考试时间均为90分钟,满分100分。 总分不低于60分。 参加NCRE“计算机基础及Photoshop应用”科目考生,可以在NCRE报名时自愿申请免试取得“Adobe Photoshop产品工程师认证”证书,即:通过NCRE“计算机基础及Photoshop应用”科目考试实现一次考试,可以同时取得全国计算机等级证书与“Adobe Photoshop产品工程师认证”证书,即“一考双证”。 二级 形式 获证条件 备注 科目 考试环境 C语言 语言程序设计类 C++ Java VB Web VFP 数据库程序设计类 Access MySQL 办公软件高级应用 办公软件高级应用 NCRE 二级上机考试环境为 Windows 7 简体中文版 Net- Beans 中国教育考试版2007 NetBeans中国教育考试版,IE6.0 及以上 考试软件 Visual C++ 6.0 Visual C++ 6.0 VB6.0 简体中文专业版 VFP6.0 简体中文专业版 MS Access2010 MySQL(CommunMS Office 2010 ity 5.5.16) 题型及分值比例 1.单项选择题,40题,40分(含公共基础知识部分10分) 2.程序填空题,3小空,18分 3.程序改错题,2个错误,24分 4.程序设计题,18分 1.单项选择题,40题,40分(含公共基础知识部分10分) 2.基本操作题,18分 3.简单应用题,24分 4.综合应用/操作题,18分 1.单项选择题,20分(含公共基础知识部分10分) 2.文字处理题(Word),30分 3.电子表格题(Excel),30分 4.演示文稿题(PowerPoint),20分 考核内容 形式 获证条件 二级定位为程序员,考核内容包括公共基础知识和程序设计。所有科目对基础知识作统一要求,使用统一的公共基础知识考试大纲和教程。二级公共基础知识在各科考试选择题中体现。程序设计部分,主要考查考生对程序设计语言使用和编程调试等基本能力,在选择题和操作题中加以体现。 完全采取上机考试形式。各科上机考试时间均为120分钟,满分100分。 总分不低于60分

三级 科目 考试环境与软件 题型及分值比例 网络技术 数据库技术 软件测试技术 信息安全技术 嵌入式系统开发技术 1.NCRE三级上机考试环境为 Windows 7 简体中文版 2.数据库技术考核C语言程序设计,使用 Visual C++ 6.0 1.单选题,40题,40分 2.综合题,40分 3.应用题,20分 1.网络技术。网络规划与设计、局域网组网技术、计算机网络信息服务系统的建立及计算机网络安全与管理。 2.数据库技术。数据库应用系统分析及规划、数据库设计及实现、数据库存储技术、并发控制技术、数据库管理与维护、数据库技术的发展及新技术。 3.软件测试技术。软件测试的基本概念、软件测试技术、软件测试过程和管理方法。 4.信息安全技术。信息安全保障概论、信息安全基础技术与原理、系统安全、网络安全、应用安全、信息安全管理、信息安全标准与法规。 5.嵌入式系统开发技术。嵌入式系统的概念与基础知识、嵌入式处理器、嵌入式系统硬件组成、嵌入式系统软件、嵌入式系统的开发等相关知识和技能。 完全采取上机考试形式。各科上机考试时间均为120分钟,满分100分。 1.总分不低于60分,并已经(或同时)获得二级相关证书。 2.三级数据库技术证书要求已经(或同时)获得二级数据库程序设计类证书;网络技术、软件测试技术、信息安全技术、嵌入式系统开发技术等四个证书要求已经(或同时)获得二级语言程序设计类证书。 3.考生早期获得的证书(如Pascal、FoxBase等),不严格区分语言程序设计和数据库程序设计,可以直接报考并获得证书。 无 四级 考核内容 形式 获证条件 备注

科目 考试环境 题型及分值比例 网络工程师 数据库工程师 软件测试工程师 信息安全工程师 嵌入式系统开发工程师 NCRE四级上机考试环境为Windows 7简体中文版。 1.单选题,60题,60分 2.多选题,20题,40分 1.网络工程师。考核计算机网络、操作系统原理两门课程。测试内容包括网络系统规划与设计的基础知识及中小型网络的系统组建、设备配置调试、网络系统现场维护与管理的基本技能。 2.数据库工程师。考核数据库原理、软件工程两门课程。测试内容包括数据库系统的基本理论以及数据库设计、维护、管理与应用开发的基本能力。 3.软件测试工程师。考核操作系统原理、软件工程两门课程。测试内容包括软件测试的基本理论、软件测试的规范及标准,以及制定测试计划、设计测试用例、选择测试工具、执行测试并分析评估结果等软件测试的基本技能。 4.信息安全工程师。考核计算机网络、操作系统原理两门课程。测试内容包括网络攻击与保护的基本理论与技术,以及操作系统、路由设备的安全防范技能。 5.嵌入式系统开发工程师。考核操作系统原理、计算机组成与接口两门课程。测试内容包括嵌入式系统基本理论、逻辑电路基础以及嵌入式系统中的信息表示与运算、评价方法等基本技能。 1.无纸化考试,考试总时间为90分钟,单课程考试没有时间要求。 2.四级考试科目由五门专业基础课程中指定的两门课程组成,总分100分,两门考核内容 形式

课程各占50分。 3.专业基础课程为计算机专业核心课程,包括:操作系统原理、计算机组成与接口、计算机网络、数据库原理、软件工程。 获证条件 备注 两门课程分别达到30分及以上,并已经(或同时)获得三级相关证书。 2013年3月及以前获得的三级各科目证书,不区分科目,可以作为四级任一科目的获证条件。 无 ·2015年NCRE继续实施2013年版考试大纲,教材参见全国计算机等级考试教材目录(2015年版)。

八、考试要求

1.掌握数据库技术的基本概念和方法。 2.熟练掌握MySQL的安装与配置。

3.熟练掌握MySQL平台下使用SQL语言实现数据库的交互操作。 4.熟练掌握MySQL的数据库编程。

5.熟悉PHP应用开发语言,初步具备利用该语言进行简单应用系统开发的能力。 6.掌握MySQL数据库的管理与维护技术。

九、考试内容

(一)基本概念与方法

1.数据库的基本概念和特点 2.数据库系统的结构 3.数据模型

4.数据库设计方法

(二)MySQL平台下的SQL交互操作 1.数据库、表、索引和视图的相关概念

2.数据库、表、索引和视图的创建及维护方法 3.数据完整性约束的概念、定义及使用方法 4.表和视图的查询及数据更新操作 (三)MySQL的数据库编程

1.触发器、事件、存储过程和存储函数的概念及作用 2.触发器的创建及使用 3.事件的创建及使用

4.存储过程和存储函数的创建及使用 (四)MySQL的管理与维护 1.MySQL的安装与配置

2.MySQL用户账号管理的作用及方法 3.MySQL账户权限管理的作用及方法 4.MySQL数据库备份与恢复的概念及方法 5.二进制日志文件的使用 (五)MySQL的应用编程 1.PHP语言的基本使用方法

2.MySQL平台下编制PHP简单应用程序

十、成绩及证书 1.NCRE实行百分制计分,但以等第通知考生成绩。等第共分优秀、及格、不及格三等。90~100分为优秀、60~89分为及格、0~59分为不及格。一般在考后30个工作日内由教育部考试中心将成绩处理结果下发给各省级承办机构。考后50个工作日,考生可登录教育部考试中心综合查询网(chaxun.neea.edu.cn)进行成绩查询。部分省市如江苏、黑龙江等也可通过省市考试院或者人事考试中心进行查询。

2.NCRE成绩在及格以上者,由教育部考试中心颁发合格证书。考后45个工作日教育部考试中心将证书发给各省级承办机构,然后由各省级承办机构逐级转发给考生。考生证书若丢失,可登录教育部考试中心综合查询

网补办合格证明书。补办合格证明书收费21元,其中制证、邮寄费用20元,银行收取手续费1元。

3.NCRE合格证书式样按国际通行证书式样设计,用中、英两种文字书写,证书编号全国统一,证书上印有持有人身份证号码。该证书全国通用,是持有人计算机应用能力的证明,也可供用人部门录用和考核工作人员时参考。

一级证书表明持有人具有计算机的基础知识和初步应用能力,掌握Office办公自动化软件的使用及因特网应用,或掌握基本图形图像工具软件(Photoshop)的基本技能,可以从事政府机关、企事业单位文秘和办公信息化工作。

二级证书表明持有人具有计算机基础知识和基本应用能力,能够使用计算机高级语言编写程序,可以从事计算机程序的编制、初级计算机教学培训以及企业中与信息化有关的业务和营销服务工作。

三级证书表明持有人初步掌握与信息技术有关岗位的基本技能,能够参与软硬件系统的开发、运维、管理和服务工作。

四级证书表明持有人掌握从事信息技术工作的专业技能,并有系统的计算机理论知识和综合应用能力。

第2章 复习技巧

一、备考指导 1.勇往直前

进入下午考试,也许有疲劳或不好的感觉,自信心就会下降;当看到题干很长,操作较复杂的题时,就有想回避或焦虑、急燥的情绪。这是典型的“两军未战,兵先屈”的败兴思绪。要知道两对手相遇勇者胜,勇者相遇智者胜。抛开所有不必要的想法,相信自己的实力,做到心无旁鹜,勇往直前。

2.审清题干

题干包含了整个题目的条件和要求,若题干比较复杂,就要注意将题干“分段”来阅读,前后注意衔接,必要时在草稿纸上记载下关键点。有时候题干很长,看似很复杂,让很多人望而却步。其实,这种题更好解,因题干长了则提示信息也就多了。主要是考你有没有勇气和耐心。

3.解读试题

首先,要翻阅一下全部试卷,注意试题的时间及分数的分配情况,做到心中有数。

其次,要弄清题意,明确题目要求。因为考试要求可能与自己习惯的答题要求有所不同,所以一定要按题意和要求去回答。

最后,要特别注意题目中比较隐蔽的条件。一般而言,条件隐蔽的问题难度较大,考生必须看清有关的线索,找出隐蔽条件,问题才能迎刃而解。

4.相信自己

当题做得非常顺利时,心里不要太得意,因为越是看似容易的题目越是错的多,当然也不要逆向思维,觉得这题这么简单是不是做错了,要相信自己,说到底还是要审清题目的意思;

二、题型分析 1.选择题

选择题为单选题,是客观性试题,试题覆盖面广,一般情况下考生不可能做到对每个题目都有把握答对。这时,就需要考生学会放弃,即不确定的题目不要在上面花费太多的时间,应该在此题上做上标记,立即转移注意力,作答其他题目。最后有空余的时间再回过头来仔细考虑此题。但要注意,对于那些实在不清楚的题目,就不要浪费时间了,放弃继续思考,不要因小失大。

绝大多数选择题的设问是正确观点,称为正面试题;如果设问是错误观点,称为反面试题。考生在作答选择题时可以使用一些答题方法,以提高答题准确率。

(1)正选法(顺选法):如果对题肢中的4个选项,一看就能肯定其中的1个是正确的,就可以直接得出答案。注意,必须要有百分之百的把握才行。

(2)逆选法(排谬法):逆选法是将错误答案排除的方法。对题肢中的4个选项,一看就知道其中的1个(或2个、3个)是错误的,可以使用逆选法,即排除错误选项。

(3)比较法(蒙猜法):这种办法是没有办法的办法,在有一定知识基础上的蒙猜也是一种方法。 2.操作题

上机考试重点考察考生的基本操作能力,要求考生具有综合运用基础知识进行实际操作的能力。上机操作题综合性强、难度较大。上机考试的评分是以机评为主,人工复查为辅的。机评当然不存在公正性的问题,但却存在呆板的问题,有时还可能因为出题者考虑不周出现错评的情况。考生做题时不充分考虑到这些情况,就有可能吃亏。

掌握好上机考试的应试技巧,可以使考生的实际水平在考试时得到充分发挥,从而取得较为理想的成绩。历次考试均有考生因为忽略了这一点,加之较为紧张的考场气氛影响了水平的发挥,致使考试成绩大大低于实际水平。因此每个考生在考试前,都应有充分的准备。总结以下几点供考生在复习和考试时借鉴:

(1)对于上机考试的复习,切不可“死记硬背”

根据以往考试经验,有部分考生能够通过笔试,而上机考试却不能通过,主要原因是这部分考生已经习惯于传统考试的“死记硬背”,而对于真正的知识应用,却显得束手无策。为了克服这个弊病,考生一定要在熟记基本知识点的基础上,加强上机训练,从历年试题中寻找解题技巧,理清解题思路,将各类典型试题反复练习。

(2)在考前,一定要重视等级考试模拟软件的使用

在考试之前,应使用等级考试模拟软件进行实际的上机操作练习,尤其要做一些具有针对性的上机模拟题,以便熟悉考试题型,体验真实的上机环境,减轻考试时的紧张程度。

(3)学会并习惯使用帮助系统

大部分软件都有较全面的帮助系统,熟练掌握帮助系统,可以使考生减少记忆量,解决解题中的疑难问题。

(4)熟悉考试场地及环境

尤其是要熟悉考场的硬件情况和所使用的相关软件的情况。考点在正式考试前,会给考生提供一次模拟上机的机会。模拟考试时,考生重点不应放在把题做出来,而是放在熟悉考试环境,相应软件的使用方法,考试系统的使用等方面。

(5)做上机题时要不急不燥,认真审题

先分析,后操作。明白了问题是什么以后,先把问题在脑海里过一遍,考虑好如何操作后,再依思路从容做答。而不要手忙脚乱、毛毛躁躁、急于作答。对于十分了解或熟悉的问题,切忌粗心大意、得意忘形、而应认真分析,必须将题目给出的全部内容逐字看清楚后针对具体问题进行操作。

常言道“熟能生巧”、“打铁还得本身硬”,再好的方法与技巧若没有基础,是发挥不了作用的;如若有了一定的功底,再差的招式也会产生很大的威力,就像金庸小说中杨过的那柄钝剑。但是如果只看不练,不会有提高。建议大家多做模拟试题和历年试题,锻炼解题的能力与节奏。

第二部分 核心讲义

【公共基础知识】

第1章 数据结构与算法

一、算法

1.算法的基本概念 (1)算法的定义

算法是指解题方案的准确而完整的描述,即算法是对特定问题求解步骤的一种描述。它是一组严谨定义运算顺序的规则,且每个规则都是明确有效的,此顺序将在有限的次数下终止。需要注意的是:算法不等于程序,也不等于计算方法。

(2)算法的基本特征 ①可行性

a.算法中的每一步骤都必须能够实现;

b.算法执行的结果要能够达到预期的目的。 ②确定性

确定性是指算法中的每一个步骤都必须有明确的定义,不允许有模棱两可的解释,也不允许有多义性。 ③有穷性

有穷性是指算法必须能在有限的时间内做完,即必须能在执行有限个步骤之后终止,且必须有合理的执行时间。

④拥有足够的情报

算法是否有效,取决于为算法所提供的情报是否足够。一般而言,当算法有足够的情报时,此算法有效,而当提供的情报不够时,算法可能无效。

2.算法设计基本方法 (1)列举法 ①基本思想

根据提出的问题,列举所有可能的情况,并用问题中给定的条件检验哪些是需要的,哪些是不需要的。常用于解决“是否存在”或“有多少种可能”等类型的问题。

②主要特点

算法比较简单,但列举情况较多时,算法工作量很大。 ③注意事项

例举算法时,通过对实际问题进行详细分析,将与问题有关的知识条理化、完备化、系统化,并从中找出规律,或对所有可能的情况进行分类,从而引出一些有用的信息,减少列举量。

(2)归纳法 ①基本思想

通过列举少量的特殊情况,经过分析,最后找出一般的关系。 ②主要特点

a.比列举法更能反映问题的本质,可解决列举量为无限的问题; b.可操作性低,不易归纳出一个具体数学模型;

c.归纳得出的结论只是一种猜测,须对这种猜测加以必要的证明。 (3)递推 ①基本思想

从已知的初始条件出发,逐次推出所要求的各中间结果和最后结果。 ②主要特点

a.初始条件或问题本身已给定,或通过对问题的分析化简得到; b.递推本质上属于归纳法,递推关系式往往是归纳的结果; c.数值型递推算法计算过程中必须注意数值计算的稳定性问题。 (4)递归 ①基本思想

将复杂问题逐层分解,归结为一些简单的问题,将简单问题解决掉,再沿着原来分解的逆过程逐步进行综合。 ②主要特点

a.递归的基础是归纳,对问题逐层分解的过程实际上并没有对问题进行求解; b.在可计算性理论和算法设计中占有重要地位; c.递归算法比递推算法清晰易读,结构简练;

d.设计递归算法比递推算法容易,但是其执行效率较低。 ③分类

a.直接递归。一个算法P显式地调用自己。

b.间接递归。算法P调用另一个算法Q,而算法Q又调用算法P。 ④递归与递推的区别

递归与递推的区别主要在于二者实现方法的不同,表现为: a.递归是从算法本身到达递归的边界的;

b.递推是从初始条件出发,逐次推出所需求的结果。 (5)减半递推技术

减半递推技术是工程上常用的分治法,其中,“减半”指将问题的规模减半,而问题的性质不变;“递推”指重复“减半”的过程。

(6)回溯法

回溯法是指通过对问题的分析,找出一个解决问题的线索,然后沿着这个线索逐步试探,若试探成功,则问题得到解决,若试探失败,则逐步回退换别的路线再进行试探。

3.算法复杂度 (1)时间复杂度 ①定义

算法的时间复杂度是指执行算法所需要的计算工作量。

算法的工作量用算法所执行的基本运算次数来度量,而算法所执行的基本运算次数是问题规模的函数,即

算法的工作量=f(n)

其中,n是问题的规模。 ②在同一问题规模下,若算法的基本运算次数取决于某一特定输入,可用以下两种方法来分析算法的工作量: a.平均性态

平均性态分析是指用各种特定输入下的基本运算次数的加权平均值来度量算法的工作量。算法的平均性态定义为:

A(n)=p(x)t(x)

xDn其中,x是所有可能输入中的某个特定输入,p(x)是x出现的概率,即输入为x的概率,t(x)是算法在

输入为x时所执行的基本运算次数,Dn表示当规模为n时,算法执行时所有可能输入的集合。

b.最坏情况复杂性

最坏情况分析是指规模为n时,算法所执行的基本运算的最大次数。其定义为:

W(n)=maxt(x)

xDn(2)空间复杂度 ①定义

算法的空间复杂度一般是指执行这个算法所需要的内存空间。 ②存储空间组成

一个算法的存储空间包括以下几种: a.算法程序占用的空间;

b.输入的初始数据占用的存储空间; c.算法执行过程中所需要的额外空间。

额外空间包括算法程序执行过程中的工作单元以及某种数据结构所需要的附加存储空间,若额外空间相对于问题规模来说是常数,则称该算法是原地工作的。

二、数据结构的基本概念 1.概述

(1)数据处理概述 ①定义

数据处理是指对数据集合中的各元素以各种方式进行运算,包括插入、删除、查找、更改等运算,也包括对数据元素进行分析。

②关键问题

大量数据元素在计算机中如何组织,以便提高数据处理的效率,从而节省计算机的存储空间,这是进行数据结构处理的关键问题。

(2)数据结构研究概述 ①研究问题

a.数据集合中各数据元素之间所固有的逻辑关系,即数据的逻辑结构;

b.在对数据进行处理时,各数据元素在计算机中的存储关系,即数据的存储结构; c.对各种数据结构进行的运算。 ②研究目的

数据结构研究和讨论上述3个问题的主要目的在于提高数据处理效率,包括:a.提高数据处理的速度;b.尽量节省在数据处理过程中所占用的计算机存储空间。

2.数据结构的概念 (1)数据结构的定义

数据结构是指相互有关联的数据元素的集合,即它是反映数据元素之间关系的数据元素集合的表示。简言之,数据结构是指带有结构的数据元素的集合,这里的“结构”指数据元素之间的前后件关系。一个数据结构应包含以下两方面内容:

①表述数据元素的信息;

②表示各数据元素之间的前后件关系。 (2)数据的逻辑结构 ①定义

数据的逻辑结构是指反映数据元素之间逻辑关系的数据结构。 ②要素:

a.数据元素的集合,通常记为D;

b.D上的关系,通常记为R,它反映了D中各数据元素之间的前后件关系。 ③表示

一个数据结构B可表示为:

B=(D,R)

为反映D中个数据元素之间的前后件关系,一般用二元组来表示。 (3)数据的存储结构 ①定义

数据的存储结构,也称数据的物理结构,是指数据逻辑结构在计算机存储空间中的存放形式。在数据的存储结构中,不仅要存放各数据元素的信息,而且要存放各数据元素之间的前后件信息。

②常用的存储结构:a.顺序;b.链接;c.索引。 采用不同的存储结构,数据处理的效率是不同的。 3.数据结构的图形表示

(1)在数据结构的图形表示中,数据集合D中每个元素用中间标有元素值的方框表示,称为数据结点(简称结点);对关系R中的每一个二元组,用一条有向线段从前件结点指向后件结点。

(2)在数据结构中,没有前件的结点称为根结点,没有后件的结点称为终端结点(也称叶子结点),其余结点都称为内部结点。

(3)数据结构中的元素结点可能是在动态变化的,这种变化体现在结点数量的增减以及各结点之间的前后件关系的动态变化上。

4.线性结构与非线性结构

根据数据结构中各数据元素之间的前后件关系的复杂程度,可将数据结构分为: (1)线性结构(线性表)

一个非空的数据结构满足下列两个条件时,称其为线性结构: ①有且只有一个根结点;

②每个结点最多只有一个前件,也最多只有一个后件。

线性结构中插入或删除任何一个结点还应是线性结构,如果不满足这个条件就不能称之为线性结构。 (2)非线性结构

如果一个数据结构不是线性结构,则称之为非线性结构。

注:线性结构与非线性结构都可以是空的数据结构。一个空的数据结构属于线性结构还是非线性结构,需要根据对该数据结构的运算是否按照线性结构的规则来处理进行判断。

三、线性表及其顺序存储结构 1.线性表的基本概念

(1)线性表是一种最常见最简单的数据结构,由一组数据元素构成。数据元素在线性表中的位置值只取决于它们自己的序号,即数据元素之间的相对位置是线性的。

(2)非空线性表的结构特征:

①有且只有一个根结点a1,它无前件; ②有且只有一个终端结点an,它无后件;

③除根结点与终端结点外,其他所有结点有且只有一个前件,也有且只有一个后件。 线性表中结点的个数n称为线性表的长度。当n=0时,称为空表。 2.线性表的顺序存储结构 (1)概述

顺序存储是一种最简单的在计算机中存放线性表的方法,也称顺序分配。 (2)特点:

①线性表中所有元素所占的存储空间是连续的;

②线性表中各数据元素在存储空间中是按逻辑顺序依次存放的。 在线性表的顺序存储结构中,其前后件两个元素在存储空间中是紧邻的,且前件元素一定存储在后件元素的前面。

(3)运算

在线性表的顺序存储结构下,可对线性表进行以下运算: ①插入:在线性表的指定位置处加入一个新的元素; ②删除:在线性表中删除指定的元素;

③查找:在线性表中查找某个(或某些)特定的元素; ④排序:对线性表中的元素进行整序;

⑤分解:按要求将一个线性表分解成多个线性表; ⑥合并:按要求将多个线性表合并成一个线性表; ⑦复制:复制一个线性表; ⑧逆转:逆转一个线性表等。 3.顺序表的插入运算

假设线性表的存储空间为V(1:m),线性表的长度为n(n≤m),插入的位置为i(表示在第i个位置插入元素),则顺序表插入新元素过程如下:

(1)首先处理以下三种异常情况:

①当存储空间已满(即n=m)时为“上溢”错误,不能进行插入,算法结束; ②当i>n时,认为在最后一个元素之后(即第n+1个元素之前)插入; ③当i<1时,认为在第1个元素之前插入。

(2)从最后一个元素开始,直到第i个元素,其中每一个元素均往后移动一个位置。 (3)最后将新元素插入到第i个位置,并且将线性表的长度增加1。 4.顺序表的删除运算

假设线性表的存储空间为V(1:m),线性表的长度为n(n≤m),删除的位置为i(表示删除第i个元素),则顺序表删除元素的过程如下:

(1)首先处理以下两种异常情况:

①当线性表为空(即n=0)时为“上溢”错误,不能进行插入,算法结束;

②当i<1或i>n时,认为在最后一个元素之后(即第n+1个元素之前)插入。

(2)然后从第i+1个元素开始,直到最后一个元素,其中每一个元素均依次往前移动一个位置。 (3)最后将线性表的长度减小1。

四、栈和队列

1.栈及其基本运算 (1)栈的定义

栈是限定在一端进行插入与删除的线性表。 (2)栈的特点:

①允许插入和删除的一端称为栈顶,不允许插入与删除的一端称为栈底。栈顶元素总是最后被插入的元素,也是最先被删除的元素;栈底元素总是最先被插入也是最后被删除的。

②栈遵循“先进后出”或“后进先出”的原则,具有记忆功能。

③通常用指针top来指示栈顶位置,用指针bottom指向栈底,栈顶指针top动态反映了栈中元素的变化情况。

(3)栈的顺序存储及其运算

在栈的顺序存储空间S(1:m)中,top=0表示栈空;top=m表示栈满。 栈的三种运算: ①入栈运算

人栈运算是指在栈顶位置插入一个新元素。操作过程如下:

a.首先判断栈顶指针是否已经指向存储空间的最后一个位置。如果是,则说明栈空间已满,不可能再进行入栈操作(这种情况称为栈“上溢”错误),算法结束。

b.然后将栈顶指针进一(即top加1)。

c.最后将新元素x插入栈顶指针指向的位置。 ②退栈运算

退栈运算是指取出栈顶元素并赋给一个指定的变量。操作过程如下:

a.首先判断栈顶指针是否为0。如果是,则说明栈空,不可能进行退栈操作(这种情况称为栈“下溢”错误),算法结束。

b.然后将栈顶元素(栈顶指针指向的元素)赋给一个指定的变量。 c.最后将栈顶指针退一(即top减1)。 ③读栈顶元素

读栈顶元素是指将栈顶元素赋给一个指定的变量。操作过程如下:

a.首先判断栈顶指针是否为0。如果是,则说明栈空,读不到栈顶元素,算法结束。 b.然后将栈顶元素赋给指定的变量y。

这个运算不删除栈顶元素,只是将它的值赋给一个变量,栈顶指针不会变。 2.队列及其基本运算 (1)什么是队列

队列(Queue)是指允许在一端进行插入、而在另一端进行删除的线性表。 (2)队列的特点

①允许插入的一端称为队尾,用队尾指针指向队尾元素;允许删除的一端称为队头,用排头指针指向排头元素的前一个位置。

②最先插入的元素最先被删除,最后插入的元素最后被删除,遵循“先进先出”或“后进后出”原则。 ③队尾指针rear和排头指针front共同反映队列中元素变动情况。

④入队运算指只涉及队尾指针rear变化,退队运算只涉及排头指针front变化。 (3)循环队列及其运算

循环队列是将队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间,供队列循环使用。在循环队列中,用队尾指针rear指向队尾元素,用排头指针front指向排头元素的前一个位置,从排头指针front指向的后一个位置到队尾指针rear指向的位置均是队列中元素。队列空的条件是s=0;队列满的条件是s=1且front=rear。

队列的两种运算

假设循环队列的初始状态为空,即:s=0,且front=rear=m。

①入队运算

入队运算是指在循环队列的队尾加入一个新元素。操作过程如下:

a.首先判断循环队列是否满。当循环队列非空(S=1)且队尾指针等于排头指针时,说明循环队列已满,不能进行入队运算。这种情况称为“上溢”。此时算法结束。

b.然后将队尾指针进一(即rear=rear+1),并当rear=m+1时置rear=1。 c.最后将新元素x插入队尾指针指向的位置,并且置循环队列非空标志。 ②退队运算

退队运算是指在循环队列的排头位置退出一个元素并赋给指定的变量。操作过程如下:

a.首先判断循环队列是否为空。当循环队列为空(s=0)时,不能进行退队运算。这种情况称为“下溢”。此时算法结束。

b.然后将排头指针进一(即front=front+1),并当front=m+1时置front=1。 c.再将排头指针指向的元素赋给指定的变量。

d.最后判断退队后循环队列是否为空。当front=rear时置循环队列空标志(即s=0)。

五、线性链表

1.线性链表的基本概念

(1)线性表的顺序存储结构存在的缺陷:

①在插入或删除元素时,为保证操作后的线性表仍然是顺序存储,需要大量移动数据元素,效率很低。 ②在顺序存储结构下,线性表的存储空间不便于扩充,易产生上溢现象。 ③线性表的顺序存储结构不便于对存储空间的动态分配。 (2)链式存储结点组成:

①数据域:用于存放数据元素值; ②指针域:用于存放指针。

指针用于指向该结点的前一个或后一个结点,存储数据结构的存储空间可以不连续,各数据结点的存储顺序与数据元素之间的逻辑关系可以不一致,而数据元素之间的逻辑关系是由指针域来确定的。

链式存储方式既可用于表示线性结构,也可用于表示非线性结构。在用链式结构表示较复杂的非线性结构时,其指针域的个数要多一些。

(3)线性链表

①定义:线性链表是线性表的链式存储结构。 ②特点

a.各数据结点的存储序号是不连续的,各结点在存储空间中的位置关系与逻辑关系也不一致; b.各数据元素之间的前后件关系是由各结点的指针域来指示的;

c.每一个结点只有一个指针域,由这个指针只能找到后件结点,不能找到前件结点,只能顺指针向链尾进行扫描。

为了弥补线性单链表的缺陷,在某些应用中为线性链表每个结点设置两个指针,左指针用以指向其前件结点,右指针指向其后件结点。

(4)带链的栈

带链的栈可以用来收集计算机存储空间中所有空闲的存储结点。 与顺序栈一样,带链栈的基本操作有以下几个: ①栈的初始化:建立一个空栈的顺序存储空间; ②入栈运算:在栈顶位置插入一个新元素;

③退栈运算:取出栈顶元素并赋给一个指定的变量; ④读栈顶元素:将栈顶元素赋给一个指定的变量。 (5)带链的队列

与顺序队列一样,带链队列的基本操作有以下几个: ①队列的初始化:建立一个空队列的顺序存储空间; ②入队运算:在循环队列的队尾加入一个新元素;

③退队运算:在循环队列的排头位置退出一个元素并赋给指定的变量。 2.线性链表的基本运算 (1)常见的线性表的运算

线性链表的运算主要有以下几个:

①在线性链表中包含指定元素的结点之前插入一个新元素; ②在线性链表中删除包含指定元素的结点; ③将两个线性链表按要求合并成一个线性链表; ④将一个线性链表按要求进行分解; ⑤逆转线性链表; ⑥复制线性链表; ⑦线性链表的排序; ⑧线性链表的查找。

(2)在线性链表中查找指定元素

非空线性链表中寻找包含指定元素值x的前一个结点p的基本方法:

从头指针指向的结点开始往后沿指针进行扫描,直到后面已没有结点或下一个结点的数据域为x为止。因此,由这种方法找到的结点p有两种可能:当线性链表中存在包含元素x的结点时,则找到的p为第一次遇到的包含元素x的前一个结点序号;当线性链表中不存在包含元素x的结点时,则找到的p为线性链表中的最后一个结点号。

(3)线性链表的插入

①定义:线性链表的插入是指在链式储存结构下的线性表中插入一个新元素。 ②插入过程:

在线性链表中包含元素x的结点之前插入一个新元素b。

a.从可利用栈取得一个结点,设该结点号为p,并置结点p的数据域为插入的元素值b。 b.在线性链表中寻找包含元素x的前一个结点,设该结点的存储序号为q。

c.最后将结点p插入到结点q之后。为了实现这一步,只要改变以下两个结点的指针域内容: 第一,使结点P指向包含元素x的结点;

第二,使结点q的指针域内容改为指向结点p。 ③插入特点:

a.不会发生上溢现象;

b.可方便实现存储空间动态分配;

c.不发生数据元素移动现象,只改变结点指针,提高插入效率。 (4)线性链表的删除

①定义:线性链表的删除是指在链式储存结构下的线性表中删除包含指定元素的结点。 ②删除过程:

在线性链表中删除包含元素x的结点。

a.在线性链表中寻找包含元素x的前一个结点,设该结点序号为q; b.将结点q后的结点p从线性链表中删除,即让结点q的指针指向包含元素x的结点p的指针指向的结点; c.将包含元素x的结点p送回可利用栈。 在线性链表中删除一个元素后,不需要移动表的数据元素,只需改变被删除元素所在结点的前一个结点的指针域即可。

3.循环链表

(1)与线性链表相比,循环链表具有的特点: ①在循环链表中增加了一个表头结点,其数据域为任意或者根据需要来设置,指针域指向线性表的第一个元素的结点。循环链表的头指针指向表头结点。

②循环链表中最后一个结点的指针域不是空,而是指向表头结点。即在循环链表中,所有结点的指针构成了一个环状链。

(2)与线性单链表相比,循环链表具有两方面优点:

①在循环链表中,只要指出表中任何一个结点的位置,就可以从它出发访问到表中其他所有的结点。而线性单链表做不到这一点。

②由于在循环链表中设置了一个表头结点,因此,在任何情况下循环链表中至少有一个结点存在,从而使空表与非空表的运算统一。

循环链表的插入与删除运算要比一般单链表简单,不用考虑在空链表和在第一个结点前插入以及空链表的删除等特殊情况,从而实现了空表与非空表运算的统一。

六、树与二叉树 1.树的基本概念

(1)树是一种简单的非线性结构,在这种结构中,所有数据元素之间的关系具有明显的层次特性。在树的图形表示中,上端结点是前件,下端结点是后件。

(2)在树结构中,每个结点只有一个前件(父结点),没有前件的结点只有一个,称为树的根结点。每个结点都可以有多个后件(子结点),没有后件的结点称为叶子结点。

(3)一个结点拥有的后件个数称为该结点的度。某结点的度为n,表示该结点有n个分支,每个分支指向一个后件,除根结点外,每个结点都有一个唯一的分支指向它。树中的结点数为树中所有结点的度之和再加1。

(4)根结点在第1层,同一层上所有结点的所有子结点都在下一层,树的最大层次称为树的深度 (5)在树中,叶子结点没有子树。 (6)用树来表示算术表达式的原则:

①表达式中的每一个运算符在树中对应一个结点,称为运算符结点;

②运算符的每一个运算对象在树中为该运算符结点的子树(在树中的顺序为从左到右); ③运算对象中的单变量均为叶子结点。 在树中,叶子结点没有子树。 2.二叉树及其基本性质 (1)二叉树定义

二叉树是一种很有用的非线性结构,与树结构很相似,树结构的所有术语都可以用到叉树这种数据结构上。 (2)二叉树的两个特点

①非空二叉树只有一个根结点;

②每一个结点最多有两棵子树,且分别称为该结点的左子树与右子树。 (3)二叉树的基本性质

①在二叉树的第k层上,最多有2k-1(k≥1)个结点。 ②深度为m的二叉树最多有2m-1个结点。

③在任意一棵二叉树中,度为0的结点(即叶子结点)总是比度为2的结点多一个。

④具有n个结点的二叉树,其深度至少为[log2n]+1,其中[[log2n]表示取log2n的整数部分。 (4)满二叉树与完全二叉树

满二叉树与完全二叉树是两种特殊形态的二叉树。 ①满二叉树

除最后一层外,每一层上的所有结点都有两个子结点。 ②完全二叉树

a.除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。

b.更确切地说,如果从根结点起,对二叉树的结点自上而下、自左至右用自然数进行连续编号,则深度为m、且有n个结点的二叉树,当且仅当其每一个结点都与深度为m的满二叉树中编号从1到n的结点一一对应时,称之为完全二叉树。

对于完全二叉树来说,叶子结点只可能在层次最大的两层上出现;对于任何一个结点,若其右分支下的子孙结点的最大层次为P,则其左分支下的子孙结点的最大层次或为P,或为p+1。

c.满二叉树也是完全二叉树,而完全二叉树一般不是满二叉树。 完全二叉树具有以下两个性质:

a.具有n个结点的完全二叉树的深度为[log2n]+1。

b.设完全二叉树共有n个结点。如果从根结点开始,按层序(每一层从左到右)用自然数1,2,…,n给结点进行编号,则对于编号为k(k=1,2,…,n)的结点有以下结论:

第一,若k=1,则该结点为根结点,它没有父结点;若k>1,则该结点的父结点编号为INT(k/2)。 第二,若2k≤n,则编号为k的结点的左子结点编号为2k;否则该结点无左子结点(显然也没有右子结点)。 第三,若2k+1≤n,则编号为k的结点的右子结点编号为2k+1;否则该结点无右子结点。

根据完全二叉树的这个性质,如果按从上到下、从左到右顺序存储完全二叉树的各结点,则很容易确定每一个结点的父结点、左子结点和右子结点的位置。

3.二叉树的存储结构

(1)在计算机中,二叉树采用链式存储结构。

(2)用于存储二叉树中各元素的存储结点由两部分组成: ①数据域 ②指针域

a.左指针:用于指向该结点的左子结点的存储地址; b.右指针:指向该结点的右指结点的存储地址。 4.二叉树的遍历

二叉树的遍历是指不重复地访问二叉树中的所有结点。在遍历二叉树结点中遵循先左后右的原则。二叉树的遍历可分为三种:

(1)前序遍历(DLR)

在访问根结点、遍历左子树与遍历右子树这三者中,首先访问根结点,然后遍历左子树,最后遍历右子树;并且,在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。该过程是一个递归的过程。

(2)中序遍历(LDR)

在访问根结点、遍历左子树与遍历右子树这三者中,首先遍历左子树,然后访问根结点,最后遍历右子树;并且,在遍历左、右子树时,仍然先遍历左子树,然后访问根结点,最后遍历右子树。因此,中序遍历二叉树的过程也是一个递归的过程。

(3)后序遍历(LRD)

在访问根结点、遍历左子树与遍历右子树这三者中,首先遍历左子树,然后遍历右子树,最后访问根结点,并且,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后访问根结点。因此,后序遍历二叉树的过程也是一个递归的过程。

如果知道了某二叉树的前序序列和中序序列,则可以唯一地恢复该二叉树,如果知道了某二叉树的后序序列和中序序列,则也可以唯一地恢复该二叉树。但如果只知道某二叉树的前序序列和后序序列,是不能唯一恢复该二叉树的。

七、查找技术

1.顺序查找(顺序搜索) (1)基本方法

从线性表的第一个元素开始,依次将线性表中的元素与被查元素进行比较,若相等则表示找到(即查找成功);若线性表中所有的元素都与被查元素进行了比较但都不相等,则表示线性表中没有要找的元素(即查找失败)。

(2)以下两种情况只能采用顺序查找:

①线性表为无序表(即表中元素的排列是无序的),则不管是顺序存储结构还是链式存储结构,都只能用顺序查找。

②即使是有序线性表,如果采用链式存储结构,也只能用顺序查找。 (3)顺序查找的缺陷:效率太低 2.二分法查找(对分查找) (1)适用范围

只适用于顺序存储的有序表,在此所说的有序表是指线性表中元素按值非递减排列。 (2)具体方法

设有序线性表的长度为n,被查元素为x,则:

①将x与线性表的中间项进行比较:若中间项的值等于x,则说明查到,查找结束;

②若x小于中间项的值,则在线性表的前半部分(即中间项以前的部分)以相同的方法进行查找 ③若x大于中间项的值,则在线性表的后半部分(即中间项以后的部分)以相同的方法进行查找 ④这个过程一直进行到查找成功或子表长度为0(说明线性表中没有这个元素)为止。

八、排序技术 1.交换类排序法 (1)冒泡排序法

①定义:冒泡排序法是一种最简单的交换类排序方法,通过相邻数据元素的交换逐步将线性表变成有序。 ②基本过程:

a.从表头开始往后扫描线性表,在扫描过程中逐次比较相邻两个元素的大小。若相邻两个元素中,前面的元素大于后面的元素,则将它们互换,称之为消去了一个逆序。

b.从后到前扫描剩下的线性表,同样,在扫描过程中逐次比较相邻两个元素的大小。若相邻两个元素中,后面的元素小于前面的元素,则将它们互换,这样就又消去了一个逆序。

c.对剩下的线性表重复上述过程,直到剩下的线性表变空为止,此时的线性表已经变为有序。

③在上述排序过程中,对线性表的每一次来回扫描后,都将其中的最大者沉到了表的底部,最小者像气泡一样冒到表的前头。冒泡排序由此而得名,且冒泡排序又称下沉排序。

假设线性表的长度为n,则在最坏情况下,冒泡排序需要经过n/2遍的从前往后的扫描和n/2遍的从后往前的扫描,需要的比较次数为n(n-1)/2。

(2)快速排序法 ①基本思想

从线性表中选取一个元素T,将线性表后面小于T的元素移到前面,前面大于T的元素移到后面,这样就以T为分割线将线性表分割成前后两个子表。再将得到的子表按照这个过程继续下去,直到所有子表为空为止。

②快速排序在最坏情况下需要进行n(n-1)/2次比较,但实际的排序效率要比冒泡排序高得多。 2.插入类排序法 (1)简单插入排序法

①定义:所谓插入排序,是指将无序序列中的各元素依次插入到已经有序的线性表中。 ②插入过程:

将第j个元素放到一个变量T中,然后从有序子表的最后一个元素(即线性表中第j-1个元素)开始,往前逐个与T进行比较,将大于T的元素均依次向后移动一个位置,直到发现一个元素不大于T为止,此时就将T(即原线性表中的第j个元素)插入到刚移出的空位置上,有序子表的长度就变为j了。

③这种排序方法的效率与冒泡排序法相同。在最坏情况下,简单插入排序需要n(n-1)/2次比较。 (2)希尔排序法

①基本思想:将整个无序序列分割成若干小的子序列分别进行插入排序。 ②子序列的分割方法:

将相隔某个增量h的元素构成一个子序列。在排序过程中,逐次减小这个增量,最后当h减到1时,进行一次插入排序,排序就完成。增量序列一般取ht=n/2k(k=1,2,…,[log2n]),其中n为待排序序列的长度。

③如果选取上述增量序列,则在最坏情况下,希尔排序所需要的比较次数为0(n1.5)。 3.选择类排序法 (1)简单选择排序法 ①基本思想:

扫描整个线性表,从中选出最小的元素,将它交换到表的最前面(这是它应有的位置);然后对剩下的子表采用同样的方法,直到子表空为止。对于长度为n的序列,选择排序需要扫描n-1遍,每一遍扫描均从剩下的子表中选出最小的元素,然后将该最小的元素与子表中的第一个元素进行交换。

②简单选择排序法在最坏情况下需要比较n(n-1)/2次。 (2)堆排序法 ①堆的定义

具有n个元素的序列(h1,h2,…,hn),当且仅当满足

(i=1,2,…,n/2)时称之为堆。

②堆排序的方法:

a.将一个无序序列建成堆;

b.将堆顶元素(序列中的最大项)与堆中最后一个元素交换(最大项应该在序列的最后); c.反复做上一步,直到剩下的子序列为空为止。

③在最坏情况下,堆排序需要比较的次数为0(nlog2n)。

第2章 程序设计基础

一、程序设计方法与风格 1.程序设计发展阶段

就程序设计方法和技术的发展而言,主要经过了结构化程序设计和面向对象的程序设计阶段。 2.程序设计方格

程序设计风格会影响软件的质量和可维护性,良好的程序设计风格可以使结构清晰合理,程序代码便于维护,程序设计风格总体强调简明清晰,易读易懂,程序必须是可理解的,总体遵循“清晰第一,效率第二”的原则。

3.良好的程序设计风格应考虑的因素 (1)源程序文档化 ①符号名的命名

符号名的命名应具有一定的实际含义,以便于对程序功能的理解。 ②程序注释 a.序言性注释

位于每个程序的开头部分,给出程序的整体说明,主要描述内容可以包括:程序标题、程序功能说明、主要算法、接口说明、程序位置、开发简历、程序设计者、复审者、复审日期、修改日期等。

b.功能性注释

嵌在源程序体之中,主要描述其后的语句或程序做什么。 ③视觉组织

在程序中利用空格、空行、缩进等技巧可以使层次清晰,便于阅读。 (2)数据说明的方法

为使程序中的数据说明更易于理解和维护,应注意以下几点: ①数据说明的次序规范化

数据说明次序固定,可以使数据的属性容易查找,也有利于测试、排错和维护。 ②说明语句中变量安排有序化

当一个说明语句说明多个变量时,变量按照字母顺序排序为好。 ③使用注释来说明复杂数据的结构。 (3)语句的结构

程序应该简单易懂,语句构造应该简单直接,不为提高效率而把语句复杂化。 ①在一行内只写一条语句; ②程序编写应优先考虑清晰性;

③除非对效率有特殊要求,程序编写要做到清晰第一,效率第二; ④首先要保证程序正确,然后才要求提高速度; ⑤避免使用临时变量而使程序的可读性下降; ⑥避免不必要的转移; ⑦尽可能使用库函数;

⑧避免采用复杂的条件语句;

⑨尽量减少使用“否定”条件的条件语句; ⑩数据结构要有利于程序的简化;

⑪要模块化,使模块功能尽可能单一化; ⑫利用信息隐蔽,确保每一个模块的独立性; ⑬从数据出发去构造程序;

⑭不要修补不好的程序,要重新编写; (4)输入和输出

输入输出的方式和格式应当尽量方便用户使用,在设计和编程时应遵循以下原则: ①对所有的输入数据都要检验数据的合法性; ②检查输入项的各种重要组合的合理性;

③输入格式要简单,以使得输入的步骤和操作尽可能简单; ④输入数据时,应允许使用自由格式;

⑤应允许缺省值;

⑥输入一批数据时,最好使用输入结束标志;

⑦在以交互式输入/输出方式进行输入时,要在屏幕上使用提示符明确提示输入的请求,同时在数据输入过程中和输入结束时,应在屏幕上给出状态信息;

⑧当程序设计语言对输入格式有严格要求时,应保持输入格式与输入语句的一致性;给所有的输出加注释,并设计输出报表格式。

二、结构化程序设计

1.结构化程序设计的原则

结构化程序设计方法的主要原则可以概括为自顶向下,逐步求精,模块化,限制使用goto语句。 (1)自顶向下

先考虑总体后考虑细节,先考虑全局目标,后考虑局部目标。先从最上层总目标开始设计,逐步使问题具体化。

(2)逐步求精

对复杂问题,应设计一些子目标作过渡,逐步细化。 (3)模块化

把程序要解决的总目标分解为分目标,再进一步分解为具体的小目标,把每个小目标称为一个模块。 (4)限制使用goto语句

①滥用GOTO语句确实有害,应尽量避免;

②完全避免使用GOTO语句也并非是个明智的方法,有些地方使用GOTO语句,会使程序流程更清楚、效率更高;

③争论的焦点不应该放在是否取消GOTO语句,而应该放在用什么样的程序结构上。其中最关键的是,肯定以提高程序清晰性为目标的结构化方法。

2.结构化程序的基本结构与特点 (1)基本结构 ①顺序结构

顺序结构是一种简单的程序设计,它是最基本、最常用的结构,按照程序语句行的自然顺序,一条语句一条语句地执行程序。

②选择结构(分支结构)

选择结构包括简单悬着多分枝选择,可根据设定条件,判断应该选择哪一个分支来执行相应的语句序列。 ③循环结构

根据给定的条件,判断是否重复执行某一个相同的或类似的程序段,利用循环可以大大简化大量的程序行。

a.当型循环结构:先判断后执行循环体; b.直到型循环结构:先执行循环体后判断。 (2)结构化程序设计方法的优点

①程序易于理解、使用和维护,便于控制、降低程序的复杂性,可理解性好; ②提高了编程工作的效率,降低了软件开发成本。 3.结构化程序设计原则和方法的应用 在结构化程序设计中应把握以下要素:

(1)使用程序设计语言中的顺序、选择、循环等有限的控制结构表示程序的控制逻辑; (2)选用的控制结构只准许有一个入口和一个出口;

(3)程序语句组成容易识别的块,每块只有一个入口和一个出口; (4)复杂结构应该用嵌套的基本控制结构进行组合嵌套来实现; (5)语言中所没有的控制结构,应该采用前后一致的方法来模拟; (6)严格控制GOTO语句的使用。其意思是指:

①用一个非结构化的程序设计语言去实现一个结构化的构造; ②若不使用GOTO语句会使功能模糊;

③在某种可以改善而不是损害程序可读性的情况下。

三、面向对象的程序设计 1.关于面向对象方法 (1)面向对象的本质

从客观世界固有的事物出发来构造系统,提倡用人类在现实生活中常用的思维方法来认识、理解和描述客观事物,强调最终建立的系统能够映射问题域,即系统中的对象以及对象之间的关系能够如实地反映问题域中固有事物及其关系。

(2)面向对象的主要优点 ①与人类习惯的思维方法一致

面向对象的设计和技术以对象为核心,与客观实体有直接的对应关系,对象之间传递信息互相联系,以模拟现实世界中不同事物彼此之间的联系。强调模拟现实世界中的概念而不是强调算法,鼓励开发者在软件开发的绝大部分过程中都应用领域的概念去思考。

②稳定性好

面向对象的软件系统结构是根据问题领域的模型建立起来,而不是基于对系统应完成功能的分解,当对系统的功能需求变化时不会引起软件结构的整体变化,仅需要做一些局部性的修改。

③可重用性好

a.面向对象方法中使用的对象和数据是作为平等地位出现的。对象有很强的自含性,且对象固有的封装性使得对象的内部实现与外界隔离,具有较强的独立性。

b.重复使用一个对象的两种方法: 第一,创建该类的实例,直接使用它;

第二,从它派生出一个满足当前需要的新类。 ④易于开发大型软件产品

用面向对象范型开发软件时,可以把一个大型产品看作是一系列本质上相互独立的小产品来处理,这就不仅降低了开发的技术难度,而且也使得对开发工作的管理变得容易。

⑤可维护性好

软件的可维护性是长期困扰人们的一个严重问题,是软件危机的突出表现。 (3)面向对象设计软件可维护性好的主要表现 ①用面向对象的方法开发的软件稳定性比较好

功能或性能的要求发生变化时,不会引起软件整体变化,只需要对局部做修改,容易实现。 ②用面向对象的方法开发的软件比较容易修改

对象具有理想的模块机制,独立性好,修改一个类很少会牵扯到其它类,特有的继承机制使得对开发的软件的修改和扩充比较容易实现。

③用面向对象的方法开发的软件比较容易理解

面向对象的技术符合人们习惯的思维方式,用这种方法所建立的软件系统的结构与问题空间的结构基本一致。因此,面向对象的软件系统比较容易理解。对面向对象软件系统进行修改和扩充,通常是通过在原有类的基础上派生出一些新类来实现。

④易于测试和调试

面向对象设计的软件在维护后的测试和调试工作主要是围绕新派生出来的类进行。类是独立性很强的模块,因此软件的测试和调试就很容易实现。

2.面向对象方法的基本概念 (1)对象 ①概念

对象用来表示客观世界中的任何实体,在应用领域中,有意义的、与所要解决的问题有关系的任何事物都可以作为对象。

②面对对象的程序设计方法中的对象

该对象是系统中用来描述客观事物的一个实体,是构成系统的一个基本单位,由一组表示其静态特征的属性和它可执行的一组操作组成。

③对象的属性和操作 a.属性

属性即对象包含的信息,在设计对象时确定,一般只能通过执行对象的操作来改变。 b.操作

描述了对象执行的功能,通过消息传递还可以为其他对象使用,操作的过程对外是封闭的,用户只能看到操作实施的结果,所有的操作过程都封装在对象中。

④对象具有的特点: a.标识唯一性

对象是可区分的,且这种区分是通过对象的内在本质,而不是通过描述来区分。 b.分类性

可以将具有相同属性和操作的对象抽象成类。 c.多态性

同一个操作可以是不同对象的行为。 d.封装性

从外面只能看到对象的外部特征,只知道数值的取值范围和可以对数据施加的操作,无法知道数据的具体结构及实现操作的算法。对象的处理能力对外不可见,从外面不能直接使用对象的处理能力,无法修改其内部状态,其内部状态只能由其自身改变。

e.模块独立性好

对象是面向对象的软件的基本模块,它是由数据及可以对这些数据施加的操作所组成的统一体,而且对象是以数据为中心的,操作围绕对其数据所需做的处理来设置,没有无关的操作。从模块的独立性考虑,对象内部各种元素彼此结合得很紧密,内聚性强。

(2)类和实例

①类是具有相同属性,共同方法的对象的集合,它描述了属于该对象类型的所有对象的性质,一个对象是其对应类的一个实例。

②使用“对象”这个术语时,可以指一个具体的对象,也可以泛指一般的对象。当使用“实例”这个术语时,必然是指一个具体的对象。

③类是关于对象性质的描述,它同对象一样,包括一组数据属性和在数据上的一组合法操作。 (3)消息

①消息是一个实例与另一个实例之间传递的信息,它请求对象执行某一处理或回答某一要求的信息,它统一了数据流和控制流。

②消息中只包含传递者的要求,告诉接收者应该做哪些处理,但不指示接收者应该怎样完成这些处理。接收者独立决定采用什么样的方式完成所需的处理。

③一个对象能够接收不同形式,不同内容的多个消息;相同形式的消息可以送往不同的对象,不同对象对于形式相同的消息可以有不同的解释,作出不同反应。

④一个消息由下述三部分组成: a.接收消息的对象的名称; b.消息标识符(也称为消息名); c.零个或多个参数。 (4)继承

①定义:继承是使用已有的类定义作为基础建立新类的定义技术,已有的类可当做基类来引用,新类当做派生类来引用。

②面对对象软件技术的许多功能和优点来源于将类组成一个层次结构的系统:一个类的上层可以有父类下层可以有子类,这种系统的重要性质是继承性;一个类直接继承父类的特性,子类自动地共享基类中定义的数据和方法。

③继承的分类: a.单继承

一个类只允许有一个父类,类等级为树状结构。 b.多继承

一个类允许有多个父类,可以组合多个父类的性质构成所需要的性质。功能更强,使用更方便;注意避免二义性。

④继承性的优点:

a.相似的对象可以共享程序代码和数据结构,从而大大减少了程序中的冗余信息,提高软件的可重用性,便于软件修改维护。

b.用户在开发新的应用系统时不必完全从零开始,可以继承原有的相似系统的功能或者从类库中选取需要

的类,再派生出新的类以实现所需要的功能。

(5)多态性

①多态性是指对象根据所接收的消息而做出动作,同样的消息被不同的对象接收时可导致完全不同的行动的一种现象。

②在面向对象的软件技术中,多态性是指子类对象可以像父类对象那样使用,同样的消息既可以发送给父类对象也可以发送给子类对象。

③多态性机制增加了面向对象软件系统的灵活性,进一步减少了信息冗余,显著地提高了软件的可重用性和可扩充性。

第3章 软件工程基础

一、软件工程基本概念 1.软件定义与软件特点 (1)软件的定义

计算机软件(Software)是计算机系统中与硬件相互依存的另一部分,是包括程序、数据及相关文档的完整集合。

(2)软件的组成

①机器可以执行的程序和数据;

②机器不可执行的,与软件开发、运行、维护、使用等有关的文档。 (3)软件的特点

①软件是一种逻辑实体,而不是物理实体,具有抽象性。可记录在纸上或存储介质上,无法看到其本身形态,必须通过观察、分析、思考、判断才能了解其功能和特性。

②软件的生产与硬件不同,它没有明显的制作过程。开发成功可以大量复制,所以对软件的质量控制主要集中在开发方面。

③软件在运行、使用期间不存在磨损、老化问题。软件虽然在生存周期后期不会因为磨损而老化,但为适应硬件等变化,必要时要做出修改。修改可能会引入错误,导致软件失效率升高,软件退化。

④软件的开发、运行对计算机系统有很大依赖性,导致软件出现移植问题。

⑤软件复杂性高,成本昂贵。软件开发涉及各行业的专业知识,需要投入大量、高强度的脑力劳动,成本高,风险大。

⑥软件开发涉及诸多的社会因素。许多软件的开发和运行涉及软件用户的机构设置,体制问题以及管理方式等,甚至涉及人们的观念和心理,软件知识产权及法律等问题。

(4)软件的分类

软件按照应用功能划分,可分为: ①应用软件

应用软件是为解决特定领域的应用而开发的软件。常用的应用软件:事务处理软件,工程与科学计算软件,实时处理软件等。

②系统软件

系统软件是计算机管理自身资源,提高计算机使用效率并服务于其他程序的软件。常用的系统软件:操作系统,编译程序,汇编程序,网络软件,数据库管理系统等

③支撑软件

支撑软件是介于系统软件和应用软件之间,协助用户开发软件的工具性软件,包括辅助和支持开发和维护应用软件的工具软件。常用的支撑软件:需求分析工具软件,设计工具软件,编码工具软件,测试工具软件等。

2.软件危机与软件工程 (1)软件危机 ①定义

软件危机泛指计算机软件的开发和维护过程中所遇到的一系列严重问题。 ②主要表现

a.软件需求的增长得不到满足,用户对系统不满意的情况经常发生;

b.软件开发成本和进度无法控制,开发成本超出预算,开发周期大大超过规定日期的情况经常发生; c.软件质量难以保证;

d.软件不可维护或维护程度非常低; e.软件的成本不断提高;

f.软件开发生产率的提高赶不上硬件的发展和应用需求的增长。 ③产生原因

a.对软件需求速度大大超过了技术进步带来的软件生产率的提高;

b.软件工程所面临的任务和其他工程之间的差异以及软件和其他工业产品的不同。 (2)软件工程 ①定义

IEEE给出一个综合的定义是:将系统化的、规范的、可度量的方法应用于软件的开发、运行和维护的过程,即将工程化应用于软件中。

②三要素

a.方法:完成软件工程项目的技术手段。

b.工具:支持软件的开发、管理、文档生成。 c.过程:支持软件开发的各个环节的控制、管理。 ③核心

把软件产品当作工程产品来处理,把需求计划、可行性研究、工程审核、质量监督等工程化的概念引入到软件生产当中,以期达到工程项目的三个基本要素:进度、经费和质量的目标。同时,也注重研究不同于其他工业产品生产的一些独特特性,并针对软件的特点提出了许多有别于一般工业工程技术的一些技术方法。代表性的有结构化的方法、面向对象方法和软件开发模型及软件开发过程等。

3.软件过程与软件生命周期 (1)软件过程 ①定义

ISO 9000定义:软件过程是把输入转化为输出的一组彼此相关的资源和活动。 ②内涵

a.为获得软件产品,在软件工具支持下由软件工程师完成的一系列软件工程活动。通常包括四方面活动: 第一,P(Plan)——软件规格说明。规定软件的功能及其运行时的限制; 第二,D(Do)——软件开发或软件设计与实现。生产满足规格说明的软件; 第三,C(Cheek)——软件确认。确认软件能够满足客户提出的要求;

第四,A(Action)——软件演进。为满足客户的变更要求,软件必须在使用的过程中演进。

b.使用适当的资源,为开发软件进行的一组开发活动,在过程结束时将输入(用户要求)转化为输出(软件产品)。

(2)软件生命周期 ①定义

软件生命周期是指软件产品从提出、实现、使用维护到停止使用退役的过程。 ②阶段

a.软件定义

软件定义阶段包括可行性研究初步项目计划和需求分析阶段。主要任务:确定软件开发工作必须完成的目标,确定工程可行性

b.软件开发

软件开发阶段包括总体设计、详细设计、编码与测试阶段。主要任务:具体完成设计和实现定义阶段所定义的软件,总体设计和详细设计又称为系统设计,编码和测试又称为系统实现。

c.软件运行维护

软件运行维护阶段包括使用、维护和退役阶段。主要任务:使软件在运行中持久地满足用户的需要,及时改正软件在使用中发生的错误,修改软件以适应不同的使用环境。

③各阶段的基本任务

a.可行性研究与计划制定

确定待开发软件系统的开发目标和总的要求,给出它的功能、性能、可靠性以及接口等方面的可能方案,制定完成开发任务的实施计划。

b.需求分析

对待开发软件提出的需求进行分析并给出详细定义。编写软件规格说明书及初步的用户手册,提交评审。 c.软件设计

系统设计人员和程序设计人员应该在反复理解软件需求的基础上,给出软件的结构、模块的划分、功能的分配以及处理流程。在系统比较复杂的情况下,设计阶段可分解成概要设计阶段和详细设计阶段。编写概要设计说明书、详细设计说明书和测试计划初稿,提交评审。

d.编码

编码是把软件设计转换成计算机可以接受的程序代码。即完成源程序的编码,编写用户手册、操作手册等面向用户的文档,编写单元测试计划。

e.软件测试

在设计测试用例的基础上,检验软件的各个组成部分。编写测试分析报告。 f.运行和维护

将已交付的软件投入运行,并在运行使用中不断地维护,根据新提出的需求进行必要而且可能的扩充和删改。

4.软件工程的目标与原则 (1)软件工程的目标 ①定义

软件工程的目标是,在给定成本、进度的前提下,开发出具有有效性、可靠性、可理解性、可维护性、可重用性、可适应性、可移植性、可追踪性和可互操作性且满足用户需求的产品。

②基本目标:

a.付出较低的开发成本; b.达到要求的软件功能; c.取得较好的软件性能; d.开发的软件易于移植; e.需要较低的维护费用;

f.能按时完成开发,及时交付使用。 ③软件工程的理论和技术性研究的内容: a.软件开发技术

第一,软件开发技术包括:软件开发方法学、开发过程、开发工具和软件工程环境,其主体内容是软件开发方法学。

第二,软件开发方法学是根据不同的软件类型,按不同的观点和原则,对软件开发中应遵循的策略、原则、步骤和必须产生的文档资料都作出规定,从而使软件的开发能够进入规范化和工程化的阶段,以克服早期的手工方法生产中的随意性和非规范性做法。

b.软件工程管理

第一,软件工程管理包括:软件管理学、软件工程经济学、软件心理学等内容。

软件工程管理是软件按工程化生产时的重要环节,它要求按照预先制定的计划、进度和预算执行,以实现预期的经济效益和社会效益。

第二,软件管理学包括人员组织、进度安排、质量保证、配置管理、项目计划等。

第三,软件工程经济学是研究软件开发中成本的估算、成本效益分析的方法和技术,用经济学的基本原理来研究软件工程开发中的经济效益问题。

第四,软件心理学是软件工程领域具有挑战性的一个全新的研究视角,它是从个体心理、人类行为、组织行为和企业文化等角度来研究软件管理和软件工程的。

(2)软件工程的原则

为了达到上述的软件工程目标,在软件开发过程中,必须遵循软件工程的基本原则。 ①抽象

抽取事物最基本的特性和行为,忽略非本质细节。采用分层次抽象,自顶向下,逐层细化的办法控制软件开发过程的复杂性。

②信息隐蔽

采用封装技术,将程序模块的实现细节隐藏起来,使模块接口尽量简单。 ③模块化

模块是一个独立的编程单位,大小应适中。过大会使内部复杂性增加,不利于修改和理解,也不利于调试和重用,过小会导致系统表示过于复杂,不利于控制复杂性。

④局部化

在一个物理模块内集中逻辑上相互关联的计算资源,保证模块间具有松散的耦合关系,模块内部有较强的内聚性,有利于控制解的复杂性。

⑤确定性

软件开发过程中所有概念的表达应是确定的、无歧义且规范的。这有助于人与人的交互不会产生误解和遗漏,以保证整个开发工作的协调一致。

⑥一致性

包括程序、数据和文档的整个软件系统的各模块应使用已知的概念、符号和术语;程序内外部接口应保持

一致,系统规格说明与系统行为应保持一致。

⑦完备性

软件系统不丢失任何重要成分,完全实现系统所需的功能。 ⑧可验证性

开发大型软件系统需要对系统自顶向下,逐层分解。系统分解应遵循容易检查、测评、评审的原则,以确保系统的正确性。

5.软件开发工具与软件开发环境 (1)软件开发工具

软件开发工具的发展是从单项工具的开发逐步向集成工具发展的,软件开发工具为软件工程方法提供了自动的或半自动的软件支撑环境。同时,软件开发方法的有效应用也必须得到相应工具的支持,否则方法将难以有效的实施。

(2)软件开发环境

软件开发环境或称软件工程环境是全面支持软件开发全过程的软件工具集合。这些软件工具按照一定的方法或模式组合起来,支持软件生命周期内的各个阶段和各项任务的完成。

二、结构化分析方法

1.需求分析与需求分析方法 (1)需求分析 ①需求的定义

1997年IEEE在《软件工程标准词汇表》中对需求定义如下: a.用户解决问题或达到目标所需的条件或权能;

b.系统或系统部件要满足合同、标准、规范或其他正式规定文档所需具有的条件或权能; c.一种反映a或b所描述的条件或权能的文档说明。

该定义从两方面阐述了需求的含义:一是从用户角度所要求的系统应具有的功能,是系统的外部行为;二是从系统开发者角度所要求的系统应具有的功能,是系统的内部特性。

②需求分析阶段的工作

需求分析阶段的工作,可以概括为四个方面: a.需求获取

第一,目的是确定对目标系统的各方面需求。涉及的主要任务是建立获取用户需求的方法框架,并支持和监控需求获取的过程。

第二,涉及的关键问题有:对问题空间的理解;人与人之间的通信;不断变化的需求。

第三,一般功能性与非功能性需求包括系统功能、物理环境、用户界面、用户因素、资源、安全性、质量保证及其他约束。

b.需求分析

对获取的需求进行分析和综合,最终给出系统的解决方案和目标系统的逻辑模型。 c.编写需求规格说明书

需求规格说明书作为需求分析的阶段成果,可以为用户、分析人员和设计人员之间的交流提供方便,可以直接支持目标软件系统的确认,又可以作为控制软件开发进程的依据。

d.需求评审

在需求分析的最后一步,对需求分析阶段的工作进行复审,验证需求文档的一致性、可行性、完整性和有效性。

(2)需求分析方法 ①结构化分析方法

a.面向数据流的结构化分析方法; b.面向数据结构的Jackson方法;

c.面向数据结构的结构化数据系统开发方法。 ②面向对象的分析方法

从需求分析建立的模型的特性来分,需求分析方法又分为静态分析方法和动态分析方法。 2.结构化分析方法

(1)关于结构化分析方法

①定义

结构化分析就是使用数据流图(DFD)、数据字典(DD)、结构化英语、判定表和判定树等工具,来建立一种新的、称为结构化规格说明的目标文档。

②实质

着眼于数据流,自顶向下,逐层分解,建立系统的处理流程,以数据流图和数据字典为主要工具,建立系统的逻辑模型。

③结构化分析的步骤:

a.通过对用户的调查,以软件的需求为线索,获得当前系统的具体模型; b.去掉具体模型中非本质因素,抽象出当前系统的逻辑模型;

c.根据计算机的特点分析当前系统与目标系统的差别,建立目标系统的逻辑模型; d.完善目标系统并补充细节,写出目标系统的软件需求规格说明; e.评审直到确认完全符合用户对软件的需求。 (2)结构化分析的常用工具 ①数据流图

a.定义:数据流图是描述数据处理过程的工具,是需求理解的逻辑模型的图形表示,它直接支持系统的功能建模。

b.数据流图中的主要图形元素与说明

第一,

加工(转换)

输入数据经加工变换产生输出。 第二,数据流

沿箭头方向传送数据的通道,一般在旁边标注数据流名。 第三,存储文件(数据源)

表示处理过程中存放各种数据的文件。 第四,

数据的源点和终点

表示系统和环境的接口,属系统之外的实体。 c.建立数据流图的步骤:

第一,由外向里:先画系统的输入输出,然后画系统的内部; 第二,自顶向下:顺序完成顶层、中问层、底层数据流图; 第三,逐层分解。

d.数据流图的构造规则和注意事项

第一,对加工处理建立唯一、层次性的编号,且每个加工处理通常要求既有输入又有输出; 第二,数据存储之间不应该有数据流; 第三,数据流图的一致性。

某个处理用以产生输出的数据没有输入,即出现遗漏,另一种是一个处理的某些输入并没有在处理中使用以产生输出;数据存储(文件)应被数据流图中的处理读和写。

第四,父图、子图关系与平衡规则

相邻两层DFD之间具有父、子关系,子图代表了父图中某个加工的详细描述,父图表示了子图间的接口。子图个数不大于父图中的处理个数。所有子图的输入、输出数据流和父图中相应处理的输入、输出数据流必须一致。

②数据字典

a.数据字典的作用

数据字典是结构化分析方法的核心,对所有与系统相关的数据元素的一个有组织的列表,以及精确的、严格的定义,使得用户和系统分析员对于输入、输出、存储成分和中间计算结果有共同的理解。它把不同的需求文档和分析模型紧密地结合在一起,与各模型的图形表示配合,能清楚地表达数据处理的要求

b.数据字典包含的内容

数据字典包含的信息有:名称、别名、何处使用/如何使用、内容描述、补充信息等。 ③判定树

分清判定条件和判定结论,根据描述材料中的连接词找出判定条件之间的从属关系、并列关系、选择关

系,根据它们构造判定树。

④判定表

判定表由以下四部分组成:

a.基本条件项:列出了各种可能的条件; b.条件项:列出了各种可能的条件组合;

c.基本动作项:列出了所有的操作; d.动作项:列出在对应的条件组合下所选的操作。 3.软件需求规格说明书

(1)软件需求规格说明书的作用

①便于用户、开发人员进行理解和交流;

②反映出用户问题的结构,可以作为软件开发工作的基础和依据; ③作为确认测试和验收的依据;

④为成本估算和编制计划进度提供基础; ⑤软件不断改进的基础。

(2)软件需求规格说明书的内容

软件需求规格说明重点描述软件的目标,软件的功能需求、性能需求、外部接口、属性及约束条件等。 ①功能需求

软件需求规格说明,给出软件要执行什么功能的详尽描述。 ②性能需求

定量地描述软件系统应满足的具体性能需求,即各种软件功能的速度、响应时间、恢复时间。 ③外部接口

软件如何与人、系统的硬件及其他硬件和其他软件进行交互。 ④属性

与软件有关的质量属性,如正确性、可用性、可靠性、安全性、可维护性等。 ⑤约束条件

包括影响软件实现的各种设计约束,如使用的标准、编程语言、数据库完整性方针、资源限制、运行环境等方面的要求。

(3)软件需求规格说明的特点

软件需求规格说明是确保软件质量的有力措施,衡量软件需求规格说明书质量好坏的标准、标准的优先级及标准的内涵是:

①正确性:体现待开发系统的真实要求。

②无歧义性:对每一个需求只有一种解释,其陈述具有唯一性。

③完整性:包括全部有意义的需求,功能的、性能的、设计的、约束的,属性或外部接口等方面的需求。 ④可验证性:描述的每一个需求都是可以验证的,即存在有限代价的有效过程验证确认。 ⑤一致性:各个需求的描述不矛盾。

⑥可理解性:需求说明必须简明易懂,尽量少包含计算机的概念和术语,以便用户和软件人员都能接受它。

⑦可修改性:SRS的结构风格在需求有必要改变时是易于实现的。

⑧可追踪性:每一个需求的来源、流向是清晰的,当产生和改变文件编制时,可以方便地引证每一个需求。

三、结构化设计方法 1.软件设计的基本概念 (1)软件设计的基础 ①软件设计的基本目标

用比较抽象概括的方式确定目标系统如何完成预定的任务,软件设计是确定系统的物理模型。 ②软件设计的重要性和地位

a.软件开发阶段占据软件项目开发总成本绝大部分,是在软件开发中形成质量的关键环节;

b.软件设计是开发阶段最重要的步骤,是将需求准确地转化为完整的软件产品或系统的唯一途径; c.软件设计作出的决策,最终影响软件实现的成败;

d.设计是软件工程和软件维护的基础。 ③从技术观点来看,软件设计包括:

a.结构设计:定义软件系统各主要部件之间的关系;

b.数据设计:将分析时创建的模型转化为数据结构的定义;

c.接口设计:描述软件内部、软件和协作系统之间以及软件与人之间如何通信; d.过程设计:把系统结构部件转换成软件的过程性描述。 ④从工程管理角度来看,软件设计分两步完成: a.概要设计(结构设计)

将软件需求转化为软件体系结构、确定系统级接口、全局数据结构或数据库模式。 b.详细设计

确立每个模块的实现算法和局部数据结构,用适当方法表示算法和数据结构的细节。 (2)软件设计的基本原理

软件设计的基本原理和有关概念可概括为: ①抽象

抽象是把事物本质的共同特性提取出来而暂时忽略它们的细节及它们之间的差异。软件设计中考虑模块化解决方案时,可以定义多个抽象级别。抽象的层次从软件的总体设计到详细设计到编码逐层降低。软件工程过程的每一步都是对软件求解的上一层抽象的一次精化。

②逐步求精和模块化

逐步求精是人们解决复杂问题时常采用的一种方法,即化繁为简,将复杂问题分解成若干小问题,在软件设计中一般是对模块的划分,将软件系统模块划分后形成的结构是模块的分层结构。

③信息隐蔽和局部化

信息隐蔽是指所涉及的木块使得其包含的信息对于不需要这些信息的模块是不能访问的;局部化是指把一些关系密切的软件元素物理地放得彼此靠近,局部化有助于实现信息隐蔽。

④模块独立性

a.模块独立性是指软件模块的编写和修改应使其具有独立功能,且与其他模块的关联尽可能少,模块的独立程度是评价设计好坏的重要度量标准;

b.模块独立程度的两个定性标准度量: 第一,模块间的耦合性

耦合性是对模块间相互连接的紧密程度的度量,模块耦合性越高,独立性就越弱。 第二,模块内的内聚性

内聚性是对一个模块内部各个元素间彼此结合的紧密程度的度量,内聚性越高,模块独立性越强。 (3)结构化设计方法 ①含义

结构化设计是采用最佳的可能方法设计系统的各个组成部分以及各成分之间的内部联系的技术。它决定用哪些方法把哪些部分联系起来,才能解决好某个具体有清楚定义的问题。

②基本思想

将软件设计成由相对独立、单一功能的模块组成的结构。 2.概要设计

(1)概要设计的任务 ①设计软件系统结构

在概要设计阶段,需要进一步分解,划分为模块以及模块的层次结构。具体过程: a.采用某种设计方法,将一个复杂的系统按功能划分成模块; b.确定每个模块的功能; c.确定模块之间的调用关系;

d.确定模块之问的接口,即模块之间传递的信息; e.评价模块结构的质量。 ②数据结构及数据库设计 a.数据设计的具体任务:

第一,确定输入、输出文件的详细数据结构;

第二,结合算法设计,确定算法所必需的逻辑数据结构及其操作;

第三,确定对逻辑数据结构所必需的那些操作的程序模块,限制和确定各个数据设计决策的影响范围; 第四,需要与操作系统或调度程序接口所必需的控制表进行数据交换时,确定其详细的数据结构和使用规则; 第五,数据的保护性设计:防卫性、一致性、冗余性设计。 b.数据设计中应注意掌握的设计原则:

第一,用于功能和行为的系统分析原则也应用于数据; 第二,应该标识所有的数据结构以及其上的操作;

第三,应当建立数据字典,并用于数据设计和程序设计; 第四,低层的设计决策应该推迟到设计过程的后期;

第五,只有那些需要直接使用数据结构、内部数据的模块才能看到该数据的表示; 第六,应该开发一个由有用的数据结构和应用于其上的操作组成的库; 第七,软件设计和程序设计语言应该支持抽象数据类型的规格说明和实现。 ③编写概要设计文档

在概要设计阶段,需要编写的文档有,概要设计说明书、数据库设计说明书、集成测试计划等。 ④概要设计文档评审

a.在概要设计中,对设计部分是否完整实现需求中规定的功能、性能等要求,设计方案的可行性,关键的处理及内外部接口定义正确性,有效性,各部分之间一致性都要做评审。b.常用的软件结构设计工具是结构图。

在结构图中,模块用矩形表示,矩形内注明模块的功能和名字,箭头表示模块之间调用关系,带实心圆的箭头表示传递的是控制信息,带空心圆的箭头表示传递的是数据。

c.常用的结构图有四种模块类型:传入模块、传出模块、变换模块和协调模块。 d.结构图中常用的术语 深度 上级模块、从属模块 宽度 扇入 扇出 原子模块 控制的层数 上下两层模块,若a调用b,则a是上级模块,b是从属模块 整体控制跨度(最大模块数的层)的表示 调用一个给定模块的模块个数 一个模块直接调用的其他模块数 树中位于叶子结点的模块 (2)面向数据流的结构化设计方法 ①数据流类型 a.变换型

信息沿输入通路进入系统,同时由外部形式变换成内部形式,进入系统的信息通过变换中心,经加工处理以后再沿输出通路变换成外部形式离开软件系统。

数据处理过程大致分为三步:取得数据、变换数据和输出数据,变换系统结构图由输入、中心变换和输出三部分组成。

b.事务型

事务是可以引发一个或多个处理,完成作业要求的功能的一类数据流。

事务型数据流的特点是:接收一项事务,根据事务处理的特点和性质,选择分派一个适当的处理单元(事务处理中心),然后给出结果。

②面向数据流设计方法的实施要点与设计过程 a.面向数据流的结构设计过程和步骤:

第一,分析、确认数据流图的类型,区分是事务型还是变换型。 第二,说明数据流的边界。

第三,把数据流图映射为程序结构。对于事务流区分事务中心和数据接收通路,将它映射成事务结构。对于变换流,区分输出和输入分支,并将其映射成变换结构。

第四,根据设计准则对产生的结构进行细化和求精。 b.变换型数据流图转换成程序结构图的实施步骤:

第一,确定数据流图是否具有变换特性。一般地说,一个系统中所有的信息流都可以认为是变换流,但是,当遇有明显的事务特性的信息流时,建议采用事务分析方法进行设计。在这时应该观察在整个数据流图中哪种属性占优势,先确定数据流的全局特性。此外还应把具有全局特性的不同特点的局部区域孤立出来,根据这些子数据流的特点作部分的处理。

第二,确定输入流和输出流的边界,划分出输入、变换和输出,独立出变换中心。

第三,进行第一级分解,将变换型映射成软件结构,其中输入数据处理模块协调对所有输入数据的接收;变换中心控制模块管理对内部形式的数据的所有操作;输出数据处理控制模块协调输出信息的产生过程。

第四,按上述步骤如出现事务流也可按事务流的映射方式对各个子流进行逐级分解,直至分解到基本功能。 第五,对每个模块写一个简要说明,内容包括该模块的接口描述、模块内部的信息、过程陈述、包括的主要判定点及任务等。

第六,利用软件结构的设计原则对软件结构进一步转化。 c.事务型数据流图转换成程序结构图的实施步骤 事务分析设计步骤与变换分析设计步骤大致类似,主要差别仅在于由数据图到软件结构的映射方法不同,它是将事务中心映射成为软件结构中发送分支的调度模块,将接收通路映射成软件结构的接收分支。

(3)设计的准则 ①提高模块独立性

对软件结构应着眼于改善模块的独立性,依据降低耦合提高内聚的原则,通过把一些模块取消或合并来修改程序结构。

②模块规模适中

当模块增大时,模块的可理解性迅速下降。对大模块分解时,不应降低模块独立性,因为在模块分解时,有可能增加模块间的依赖性。

③深度、宽度、扇出和扇入适当

a.深度过大,说明有的控制模块可能简单; b.宽度过大,说明系统的控制过于集中;

c.扇出过大,说明模块过分复杂,需控制和协调过多的下级模块,适当增加中间层次; d.扇出太小,可以把下级模块进一步分解成若干子功能模块,或者合并到上级模块中去。 好的软件设计结构通常顶层高扇出,中间扇出较少,底层高扇入。 ④使模块的作用域在该模块的控制域内

a.模块的作用域是指模块内一个判定的作用范围,凡是受这个判定影响的所有模块都属于这个判定的作用域。

b.模块的控制域是指这个模块本身以及所有直接或间接从属予它的模块的集合。

在一个设计很好的系统中,所有受某个判定影响的模块都应从属于做出判定的模块,最好局限于做出判定的那个模块本身及它的直属下级模块。对不满足这一条件的结构,修改方法是:将判定点上移或者将那些在作用范围内但是不在控制范围内的模块移到控制范围以内。

⑤应减少模块的接口和界面的复杂牲

模块的接口复杂是软件容易发生错误的一个主要原因。应该仔细设计模块接口,使得信息传递简单并且和模块的功能一致。

⑥设计成单入口、单出口的模块 ⑦设计功能可预测的模块

如果一个模块可以当做一个“黑盒”,也就是不考虑模块的内部结构和处理过程,则这个模块的功能就是可以预测的。

3.详细设计

(1)详细设计的任务

为软件结构图中的每一个模块确定实现算法和局部数据结构,用某种选定的表达工具表示算法和数据结构的细节。

(2)常见的过程设计工具有:

①图形工具:程序流程图,N-S图,PAD图,HIPO图; ②表格工具:判定表; ③语言工具:PDL(伪码)。 (3)程序流程图(程序框图)

①程序流程图是一种传统的、应用广泛的软件过程设计表示工具,具有表达直观、清晰,易于学习掌握,且独立与任何一种程序设计语言的特点。

构成程序流程图的最基本图符及含义如图3-1所示。

图3-1 程序流程图的基本图符

②程序流程图的5种控制结构:

a.顺序型:几个连续的加工步骤依次排列构成;

b.选择型:由某个逻辑判断式的取值决定选择两个加工中的一个;

c.先判断重复型:先判断循环控制条件是否成立,成立则执行循环体语句; d.后判断重复型:重复执行某些特定的加工,直到控制条件成立;

e.多分支选择型:列举多种加工情况,根据控制变量的取值,选择执行其中之一。 (4)N-S图

①N-S图的基本图符及表示的5种基本控制结构如图3-2所示。

图3-2 N-S图图符与构成的5种控制结构

②N-S图的特征:

a.每个构件具有明确的功能域;

b.控制转移必须遵守结构化设计要求;

c.易于确定局部数据和(或)全局数据的作用域; d.易于表达嵌套关系和模块的层次结构。 (5)PAD图

①PAD图的基本图符及表示的5种基本控制结构如图3-3所示。

图3-3 PAD图图符与构成的5种控制结构

②PAD图有以下特征:

a.结构清晰,结构化程度高; b.易于阅读;

c.最左端的纵线是程序主干线,对应程序的第一层结构;每增加一层PAD图向右扩展一条纵线,故程序的纵线数等于程序层次数;

d.程序执行:从PAD图最左主干线上端结点开始,自上而下、自左向右依次执行,程序终止于最左主干线。 (6)PDL(Procedure Design Language)

①过程设计语言(PDL)也称为结构化的英语和伪码,它是一种混合语言,采用英语的词汇和结构化程序设

计语言的语法,类似编程语言。

②用PDL表示的基本控制结构的常用词汇如下: 顺序:

条件:IF/THEN/ELSE/ENDIF 循环:DO WHILE/ENDDO

循环:REPEAT UNTIL/ENDREPEAT

分支:CASE-OF/WHEN/SELECT/WHEN/SELECT/ENDCASE ③PDL具备以下特征:

a.有为结构化构成元素、数据说明和模块化特征提供的关键词语法; b.处理部分的描述采用自然语言语法; c.可以说明简单和复杂的数据结构;

d.支持各种接口描述的子程序定义和调用技术。

四、软件测试

1.软件测试的目的和定义 (1)软件测试的定义

①在规定条件下运行系统或构件的过程:在此过程中观察和记录结果,并对系统或构件的某些方面给出评价。 ②软件项目的过程:检测现有状况和所需状况的不同(即bug),并评估软件项目的特性。 (2)软件测试的目的

软件测试是为了发现错误而执行程序的过程,是以查找错误为中心,而不是为了演示软件的正确功能。 2.软件测试的准则

(1)所有测试都应追溯到需求

软件测试的目的是发现错误,而最严重的错误不外乎是导致程序无法满足用户需求的错误。 (2)严格执行测试计划,排除测试的随意性

软件测试应当制定明确的测试计划并按照计划执行。

测试计划应包括:所测软件的功能、输入和输出、测试内容、各项测试的目的和进度安排、测试资料、测试工具、测试用例的选择、资源要求、测试的控制方式和过程等。

(3)充分注意测试中的群集现象 经验表明,程序中存在错误的概率与该程序中已发现的错误数成正比。测试人员应该集中对付那些错误群集的程序。

(4)程序员应避免检查自己的程序

为了达到好的测试效果,应该由独立的第三方来构造测试。因为从心理学角度讲,程序人员或设计方在测试自己的程序时,要采取客观的态度是程度不同地存在障碍的。

(5)穷举测试不可能

穷举就是把程序中所有可能的执行路径进行检查,即使是很小规模的程序,其路径排列数也是相当大的,在实际测试中不可能穷尽每一种组合,测试只能证明程序中有错误,不能证明程序中没有错误。

(6)妥善保存测试计划、测试用例、出错统计和最终分析报告,为维护提供方便。 3.软件测试方法与技术综述

对软件测试方法和技术,可以从不同角度分类:从是否需要执行被测软件的角度,可以分为静态测试和动态测试方法;按照功能划分可以分为白盒测试和黑盒测试方法。

(1)静态测试与动态测试 ①静态测试

静态测试包括代码检查、静态结构分析、代码质量度量等,可由人工进行或借助软件自动进行。 a.代码检查

主要检查代码和设计的一致性,包括:逻辑表达的正确性、结构的合理性等。代码检查包括代码审查、代码走查、桌面检查、静态分析等具体方式。

第一,代码审查:小组集体阅读、讨论检查代码。

第二,代码走查:小组成员通过用“脑”研究、执行程序来检查代码。

第三,桌面检查:由程序员自己检查自己编写的程序。程序员在程序通过编译之后,进行单元测试之前,对源代码进行分析、检验,并补充相关文档,目的是发现程序的错误。

第四,静态分析:对代码的机械性、程式化的特性分析方法,包括控制流分析、数据流分析、接口分析、表达式分析。

代码检查可以发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分、违背程序编程风格的问题,包括变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等内容。

②动态测试

静态测试不实际运行软件,主要通过人工进行,是基于计算机的测试,为发现错误而执行程序的过程。设计高效、合理的测试用例是动态测试的关键,测试用例的格式为:[(输入值集),(输出值集)]

(2)白盒测试(结构测试或逻辑驱动测试)方法与测试用例设计

①根基软件产品的内部工作过程,检查内部成分,以确认每种内部操作符合设计规格要求。将测试对象看成一个能打开的盒子,允许测试人员利用程序内部的逻辑结构及有关信息来设计或选择测试用例,在程序内部进行,主要用于完成软件内部操作的验证。

②白盒测试的基本原则:

a.保证所测模块中每一独立路径至少执行一次;

b.保证所测模块所有判断的每一分支至少执行一次;

c.保证所测模块每一循环都在边界条件和一般条件下至少各执行一次; d.验证所有内部数据结构的有效性。

③白盒测试采用穷举路径测试,测试者必须检查程序内部结构,但即使每条路径都测试了仍可能有错误,这是因为:

a.穷举路径测试决不能查出程序是否违反了设计规范,即程序本身是个错误的程序; b.穷举路径测试不可能查出程序中因遗漏路径而出错; c.穷举路径测试可能发现不了一些与数据相关的错误。 ④白盒测试的主要方法有逻辑覆盖、基本路径测试等。 a.逻辑覆盖测试

逻辑覆盖是泛指一系列以程序内部的逻辑结构为基础的测试用例设计技术。 第一,语句覆盖

选择足够的测试用例,使得程序中每个语句至少都能被执行一次。 语句覆盖是逻辑覆盖中基本的覆盖,尤其对单元测试来说。但是语句覆盖往往没有关注判断中的条件有可能隐含的错误。

第二,路径覆盖

执行足够的测试用例,使程序中所有可能的路径都至少经历一次。 第三,判定覆盖

使设计的测试用例保证程序中每个判断的每个取值分支(T或F)至少经历一次。 第四,条件覆盖

设计的测试用例保证程序中每个判断的每个条件的可能取值至少执行一次。

条件覆盖深入到判断中的每个条件,但是可能会忽略全面的判断覆盖的要求。有必要考虑判断-条件覆盖。 第五,判断-条件覆盖 设计足够的测试用例,使判断中每个条件的所有可能取值至少执行一次,同时每个判断的所有可能取值分支至少执行一次。判断-条件覆盖也有缺陷,对质量要求高的软件单元,可根据情况提出多重条件组合覆盖以及其他更高的覆盖要求。

b.基本路径测试

基本思想和步骤::根据软件过程性描述中的控制流程确定程序的环路复杂性度量,用此度量定义基本路径集合,并由此导出一组测试用例对每一条独立执行路径进行测试。

(3)黑盒测试(功能测试或数据驱动测试)方法与测试用例设计 ①对软件已经实现的功能是否满足需求进行测试和验证,完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求和功能规格说明,检查程序的功能是否符合它的功能说明。是在软件接口处进行,完成功能验证。

②黑盒测试只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息,并且保持外部信息(如数据库或文件)的完整性。主要诊断功能不对或遗漏、界面错误、数据结构或外部数据库访问错误、性能错误、初始化和终止条件错。

③黑盒测试方法主要有等价类划分法、边界值分析法、错误推测法、因果图等,主要用于软件确认测试。

a.等价类划分法

将程序的所有可能的输人数据划分成若干部分(即若干等价类),然后从每个等价类中选取数据作为测试用例。

第一,等价类分类

有效等价类:合理、有意义的输入数据构成的集合。可以检验程序中符合规定的功能、性能。 无效等价类:不合理、无意义的输入数据构成的集合。可以检验程序中不符合规定的功能、性能。 第二,等价类划分法实施步骤

先划分等价类,然后根据等价类选取相应的测试用例。 第三,划分等价类常用的几条原则:

若输入条件规定了确切的取值范围,则可划分出一个有效等价类和两个无效等价类。 若输入条件规定了输入值的集合(或有“必须如何”的条件),可确定一个有效等价类和一个无效等价类。 若输入条件是一个布尔量,则可确定一个有效等价类和一个无效等价类。 若输入数据是一组值,且程序要对每个值分别处理。可为每个输入值确定一个有效等价类和一个无效等价类。 若规定了输入数据必须遵守一定规则,则可确定一个有效等价类和若干个无效等价类。

若已划分的等价类中各元素在程序中处理方式不同,须将该等价类进一步划分(更小的等价类)。 b.边界值分析法

边界值分析法是对各种输入、输出范围的边界情况设计测试用例的方法。 边界值分析方法的使用要注意以下几点:

第一,如果输入条件规定了取值范围或数据个数,则可选择正好等于边界值、刚刚在边界范围内和刚刚超越边界外的值进行测试;

第二,针对规格说明的每个输入条件,使用上述原则:

第三,对于有序数列,选择第一个和最后一个作为测试数据。 c.错误推测法 第一,基本思想

列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据它们选择测试用例。错误推测法针对性强,可以直接切入可能的错误,直接定位,是一种非常实用、有效的方法。但是它需要丰富的经验和专业知识。

第二,实施步骤

对被测软件首先列出所有可能有的错误和易错情况表,然后基于该表设计测试用例。 4.软件测试的策略 (1)定义

软件测试的策略是指在软件测试过程中对各种活动的组织和管理。 (2)步骤

软件测试过程一般按4个步骤进行,即单元测试、集成测试、验收测试(确认测试)和系统测试来验证软件是否合格,能否交付用户使用。

①单元测试

a.单元测试的目的是发现各模块内部可能存在的各种错误。 b.单元测试的依据是详细设计说明书和源程序。 c.单元测试的技术可以采用静态分析和动态测试。对动态测试通常以白盒动态测试为主,辅之以黑盒测试。 d.单元测试主要针对模块的下列5个基本特性进行: 第一,模块接口测试——测试通过模块的数据流

检查模块的输入参数和输出参数、全局量、文件属性与操作等都属于模块接口测试的内容。 第二,局部数据结构测试

检查局部数据说明的一致性,数据的初始化,数据类型的一致以及数据的下溢、上溢等。 第三,重要的执行路径的检查。 第四,出错处理测试

检查模块的错误处理功能。

第五,影响以上各点及其他相关点的边界条件测试。

单元测试是针对某个模块,这样的模块通常并不是一个独立的程序,因此模块自己不能运行,而要靠辅助其他模块调用或驱动

②集成测试

集成测试是测试和组装软件的过程,是把模块在按照设计要求组装起来的同时进行测试,其主要目的是发现与接口有关的错误。集成测试的依据是概要设计说明书,涉及的内容包括软件单元的接口测试、全局数据结构测试、边界条件和非法输入的测试等。

集成测试时将模块组装成程序通常采用两种方式:非增量方式组装与增量方式组装。 a.非增量方式(一次性组装方式)

将测试好的每一个软件单元一次组装在一起再进行整体测试。 b.增量方式

将测试好的模块逐步组装成较大系统,边连接边测试,通过增值,逐步组装所需要的软件系统。增量方式包括自顶向下、自底向上、自顶向下与自底向上相结合的混合增量方法。

第一,自顶向下的增量方式

将模块按系统程序结构,从主控模块(主程序)开始,沿控制层次自顶向下地逐个把模块连接起来。在测试过程中能较早地验证主要的控制和判断点。

自顶向下集成的过程与步骤如下:

ⅰ主控模块作为测试驱动器,直接附属于主控模块的各模块全都用桩模块代替; ⅱ按照一定的组装次序,每次用一个真模块取代一个附属的桩模块; ⅲ当装入每个真模块时都要进行测试;

ⅳ做完每一组测试后再用一个真模块代替另一个桩模块;

ⅴ可以进行回归测试(即重新再做过去做过的全部或部分测试),以便确定没有新的错误发生。 第二,自底向上的增量方式 从软件结构中最底层的、最基本的软件单元开始进行集成和测试。在逐步向上组装过程中下层模块总是存在的,因此不再需要桩模块,但是需要调用这些模块的驱动模块。

自底向上集成的过程与步骤如下:

ⅰ低层的模块组成簇,以执行某个特定的软件子功能;

ⅱ编写一个驱动模块作为测试的控制程序,和被测试的簇连在一起,负责安排测试用例的输入及输出; ⅲ对簇进行测试;

ⅳ拆去各个小簇的驱动模块,把几个小簇合并成大簇,再重复做前三步。这样在软件结构上逐步向上组装。 第三,混合增量方式

自顶向下增量的方式和自底向上增量的方式各有优缺点,一种方式的优点是另一种方式的缺点。自顶向下测试的主要优点是能较早显示出整个程序的轮廓,主要缺点是:当测试上层模块时使用桩模块较多,很难模拟出真实模块的全部功能,使部分测试内容被迫推迟,直至换上真实模块后再补充测试。

针对自顶向下、自底向上方法各自的优点和不足,人们提出了自顶向下和自底向上相结合、从两头向中间逼近的混合式组装方法,被形象称为“三明治”方法。这种方式结合考虑软件总体结构的良好设计原则,在程序结构的高层使用自顶向下方式,在程序结构的低层使用自底向上方式。

③确认测试

第一,确认测试任务

验证软件的功能和性能及其他特性是否满足了需求规格说明中确定的各种需求,以及软件配置是否完全、正确。

第二,确认测试的实施

首先运用黑盒测试方法,对软件进行有效性测试,验证被测软件是否满足需求规格说明确认的标准。复审的目的在于保证软件配置齐全、分类有序,以及软件配置所有成分的完备性、一致性、准确性和可操作性,并且包括软件维护所必需的细节。

④系统测试

将通过测试确认的软件,作为整个基于计算机系统的一个元素,与计算机硬件、外设、支持软件、数据和人员等其他元素组合一起,在实际环境中对计算机系统进行一系列集成测试和确认测试。

第一,系统测试的目的

在真实的系统工作环境下检验软件是否能与系统正确连接,发现软件与系统需求不一致的地方。 第二,系统测试的具体实施

一般包括:功能测试、性能测试、操作测试、配置测试、外部接口测试、安全性测试等。

五、程序的调试

1.基本概念

程序调试主要在开发阶段,其任务是诊断和改正程序中的错误。程序调试活动由两部分组成,其一是根据错误的迹象确定程序中错误的确切性质、原因和位置。其二,对程序进行修改,排除这个错误。

(1)程序调试的基本步骤 ①错误定位

从错误外部表现形式入手,确定程序出错位置,找出错误的内在原因,确定错误位置占据软件调试绝大部分工作量。

从技术角度来看,错误的特征和查找错误的难度在于:

a.现象与原因所处的位置可能相距很远。就是说,现象可能出现在程序的一个部位,而原因可能在离此很远的另一个位置。高耦合的程序结构中这种情况更为明显。

b.当纠正其他错误时,这一错误所表现出的现象可能会消失或暂时性消失,但并未实际排除。 c.现象可能并不是由错误引起的(如舍入误差)。

d.现象可能是由于一些不容易发现的人为错误引起的。 e.错误现象可能时有时无。

f.现象是由于难于再现的输入状态(例如实时应用中输入顺序不确定)引起。 g.现象可能是周期出现的。如在软件、硬件结合的嵌入式系统中常常遇到。 ②修改设计和代码,以排除错误

软件运行失效或出现问题,往往只是潜在错误的外部表现,外部表现和内在原因之间一般没有明显关系,调试是通过现象找出原因的一个思维分析的过程。

③进行回归测试,防止引进新的错误 修改程序可能带来新的错误,重复进行暴露这个错误的原始测试或某些有关测试,以确认该错误是否被排除、是否引进了新的错误。如果所做的修正无效,则撤销这次改动,重复上述过程,直到找到一个有效的解决办法为止。

(2)程序调试的原则

调试原则从以下两个方面考虑:

①确定错误的性质和位置时的注意事项 a.分析思考与错误征兆有关的信息。 b.避开死胡同

如果程序调试人员在调试中陷入困境,最好暂时把问题抛开,留到后面适当的时间再去考虑,或者向其他人讲解这个问题,去寻求新的解决思路。

c.只把调试工具当做辅助手段来使用

利用调试工具,可以帮助思考,但不能代替思考。因为调试工具给人提供的是一种无规律的调试方法。 d.避免用试探法,最多只能把它当做最后手段

这是一种碰运气的盲目的动作,它的成功概率很小,而且还常把新的错误带到问题中来。 ②修改错误的原则

a.在出现错误的地方,很可能还有别的错误

错误有群集现象,当在某一程序段发现有错误时,在该程序段中还存在别的错误的概率也很高。因此,在修改一个错误时,还要观察和检查相关的代码,看是否还有别的错误。

b.修改错误的一个常见失误是只修改了这个错误的征兆或这个错误的表现,而没有修改错误本身。 c.注意修正一个错误的同时有可能会引入新的错误。 人们不仅需要注意不正确的修改,而且还要注意看起来是正确的修改可能会带来的副作用,即引进新的错误。因此在修改了错误之后,必须进行回归测试。

d.修改错误的过程将迫使人们暂时回到程序设计阶段。 修改错误也是程序设计的一种形式。一般说来,在程序设计阶段所使用的任何方法都可以应用到错误修正的过程中来。

e.修改源代码程序,不要改变目标代码。 2.软件调试方法

调试的关键在于推断程序内部的错误位置及原因。软件调试可以分为静态调试和动态调试。静态调试主要指通过人的思维来分析源程序代码和排错,是主要的调试手段,而动态调试是辅助静态调试的。主要的调试方法可以采用:

(1)强行排错法

作为传统的调试方法,其过程可概括为,设置断点、程序暂停、观察程序状态、继续运行程序。这是目前使用较多、效率较低的调试方法。涉及的调试技术主要是设置断点和监视表达式。主要方法有:

①通过内存全部打印来排错;

②在程序特定部位设置打印语句——断点法; ③自动调试工具。

应用以上任何一种技术之前,都应当对错误的征兆进行全面彻底的分析,得出对出错位置及错误性质的推测,再使用一种适当的排错方法来检验推测的正确性。

(2)回溯法

适合于小规模程序的排错,即一旦发现了错误,先分析错误征兆,确定最先发现“症状”的位置。然后,从发现“症状”的地方开始,沿程序的控制流程,逆向跟踪源程序代码,直到找到错误根源或确定错误产生的范围。

(3)原因排除法

原因排除法是通过演绎和归纳,以及二分法来实现的。 ①演绎法

一种从一般原理或前提出发,经过排除和精化的过程来推导出结论的思考方法。演绎法排错是测试人员首先根据已有的测试用例,设想及枚举出所有可能出错的原因作为假设。然后再用原始测试数据或新的测试,从中逐个排除不可能正确的假设。最后,再用测试数据验证余下的假设确定出错的原因。

②归纳法

一种从特殊推断出一般的系统化思考方法。其基本思想是从一些线索(错误征兆或与错误发生有关的数据)着手,通过分析寻找到潜在的原因,从而找出错误。

③二分法 基本思想:如果已知每个变量在程序中若干个关键点的正确值,则可以使用定值语句在程序中的某点附近给这些变量赋正确值,然后运行程序并检查程序的输出。如果输出结果是正确的,则错误原因在程序的前半部分;反之,错误原因在程序的后半部分。对错误原因所在的部分重复使用这种方法,直到将出错范围缩小到容易诊断的程度为止。

第4章 数据库设计基础

一、数据库系统的基本概念

1.数据、数据库、数据库管理系统 (1)数据

①定义:数据是描述事物的符号记录。 ②分类

a.临时性数据

与计算机程序仅有短时间交互关系,随程序结束消亡,一般存放在计算机内存中。 b.持久性数据

对系统起着长期持久作用,数据库系统中处理的就是这种持久性数据。 ③数据的结构 a.型

数据的型给出数据的表示类型,常见的有整型、实型、字符型,还包括将多种相关数据以一定结构方式组合构成特定的数据框架。

b.值

数据的值给出符合给定型的值 (2)数据库

①定义:数据库是数据的集合,具有统一的结构形式并存放在统一的存储介质,是多种应用数据的集成,并可被各个应用程序所共享。

②按数据所提供的数据模式存放的,构造复杂的数据结构以建立数据间内在联系与复杂关系,从而构成数据的全局结构模式。

(3)数据库管理系统 ①定义

数据库管理系统是数据库的机构,它是一种系统软件,负责数据库中的数据组织、数据操纵、数据维护、控制及保护和数据服务等。

②数据库管理系统的功能

数据库管理系统是数据库系统的核心,它主要有如下几方面的具体功能: a.数据模式定义

负责为数据库构建模式,即为数据库构建其数据框架。 b.数据存取的物理构建

负责为数据模式的物理存取及构建提供有效的存取方法与手段。 ③数据操纵

提供查询、插入、修改以及删除数据的功能,还具有简单运算及统计能力,与某些过程性语言结合,使其具有强大的过程性操作能力。

④数据的完整性、安全性定义与检查

数据的完整性是保证数据库中数据正确的必要条件,数据共享可能引发数据的非法使用,必须在数据使用时作必要检查,完整性和安全性的维护是数据库系统的基本功能。

⑤数据库的并发控制与故障恢复

数据库能为多个应用程序服务,存在应用程序对数据库的并发操作,如果不加控制和管理,多个应用程序就会相互干扰,数据库管理系统必须对多个应用程序的并发操作作出必要的控制以保证数据不被破坏,数据库中的数据一旦遭到破坏,数据库管理系统必须有能力及时进行恢复。

⑥数据的服务

数据库管理系统提供对数据库中数据的多种服务功能,如数据拷贝、转存、重组、性能监测、分析等。 ⑦数据库管理系统提供的数据语言: a.数据定义语言

负责数据的模式定义与数据的物理存取构建。 b.数据操纵语言

语言负责数据的操纵,包括查询及增、删、改等操作。 c.数据控制语言

负责数据完整性、安全性的定义与检查以及并发控制、故障恢复等功能,包括系统初启程序、文件读写与维护程序、存取路径管理程序、缓冲区管理程序、安全性控制程序、完整性检查程序、并发控制程序、事务管理程序、运行日志管理程序、数据库恢复程序等。

⑧数据语言的两种结构形式: a.交互式命令语言

语言简单,能在终端上即时操作,又称为自含型或自主型语言。 b.宿主型语言

一般可嵌入某些宿主语言(Host Language)中,如C/C++、Java和COBOL等高级过程性语言中。

⑨SQL(结构化查询语言)是一种介于关系代数和关系演算之间的非过程性操作语言,不仅具有丰富的查询功能,还兼具数据定义和数据控制功能。此外,数据库管理系统还有为用户提供服务的服务性(Utility)程序,包括数据初始装入程序、数据转存程序、性能监测程序、数据库再组织程序、数据转换程序、通信程序等。

(4)数据库管理员(DBA)

①数据库管理员是对数据库的规划、设计、维护、监视等进行专业管理的人员。 ②数据库管理员的主要工作: a.数据库设计

数据库管理员主要任务是进行数据模式的设计,由于数据库的集成与共享性,需要专业人员对多个应用的数据库需求作全面规划、设计与集成。

b.数据库维护

DBA必须对数据库中的数据安全性、完整性、并发控制及系统恢复、数据定期转存等实施与维护。 c.改善系统性能,提高系统效率

DBA必须随时监视数据库运行状态,不断调整内部结构,使系统保持最佳状态与最高效率。 (5)数据库系统

数据库系统由数据库、数据库管理系统、数据库管理员、硬件平台、软件平台构成一个以数据库为核心的完整的运行实体。

①硬件平台 a.计算机

计算机是系统中硬件的基础平台,目前常用的有微型机、小型机、中型机、大型机及巨型机。 b.网络

数据库系统今后都会以建立在网络上为主,结构形式以客户/服务器方式和浏览器/服务器方式为主。 ②软件平台 a.操作系统

系统的基础软件平台,目前常用的有各种UNIX(包括Linux)与Windows两种。 b.数据库系统开发工具

为开发数据库应用程序所提供的工具,包括过程性程序设计语言如 C/C++、Java等,也包括可视化开发工具VB、PB、Delphi等,它还包括与Internet Web有关的 HTML及XML等以及一些专用开发工具。

c.接口软件

在网络环境下数据库系统中数据库与应用程序,数据库与网络间存在着多种接口,这些接口软件包括ODBC、JDBC、OLEDB、CORBA、COM、DCOM等。

(6)数据库应用系统

数据库应用系统由:数据库、数据库管理系统、数据库管理员、硬件平台、软件平台、应用软件、应用界面组成。应用软件是由数据库系统所提供的数据库管理系统(软件)及数据库系统开发工具所书写而成,而应用界面大多由相关的可视化工具开发而成。数据库应用系统的结构如图4-1所示。

图4-1 数据库系统的软硬件层次结构图

2.数据库系统的发展 (1)文件系统阶段

数据库系统发展的初级阶段,提供了简单的数据共享和数据管理能力,无法提供完整的、统一的、管理和数据共享的能力。附属于操作系统而不成为独立的软件,不是真正的数据库系统。

(2)层次数据库与网状数据库系统阶段 为统一管理与共享数据提供了有力支撑,这两种系统存在的主要不足是它们完全脱胎于文件系统,受文件的物理影响很大,对数据库使用带来诸多不便,且数据库模式构造繁琐,不宜于推广使用。

(3)关系数据库系统阶段

结构简单,使用方便,逻辑性强物理性少,由于该系统源于商业应用,适合事物处理领域而对非事务处理领域应用受到限制。

关于数据管理三个阶段中的软硬件背景及处理特点如表4-1所示。

表4-1 数据管理三个阶段的比较 应用背景 背 景 硬件背景 软件背景 处理方式 数据管理者 数据面向对象 人工管理 科学计算 无直接存取设备 没有操作系统 批处理 人 某个应用程序 文件系统 科学计算、管理 磁盘、磁鼓 有文件系统 联机实时处理 批处理 文件系统 某个应用程序 数据库系统 大规模管理 大容量磁盘 有数据库管理系统 联机实时处理 分布处理 批处理 数据库管理系统 现实世界 无共享 共享性差 共享性大 数据共享程度 冗余度大 冗余度大 冗余度小 数据独立性 不独立,完全依赖于程独立性差 具有高度的物理独立性和一定的逻 序 辑独立性 特 记录内有结构 整体结构化,用数据模型描述 点 数据结构化 无结构 整体无结构 数据控制能力 应用程序自己控制 应用程序自己 由DBMS提供数据安全性、完整控制 性、并发控制和恢复 (4)数据库诸多新技术中比较重要的三个方面

①面向对象数据库系统:

用面向对象方法构筑面向对象数据模型,使其具有比关系数据库系统更通用的能力 ②知识库系统:

用人工智能中的方法特别是用谓词逻辑知识表示方法构筑数据模型,使其模型具有特别通用的能力 ③关系数据库系统的扩充:

利用关系数据库作进一步扩展,使其在模型的表达能力与功能上有进一步的加强。 3.数据库系统的基本特点 (1)数据的集成性

数据库系统的数据集成性主要表现在如下几个方面: ①采用统一的数据结构方式;

②按照多个应用的需要组织全局的统一的数据结构(即数据模式),数据模式可建立全局的数据结构,还可以建立数据间的语义联系,从而构成一个内在紧密联系的数据整体;

③数据模式是多个应用共同的、全局的数据结构,而每个应用的数据则是全局结构中的一部分,称为局部结构,这种全局与局部的结构模式构成了数据库系统数据集成性的主要特征。

(2)数据的高共享性与低冗余性

由于数据的集成性使得数据可为多个应用所共享,数据的共享自身又可极大地减少数据冗余性,不仅减少了不必要的存储空间,更为重要的是可以避免数据的不一致性。

数据的一致性是指在系统中同一数据的不同出现应保持相同的值;数据的不一致性指的是同一数据在系统的不同拷贝处有不同的值。因此,减少冗余性以避免数据的不同出现是保证系统一致性的基础。

(3)数据独立性

数据库中的数据独立于应用程序,数据的逻辑结构、存储结构与存取方式不会影响应用程序,数据独立性分为物理独立性和逻辑独立性。

①物理独立性。数据物理结构的改变不至于引起应用程序的变化。

②逻辑独立性。数据库总体逻辑结构的改变,不需要相应修改应用程序。 (4)数据统一管理与控制

数据库系统不仅为数据提供高度集成环境,同时它还为数据提供统一管理的手段,这主要包含以下三个方面: ①数据的完整性检查:检查数据库中数据的正确性以保证数据的正确。 ②数据的安全性保护:检查数据库访问者以防止非法访问。

③并发控制:控制多个应用的并发访问所产生的相互干扰以保证其正确性。 4.数据库系统的内部结构体系 (1)数据库系统的三级模式

数据模式是数据库系统中数据结构的一种表示形式,它具有不同的层次与结构方式。 ①概念模式

概念模式是数据库系统中全局数据逻辑结构的描述,是全体用户公共数据视图。是一种抽象的描述,它不涉及具体的硬件环境与平台,也与具体的软件环境无关。主要描述数据的概念记录类型以及它们间的关系,它还包括一些数据间的语义约束,对它的描述可用DBMS中的DDL语言定义。

②外模式(子模式或用户模式)

它是用户的数据视图,也是用户所见到的数据模式,由概念模式推导而出。概念模式给出了系统全局的数据描述而外模式则给出每个用户的局部数据描述。一个概念模式可以有若干个外模式,每个用户只关心与它有关的模式,这样不仅可以屏蔽大量无关信息而且有利于数据保护。在一般的DBMS中都提供有相关的外模式描述语言(外模式DDL)。

③内模式(物理模式)

它给出了数据库物理存储结构与物理存取方法,内模式的物理性主要体现在操作系统及文件级上,它还未深入到设备级上。对一般用户是透明的,但它的设计直接影响数据库的性能。一般提供相关的内模式描述语言(内模式DDL)。

a.以概念模式为框架所组成的数据库叫概念数据库,以外模式为框架所组成的数据库叫用户数据库,以内模式为框架所组成的数据库叫物理数据库。只有物理数据库真实存在于计算机外存中,其它两个数据库不是真实存在于计算机中,而是通过两种映射由物理数据库映射而成。

b.内模式处于最底层,它反映了数据在计算机物理结构中的实际存储形式,概念模式处于中层,它反映了设计者的数据全局逻辑要求,而外模式处于最外层,它反映了用户对数据的要求。

(2)数据库系统的两级映射 ①概念模式到内模式的映射

该映射给出概念模式中数据的全局逻辑结构到数据的物理存储结构间的对应关系,此种映射一般由DBMS实现。

②外模式到概念模式的映射

概念模式是一个全局模式而外模式是用户的局部模式。一个概念模式中可以定义多个外模式,而每个外模式是概念模式的一个基本视图。外模式到概念模式的映射给出了外模式与概念模式的对应关系,这种映射一般也是由DBMS来实现的。

二、数据模型

1.数据模型的基本概念 (1)数据模型的概念

数据库中的数据模型可以将复杂的现实世界要求反映到计算机数据库中的物理世界,这种反映是一个逐步转化的过程。它分为两个阶段:由现实世界开始,经历信息世界而至计算机世界,从而完成整个转化。

①现实世界

现实世界是指用户为了某种需要,需将现实世界中的部分需求用数据库实现,这样,我们所见到的是客观世界中的划定边界的一个部分环境。

②信息世界

信息世界是指通过抽象对现实世界进行数据库级上的刻画所构成的逻辑模型,与数据库的具体模型有关。 ③计算机世界

计算机世界是指在信息世界基础上致力于其在计算机物理结构上的描述,从而形成的物理模型。现实世界的要求只有在计算机世界中才得到真正的物理实现,而这种实现是通过信息世界逐步转化得到的。

(2)数据模型描述的内容 ①数据结构

主要描述数据的类型、内容、性质以及数据间的联系等。它是数据模型的基础,数据操作与约束均建立在数据结构上。

②数据操作

主要描述在相应数据结构上的操作类型与操作方式。 ③数据约束

主要描述数据内数据间的语法、语义联系,它们之间的制约与依存关系,以及数据动态变化的规则,以保证数据的正确、有效与相容

(3)数据模型分类

①概念数据模型(概念模型)

它是一种面向客观世界、面向用户的模型;与具体的数据库管理系统无关,与具体的计算机平台无关;着重于对客观世界复杂事物的结构描述及它们之间的内在联系的刻画;是整个数据模型的基础。目前,较为有名的概念模型有E-R模型、扩充的E-R模型、面向对象模型及谓词模型等。

②逻辑数据模型(数据模型) 它是一种面向数据库系统的模型,该模型着重于在数据库系统一级的实现。概念模型只有在转换成数据模型后才能在数据库中得以表示。逻辑数据模型也有很多种,较为成熟并先后被人们大量使用过的有:层次模型、网状模型、关系模型、面向对象模型等。

③物理数据模型(物理模型)

它是一种面向计算机物理表示的模型,此模型给出了数据模型在计算机上物理结构的表示。 2.E-R模型

该模型将现实世界的要求转化成实体、联系、属性等几个基本概念,以及它们间的两种基本连接关系,并且可以用一种图非常直观地表示出来。

(1)E-R模型的基本概念 ①实体

现实世界中的事物可以抽象成为实体,实体是概念世界中的基本单位,它们是客观存在的且又能相互区别的事物。凡是有共性的实体可组成一个集合称为实体集

②属性

属性刻画了实体的特征,一个实体往往可以有若干个属性。每个属性可以有值,一个属性的取值范围称为该属性的值域。

③联系

现实世界中事物间的关联称为联系。在概念世界中联系反映了实体集间的一定关系。 a.实体集间的联系有多种,就实体集的个数而言有:

第一,两个实体集间的联系

两个实体集间的联系是一种最为常见的联系。 第二,多个实体集间的联系

这种联系包括三个实体集间的联系以及三个以上实体集间的联系。 第三,一个实体集内部的联系

一个实体集内有若干个实体,它们之间的联系称实体集内部联系。

b.两个实体集间的联系实际上是实体集间的函数关系,这种函数关系可以有以下几种: 第一,一对一的联系,简记为1:1。

这种函数关系是常见的函数关系之一,如学校与校长间的联系,一个学校与一个校长间相互一一对应。 第二,一对多或多对一联系,简记为1:M或M:1。

这两种函数关系实际上是一种函数关系,如学生与其宿舍房间的联系是多对一的联系(反之,则为一对多联系),即多个学生对应一个房间。

第三,多对多联系,简记为M:N 这是一种较为复杂的函数关系,如教师与学生这两个实体集间的教与学的联系是多对多的,因为一个教师可以教授多个学生,而一个学生又可以受教于多个教师。

(2)E-R模型三个基本概念之间的连接关系

E-R模型由上面三个基本概念组成。由实体、联系、属性三者结合起来才能表示现实世界。 ①实体集(联系)与属性间的连接关系

a.实体是概念世界的基本单位,属性附属于实体,一个实体可以有若干个属性,实体及它的所有属性构成实体的完整描述。

b.属性有属性域,每个实体可取属性域内的值。一个实体的所有属性取值组成了一个值集叫元组。在概念世界中,可以用元组表示实体,也可用它区别不同的实体。

c.实体有型与值之别,一个实体的所有属性构成了这个实体的型,而实体中属性值的集合(即元组)则构成了这个实体的值。

d.联系也可以附有属性,联系和它的所有属性构成了联系的一个完整描述,因此,联系与属性间也有连接关系。

②实体(集)与联系 a.实体集间可通过联系建立连接关系,实体集间无法建立直接关系,它只能通过联系才能建立起连接关系。 b.在E-R模型中有三个基本概念以及它们之间的两种基本连接关系。它们将现实世界中的错综复杂的现象抽象成简单明了的几个概念与关系,具有极强的概括性和表达能力。

(3)E-R模型的图示法

在E-R图中分别用不同的几何图形表示E-R模型中的三个概念与两个连接关系。 ①实体集表示法

用矩形表示实体集,在矩形内写上该实体集的名字。 ②属性表示法

用椭圆形表示属性,在椭圆形内写上该属性的名称。 ③联系表示法

用菱形(内写上联系名)表示联系。 ④实体集(联系)与属性间的连接关系

属性依附于实体集,因此,它们之间有连接关系。 ⑤实体集与联系间的连接关系

实体集与联系间的连接关系可用连接这两个图形间的无向线段表示。 两个实体集间联系叫二元联系,多个实体集间联系叫多元联系。 3.层次模型

层次模型的基本结构是树形结构,自顶向下,层次分明。 (1)树结构的特性

①每棵树有且仅有一个无双亲结点,称为根。 ②树中除根外所有结点有且仅有一个双亲。 (2)层次模型的完整性约束条件

①进行插入操作时,如果没有相应的双亲结点值就不能插入子女结点值;

②进行删除操作时,如果删除双亲结点值,则相应的子女结点值也被同时删除; ③进行更新操作时,应更新所有相应记录,以保证数据的一致性。 (3)层次模型的优缺点 优点:

①结构比较简单,操作简单;

②对于实体间联系是固定的、且预先定义好的应用系统,层次模型有较高的性能; ③层次模型还可以提供良好的完整性支持。 缺点:

①受文件系统影响大,模型受限多,物理成分复杂,不适合表示非层次性的联系; ②对于插入和删除操作的限制比较多; ③查询子女结点必须通过双亲结点。 4.网状模型

(1)网状模型是一个不加任何条件限制的无向图。将通用的网络拓扑结构分成一些基本结构,分解方法是将一个网络分成若干个二级树

(2)在网状模型标准中,基本结构简单二级树叫系,系的基本数据单位是记录,它相当于E-R模型中的实体(集);记录又可由若干数据项组成,它相当于E-R模型中的属性。

(3)系由一个首记录和若干成员记录组成 ①首记录相当于简单二级树的根;

②成员记录,它相当于简单二级树中的叶;

首记录与成员记录之间的联系用有向线段表示,在系中首记录与成员记录间是一对多联系。 5.关系模型

(1)关系的数据结构

①关系模型中二维表的组成

二维表由表框架及表的元组组成。表框架由n个命名的属性组成,n称为属性元数。每个属性有一个取值范围称为值域。表框架对应了关系的模式,即类型的概念。表框架中,按行存放数据,每行数据称为元组,一个表框架可以存放m个元组,m称为表的基数。

②二维表满足的性质:

a.二维表中元组个数是有限的——元组个数有限性。 b.二维表中元组均不相同——元组的唯一性。

c.二维表中元组的次序可以任意交换——元组的次序无关性。

d.二维表中元组的分量是不可分割的基本数据项——元组分量的原子性。 e.二维表中属性名各不相同——属性名唯一性。

f.二维表中属性与次序无关,可任意交换——属性的次序无关性。

g.二维表属性的分量具有与该属性相同的值域——分量值域的同一性。

满足以上7个性质的二维表称为关系,以二维表为基本结构所建立的模型称为关系模型。 ③键 a.二维表中凡能唯一标识元组的最小属性集称为该表的键,键具有标识元组,建立元组间联系等重要作用。 b.二维表中可能有若干个键,它们称为表的候选键,从二维表汇总选取一个作为用户使用的键称为主键 c.关系元组分量中允许出现空值以表示信息空缺。一般关系数据库系统都支持空值,但是有两个限制:第一,关系的主键不允许出现空值;第二,需要定义有关空值的运算。

(2)关系操纵 ①数据查询

a.对一个关系内的查询

第一,对一个关系内查询的基本单位是元组分量,其基本过程是先定位后操作。

第二,定位包括纵向定位和横向定位,纵向定位是指定关系中的一些属性,横向定位是选择满足某些逻辑条件的元组。通过纵向与横向定位后一个关系中的元组分量即可确定了。在定位后即可进行查询操作,就是将定位的数据从关系数据库中取出并放入至指定内存。

b.对多个关系间的数据查询

对多个关系间的数据查询则可分为三步: 第一,将多个关系合并成一个关系;

第二,对合并后的一个关系作定位; 第三,操作。 ②数据删除

第一,数据删除的基本单位是一个关系内的元组,它的功能是将指定关系内的指定元组删除。

第二,分为定位与操作两部分,其中定位部分只需要横向定位而无需纵向定位,定位后即执行删除操作。因此数据删除可以分解为一个关系内的元组选择与关系中元组删除两个基本操作。

③数据插入

数据插入仅对一个关系而言,在指定关系中插入一个或多个元组。在数据插入中不需定位,仅需做关系中元组插入操作,因此数据插入只有一个基本操作。

④数据修改

数据修改是在一个关系中修改指定的元组与属性。数据修改不是一个基本操作,它可以分解为删除需修改的元组与插入修改后的元组两个更基本的操作。

⑤关系模型的六种基本操作: a.关系的属性指定; b.关系的元组选择; c.两个关系合并;

d.一个或多个关系的查询; e.关系中元组的插入; f.关系中元组的删除。 (3)关系中的数据约束 ①实体完整性约束

该约束要求关系的主键中属性值不为空,由关系数据库系统自动支持。 ②参照完整性约束

该约束是关系之间相关联的基本约束,不允许引用不存在的元组,由关系数据库系统自动支持。 ③用户定义的完整性约束

由关系数据库系统提供完整性约束语言,用户利用该语言写出约束条件,运行时由系统自动检查。这是针对具体数据环境与应用环境由用户具体设置的约束,它反映了具体应用中数据的语义要求。

三、关系代数

1.关系模型的基本操作

关系模型有插入、删除、修改和查询四种操作,它们又可以进一步分解成六种基本操作: (1)关系的属性指定

指定一个关系内的某些属性,用它确定关系这个二维表中的列,它主要用于检索或定位。 (2)关系的元组的选择

用一个逻辑表达式给出关系中所满足此表达式的元组,用它确定关系这个二维表的行,它主要用于检索或定位。

(3)两个关系的合并

将两个关系合并成一个关系。用此操作可以不断合并从而可以将若干个关系合并成一个关系,以建立多个关系间的检索与定位。

(4)关系的查询

在一个关系或多个关系间做查询,查询的结果也为关系。 (5)关系元组的插入

在关系中增添一些元组,用它完成插入与修改。 (6)关系元组的删除

在关系中删除一些元组,用它完成删除与修改。 2.关系模型的基本运算 (1)插入

插入可用集合并运算表示为:R∪R′ (2)删除

删除可用集合差运算表示为:R-R′

(3)修改

修改关系R内的元组内容可用下面的方法实现: ①设需修改的元组构成关系R′,则先做删除得:R-R′

②设修改后的元组构成关系R″,此时将其插入即得到结果:(R-R′)∪R″ (4)查询

用于查询的三个操作无法用传统的集合运算表示,需要引入一些新的运算。 ①投影运算

对于关系内的域指定可引入新的运算叫投影运算,它是一元运算。

一个关系通过投影运算(并由该运算给出所指定的属性)后仍为一个关系R′。R′是R中投影运算所指出的那些域的列所组成的关系。 ②选择运算。

它是一个一元运算,关系R通过选择运算后仍为一个关系。这个关系是由R中那些满足逻辑条件的元组所组成。设关系的逻辑条件为F,则R满足F的选择运算可写成为:σF(R)

③笛卡儿积运算。

对于两个关系的合并操作可以用笛卡儿积表示。设有n元关系R及m元关系S,它们分别有p、q个元组,则关系R与S经笛卡儿积记为R×S,该关系是一个n+m元关系,元组个数是p×q,由R与S的有序组组合而成。

3.关系代数中的扩充运算 (1)交运算

关系R与S经交运算后所得到的关系是由那些既在R内又在S内的有序组所组成,记为R∩S。交运算可由基本运算推导而得:R∩S=R-(R-S)。 (2)除运算

除运算是笛卡尔积运算的逆运算,若T=R×S时,除运算可写成:T÷R=S或T/R=S。 (3)连接与自然连接运算

①连接运算又可称为θ-连接运算,这是一种二元运算,通过它可以将两个关系合并成一个大关系。设有关系R、S以及比较式iθj,其中i为R中的域,j为S中的域,θ含义同前。则可以将R、S在域i,j上的θ连接记为:

它的含义可用下式定义:

即R与S的θ连接是由R与S的笛卡儿积中满足限制iθj的元组构成的关系,一般其元组的数目远远少于R×S的数目。应当注意的是,在θ连接中,i与j需具有相同域,否则无法作比较。

在θ连接中如果θ为“=”,就称此连接为等值连接,否则称为不等值连接。 ②自然连接满足下面的条件: a.两关系间有公共域;

b.通过公共域的相等值进行连接。

四、数据库设计与管理 1.数据库设计概述

(1)数据库设计基本任务

在一定平台制约下,根据用户对象的信息需求、处理需求和数据库的支持环境设计出性能良好的数据模式。 (2)数据库设计的方法

①面向数据的方法:以信息需求为主,兼顾处理需求,已成为主流。 ②面向过程的方法:以处理需求为主,兼顾信息需求 (3)数据库设计的生命周期法

将整个数据库应用系统的开发分解成目标独立的若干阶段。它们分别是:需求分析阶段、概念设计阶段、逻辑设计阶段、物理设计阶段、编码阶段、测试阶段、运行阶段、进一步修改阶段。

2.数据库设计的需求分析 (1)需求分析阶段的主要任务

通过详细调查现实世界要处理的对象,充分了解原系统的工作概况,明确用户的各种需求,然后在此基础上确定新系统的功能。新系统必须充分考虑今后可能的扩充和改变,不能仅按当前应用需求来设计数据库。

(2)调查的重点是“数据”和“处理”,通过调查要从中获得每个用户对数据库的如下要求: ①信息要求

指用户需要从数据库中获得信息的内容与性质。由信息要求可以导出数据要求,即在数据库中需存储哪些数据。

②处理要求

指用户要完成什么处理功能,对处理的响应时间有何要求,处理的方式是批处理还是联机处理。 ③安全性和完整性的要求

设计人员必须不断和用户进行交流,与用户达成共识,确定用户实际需求,然后分析和表达这些需求。需求分析是整个设计活动的基础,也是最困难最花时间的一步。

(3)分析和表达用户需求常采用结构化分析方法和面向对象的方法 ①结构化分析方法

a.用自顶向下、逐层分解的方式分析系统,用数据流图表达了数据和处理过程的关系 b.数据字典是各类数据描述的集合,它通常包括5个部分: 第一,数据项:是数据的最小单位;

第二,数据结构:是若干数据项有意义的集合;

第三,数据流:可以是数据项,也可以是数据结构,表示某一处理过程的输入或输出;第四,数据存储:处理过程中存取的数据,常常是手工凭证、手工文档或计算机文件;第五,处理过程。 (4)数据库设计在实际开展时应注意以下几点

①在需求分析阶段一个重要而困难的任务是收集将来应用所涉及的数据。设计人员应充分考虑到可能的扩充和改变,使设计易于更动。

②必须强调用户的参与,设计人员应该和用户充分合作进行设计,并对设计工作的最后结果承担共同的责任。 3.数据库概念设计

(1)数据库概念设计概述

数据库概念设计的目的是分析数据间内在语义关联,在此基础上建立一个数据的抽象模型。数据库概念设计的方法有以下两种:

①集中式模式设计法

a.根据需求由一个统一机构或人员设计一个综合的全局模式。

b.这种方法设计简单方便,它强调统一与一致,适用于小型或并不复杂的单位或部门,而对大型的或语义关联复杂的单位则并不适合。

②视图集成设计法

a.将一个单位分解成若干个部分,先对每个部分作局部模式设计,建立各个部分的视图,然后以各视图为基础进行集成。需对视图作修正,最终形成全局模式。

b.是一种由分散到集中的方法,它的设计过程复杂但它能较好地反映需求,适合于大型与复杂的单位,避免设计的粗糙与不周到,目前此种方法使用较多。

(2)数据库概念设计的过程 ①选择局部应用

根据系统的具体情况,在多层的数据流图中选择一个适当层次的数据流图,让这组图中每一部分对应一个局部应用,以这一层次的数据流图为出发点,设计分E-R图。

②视图设计

视图设计一般有三种设计次序,它们是: a.自顶向下

先从抽象级别高且普遍性强的对象开始逐步细化、具体化与特殊化。 b.由底向上

先从具体的对象开始,逐步抽象,普遍化与一般化,最后形成一个完整的视图设计。 c.由内向外

先从最基本与最明显的对象着手逐步扩充至非基本、不明显的其他对象。

在进行设计时,实体与属性是相对而言的。同一事物,在一种应用环境中作为“属性”,在另一种应用环境中就必须作为“实体”。但是,在给定的应用环境中,属性必须是不可分的数据项,属性不能与其他实体发生联系,联系只发生在实体之间。

③视图集成

a.视图集成的实质是将所有的局部视图统一与合并成一个完整的数据模式。在进行视图集成时,最重要的工作便是解决局部设计中的冲突。

b.在集成过程中常见冲突有下列几种: 第一,命名冲突

有同名异义和同义异名两种。 第二,概念冲突

同一概念在一处为实体而在另一处为属性或联系。 第三,域冲突

相同的属性在不同视图中有不同的域。 第四,约束冲突

不同的视图可能有不同的约束。

(3)视图合并生产E-R图必须满足以下条件,避免数据冗余和联系冗余 ①整体概念结构内部必须具有一致性,即不能存在互相矛盾的表达;

②整体概念结构能准确地反映原来的每个视图结构,包括属性、实体及实体间的联系; ③整体概念结构能满足需求分析阶段所确定的所有要求;

④整体概念结构最终还应该提交给用户,征求用户和有关人员的意见,进行评审、修改和优化,然后把它确定下来,作为数据库的概念结构,作为进一步设计数据库的依据。

4.数据库的逻辑设计

(1)从E-R图向关系模式转换

①数据库的逻辑设计主要工作是将E-R图转换成指定RDBMS中的关系模式。E-R模型与关系间的转换如表4-2所示。

表4-2 E-R模型与关系间的比较表

E-R模型 属性 实体 关系 属性 元组 E-R模型 实体集 联系 关系 关系 关系 ②由E-R图转换成关系模式时会遇到的一些转换问题。 a.命名与属性域的处理

关系模式中的命名可以用E-R图中原有命名,也可另行命名,但是应尽量避免重名,RDBMS一般只支持有限种数据类型而E-R中的属性域则不受此限制。

b.非原子属性处理

E-R图中允许出现非原子属性,但在关系模式中一般不允许出现非原子属性,非原子属性主要有集合型和元组型。如出现此种情况时可以进行转换,其转换办法是集合属性纵向展开而元组属性则横向展开。

c.联系的转换

在一般情况下联系可用关系表示,但是在有些情况下联系可归并到相关联的实体中。 (2)逻辑模式规范化及调整、实现 ①规范化

a.关系数据库设计的关键是确定构造几个关系模式及每个模式各自包含的属性,将相互关联的模式组合成合适的关系模型。其设计必须在关系数据库规范化理论的指导下进行。设计不良的关系模式会有数据冗余、插入异常、删除异常及修改异常等问题。

b.三种范式 第一,第一范式

每个属性都已不能再分为简单项。 第二,第二范式

如果某个关系模式R为第一范式,并且R中每一个非主属性完全函数依赖于R的某个候选键,则称其为第二范式模式。第二范式消除了非主属性对主键的部分依赖。

第三,第三范式

如果关系模式R是第二范式,并非每个非主属性都不传递依赖于R的候选键,则称R为第三范式模式,大部分应用中都将关系分解为第三范式。

关系模式进行规范化的目的是使关系结构更合理,消除存储异常,使数据冗余尽量小,便于插入、删除和更

新等操作。关系模式进行规范化的原则是:遵从概念单一化“一事一地”原则,即一个关系模式描述一个实体或实体间的一种联系。规范化的实质就是概念的单一化。

②RDBMS

对逻辑模式进行调整以满足RDBMS的性能、存储空间等要求,同时对模式做适应RDBMS限制条件的修改,它们包括如下内容:

a.调整性能以减少连接运算;

b.调整关系大小,使每个关系数量保持在合理水平,从而可以提高存取效率; c.尽量采用快照(snapshot),因在应用中经常仅需某固定时刻的值,此时可用快照将某时刻值固定,并定期更换,此种方式可以显著提高查询速度。

(3)关系视图设计(外模式设计) 关系视图的作用大致有如下几点:

①提供数据逻辑独立性:使应用程序不受逻辑模式变化的影响。 ②能适应用户对数据的不同需求 ③有一定数据保密功能 5.数据库的物理设计

数据库物理设计的主要目标是对数据库内部物理结构作调整并选择合理的存取路径,以提高数据库访问速度及有效利用存储空间。

6.数据库管理

数据库管理一般包含以下内容: (1)数据库的建立

数据库的建立包括两部分内容,数据模式的建立及数据加载。 ①数据模式建立

由DBA负责建立,DBA利用RDBMS中的DDL语言定义数据库名,定义表及相应属性,定义主关键字、索引、集簇、完整性约束、用户访问权限,申请空间资源,定义分区等,此外还需定义视图。

②数据加载

在数据模式定义后即可加载数据,DBA可以编制加载程序将外界数据加载至数据模式内,从而完成数据库的建立。

(2)数据库的调整

在数据库建立并经一段时间运行后往往会产生一些不适应的情况,此时需要对其作调整,数据库的调整一般由DBA完成,调整包括下面一些内容:

①调整关系模式与视图使之更能适应用户的需求; ②调整索引与集簇使数据库性能与效率更佳;

③调整分区、数据库缓冲区大小以及并发度使数据库物理性能更好。 (3)数据库的重组

数据库在运行一段时间后性能会下降,主要是不断修改、删除、插入造成的。由于不断删除造成盘区内废块增多,影响I/O速度,导致数据库性能下降。基于这些原因需要对数据库进行重新整理,调整存储空间,这项工作叫做数据库重组。

(4)数据库安全性控制与完整性控制 数据库是一个单位的重要资源,它的安全性是极端重要的,DBA应采取措施保证数据不受非法盗用与破坏。此外,为保证数据的正确性,使录入库内的数据均能保持正确,需要有数据库的完整性控制。

(5)数据库的故障校复

一旦数据库中的数据遭受破坏,需要及时进行恢复,RDBMS一般都提供此种功能,并由DBA负责执行故障恢复功能。

(6)数据库监控

DBA需随时观察数据库的动态变化,并在发生错误、故障或产生不适应情况时随时采取措施,如数据库死锁、对数据库的误操作等;同时还需监视数据库的性能变化,在必要时对数据库作调整。

【MySQL数据库程序设计】

第1章 数据库技术的基本概念与方法

一、基本概念 1.数据(Data) (1)数据的概念

数据是数据库中存储的基本对象。数据定义如下:

描述事物的符号记录称为数据。描述事物的符号可以是数字,也可以是文字、图形、图像、声音等,因而数据有多种表现形式,都可以经过数字化后存入计算机。

(2)数据的解释

数据的描述形式还不能完全表达其内容,需要经过解释。数据和关于数据的解释是不可分的,数据的解释是指对数据含义的说明,数据的含义也称数据的语义,因此数据与其语义密不可分。

2.数据库(DataBase,DB) 数据库是存放数据的仓库。

数据库就是长期储存在计算机内的、有组织的、可共享的数据集合。数据库中的数据按一定的数据模型组织、描述和存储,具有较小的冗余度、较高的数据独立性和易扩展性,并可为各种用户共享。

3.数据库管理系统(DataBase Management System,DBMS) (1)数据库管理系统的概念

数据库管理系统是位于操作系统与用户之间的一层数据管理软件,按照一定的数据模型科学地组织和存储数据,并能提供数据高效的获取与维护。

(2)DBMS的主要功能 ①数据定义功能

DBMS提供数据定义语言(Data Definition Language,DDL),用户通过它可以方便地对数据库中的数据对象进行定义。

②数据操纵功能

DBMS还提供数据操纵语言(Data Manipulation Language,DML),用户可以使用DML操纵数据,实现对数据库的基本操作,如查询、插入、删除和修改等。

③数据库的运行管理

数据库在建立、运用和维护时由数据库管理系统统一管理、统一控制,以保证数据的安全性、完整性、多用户对数据的并发使用及发生故障后的系统恢复。

例如,数据的完整性检查功能保证用户输入的数据应满足相应的约束条件;数据库的安全保护功能保证只有赋予权限的用户才能访问数据库中的数据;数据库的并发控制功能使多个应用程序可在同一时刻并发地访问数据库的数据;数据库系统的故障恢复功能使数据库运行出现故障时进行数据库恢复,以保证数据库可靠地运行。

④数据库的建立和维护功能

包括数据库初始数据的输入、转换功能,数据库的转储、恢复功能,数据库的重组织功能和性能监视、分析功能等。

⑤提供方便、有效存取数据库信息的接口和工具

编程人员可通过程序开发工具与数据库的接口编写数据库应用程序。数据库管理员(DataBase Administrator,DBA)可通过提供的工具对数据库进行管理。

4.数据库系统(DataBase System,DBS)

数据库系统是指在计算机系统中引人数据库后的系统,一般由数据库、数据库管理系统、应用开发工具、应用系统、数据库管理员和用户构成。数据库管理系统是数据库系统的一个重要组成部分。但是,数据库的建立、使用和维护等工作不仅需要数据库管理系统,还需要数据库管理员DBA来完成。

在不引起混淆的情况下,常常将数据库系统简称为数据库。

二、数据库系统的特点 1.数据结构化

在数据库系统中,数据不针对某一应用,面向全组织,具有整体的结构化。不仅数据是结构化的,而且存取数据的方式也很灵活,可以存取数据库中的某一个数据项、一组数据项、一个记录或一组记录,数据库中的结构化由DBMS统一管理。DBMS既管理数据的物理结构,也管理数据的逻辑结构;既考虑数据本身,也考虑数据之间的联系。

2.数据冗余度小

数据库系统是从整体和全局上看待和描述数据本身。数据不仅面向某个应用,而且面向整体应用,从而可大大减少数据冗余,节约存储空间,避免因数据的重复存储和不同拷贝而造成的数据之间的不一致性。

3.数据共享性好

由于数据库系统是从整体和全局上看待和描述数据,使得数据不仅面向某个应用,而且面向整个系统,因此数据可以被多个用户和多个应用共享使用。

4.数据独立性高

数据独立性包括数据的物理独立性数据的逻辑独立性。物理独立性是指用户的应用程序与存储在磁盘上的数据库中的数据是相互独立的。逻辑独立性是指用户的应用程序与数据库的逻辑结构是相互独立的。数据独立性是数据库的一种特征和优点,有利于在数据库结构修改时保持应用程序尽可能地不改变或少改变。

5.数据由DBMS统一管理和控制

DBMS提供了数据控制功能,包括数据的安全性、完整性以及并发和恢复的控制。

(1)数据的安全性是指保护数据,以防止不合法的使用造成的数据泄密和破坏,使每个用户只能按规定对某些数据以某些方式进行使用和处理;

(2)数据的完整性是对数据的正确性、有效性和相容性要求,即控制数据在一定的范围内有效或要求数据之间满足一定的关系;

(3)并发控制是指当多个用户的并发进程同时存取、修改数据库时,可能会发生相互干扰而得到错误结果,并使得数据库的完整性遭到破坏,因而对多用户的并发操作加以控制和协调;

(4)数据库的恢复是DBMS必须具有将数据库从错误状态恢复到某一已知的正确状态的功能。

三、数据库系统的结构

1.各种视角下的数据库系统结构

从数据库用户视图的视角来看,数据库系统通常采用三级模式结构,这是数据库管理系统内部的系统结构; 从数据库管理系统的角度来看,数据库系统的结构分为集中式结构、分布式结构、客户/服务器结构和并行结构,这是数据库系统的外部体系结构;

从数据库系统应用的角度来看,目前数据库系统常见的结构有客户/服务器结构和浏览器/服务器结构,这是数据库系统整体的运行结构。

2.数据库系统的三级模式结构

数据库系统的三级模式结构是指数据库系统是由模式、外模式和内模式三级构成。 (1)模式(Schema)

模式是对数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图。它是数据库系统三级模式结构的中间层,既不涉及数据的物理存储细节和硬件环境,也与具体的应用程序、所使用的应用开发工具及程序设计语言(如PHP、Perl、C)无关。

模式实际上是数据库数据在逻辑级上的视图,因而模式也称逻辑模式或概念模式。一个数据库只有一个模式。数据库模式以某一种数据模型为基础,统一综合地考虑了所有用户的需求,并将这些需求有机地结合成一个逻辑整体。定义模式时不仅要定义数据的逻辑结构,而且要定义数据之间的联系与约束,以及定义与数据有关的安全性、完整性要求。DBMS提供模式描述语言(Schema DDL)来严格地定义模式。

(2)外模式(External Schema)

外模式也称子模式(Subschema)或用户模式,是对数据库用户(包括应用程序员和最终用户)能够看见和

使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。

外模式通常是模式的子集。一个数据库可以有多个外模式。由于它是各个用户的数据视图,不同的用户在应用需求、看待数据的方式、对数据保密的要求等方面存在差异,其外模式描述就是不同的。即使对模式中同一数据,在外模式中的结构、类型、长度、保密级别等都可以不同。同一外模式也可以为某一用户的多个应用系统所使用,但一个应用程序只能使用一个外模式。

外模式是保证数据库安全性和保密性的一个有力措施,每个用户只能看见和访问所对应的外模式中的数据,而数据库中其余数据是不可见的。同时,外模式简化了数据库系统的用户接口,便于用户使用,并有效支持了数据的独立性和共享性。DBMS提供子模式描述语言(Subschema DDL)来严格地定义子模式。

(3)内模式(Internal Schema)

内模式也称存储模式(Storage Schema),是对数据库中数据物理结构和存储方式的描述,是数据在数据库内部的表示形式。它定义了所有内部记录类型、索引和文件的组织方式,以及所有数据控制方面的细节。

内部模式与这样一些工作相关:数据和索引的存储空间分配;用于存储的记录描述(数据项的存储大小);记录的放置;数据压缩和数据加密技术。一个数据库只有一个内模式。DBMS提供内模式描述语言(内模式DDL,或者存储模式DDL)来严格地定义内模式。

3.三级模式结构的两层映像与两级数据独立性 (1)三级模式结构的特点

①一个数据库的整体逻辑结构和特征的描述(概念结构)是独立于数据库其他层次结构(内/外模式)的描述。

②一个数据库的内部存储模式依赖于概念模式,但存储模式独立于外部模式,也独立于具体的存储设备。 ③用户逻辑结构(外模式)是在全局逻辑结构描述的基础上定义的,它面向具体的应用程序,独立于内部模式和存储设备。

④特定的应用程序是在外模式描述的逻辑结构上编写的,依赖于特定的外模式,与数据库的模式和存储结构独立。

(2)数据库管理系统在这三级模式之间提供的两层映像 ①外模式/模式映像

映像是一种对应规则,指出映像双方是如何进行转换的。外模式/模式映像定义了各个外模式与概念模式之间的映像关系。映像定义通常在各自的外模式中加以描述。对于同一个模式可以有任意多个外模式;对于每一个外模式,数据库系统都有一个外模式/模式映像。当模式发生改变时,如增加新的关系、新的属性、改变属性的数据类型等,由数据库管理员DBA对各个外模式/模式的映像做相应的改变,以使外模式保持不变。由于应用程序是依据数据的外模式编写的,从而应用程序不必修改,如此就保证了数据与程序的逻辑独立性,使得外模式不受概念模式变化的影响,这种数据独立性就是数据的逻辑独立性。

②模式/内模式映像

数据库中只有一个模式,也只有一个内模式,所以模式/内模式映像是唯一的,它定义了数据库全局逻辑结构与存储结构之间的对应关系。这个映像定义在模式中加以描述的。

当数据库的存储结构改变了,如选用了另外一种存储结构,由数据库管理员DBA对模式/内模式映像做相应改变,可以使模式保持不变,从而应用程序也不必改变,如此就保证了数据与程序的物理独立性,使得概念模式不受内模式变化的影响,这种数据独立性就是数据的物理独立性。

这两层映像保证了数据库系统中的数据能够具有较高的逻辑独立性和物理独立性,使得数据的定义和描述可以从应用程序中分离出去。

4.数据库系统的运行与应用结构

(1)客户/服务器(Client/Server,C/S)结构

在数据库系统中,数据库的使用者(如DBA、程序设计者)可以使用命令行客户端、图形化界面管理工具或应用程序等来连接数据库管理系统,并可以通过数据库管理系统查询和处理存储在底层数据库中的各种数据。数据库系统的这种工作模式采用的就是客户/服务器结构。其中,数据库的使用者是与命令行客户端、图形化界面管理工具或应用程序等直接交互,而不与数据库管理系统直接联系。

在这种结构中,命令行客户端、图形化界面管理工具或应用程序等称为“客户端”“前台”或“表示层”,主要完成与数据库使用者的交互任务;而数据库管理系统则称为“服务器”“后台”或“数据层”,其主要负责数据管理。这种操作数据库的模式也称客户/服务器(C/S)模式,图1-1给出了客户/服务器(C/S)模式的一般处理

流程。

图1-1 客户/服务器(C/S)模式的一般处理流程

在客户/服务器(C/S)模式中,客户端和服务器可以同时工作在同一台计算机上,这种工作方式称为“单机方式”;也可以“网络方式”进行运行,即服务器被安装和部署在网络中某一台机器上,而客户端被安装和部署在网络中不同的一台或多台主机上。客户端应用程序的开发,目前常用的语言工具主要有Visual C++、.NET框架、Delphi、Visual Basic等。

(2)浏览器/服务器(Brower/Server,B/S)结构

浏览器/服务器结构是一种基于Web应用的客户/服务器结构,也称三层客户/服务器结构。在数据库系统中,将与数据库管理系统交互的客户端进一步细分为“表示层”和“处理层”。“表示层”是数据库使用者的操作和展示界面,由用于上网的各种浏览器构成,减轻了数据库系统中客户端的工作负担;“处理层”也称“中间层”,主要负责处理数据库使用者的具体应用逻辑,与后台的数据库管理系统共同组成功能更加丰富的“胖服务器”。数据库系统的这种工作模式就称为浏览器/服务器(B/S)模式,图1-2给出了浏览器/服务器(B/S)模式的一般处理流程。

图1-2 浏览器/服务器(B/S)模式的一般处理流程

基于浏览器/服务器结构的数据库应用系统的开发,目前主要使用的开发语言有PHP、Java、Peal、C#等。

四、数据模型

1.数据模型的介绍

模型是对现实世界特征的模拟和抽象,数据模型(Data Model)是对现实世界中数据特征的抽象,描述的是数据的共性。数据模型是用来在数据库中抽象、表示和处理现实世界中的数据和信息的。

数据模型应满足三方面要求:一是能比较真实地模拟现实世界;二是容易为人们所理解;三是便于在计算机上实现。一种数据模型要很好地满足这三方面的要求在目前尚很困难,在数据库系统中针对不同的使用对象和应用目的,通常采用逐步抽象的方法,在不同层次采用不同的数据模型。一般可分下面三层:

(1)物理层

物理层是数据抽象的最底层,用来描述数据物理存储结构和存储方法。这一层的数据抽象称为物理数据模型,它不但由DBMS的设计决定,而且与操作系统、计算机硬件密切相关。物理数据结构一般都向用户屏蔽。

(2)逻辑层

逻辑层是数据抽象的中间层,描述数据库数据整体的逻辑结构。这一层的数据抽象称为逻辑数据模型,简称数据模型。是用户通过DBMS看到的现实世界,是基于计算机系统的观点来对数据进行建模和表示。它既要考虑用户容易理解,又要考虑便于DBMS实现。不同的DBMS提供不同的逻辑数据模型,常见的数据模型有层次模型(Hierarchical Model)、网状模型(Network Model)、关系模型(Relational Model)和面向对象模型(Object Oriented Model)。

(3)概念层

概念层是数据抽象级别的最高层,其目的是按用户的观点来对现实世界建模。概念层的数据模型称为概念数据模型,简称概念模型。概念模型独立于任何DBMS,但容易向DBMS所支持的逻辑数据模型转换。常用的概念模型有实体-联系模型(Entity-Relationship Model,简称E-R模型)。

2.概念模型

(1)概念模型的含义

概念模型用于信息世界的建模,是实现现实世界到信息世界的第一层抽象,是数据库设计人员进行数据库设计的有力工具,也是数据库设计人员和用户之间进行交流的语言,因此概念模型一方面具有较强的语义表达能力,能够方便、直接地表达应用中的各种语义知识;另一方面是表达简单、清晰、易于用户理解。

(2)信息世界中的基本概念 ①实体(Entity)

客观存在并可相互区别的事物称为实体。实体可以是具体的人、事、物,也可以是抽象的概念或联系。 ②属性(Attribute)

实体所具有的某一特性称为属性。一个实体可以由若干个属性来刻画。 ③码(Key)

唯一标识实体的属性集称为码。 ④域(Domain)

属性的取值范围称为该属性的域。 ⑤实体型(Entity Type)

具有相同属性的实体必然具有共同的特征和性质。用实体名与属性名集合来抽象和刻画同类实体,称为实体型。

⑥实体集(Entity Set)

同型实体的集合称为实体集。 ⑦联系(Relationship)

在现实世界中,事物内部以及事物之间是有联系的,这些联系在信息世界中反映为实体(型)内部的联系和实体(型)之间的联系。实体内部的联系通常是指组成实体的各属性之间的联系。实体之间的联系通常是指不同实体集之间的联系。

两个实体型之间的联系通常可以分为以下三类: a.一对一联系(1:1)

如果对于实体集A中的每一个实体,实体集B中至多有一个(也可以没有)实体与之联系,反之亦然,则称实体集A与实体集B具有一对一联系,记为1:1。

b.一对多联系(1:N)

如果对于实体集A中的每一个实体,实体集B中有N个实体与之联系,反之,对于实体集B中的每一个实体,实体集A中至多有一个实体与之联系,则称实体集A与实体集B具有一对多联系,记为1:N。

c.多对多联系(M:N)

如果对于实体集A中的每一个实体,实体集B中有N个实体与之联系,反之,对于实体集B中的每一个实体,实体集A中实体集B具有多对多联系,记为M:N。

(3)概念模型的表示方法

概念模型就是对信息世界建模。概念模型的表示方法很多,其中最为常用的是实体-联系方法(Entity-Relationship Approach)。该方法用E-R图来描述现实世界的概念模型,E-R方法也称E-R模型。

E-R图提供了表示信息世界中实体、属性和联系的方法,具体为: ①实体型:用矩形表示,矩形框内写明实体的名称。

②属性:用椭圆形表示.并用无向边将其与相应的实体连接起来。

③联系:用菱形表示,菱形框内写明联系的名称,并用无向边与有关实体连接起来,同时在无向边旁标上联系的类型(1:1、1:M、M:N)。如果一个联系具有属性,则这些属性也要用无向边与该联系连接起来。

实体-联系方法是抽象和描述现实世界的有力工具。用E-R图表示的概念模型独立于具体的DBMS所支持的数据模型,它是各种数据模型的共同基础,。

3.关系模型

(1)关系模型中的基本概念

①关系:一个关系逻辑上对应一张二维表(格)。可以为每个关系取一个名称进行标识。与之定义的术语是“表”。

②元组:表中的一行即为一个元组。与之同义的术语是“行”。

③属性:表中的一列即为一个属性,给每一个属性起一个名称即属性名。与之同义的术语是“列”。 ④主码:表中的某个属性组,它可以唯一确定一个元组。与之同义的术语是“主键”。 ⑤域:属性的取值范围。与之同义的术语是“数据类型”。 ⑥分量:元组中的一个属性值。与之同义的术语是“列值”。

⑦关系模式:对关系的描述,一般表示为“关系名(属性1,属性2,…,属性n)”。 ⑧表:由行和列组成。可以为每个表取一个表名进行标识。 ⑨行:表中的一条记录。表中的数据是按行存储的。

⑩列:表中的一个字段。所有表都是由一个或多个列组成的。 ⑪主键:表中的一列或一组列,其值能够唯一区分表中的每个行。其中,由一组列构成的主键称为组合主键。 ⑫外键:表中的一列或一组列,其包含另一张表的主键值,主要用于定义两个表之间的关系。与之同义的术语是“外部码”。

⑬数据类型:所容许的数据的类型。每个表列都有相应的数据类型,它限制(或容许)该列中存储的数据。 (2)关系规范化的基本方法

①第一范式(1NF)对表的约束要求

表中每个列只包含具有原子性的值,即关系的每一个分量必须是一个不可分的数据项。 ②第二范式(2NF)对表的约束要求 a.首先要符合第一范式。

b.没有部分函数依赖性,即表中不存在非主键的列依赖于组合主键某个部分的现象。 ③第三范式(3NF)对表的约束要求 a.首先要符合第二范式。

b.没有传递函数依赖性,即表中不存在任何非主键列与其他非主键列相互关联的现象。 ④BCNF对表的约束要求 a.首先要符合第三范式。

b.表中不存在主键列对主键的部分函数依赖和传递函数依赖。 (3)关系规范化的定义

一个低一级范式的关系模式,通过模式分解逐步消除数据依赖中不合适的部分,使模式中的各关系模式达到某种程度的分离,转换为若干个高一级范式的关系模式的集合,这种过程就是关系规范化。

(4)关系规范化的过程

①通过消除非主键列对主键的部分函数依赖,将INF表规范为2NF表。 ②通过消除非主键列对主键的传递函数依赖,将2NF表规范为3NF表。

③通过消除主键列对主键的部分函数依赖和传递函数依赖,将2NF表规范为BCNF表。

(5)在关系模型中,满足关系规范化要求的表与表之间的联系 ①一对一(1:1)的关联

一对一的关联从概念上表达的是一个数据对象与另外一个数据对象之间仅表现为一对一的关系;从逻辑上表达的是某个表中的一行数据行仅与另一个表中的某一数据行相对应。

②一对多(1:N)的关联

一对多的关联从概念上表达的是一个数据对象与另外一个数据对象之间表现为一对多的关系;从逻辑上表达的是某个表中的一行数据行可与另一个表中的多条数据行相对应。

③多对多(M:N)的关联

多对多的关联从概念上表达的是一个数据对象与另外一个数据对象之间表现为多对多的关系;从逻辑上表达的是某个表A中的一行数据行与另一个表B中的多条数据行相对应,同时这个表A中的多条数据行又与表B中的某一行数据行对应。

五、数据库设计

1.数据库设计的介绍

(1)数据库设计是建立数据库及其应用系统的技术,是信息系统开发和建设中的核心技术。

(2)数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库,使之能够有效地存储数据,满足各种用户的应用需求、信息需求和处理需求。

(3)在数据库领域里,通常把使用数据库的各类系统称数据库应用系统。

(4)按照数据库规范设计的方法,可将数据库设计分为六个阶段:需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库实施、数据库运行与维护。

2.概念结构设计

概念结构设计是将需求分析得到的用户需求抽象为信息结构(即概念模型)的过程,它是整个数据库设计的关键。通常使用E-R图来描述现实世界的概念模型。

某单位员工信息管理系统的E-R图如图1-3所示。该E-R图中,描述了员工信息管理系统中的四种实体,“用户”“用户组”“部门”和“用户权限”,以及每个实体所涉及的多个属性,还有三种实体间的联系,分别是“用户组”实体与“用户”实体间的一对多联系,用于描述一个“用户组”实体可以包含多个“用户”实体;“部门”实体与“用户”实体间的一对多联系,用于描述一个“部门”实体可以包含多个“用户”实体;“用户组”实体与“权限”实体间的多对多联系,用于描述一个“用户组”实体可以分配多个“权限”实体,同时一个“权限”实体也可以被分配给多个“用户组”实体。

图1-3 员工信息管理系统的E-R图

3.逻辑结构设计

(1)逻辑结构设计的含义

概念结构是独立于任何一种(逻辑)数据模型的信息结构。在关系数据库设计中,逻辑结构设计的任务就是把概念结构设计阶段已设计好的基本E-R图转换为关系模型。关系模型的逻辑结构是一组关系模式的集合,而E-R图则是由实体、实体的属性和实体间的联系三个要素所组成的。将E-R图转换为关系模型实际上是将实体、实体的属性和实体间的联系转换为某种关系模式。

(2)基本E-R图向关系模型的转换规则

①一个实体型转换为一个关系模式,实体的属性作为关系的属性,实体的码作为关系的码。

②一个一对一(1:1)联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,每个实体的码均是该关系的候选码;如果与某一端实体对应的关系模式合并,则需要在该关系模式的属性中加入另一个关系模式的码和联系本身的属性。

③一个一对多(1:N)联系可以转换为一个独立的关系模式,也可以与N端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为N端实体的码。

④一个多对多(M:N)联系转换为一个关系模式,与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为各实体码的组合。

⑤三个或三个以上实体间的一个多元联系可以转换为一个关系模式,与该多元联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为各实体码的组合。

⑥具有相同码的关系模式可合并。

(3)基本E-R图向关系模型转换的实例 基于上述E-R图转换为关系模型的方法,可将图1-3所示的E-R图转换为下面五种关系,其中主码用下划线标识。

用户(用户ID,用户名,口令,年龄,所属用户组,所在部门) 用户组(用户组ID,用户组名,用户组描述) 部门(部门ID,部门名,部门所在地,部门领导) 权限(权限ID,权限名称,权限链接) 用户组权限(ID号,用户组ID,权限ID)

这是因为“用户组”关系和“用户”关系之间是“一对多联系”;“部门”关系和“用户”关系之间是“一对多联系”;“用户组”关系与“权限”关系之间是“多对多联系”。那么“用户组”关系的主码可作为“用户”关系的外部码加入到“用户”关系中,表示用户隶属的用户组;同样,“部门”关系的主码也可作为外部码加入到“用户”关系中,表示用户所在的部门。而在“用户组”关系与“权限”关系之间,可增加一个中间关系“用户组权限”,该关系用于包含“用户组”关系与“权限”关系各自的主码作为其外部码。同时,“用户”关系、“用户组”关系、“部门”关系和“权限”关系分别包含了各自的基本属性信息。

(4)数据模型的优化

数据库逻辑设计的结果不是唯一的。为了进一步提高数据库应用系统的性能,还应该根据应用需要适当地修改、调整数据模型的结构,这就是数据模型的优化。

关系数据模型的优化通常以关系规范化理论为指导,其方法是: ①确定数据依赖。

②对于各个关系模式之间的数据以来进行极小化处理,消除冗余的联系。

③按照数据依赖的理论对关系模式逐一分析,考察是否存在部分函数依赖、传递函数依赖等,确定各关系模式分别属于第几范式。

④按照需求分析阶段得到的处理要求;分析这些模式对于这样的应用环境是否合适,确定是否要对某些模式进行合并或分解。

⑤对关系模式进行必要的分解,提高数据操作的效率和存储空间的利用率。 (5)设计用户子模式

将概念模型转换为全局逻辑模型之后,可根据局部应用需求,利用视图(View)设计更符合局部用户需要的用户模式。

4.物理设计

数据库在物理设备上的存储结构和存取方式称为数据库的物理结构,它依赖于给定的计算机系统。为一个给定的逻辑数据模型选定一个最适合应用要求的物理结构的过程,就是数据库的物理设计。

数据库的物理设计通常分为以下两步: (1)确定数据库的物理结构

在关系数据库中主要指存取方法和存储结构,如设计关系、索引等数据库文件的物理存储结构。 (2)对物理结构进行评价

评价的重点是时间和空间效率。如果评价结果满足原设计要求,则可进入到物理实施阶段,否则需要重新设计或修改物理结构,有时甚至需要返回逻辑设计阶段修改数据模型。

第2章 MySQL概述

一、MySQL系统特性

1.MySQL数据库管理系统的系统特性

(1)使用C和C++语言编写,多种编译器进行测试,保证了源代码的可移植性。

(2)支持AIX、FreeBSD、HP-UX、Linux、Mac OS、Novell Netware、Open BSD、OS/2 Wrap、Solaris、Windows等多种操作系统平台。

(3)为包括C、C++、Python、java、Perl、PHP、Eiffel、Ruby和Tel等在内的多种编程语言提供了API。 (4)支持多线程,可充分利用CPU资源。

(5)优化的SQL查询算法,能有效地提高查询速度。

(6)既能够作为一个单独的应用程序应用在客户端/服务器网络环境中,也能够作为一个库嵌入到其他的软件中。

(7)支持多种语言,常见的编码如中文的GB2312、BIG5等都可以用作数据表名和数据列名。 (8)提供TCP/IP、ODBC和JDBC等多种数据库连接途径。 (9)提供用于管理、检查、优化数据库操作的管理工具。

(10)支持大型的数据库,可以处理拥有上千万条记录的大型数据库,数据类型丰富。支持多种存储引擎。

2.MySQL数据库管理系统的两种主要构架方式

(1)LAMP(Linux+Apache+MySQL+PHP/Perl/Python),即使用Linux作为操作系统,Apache作为Web服务器,MySQL作为数据库管理系统,PHP/Perl/Python作为服务器端脚本解释器。

(2)WAMP(Windows+Apache+MySQL+PHP/Perl/Python),即使用Windows作为操作系统,Apache作为Web服务器,MySQL作为数据库管理系统,PHP/Perl/Python作为服务器端脚本解释器。

二、MySQL服务器的安装和配置 1.MySQL的一些基本信息

MySQL开放源代码,允许任何人使用和修改该软件,因此任何人均可以从Internet上下载和使用MySQL,而不需要支付任何费用。

使用者可以根据自身的操作系统平台,从http://dev.mvsql.com/downloads/mysql上免费下载对应的MySQL服务器安装包。

2.在Windows XP操作系统下安装和配置MySQL的过程

(1)下载Windows(x86,32-bit)版的MySQL5.5.25a在本地计算机之后,双击安装文件直接进入MySQL安装向导界面,如图2-1所示。

图2-1 MySQL安装向导界面

(2)单击“Next”按钮,进入如图2-2所示的MySQL许可证协议界面,这里需要勾选“I accept the terms in the License Agreement”。

图2-2 MySQL许可证协议界面

(3)单击“Next”按钮,进入如图2-3所示的MySQL安装类型选择界面,这里有Typical(典型安装)、Custom(定制安装)和Complete(完全安装)三种安装方式可供选择,对于大多数用户,选择“Typical”即可。

图2-3 MySQL安装类型选择界面

(4)接着单击“Next”按钮即可完成MySQL的安装,并进入如图2-4所示的MySQL安装完成提示界面。此时若需配置MySQL,则只需勾选该提示界面中的“Launch the MySQL Instance Configuration Wizard”,然后单击“Finish”按钮即进入MySQL的配置过程。

图2-4 MySQL安装完成界面

(5)如图2-5所示,在MySQL的配置向导中有两种配置类型供选择,即:Detailed Configuraotion(详细配置)和Standard Configuration(标准配置)。标准配置选项适合希望快速启动MySQL而不必考虑服务器配置的新用户;而详细配置选项适合要求更加细粒度控制服务器配置的高级用户。这里选择“Detailed Configuration”。

图2-5 MySQL配置类型选择界面

(6)接着单击“Next”按钮,进入如图2-6所示的MySQL服务器类型选择界面,该界面中有Developer Machine(开发者机器)、Server Machine(服务器)和Dedicated MySQL Server Machine(专用MySQL服务器)三个选项可供选择。作为MySQL初学者,这里可选择“Developer Machine”选项。

图2-6 MySQL服务器类型选择界面

(7)单击“Next”按钮,进入如图2-7所示的MySQL数据库使用情况对话框,其中有三个选项:Multifunctional Database(多功能数据库)、Transactional Database Only(仅事务处理数据库)和Non-Transactional Database Only(仅非事务处理数据库)。由于多功能数据库对InnoDB和MyISAM表都适用,这里则选择“Multifunctional Database”。

图2-7 MySQL数据库使用情况对话框

(8)然后单击“Next”按钮,进入如图2-8所示的InnoDB表空间对话框,在此可以修改InnoDB表空间文件的位置。这里不做修改,直接进入下一步。

图2-8 InnoDB表空间对话框

(9)接下来进入如图2-9所示的MySQL并发连接选择对话框界面,其中有三个选项,分别为Decision Support(决策支持)(DSS)/OLAP:如果服务器不需要大量的并行连接可以选择该选项;Online Transaction Processing(联机事务处理)(OLTP):如果服务器需要大量的并行连接则选择该选项;Manual Setting(人工设置):选择该选项可以手动设置服务器并行连接的最大数目。这里选择“Decision Support(DSS)/OLAP”。

图2-9 MySQL并发连接选择对话框

(10)单击“Next”按钮,进入如图2-10所示的MySQL联网选项对话框界面,这里选择默认选项,即启用TCP/IP网络,默认端口为3306。

图2-10 MySQL联网选项对话框

(11)单击“Next”按钮,进入如图2-11所示的MySQL字符集选择对话框界面,其中有三个选项。为能支持中文,这里选择“Manual Selected Default Character Set/Collation”选项,并在“Character Set”选择框中选定为gb2312。

图2-11 MySQL字符集选择对话框

(12)接着进入如图2-12所示的MySQL服务选项对话框界面,这里选用“Service Name”(服务名)的默认值MySQL。

图2-12 MySQL服务选项对话框

(13)单击“Next”按钮,进入如图2-13所示MySQL安全选项对话框界面。默认项为“Modify security settings”(修改安全设置),在“New root password”输入框中输入需要设定的root用户密码;若希望通过网络以root登录,则可勾选“Enable root access from remote machines(允许从远程登录连接root)”选项旁边的框。若希望创建一个匿名用户账户,则勾选“Create An Anonymous Account(创建匿名账户)”,出于安全因素考虑,这里不建议勾选此项。

图2-13 MySQL安全选项对话框

(14)完成上述步骤后,单击“Next”按钮,进入如图2-14所示的MySQL配置向导执行界面。这里单击“Execute”按钮,即可开始MySQL配置向导的执行操作,直至整个配置过程结束。

图2-14 MySQL配置向导执行界面

当MySQL服务器的安装和配置过程正常结束之后,在MySQL主目录“C:\\Program Files\\MySQL\\MySQL Server 5.5”下会生成一个my.ini文件,这是MySQL的选项文件,在MySQL启动时会自动加载该文件中的一些选项,因此使用者可以通过修改my.ini文件来修改MySQL的一些默认设置。另外,MySQL有一个用于存放数据库文件的data目录,默认路径为“C:\\Documents and Settings\\All Users\\Application Data\\MySQL\\MySQL Server 5.5\\data”,在data目录中,MySQL为每一个数据库建立一个文件夹,所有的表文件则存放在相应的数据库文件夹中。

三、MySQL服务器的启动与关闭

MySQL服务器安装完毕后,可随时通过手工方式在本机上对其进行启动和关闭。具体操作如下:首先在“Windows开始菜单”→“运行”→“打开”的文本框中输入“services.msc”命令,接着会弹出如图2-15所示的本地服务列表,然后找到并选中服务列表中的“MySQL”服务,此时可使用图中所示的“关闭”“暂停”和“启动”等功能按钮对其操作。

图2-15 本地服务列表

四、MySQL客户端管理工具 1.MySQL命令行客户端

MySQL命令行客户端是在安装MySQL的过程中被自动配置到计算机上的,它以C/S工作模式连接和管

理MySQL服务器。

可以通过“Windows开始菜单”→“所有程序”→“MySQL”→“MySQL Server 5.5”→“MySQL 5.5 Command Line Client”,进入到MySQL命令行客户端。然后,在这个命令行客户端窗口输入管理员口令,就能以root用户身份登录到MySQL服务器了,此时在窗口中会出现如图2-16所示的命令行提示符“mysql>”。在该提示符下,可以输入各种SQL语句对数据库进行操作。当然,也可以切换成其他用户登录MySQL服务器,然后同样可在提示符“mysql>”下执行各种操作MySQL数据库的SQL语句。

图2-16 MySQL的命令行客户端

2.MySQL客户端程序与实用工具

myisampack:用于压缩MyISAM表以产生更小的只读表的以一个工具。 mysql:交互式输入SQL语句或从文件以批处理模式执行它们的令行工具。 mysqlaccess:用于检查访问主机名、用户名和数据库组合的权限客户端脚本。

mysqladmin:用于执行管理操作的客户程序,如创建或删除数数据库,重载授权表,将表刷新到硬盘上,以及重新打开日志文件等。另外,还可以用来捡索版本、进程,以及服务器的状态信息。

mysqlbinlog:用于从二进制日志读取语句的工具。在二进制日志文件中包含的执行过的语句的日志可用来帮助从崩溃中恢复。

mysqlcheck:用于检查、修复、分析以及优化表的维护客户程序。 mysqldump:用于将MySQL数据库转储到一个文件的客户程序。

mysqlhotcopy:用于当服务器在运行时,快速备份MyISAM或ISAM表的工具。 mysqlimport:用于使用LOAD DATA INFILE将文本文件导入相关表的客户程序。 mysqlshow:用于显示数据库、表、列以及索引相关信息的客户程序。 perror:用于显示系统或MySQL错误代码含义的工具。

replace:用于更改文件中或标准输入中的字符串的实用工具。

MySQL客户端程序与实用工具需要在MySQL客户端程序运行平台中正确执行,才能以C/S工作模式来连接和管理MySQL服务器。在计算机中,开启一个DOS终端作为MySQL客户端程序与实用工具的运行平台。然后,进入MySQL安装目录下的bin子目录,例如C:\\Program Files\\MySQL\\MySQL Server 5.5\\bin,会出现如图2-17所示的MySQL客户端程序运行界面,由此就可以在该界面光标闪烁处输入各种MySQL客户端脚本和程序命令了。

图2-17 MySQL客户端程序运行界面

3.MySQL图形化管理工具 (1)phpMyAdmin

phpMyAdmin是使用PHP语言开发的一类基于Web方式的MySQL图形化管理工具,通过B/S工作模式来连接和操作MySQL服务器,其界面如图2-18所示。

图2-18 phpMyAdmin运行界面

通过使用phpMyAdmin,可以方便地完成各种数据库管理任务,不必关心SQL语句的语法。主要功能有: ①创建和删除数据库。

②创建、复制、删除、修改表。删除、编辑、添加字段。 ③执行任何SQL语句,包括批查询。管理字段中的键值。 ④将文本文件输入到数据表。

目前,phpMyAdmin使用者众多,它可支持中文,管理十分便捷。不足之处在于对大数据库的备份和恢复不是很方便。可从http://www.phpmyadmin.net/处下载phpMyAdmin。

(2)Navicat

Navicat是一个桌面版MySQL数据库管理和开发工具,它通过C/S工作模式连接和管理MySQL服务器。Navicat使用图形化的用户界面,简单易用,支持中文,并且有免费版本提供。可从http://www.navicat.com/处下载Navicat。

(3)MySQL Workbench

MySQL Workbench是一个集成化的MySQL数据库设计与管理工具。可从http://dev.mysql.com/downloads/workbench/5.2.html处下载MySQL Workbench。

五、MySQL语言结构 1.MySQL交互介绍

MySQL服务器正确安装完毕后,就在机器系统上搭建好了一个完整的DBMS。

数据库的使用者可以通过命令行或者图形化界面等多种客户端实用工具,来建立与MySQL数据库服务器的连接,从而实施各种数据库相关的操作。各种客户端工具,其与MySQL数据库服务器的交互实质上都是通过结构化查询语言(Structured Query Language,SQL)来实现的。

2.结构化查询语言SQL (1)SQL的介绍

①SQL是结构化查询语言(Structured Query Language)的英文缩写,是一种专门用来与数据库通信的语言。 ②SQL由很少的关键字词构成,每个SQL语句都是由一个或多个关键字构成的。

③设计SQL的目的就是要能够很好地提供一种从数据库中读写数据的简单而有效的方法。

④SQL语句不区分大小写。许多SQL开发人员习惯于对所有SQL关键字使用大写,而对所有列和表的名称使用小写,这样的书写方式可使代码更易于阅读和调试。

(2)SQL的优点

①SQL不是某个特定数据库供应商专有的语言。几乎所有重要的DBMS都支持SQL。

②SQL简单易学。其语句全都是由具有很强描述性的英语单词组成,而且这些单词的数目不多。 ③SQL看上去很简单,但是一种强有力的语言。 (3)SQL的扩展

许多DBMS供应商通过增加语句或指令的方式,对SQL进行了的扩展,但它们仍然遵循标准SQL(即ANSI SQL),并以标准SQL为主体,MySQL也不例外。

扩展的目的主要是为了提供执行特定操作的额外功能或简化方法。

3.MySQL语言组成

MySQL数据库所支持的SQL语言主要包含以下几个部分。 (1)数据定义语言(DDL) ①数据定义语言的作用

数据定义语言主要用于对数据库及数据库中的各种对象进行创建、删除、修改等操作。其中,数据库对象主要有表、默认约束、规则、视图、触发器、存储过程等。

②数据定义语言包括的主要SQL语句

a.CREATE:用于创建数据库或数据库对象。

b.ALTER:用于对数据库或数据库对象进行修改。 c.DROP:用于删除数据库或数据库对象。

对于不同的数据库对象,这三个SQL语句所使用的语法格式也不相同。 (2)数据操纵语言(DML) ①数据操纵语言的作用

用于操纵数据库中各种对象,特别是检索和修改数据。 ②数据操纵语言包括的主要SQL语句

a.SELECT:用于从表或视图中检索数据,是数据库中使用最为频繁的SQL语句之一。 b.INSERT:用于将数据插入到表或视图。

c.UPDATE:用于修改表或视图中的数据,既可修改表或视图中行数据,也可同时修改多行或全部数据。 d.DELETE:用于从表或视图中删除数据其中可根据条件删除指定的数据。 (3)数据控制语言(DCL) ①数据控制语言的作用

数据控制语言主要用于安全管理,如确定哪些用户以查看或修改数据库中的数据。 ②数据控制语言包括的主要SQL语句

a.GRANT:用于授予权限,把语句许可或对象许可的权限授予其他用户和角色。

b.REVOKE:用于收回权限,其功能与GRANT相反,但不影响该用户或角色从其他角色中作为成员继承许可权限。

(4)MySQL扩展增加的语言要素

不是SQL标准所包含的内容,是为了用户编程的方便所增加的语言要素。包括常量、变量、运算符、表达式、函数、流程控制语句和注解等。

①常量

常量是指在程序运行过程中值不变的量,也称字面值或标量值。常量的使用格式取决于值的数据类型。 a.字符串常量:指用单引号或双引号括起来的字符序列,分为ASCII字符串常量和Unicode字符串常量。 b.数值常量:可以分为整数常量和浮点数常量。其中,整数常量是不带小数点的十进制数,浮点数常量则是使用小数点的数值常量。

c.十六进制常量:一个十六进制值指定为一个字符串常量,每对十六进制数字被转换为一个字符,其最前面有一个大写字母“X”或小写字母“x”。

d.日期时间常量:用单引号将表示日期时间的字符串括起来而构成的。

e.位字段值:可以使用b'value'格式符号书写位字段值。其中,value是一个用0或1书写的二进制值。位字段符号可以方便地指定分配给BIT列的值。

f.布尔值:只包含两个可能的值,TRUE和FALSE。FALSE的数字值是“0”,TRUE的数字值是“1”。 g.NULL值:用于表示“没有值”“无数据”等意义,它与数字类型的“0”或字符串类型的空字符串是完全不同的。

②变量

a.变量用于临时存放数据,变量中的数据可以随着程序的运行而变化。

b.变量有名字和数据类型两个属性。其中,变量的名字用于标识变量,变量的数据类型用于确定变量中存放数值的格式和可执行的运算。

c.在MySQL中,变量分为用户变量和系统变量。用户变量前常添加一个符号“@”,用于将其与列名区分开;而大多数系统变量应用于其他SQL语句中时,必须在系统变量名称前添加两个“@”符号。

③运算符

a.算术运算符:+(加)、-(减)、*(乘)、/(除)和%(求模)。 b.位运算符:&(位与)、|(位或)、^(位异或)、~(位取反)、>>(位右移)、<<(位左移)。 c.比较运算符:=(等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、<>(不等于)、!=(不等于)、<=>(相等或都等于空)。

d.逻辑运算符:NOT或!(逻辑非)、AND或&&(逻辑与)、OR或||(逻辑或)、XOR(逻辑异或)。 ④表达式

a.表达式是常量、变量、列名、复杂计算、运算符和函数的组合。 b.一个表达式可以得到一个值。

c.与常量、变量一样,表达式的值也具有某种数据类型,可能的数据类型有字符类型、数值类型、日期时间类型。根据表达式的值的数据类型,表达式可分为字符型表达式、数值型表达式和日期表达式。

⑤内置函数

在编写MySQL数据库程序时,可直接调用系统提供的内置函数来对数据库表进行相关操作。MySQL中包含了100多个函数,大致可分为这样几类:

a.数学函数:例如,ABS( )函数。 b.聚合函数:例如,COUNT( )函数。

c.字符串函数:例如,ASCII( )函数、CHAR( )函数。 d.日期和时间函数:例如,NOW( )函数、YEAR( )函数。 e.加密函数:例如,ENCODE( )函数、ENCRYPT( )函数。 f.控制流程函数:例如,IF( )函数、IFNULL( )函数。 g.格式化函数:例如,FORMAT( )函数。 h.类型转换函数:例如,CAST( )函数。

i.系统信息函数:例如,USER( )函数、VERSION( )函数。

第3章 数据库和表

一、数据库的创建与使用 1.创建数据库

(1)使用命令创建数据库的语法格式

CREATE { DATABASE | SCHEMA}[IF NOT EXISTS] db_name

[create_specification]...

其中,create_specification的格式为:

[DEFAULT] CHARACTER SET [=] charset_name | [DEFAULT] COLLATE [=] collation_name (2)使用命令创建数据库的语法说明 ①语句中“[ ]”内为可选项。

②语句中“|”用于分隔花括号中的选择项,表示可任选其中一项来与花括号外的语法成分共同组成SQL语句命令,即选项彼此间是“或”的关系。

③db_name

数据库名。在文件系统中,MySQL的数据存储区将以目录方式表示MySQL数据库。因此,命令中的数据库名字必须符合操作系统文件夹命名规则,而在MySQL中是不区分大小写的。

④IF NOT EXISTS

在创建数据库前进行判断,只有该数据库目前尚不存在时才执行CREATE DATABASE操作。 ⑤DEFAULT:指定默认值。

⑥CHARACTER SET:用于指定数据库字符集(Charset)。charset_name为字符集名称。 ⑦COLLATE:用于指定字符集的校对规则。collation_name为校对规则的名称。 (3)创建数据库的注意事项

①MySQL不允许在同一系统中两个数据库使用相同的名字。

②用户在使用CREATE DATABASE或CREATE SCHEMA命令创建数据库时,必须获得相应的权限。

2.选择数据库

(1)USE命令的作用

在MySQL中,USE命令可以用来从一个数据库“跳转”到另一个数据库。 在用CREATE DATABASE语句创建了数据库之后,该数据库不会自动成为当前数据库,需要用这条USE语句来指定当前数据库。

(2)USE命令的语法格式

USE db_name;

(3)USE命令的使用说明

①创建了一个数据库之后,可使用USE命令指定其为当前数据库。

②当前数据库会在当前工作会话关闭(断开与该数据库的连接)或再次使用USE命令指定数据库时,结束工作状态。

③只有使用USE命令指定某个数据库为当前数据库之后,才能对该数据库及其存储的数据对象执行各种后续操作。

3.修改数据库

(1)修改已创建的数据库的相关参数的语法格式

ALTER {DATABASE | SCHEMA } [db_name]

alter_specification ...

ALTER {DATABASE | SCHEMA } db_name

UPGRADE DATA DIRECTORY NAME

其中,alter_specification的格式为:

[DEFAULT] CHARACTER SET [=] charset_name | [DEFAULT] COLLATE [=] collation_name

(2)修改已创建的数据库的相关参数的使用说明

a.ALTER DATABASE或ALTER SCHEMA命令可用于更改数据库的全局特性,这些特性存储在数据库目录中的db.opt文件中。

b.使用ALTER DATABASE或ALTER SCHEMA命令时,用户必须具有对数据库进行修改的权限。 c.语句的使用中数据库的名称可以被省略,表示修改当前(默认)数据库。

d.选项CHARACTER SET和COLLATE与创建数据库语句中的选项相同,功能不再重复说明。但需要指出的是,当修改数据库默认字符集或校对规则时,必须删除并重新创建使用数据库默认参数的存储过程,方能使新的数据库默认特性得到使用。

e.在MySQL 5.1之后的版本中,ALTER DATABASE或ALTER SCHEMA命令增加了UPGRADE DATA DIRECTORY NAME从句,用于使用MySQL 5.1版本的字符编码规则更新5.1之前版本数据库的目录名称,以提高文件系统的安全性。

4.删除数据库

(1)DROP DATABASE或DROP SCHEMA的语法格式 DROP {DATABASE | SCHEMA}[IF EXISTS] db_name (2)DROP DATABASE或DROP SCHEMA的使用说明 ①db_name:指定要删除的数据库名。

②DROP DATABASE或DROP SCHEMA命令会删除指定的整个数据库,该数据库中的所有表(包括其中的数据)也将永久删除,因而使用该语句时尤其要小心,以免错误删除。

③对该命令的使用,需要用户具有相应的权限。

④当某个数据库被删除之后,该数据库上的用户权限是不会自动被删除的。

⑤可选项IF EXISTS子句可以避免删除不存在的数据库时出现的MySQL错误信息。 (3)删除数据库时的注意事项

MySQL安装后,系统会自动地创建名为information_schema和mysql两个系统数据库,MySQL把与数据库相关的信息存储在这两个系统数据库中,如果删除了这些数据库,MySQL将不能正常工作。

5.查看数据库

(1)SHOW DATABASES或SHOW SCHEMAS的语法格式

SHOW {DATABASES | SCHEMAS}

[LIKE 'pattern'|WHERE expr]

(2)SHOW DATABASES或SHOW SCHEMAS的使用说明 ①可选项LIKE从句用于匹配指定的数据库名称。

②可选项WHERE从句用于指定数据库名称查询范围的条件。

③使用SHOW DATABASES或SHOW SCHEMAS命令,只会列出当前用户权限范围内所能查看到的所有数据库名称。

另外,在MySQL中还有SHOW CHARACTER SET、SHOW COLLATION等命令,分别可用于查看数据库的字符集和校对规则。

二、创建和操纵表 1.创建表

(1)CREATE TABLE的语法格式

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tb1_name

[(creat_definition),...] [table_options] [partition_options] 或:

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name

[(create_definition,...)] [table_options] [partition_options] select_statement

①create_definition的格式为:

②column_definition的格式为:

③data_type的格式为:

④index_col_name的格式为: col_name[(length)][ASC|DESC] ⑤index_type的格式为: USING {BTREE|HASH} ⑥index_option的格式为: KEY_BLOCK_SIZE [=] value | index_type

| WITH PARSER parser_name | COMMENT 'string'

⑦reference_definition的格式为:

REFERENCES tbl_name(index_col_name,...)

[MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETE reference_option] [ON UPDATE reference_option] ⑧reference_option的格式为:

RESTRCT | CASCADE | SET NULL | NO ACTION ⑨table_options的格式为: table_option[[,]table_option]... ⑩table_option的格式为:

⑪partition_options的格式为: PARTITION BY

|[LINEAR] HASH(expr)

|[LINEAR]KEY(column_list)

|RANGE{(expr)|COLUMNS(column_list)} |LIST{(expr)|COLUMNS(column_list)} [PARTITION num] [SUBPATITION BY

{[LINEAR] HASH(expr)|[LINEAR]KEY(column_list)} [SUBPARTITIONS num] ]

[(partition_definition[,partition_definition]...)] ⑫partition_definition的格式为:

⑬subpartition_definition的格式为:

⑭select_statement的格式为:

[IGNORE | REPLACE][AS] SELECT...(Some valid select statement)

CREATE TABLE命令的语法内容较多,主要由表创建定义(create_definition)、表选项(table_options)和分区选项(partition_options)所组成。这里首先描述一个简单的新建表的例子,然后重点介绍CREATE TABLE命令中一些主要的语法知识点。

【例3.1】在一个已有数据库mysql_test中新建一个包含客户姓名、性别、地址、联系方式等内容的客户基本信息表,要求将客户的cust_id号指定为该表的主键,并使用InnoDB引擎存储表数据。

在当前用户的MySQL命令行客户端输入如下SQL语句即可:

注:本书诸多例子将基于这里创建的表customers。 (2)CREATE TABLE语句的主要语法及使用说明 ①表创建基础

a.在CREATE TABLE命令中必须在语句中给出下列信息: 第一,table_name

指定要创建表的表名,其在关键字CREATE TABLE之后给出,且必须符合标志符的命名规则。表的创建需要首先选定当前数据库,若表名称被指定为db_name.tbl_name的格式,则可在特定的数据库中创建表,而不论是否有当前数据库,都可以通过这种方式来创建表如果使用加引号的识别名方式,则对数据库和表名称都应分别加引号。创建者必须拥有表的CREATE权限。

第二,create_definition

表创建定义(create_definition),其由表列的名字(col_name)、表列的定义(column_definition),以及可能的一个空值声明、一个完整性约束或表索引项等组成。其中,表索引项主要定义表的索引、主键、外键等。实际的表定义(包含所有表列)均被括在圆括号中,各列彼此间用逗号分隔,每列的定义以列名(在该表中必须是唯一的)开始,后跟列的数据类型以及可选参数。

第三,select_statement

SELECT语句,其出现在CREATE TABLE语句的另外一种使用语法中即允许在CREATE TABLE语句的末尾添加一个SELECT语句,用于在一个数据库查询操作的基础上创建新表。

b.在CREATE TABLE语句中可以选择包含的关键字或可选项: 第一,TEMPORARY:为可选项

表示用CREATE命令新建的表为临时表,而不加读关键字创建的表则通常称为持久表。在数据库中持久表一旦创建将一直存在,多个用户或者多个应用程序可以同时使用持久表。有时用户也需要临时存放数据,比如临时存储复杂的SELECT语句的结果,此后可能需要重复地使用这个结果,但这个结果又不希望永久保存,这时就可以使用临时表。用户可以像操作持久表一样操作临时表,只不过临时表的生命周期较短而且只能对创建它的用户可见,当断开与该数据库的连接时,MySQL会自动删除它们,这意味表两个不同的连接可以使用相同的临时表名称,同时两个临时表不会互相冲突,也不与原有的同名的非临时表冲突。

第二,IF NOT EXISTS子句

该子句为可选项,主要用于在建表之前加上一个判断,只有该表名目前尚不存在时才执行CREATE TABLE操作,由此避免出现表名已经存在无法再新建的错误,对于系统中已有表的结构与CREATE TABLE语句的表定义中所描述的表的结构是否相同,不做检查。如果用户在CREATE TABLE...SELECT语句中使用IF NOT EXISTS,则不论该表是否已存在,由SELECT从句部分所选择的记录都会被插入。

第三,table_option:表选项

用于描述表的存储特性。大多数选项涉及的是表数据如何存储及存储在何处。多数情况下,用户不必指定表选项。

第四,partition_options:分区选项 ②数据类型

数据类型(data_type)是指系统中所允许的数据的类型。数据库中每个列都应有适当的数据类型,用于限制或允许该列中存储的数据。数据类型可帮助正确地排序数据,并在优化磁盘使用方面起着重要的作用。因此,在创建表时必须为每个表列指定正确的数据类型及可能的数据长度。

a.数值类型

BIT[(M)]:位字段类型。M表示每个值的位数,范围为1~64。如果M被省略,默认为1。 TINYINT[(M)][UNSIGNED][ZEROFILL]:很小的整数。带符号的范围是-128~127,无符号的范围是0~255。 BOOL,BOOLEAN:是TINYINT(1)的同义词。zero值被视为假,非zero值视为真。

SMALLINT [(M)][UNSIGNED][ZEROFILL]:小的整数。带符号的范围是-32768~32767,无符号的范围是0~65535。

MEDIUMINT[(M)][UNSIGNED][ZEROFILL]:中等大小的整数。带符号的范围是-8388608~8388607,无符号的范围是0~16777215。

INT[(M)][UNSIGNED][ZEROFILL]:普通大小的整数。带符号的范围是-2147483648~2147483647,无符号的范围是0~4294967295。

INTEGE[(M)][UNSIGNED][ZEROFILL]:INT的同义。

BIGINT[(M)][UNSIGNED][ZEROFILL]:大整数。带符号的范围是

-9223372036854775808~9223372036854775807,无符号的范围是0~18446744073709551615。 DOUBLE[(M,D)][UNSIGNED][ZEROFILL]

普通大小(双精度)浮点数。允许的值是-1.7976931348623157E+308~ 2.2250738585072014E-308、0和2.225073858507 2014E-308~1.7976931348623157E+308。这些是理论限制,基于IEEE标准。实际的范围根据硬件或操作系统的不同可能稍微小些。M是小数总位数,D是小数点后面的位数。如果M和D被省略,根据硬件允许的限制来保存值。双精度浮点数精确到大约15位小数位。如果指定UNSIGNED,不允许负值。

DECIMAL[(M,D])][UNSIGNED][ZEROFILL] 压缩的“严格”定点数。M是小数位数(精度)的总数,D是小数点(标度)后面的位数。小数点和(负数)的“-”符号不包括在M中。如果D是0,则值没有小数点或分数部分。DECIMAL整数最大位数(M)为65。支持的十进制数的最大位数(D)是30。如果D被省略,默认是0。如果M被省略,默认是10。如果指定UNSIGNED,不允许负值。

DEC:DECIMAL的同义词。 b.日期和时间类型 DATE:日期型

支持的范围为‘1000-01-01’到‘9999-12-31’。MySQL以‘YYYY-MM-DD’格式显示DATE值,但允许使用字符串或数字为DATE列分配值。

DATETIME:日期和时间的组合

支持的范围是‘1000-01-0100:00:00’到‘9999-12-3123:59:59’。MySQL以‘YYYY-MM-DD HH:MM:SS’格式显示DATETIME值,但允许使用字符串或数字为DATETIME列分配值。

TIMESTAMP[(M)]:时间戳

范围是‘1970-01-01 00:00:00’到2037年。TIMESTAMP列用于INSERT或UPDATE操作时记录日期和时间。如果不分配一个值,表中的第一个TIMESTAMP列自动设置为最近操作的日期和时间,也可以通过分配一个NULL值,将TIMESTAMP列设置为当前的日期和时间。TIMESTAMP值返回后显示为‘YYYY-MM-DD HH:MM:SS’格式的字符串,显示宽度固定为19个字符。如果想要获得数字值,应在TIMESTAMP列添加+0。

TIME:时间型。范围是‘-838:59:59’到‘838:59:59’。MySQL以‘HH:MM:SS’格式显示TIME值,但允许使用字符串或数字为TIME列分配值。

YEAR[(214)]:两位或四位格式的年。默认是四位格式。在四位格式中,允许的值是1901~2155和0000。在两位格式中,允许的值是70~69,表示从1970年到2069年。MySQL以 YYYY格式显示YEAR值,但允许使用字符串或数字为YEAR列分配值。

c.字符串类型

CHAR[(M)]或CHARACTER[(M)]

固定长度的字符数据类型,用于保存以文本格式存储的信息。当保存时在右侧填充空格以达到指定的长度。M表示列长度,其范围是0~255个字符。VARCHAR[(M)]:可变长的字符数据类型,用于保存以文本格式存储的信息。M表示最大列长度,其范围是0~65535。

TINYBLOB:最大长度为255(28-1)字节的BLOB列。 TINYTEXT:最大长度为255(28-1)字符的TEXT列。

BLOB[(M)]:最大长度为65535(216-1)字节的BLOB列。 TEXT[(M)]:最大长度为65535(216-1)字符的TEXT列。 ENUM(‘value1’,‘value2’,…):枚举类型。只能有一个值的字符串被选出。ENUM列最多可以有65535个截然不同的值。ENUM值在内部用整数表示。

在字符数据类型和数值数据类型之后,MySQL允许指定一个数据类型选项用来改变数据类型的属性和功能。具体而言,对于字符数据类型,MySQL支持两种数据类型选项,即CHARACTER SET和COLLATE,如果要区分字符的大小写情况,可以在字符类型后面加上BINGARY;对于除BIT以外的数值数据类型,MySQL允许添加一个或多个数据类型选项,UNSIGNED指定不允许负值,ZEROFILL指定当插入的值长度小于字段设定的长度时,剩余部分用0填补。

③AUTO_INCREMENT的使用

在MYSQL中,关键字AUTO_INCREMENT用于为列设置自增属性,只有整型列才能设置此属性。当插入NULL值或数字0到一个AUT0_INCREMENT列中时,该列的值会被设置为置为value+1,这里的value是此前表中该列的最大值。AUTO_INCREMENT顺序从数字1开始。每个表只能有一个AUTO_INCREMENT列,并且它必须被索引。

当一个表列被指定为AUTO_INCREMENT后,其值是可以被覆盖的,即可以简单地在表数据插入语句(INSERT语句)中为该列指定一个值,只要该值是唯一的(至今尚未使用过),那么这个值将被用来替代系统自动生成的值,并且后续的增量将基于该手工插入的值。

④指定默认值

默认值是指在向表插入数据时,如果没有明确给出某个表列所对应的值,则此时DBMS允许为此表列指定的一个值。默认值是用CREATE TABLE语句的列定义中DEFAULT关键字来指定的。只支持常量作为默认值。

BLOB和TEXT类型的列不能被赋予默认值。如果没有为列指定默认值,MySQL会自动地为其分配一个。如果列可以取NULL值,则默认值就是NULL,而如果列被声明为NOT NULL,那么默认值就取决予列的类型:

a.没有声明AUTOJNCREMENT属性的数字类型,默认值是0;对于一个AUTO_INCREMENT列,默认值是在顺序的下一个值。

b.除TIMESTAMP以外的日期和时间类型,默认值是该类型适当的“零”值;对于表中第一个TIMESTAMP列,默认值是当前的日期和时间。

c.对于除ENUM的字符串类型,默认值是空字符串;对于ENUM,默认值是第一个枚举值。 ⑤NULL值

a.NULL值就是没有值或缺值。允许NULL的列也允许在插入行时不给出该列的值。不允许 NULL值的列则不接受该列没有值的行。

b.在MySQL中,每个表列要么是NULL列,要么是NOT NULL列,这种状态在创建时由表的定义所规定。NULL为默认设置,如果不指定NOT NULL,则认为指定的是NULL。

c.不要将NULL值与空串相混淆,NULL值是没有值,它不是空串。如果指定‘’,这在NOT NULL列中是允许的,因为空串是一个有效的值,它不是无值,所以NULL值用关键字NULL而不是空串指定。

⑥主键

主键是通过PRIMARY KEY关键字来指定的。主键值必须唯一,即表中的每个行必须具有唯一的主键值,而且主键一定要为NOT NULL。如果主键使用单个列,则它的值必须唯一;如果使用多个列,则这些列的组合值也必须唯一。

⑦引擎类型

MySQL支持多种类型的数据库引擎,可分别根据各引擎的功能和特性,为不同的数据库处理任务提供各自不同的适应性和灵活性。

可以通过SHOW ENGINES语句来显示系统中可用的数据库引擎和默认引擎,示例如下:

其中,InnoDB是系统的默认引擎,其支持可靠的事务处理。在CREATE TABLE语句中使用ENGINE选项为新建表指定数据库引擎。

2.更新表

(1)更新表的作用

为实现数据库中表规范化设计的目的,有时需要对之前已经创建的表做进一步的结构修改与调整。在MySQL中,可以使用ALTER TABLE语句来更改原有表的结构。使用ALTER TABLE语句可以增加或删减列、创建或取消索引、更改原有列的数据类型、重新命名列或表,还可以更改表的评注和表的引擎类型等。

(2)ALTER TABLE的语法格式

ALTER [ONLINE | OFFLINE] [IGNORE] TABLE tbl_name

[alter_specification][,alter_specification]...] [partition_options]

①alter_specification的格式为:

②index_col_name的格式为:

col_name[(length)][ASC | DESC] ③index_type的格式为: USING { BTREE | HASH} ④index_option的格式为:

KEY_BLOCK_SIZE[=]value | index_type

|WITH PARSER parser_name | COMMENT ‘string’

⑤table_options的格式为: table_option [[,] table_option]... (see CREATE TABLE options) ⑥partition_options的格式为: (see CREATE TABLE options) (3)ALTER TABLE的语法说明 ①tbl_name:表名。

②col_name:指定的列名。 ③IGNORE

它是MySQL相对于标准SQL的扩展。若在修改后的新表中存在重复关键字,如果没有指定IGNORE,当重复关键字错误发生时操作失败;如果指定了IGNORE,则对于有重复关键字的行只使用第一行,其他有冲突的行被删除。

④column_definition:定义列的数据类型和属性,具体内容在CREATE TABLE的语法中已做说明。

⑤index_col_name:索引列名。 ⑥index_type:索引的类型。

⑦index_option:索引选项,相关内容将在有关索引的章节中介绍。 ⑧table_options:表选项,与CREATE TABLE语句中的语法相同。

⑨partition_options:分区选项,与CREATE TABLE语句中的语法相同。 (4)ALTER TABLE语句中常用的子句 ①ADD[COLUMN]子句

ADD[COLUMN]子句用于向表中增加新列,可同时增加多个列。

类似地,可以通过ADD PRIMARY KEY子句、ADD FOREIGN KEY子句、ADD INDEX子句为原表添加一个主键、外键和索引等。其中,要求首先删除原表中已有的主键。

②CHANGE[COLUMN]子句

CHANGE[COLUMN]子句可同时修改表中指定列的名称和数据类型。ALTER TABLE语句中可以同时放人多个CHANGE[COLUMN]子句,只需彼此间用逗号分隔。

【例3.2】将数据库mysql_test中表customers的cust_sex列重命名为sex,且将其数据类型更改为char(1),允许其为NULL,默认值为‘M’。

在MySQL的命令行客户端输入如下SQL语句即可:

注意:如果将列原有的数据类型更换为另外一种类型,可能会丢失该列原有的数据;如果试图改变的数据类型与原有数据类型不兼容,SQL命令则不会执行,且系统会提示错误,而在类型兼容的情况下,该列的数据可能会被截断。

③ALTER[COLUMN]

ALTER[COLUMN]子句可以修改或删除表中指定列的默认值。

【例3.3】将数据库mysql_test中表customers的cust_city列的默认值修改为‘Beijing’。 在MySQL的命令行客户端输入如下SQL语句即可:

④MODIFY[COLUMN]子句

与CHANGE[COLUMN]子句有所不同,MODIFY[COLUMN]子句只会修改指定列的数据类型,而不会干涉它的列名。另外,MODIFY[COLUMN]子句还可以通过FIRST或AFTER关键字修改指定列在表中的位置。

【例3.4】将数据库mysql_test中表customers的cust_name列的数据类型由之前的char(50)更改为char(20),并将此列设置成表test.customers的第一列。

在MySQL的命令行客户端输入如下SQL语句即可:

⑤DROP [COLUMN]子句

一旦删除列,原本存储在该列中的一切内容都会跟着被删除,所以在使用DROP[COLUMN]子句时必须格外小心。

【例3.5】删除数据库mysql_test中表customers的cust_contact列。 在MySQL的命令行客户端输入如下SQL语句即可:

类似地,也可分别通过DROP PRIMARY KEY子句、DROP FOREIGN KEY子句、DROP INDEX子句删除原表的主键、外键和索引等。

⑥RENAME[TO]子句

在ALTER TABLE命令中,使用RENAME[To]子句可以为表重新赋予一个表名。

【例3.6】使用RENAME[TO]子句,重命名数据库mysql_test中表customers的表名为backup_customers。 在MySQL的命令行客户端输入如下SQL语句即可:

3.重命名表

除了使用ALTER TABLE命令,还可以直接用RENAME TABLE语句来更改表的名字,其语法格式是: RENAME TABLE tbl_name TO new_tbl_name [,tbl_name2 TO new_tbl_name2]... 语法及使用说明如下:

(1)tbl_name:修改之前的表名。

(2)new_tbl_name:修改之后的表名。

(3)RENAME TABLE可以同时重命名多个表。

4.复制表

(1)复制表的含义

使用CREATE TABLE命令创建表的语句,存在着另外一种语法结构,其实质是在旧表的基础上创建一份该表的拷贝,也就是复制表。

(2)复制表语句的语法格式

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name { LIKE old_tbl_name | (LIKE old_tbl_name)} (3)复制表语句的使用说明

①该语句中使用关键字LIKE可以创建一个与old_table_name表相同结构的新表,其中列名、数据类型、空指定和索引都将复制,但是表的内容不会复制,因此创建的新表是一个空表。

②若在复制表结构的同时,试图复制表的内容,可以通过使用AS(select_statement)子句来完成。使用关键字AS可以复制表的内容,但索引和完整性约束不会被复制,select_statement表示一个SQL语句表达式。

5.删除表

(1)DROP TABLE语句的语法格式

DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [,tbl_name]... [RESTRICT | CASCADE]

(2)DROP TABLE语句的语法及使用说明如下:

①tbl_name:要被删除的表名。DROP TABLE命令可以同时删除多个表,其中用户必须拥有该命令的权限。 ②IF EXISTS:该子句为可选项,用于避免要删除的表不存在时出现错误信息。表名必须是在数据库中存在的,否则语句执行时系统会提示错误。

③表被删除时,其中存储的数据和分区信息均会被删除,所以使用该语句须格外小心。当表被删除时,用户在该表上的权限并不会自动被删除。

6.查看表

在MySQL中,查看表包括显示表的名称和显示表的结构。 (1)显示表的名称

可以使用SHOW TABLES语句来显示指定数据库中存放的所有表名,其语法格式是: SHOW [FULL] TABLES [{FROM | IN} db_name]

[LIKE ‘pattern’| WHERE expr] (2)显示表的结构

可以使用SHOW COLUMNS语句来显示指定数据表的结构,其语法格式是: SHOW [FULL] COLUMNS {FROM | IN} tbl_name [{FROM | IN} db_name]

[LIKE‘patten’| WHERE expr]

或者使用DESCRIBE语句来完成,其语法格式: {DESCRIBE | DESC } tbl_name [col_name | wild]

说明:MySQL支持用DESCRIBE作为SHOW COLUMNS FROM的一种快捷方式。 【例3.7】显示数据库mysql_test中表customers的结构。 在MySQL的命令行客户端输入如下SQL语句即可:

7.对表结构的进一步说明

表的结构包含了表的名字、列名及对应的数据类型和长度、是否可为空值、默认值的指定、是否要使用以及何时使用约束、默认设置或规则及所需索引的情况、哪些列指定为主键、哪些列指定为外键等。这些表结构的组成要素都需要在创建表之前确定下来。

(1)关于空值(NULL)

空值(NULL)通常用于表示未知、不可用或将在以后添加的数据,不可将它与数字0或字符类型的空字符混为一谈。在向表中插入记录时,若一个列允许为空值,则可以不为该列指定具体值;而如果这个列不允许为空值,则必须指定该列的具体值,否则数据的插入操作会出错。表的关键字是不允许为空值的。任意两个空值不相等。

(2)关于列的标志(IDENTITY)属性

①任何表都可以创建一个包含系统所生成序号值的标志列。该序号值唯一标志表中的一列,且可以作为键值。 ②每个表只能有一个列设置为标志属性,并且该列只能是DECIMAL、INT、NUMERIC、SMALLINT、BIGINT或TINYINT数据类型。

③定义标志属性时,可指定其种子值(即起始值)、增量值,二者的默认值均为数字1。系统可自动更新标志列值,但标志列不允许为空值(NULL)。

(3)关于列类型的隐含改变

在以下情形,系统会隐含地改变在CREATE TABLE语句或ALTER TABLE语句中所指定的列类型: ①长度小于4的VARCHAR类型会被改变为CHAR类型。 ②由于只要在一个表中存在着任何可变长度的列,都会使表中整个数据列成为变长的,因此当一张表包含有任何变长的列时,该表中所有大于3个字符的其他CHAR类型列会被改变为VARCHAR类型列,而这不影响用户如何使用这些列。在MySQL中,这种改变的好处是可以节省空间,并且使表操作更加快捷。

③由于timestamp类型列值的显示尺寸必须是偶数且在2~14的范围内,因此若没有为其指定在这个范围之内,尺寸会被强制设为14,而1~13范围内的奇数值尺寸则会被强制设为下一个更大的偶数。

④由于不能在一个timestamp类型列中存储空值NULL,因此当将该列的值设为NULL时, MySQL会将它默认为当前的日期和时间。

第4章 表数据的基本操作

一、插入表数据 1.插入表数据介绍

在操作前使用USE语句将表所在数据库指定为当前数据库。

在MySQL中,可以使用INSERT或REPLACE语句向数据库中一个已有的表插入一行或多行元组数据。

2.使用INSERT语句插入表数据 (1)INSERT语句的语法格式

·

(2)INSERT语句的使用说明 ①tbl_name:指定被操作的表名。

②col_name:指定需要插入数据的列名。如果要向表中所有列插入数据,则全部列名均可省略。不必指定所有列名的语法非常简单,在表的结构有可能发生改变时就会显得特别不安全,所以应尽量避免使用这种语法,总是使用明确指定列名的列表。

如果只是向表的部分列插入数据,则需要明确指定这些列的列名,而对于那些没有被指定的列,它们的值可根据列的默认值或相关属性来确定,通常MySQL是按照下列原则进行处理的:

a.对于具有标志(IDENTITY)属性的列,系统会自动生成序号值来唯一标志该列。

b.具有默认值的列,其值可通过在INSERT语句中指定关键字DEFAULT将其设为默认值。

c.没有默认值的列,若允许为空值,则其值可通过在INSERT语句中指定关键字NULL将其设为空值;若不允许为空值,则INSERT语句执行出错。

d.对于类型为TIMESTAMP的列,系统会为其自动赋值。

e.由于AUTO_INCREMENT属性裂的值是在表中其他列被赋值后生成的.所以在对表中其他列做任何赋值操作(如INSERT语句)时该AUTO_INCREMENT属性列的引用只会返回数字0。

③VALUES或VALUE子句:该子句跟在关键字VALUES或VALUE之后,其包含各列需要插入的数据清单。数据清单中数据的顺序必须与列的顺序相对应。

VALUES子句中的值可是:

a.expr:可以是一个常量、变量或一个表达式,也可以是空值NULL,其值的数据类型要与列的数据类型一致。如果表达式的类型与列值不匹配,这样做会造成类型转化或插入语句出错。当列值为字符型时,需要用单引号括起。

b.DEFAULT:用于制定此列值为该列的默认值。前提是该列之前已经明确指定了默认值,否则插入语句会出错。

④LOW_PRIORITY

此关键字是INSERT、DELETE和UPDATE都支持的一种可选修饰符,通常在多用户访问数据库的情形中,用于指示MySQL降低INSERT、DELETE和UPDATE操作执行的优先级。

⑤DELAYED

此关键字是INSERT语句支持的一种可选修饰符。若使用此关键字,则MySQL服务器会把待插入的行数

据放至一个缓冲器中,直至待插入数据的表空闲时,才真正在表中插入数据行。

⑥HIGH_PRIORITY

此关键字是INSERT和SELECT语句都支持的一种可选修饰符,其作用与关键字LOW_PRIORITY类似,主要用于指示MySQL使INSERT和SELECT操作优先执行。

⑦IGNORE:此关键字为可选项。若指定此关键字,在执行INSERT语句时,所出现的错误都会被当做警告处理。

⑧ON DUPLICATE KEY UPDATE子句:该子句为可选项。若选用此项,则在向表中插入行时,如果导致UNIQUE KEY或PRIMARY KEY出现重复值,系统会根据UPDATE后的语句修改表中原有的行数据。另外,使用此选项时DELAYED会被忽略。

⑨SET子句

SET子句对应的是INSERT…SET语句。这个语句用于直接给表中的某(些)列指定对应的列值,即要插入数据的列名在SET子句中指定,col_name为指定的列名,等号后面为指定数据,而对于未指定的列,列值则会指定为该列的默认值。

⑩SELECT子句

SELECT子句对应的是INSERT…SELECT语句。这个语句用于快速地从一个或多个表中取出数据,并将这些数据作为行数据插入到另一个表中。SELECT子句返回的是一个查询到的结果集,INSERT语句将这个结果集插入到指定表中,结果集中每行数据的字段数、字段的数据类型必须与被操作的表完全一致。

由INSERT语句的三种语法形式可以看出,使用INSERT…VALUES语句可以向表中插入一行数据,也可以插入多行数据;使用INSERT…SET语句可以指定插入行中每列的值,也可只指定部分列的值。另外,还可以使用INSERT…SELECT语句向表中插入其他表的数据。

为了编写更为安全的INSERT…VALUES语句,通常需要在表名后的括号中明确地给出列名清单。在插入行时,MySQL将用VALUES列表中的相应值填入到列表中的对应项。由于提供了列名,VALUES必须以其指定的次序匹配指定的列名,不一定按各个列出现在实际表中的次序,其优点是即使表的结构发生了改变,这条INSERT语句仍能正确执行。

(3)INSERT语句的实例

【例4.1】使用INSERT…VALUES语句向数据库mysql_test的表customers中插入一行数据,要求该数据目前只用明确给出cust_name列和cast_address列的信息,即分别为“李四”和“武汉市”,而cast_id列的值由系统自动生成,cast_sex列选用表中默认值,另外cast_contact列的值暂不确定,可不用指定。

在MySQL的命令行客户端输入如下SQL语句即可: mysql>INSERT INTO mysql_test.customers

->VALUES(0,’李四’,DEFAULT,’武汉市’,NULL); Query OK,1 row affected(0.11 sec)

【例4.2】假设数据库mysql_test的表customers有一个拷贝备份表customers_copy,现使用INSERT…SELECT语句将表customers_copy中的数据合并到表customers。

在MySQL的命令行客户端输入如下SQL语句即可实现: mysql>INSERT INTO mysql_test.customers

->(cust_id,cust_name,cust_sex,cust_address,cust_contact)

->SELECT cust_id,cust_flame,cust_sex,cust_address,cust_contact ->FROM mysql_test.customers_copy; Query OK,1 row affected(0.09 Sec) 例4.2说明如下:

①INSERT语句与SELECT语句中可使用相同的列名,也可以使用不相同的列名,即不要求列名一定匹配。MySQL不关心SELECT语句返回的列名,它使用的是列的位置,因此SELECT语句中的第一列(无论其为何列名)将用来填充待插入表列中指定的第一个列,第二列将用来填充待插入表列中指定的第二个列,如此顺序依次填充。

②对于oust_id这类主键,当出现主键值重复时,后续的INSERT操作会出错。此时可在

INSERT…SELECT语句中省略这个列,让该列的值由MySQL在导入数据的过程中自动产生新值。

③SELECT语句用于从一个表中检索出要插入的值,而非列出这些值。SELECT语句中列出的每个列对应于待插入表的表名后所跟的列表中的每个列。如果SELECT语句检索出的数据行数为0,则表示没有行会被插入到待插入表中去,此时的操作是合法的,不会产生错误。

④INSERT…SELECT语句中的SELECT子句可包含WHERE从句来过滤待插入的数据。

3.使用REPLACE语句插入表数据 (1)REPLACE语句的介绍

如果一个待插入的表中存在有PRIMARY KEY或UNIQUE KEY,而待插入的数据行中包含有与待插入表的已有数据行中相同的PRIMARY KEY或UNIQUE KEY列值,那么INSERT语句将无法插入此行。此时若需要插入这行数据,则可使用REPLACE语句来实现。使用REPLACE语句可以在插入数据之前将表中与待插入的新记录相冲突的旧记录删除,从而保证新记录能够正常插入。

(2)REPLACE语句的语法格式

(3)REPLACE语句的实例

【例4.3】使用INSERT语句成功执行例4.2后,数据库mysql_test的表customers中会存在这样一条数据记录:(901,张三,F,北京市,朝阳区),其中该表中cust_id列是主键。现向该表中再次插入一行数据:(901,王五,M,广州市,越秀区)。

①在MySQL的命令行客户端输入如下SQL语句: mysql>INSERT INTO mysql..test.ctlstomers

->(cast_id,cust_name,cust_sex,cust_address.cust_contact) ->VALUES(901,'王五', 'M', '广州市', '越秀区'); ERROR 1062(23000):Duplicate entry‘901’for key‘PRIMARY’

②根据系统返回的结果可以看出,该语句不能成功执行,其原因在于待插入的新记录中的主键值与表中原有一条记录的主键值相同,且均为901。此时可以使用REPLACE语句,在MySQL的命令行客户端重新输入如下SQL语句:

mysql>REPLACE INTO mysql_test.customers

->(oust_id,cust_name,cust_sex,cust_address,oust_contact) ->VALUES(901,'王五', 'M', '广州市', '越秀区'); Query OK,2 rows affected(0.34 sec)

这个语句成功执行,表customers中原有的一条记录(901,张三,F,北京市,朝阳区)被新记录(901,王五,M,广州市,越秀区)替换。

二、删除表数据

1.使用DELETE语句从单个表中删除数据

(1)DELETE语句从单个表中删除数据的语法格式

(2)DELETE语句从单个表中删除数据的语法说明

QUICK:此关键字是DELETE语句支持的一种可选修饰符,用于加快部分种类的删除操作的速度。 tbl_name:指定要删除数据的表名。

WHERE子句:该子句为可选项。若选用此项,表示为删除操作限定删除条件,从而删除特定的行;若省略WHERE子句,则表示删除该表中的所有行。

ORDER BY子句:该子句为可选项。若选用此项,表示各行将按照子句中指定的顺序进行删除。 LIMIT子句:该子句为可选项,用于告知服务器在控制命令被返回到客户端前被删除的行的最大值。

2.使用DELETE语句从多个表中删除数据

(1)DELETE语句同时删除多个表中的数据行的语法格式

(2)DELETE语句同时删除多个表中的数据行的语法说明

①对于第一种语法,只删除位于FROM子句之前的表中对应的行。

②对于第二种语法,只删除位于FROM子句之中(在USING子句之前)的表中对应的行。 ③table_references:指定多个表的联合。

(3)DELETE语句从单个表中删除数据的实例

【例4.4】假设数据库中有三个表tbl1、tbl2和tbl3,它们均含有id列,现要求删除表tbl1中id值等于表tbl2的id值的所有行,以及表tbl2中id值等于表tbl3的id值的所有行。

在MySQL的命令行客户端输入如下SQL语句即可实现: mysql>DELETEtbl1,tbl2 FROM tbl1,tbl2,tbl3 ->WHERE tbl1.id=tbl2.id AND tbl2.id=tbl3.id;

或者,在MySQL的命令行客户端输入下面SQL语句也可实现:

mysql>DELETE FROMtbl1,tbl2 USING tbl1,tbl2,tbl3 ->WHERE tab1.id=tab2.id AND tab2.id=tab3.id;

3.使用TRUNCATE删除表数据 (1)TRUNCATE语句的介绍

如若要从表中删除所有的行,不必使用DELETE语句,可以使用TRUNCATE语句直接删除指定表中的所有数据,而且执行速度会比DELETE操作更快。这是因为,TRUNCATE操作的实际过程是先删除原来的表,并再重新创建一个表,而不是逐行删除表中的数据。TRUNCATE语句又称清除表数据语句。

(2)TRUNCATE语句的语法格式 TRUNCATE [TABLE] tbl_name

其中,tbl_name用于指定要删除数据的表名。 (3)TRUNCATE语句的使用时的注意事项

①由于TRUNCATE语句在功能上与不带WHERE子句的DELETE语句相同,它将删除表中的所有数据,且无法恢复,因此使用时必须十分小心。

②使用TRUNCATE语句后,表中的AUTO_INCREMENT计数器将被重新设置为该列的初始值。 ③对于参与了索引和视图的表,不能使用TRUNCATE语句来删除数据,而应使用DELETE语句。

④TRUNCATE操作比DELETE操作使用的系统和事务日志资源少。DELETE语句每次删除一行,会在事务日志中为所删除的每行记录一项,而TRUNCATE语句是通过释放存储表数据所用的数据页来删除数据的,因而只在事务日志中记录页的释放。

三、修改表数据

1.使用UPDATE语句修改单个表

(1)UPDATE语句修改单个表的语法格式

(2)UPDATE语句修改单个表的语法说明 ①LOW_PRIORITY

此关键字UPDATE语句的可选修饰符。它在多用户访问数据库的情形下可用于延迟UPDATE操作,直到没有别的用户再从表中读取数据为止。这个过程只对仅使用表级锁的存储引擎,例如MyISAM,MEMORY和MERGE。

②IGNORE

此关键字是UPDATE语句的可选项。如果用UPDATE语句更新表中多行数据,并且在更新这些行中的一行或多行时出现了一个错误,则整个UPDATE操作会被取消,错误发生前更新的所有行将被恢复到它们原来的值。因此,为了即使发生错误也要继续进行更新,则可以在UPDATE语句中使用IGNORE关键字来实觋。

③table_reference:用于指定要修改的单个表的名称。

④SET子句:用于指定表中要修改的列名及其列值。其中,每个指定的列值可以是表达式,也可是该列所对应的默默认值。如果指定的是默认值,则用关键字DEFAULT表示列值。

⑤WHERE子句:此子句为可选项,于限定表中要修改的行。若不指定此子句,则UPDATE语句会修改表中所有的行。

⑥ORDER BY子句:此子句为可选项,用于限定表中的行被修改的次序。 ⑦LIMIT子句:此子句为可选项,用于限定被修改的行数。 (3)UPDATE语句修改单个表的实例

【例4.5】使用UPDATE语句将数据库mysql_test的表customers中姓名为“张三”的客户的地址更新为“武汉市”。

在MySQL的命令行客户端输入如下SQL语句即可实现:

(4)UPDATE语句的使用说明

①UPDATE语句可修改表中行的列数据。

②为了删除表中某个列的值,在允许该列可为空值的前提下,可将它设置为NULL来实现。 ③可同时修改数据行的多个列值,彼此间用逗号分隔。

2.使用UPDATE语句修改多个表

(1)UPDATE语句同时修改多个表的语法格式

(2)UPDATE语句同时修改多个表的主要语法及使用说明

①table_references:用于指定多个表的联合,各表之间可用逗号分隔。

②对于多个表的修改,UPDATE语句会同时修改table_references中满足限定条件的每个表,在这种修改中不能使用ORDER BY子句和LIMIT子句。

第5章 数据库的查询

一、SELECT语句

1.SELECT语句的作用

使用SELECT语句可以在需要时从MySQL中快捷方便地检索、统计或输出数据。该语句的执行过程是从数据库中选取匹配的特定行和列,并将这些数据组织成一个结果集,然后以一张临时表的形式返回。

2.SELECT语句的语法格式

3.SELECT语句的的主要语法说明

(1)ALL | DISTINCT | DISTINCTROW:可选项

用于指定是否应返回结果集中的重复行。若没有指定这些选项,则默认为ALL,即SELECT操作中所有匹配的行,包括可能存在的重复行,都将被返回;若指定选项DISTINCT或DISTINCTROW,则会消除结果集中的重复行。DISTINCT或DISTINCTROW为同义词,且这两个关键字应用于SELECT语句中所指定的所有列,而不仅仅是前置某个列。

(2)HIGH_PRIORITY:可选项

用于给予SELECT操作更高的优先权,使查询立刻执行,加快查询速度。 (3)STRAIGHT_JOIN:可选项

用于促使MySQL优化器把表联合在一起,加快查询速度。 (4)SQL_SMALL_RESULT;可选项

可与GROUP BY DISTINCT同时使用,来告知MySQL优化器结果集较小。在此情形下,MySQL会使用快速临时表来存储生成的表,而不使用分类。

(5)SQL_BIG_RESULT:可选项

可与GROUP BY 或DISTINCT同时使用,来告知MySQL优化器结果集中有很多行。在此情形下,MySQL会优先进行分类,而不优先使用临时表。

(6)SQL_BUFFER_RESULT;可选项

用于促使结果被放入一个临时表中。可以帮助MySQL提前解开表锁定,在需要花费较长时间的情况下,也可以帮助把结果集发送到客户端手中。

(7)SQL_CACHE:为可选项

用于告知MySQL把查询结果存储在查询缓存中。对于使用UNION的查询或子查询、该选项会影响查询中的所有SELECT。

(8)SQL_NO_CACHE;为可选项

用于告知MySQL不要把查询结果存储在查询缓存中。 (9)SQL_CALC_FOUND_ROWS:为可选项

用于告知MySQL计算有多少行应位于查询结果集中,并不考虑任何LIMIT子句。 (10)select_expr:用于指定需要查询的内容。

(11)FROM子句、WHERE子句、GRUP BY子句、HAVING子句、ORDER BY子句、LIMIT子句

这些子句均为可选项,它们是体现SELECT语句功能强大的重要语法要素。在SELECT语句的使用中,所有被添加选用的子句必须依照SELECT语句的语法格式所罗列的顺序来使用,例如,一个HAVING子句必须位于GROUP BY子句之后,并位于ORDER BY子句之前。表5-1描述了SELECT语句中各子句的使用次序及说明。

表5-1 SELECT语句中各子句的使用次序及说明 子句 SELECT FROM WHERE GROUP BY HAVING ORDER BY LIMIT 说明 要返回的列或表达式 从中检索数据的表 行级过滤 分组说明 组级过滤 输出排序顺序 要检索的行数 是否必须使用 是 仅在从表选择数据时使用 否 仅在按组计算聚合时使用 否 否 否 (12)INTO OUTFILE:与关键字SELECT构成SELECT…INTO OUTFILE语句,用于将表中的行导出到服务器主机的一个文件中。

二、列的选择与指定 1.SELECT子句的作用

由SELECT语句的语法可知,最简单的SELECT语句形式是“SELECT select_expr”。使用这种最简单的SELECT语句就可以进行MySQL所支持的任何运算。

在SELECT语句中,select_expr部分主要用于指定需要查询的内容。

2.选择指定的列

选择一个或多个表中的某个或某些列作为SELECT语句的查询列。

若查询列有多个,则各个列名之间需要用逗号进行分隔,且查询结果返回时,结果集中各列的次序是依照SELECT语句中指定列的次序给出的。

若查询一个表中的所有列,则可在SELECT语句指定列的位置上直接使用星号(*)通配符,而不必逐个列出所有列名,此时结果集中各列的次序一般是这些列在表定义中出现的次序。

列名的指定可以采用直接给出该列的名称的方式,也可以使用完全限定的列名方式,即“tbl_name.col_name”的列名格式。

3.定义并使用列的别名 (1)别名的作用

在系统输出查询结果集中某些列或所有列的名称时,若希望这些列的名称显示为自定义的列名,而非原表中的列名,则可以在SELECT语句中添加AS子句到指定的列名之后,以此来修改查询结果集中列的别名。

(2)定义别名的语法格式 column_name [As] column_alias (3)定义别名的实例

【例5.1】查询数据库mysql_test的表customers中客户的cust_name列、cust_address列和cust_contact,要求将结果集中cust_address列的名称使用别名“地址”替代。

在MySQL的命令行客户端输入如下SQL语句即可:

mysql>SELECT cust_name,oust_address AS地址,cust_contact ->FROM mysql_test.customers:

当自定义的列别名中含有空格时,必须使用单引号将列别名括起来。 列别名不允许出现在WHERE子句中。

4.替换查询结果集中的数据 (1)CASE表达式的作用

在对表进行查询时,若希望得到对某些列的查询分析结果,而不是由查询得到的原始具体数据,则可以在SELECT语句中替换这些列,其中需要用到CASE表达式。

(2)CASE表达式的语法格式

(3)CASE表达式的实例

【例5.2】查询数据库mysql_test的表customers中客户的cust_name列和cust_sex列,要求判断结果集中cust_sex列的值,如果该列的值为M,则显示输出“男”,否则'为“女”,同时在结果集的显示中将cust_sex列用别名“性别”标注。

在MySQL的命令行客户端输入如下SQL语句即可: mysql>SELECT oust_name, ->CASE

->WHEN cust_sex='M' THEN '男' ->ELSE‘女’ ->END AS性别

->FROM mysql_test.customers;

5.计算列值

使用SELECT语句对列进行查询时,在结果集中可以输出对列值计算后的值,其具体使用方法是将SELECT语句的语法中select_expr部分指定为对应列参与计算的表达式。

【例5.3】查询数据库mysql_test的表customers中每个客户的cust_name列、cust_sex列,以及对oust_id列加上数字100后的值。

在MySQL的命令行客户端输入如下SQL语句即可: mysql>SELECT cust_name,cust_sex,cust_id+100 ->FROM mysql_test.customers;

6.聚合函数

SELECT语句的语法中select_expr部分可以指定为聚合函数(aggregation function)。聚合函数是MySQL中一类系统内置函数,常用于对一组值进行计算,然后返回单个值。它通常与GROUP BY子句一起使用,如果SELECT语句中有一个GROUP BY子句,则这个聚合函数对所有列起作用;如果没有,则SELECT语句只产生一行作为结果。另外,除COUNT函数外,聚合函数都会忽略空值。表5-2列出了MySQL中常用的聚合函数。

表5-2 MySQL中常用的聚合函数 函数名 COUNT MAX MIN SUM 说明 求组中项数,返回INT类型整数 求最大值 求最小值 返回表达式中所有值的和

AVG STD或STDDEV VARIANCE GROUP_CONCAT BIT_AND BIT_OR BIT_XOR

三、FROM子句与连接表

SELECT语句的查询对象是由FROM子句指定。 1.FROM子句的语法

(1)FROM子句的语法格式

①table_references的格式

求组中值的平均值 返回给定表达式中所有值的标准值 返回给定表达式中所有值的方差 返回由属于一组的列值连接组合而成的结果 逻辑或 逻辑与 逻辑异或

②table_factor的格式

③join_table的格式

④index_hint_list的格式

⑤index_hint的格式

⑥index_list的格式

⑦join_condition的格式

(2)FROM子句的主要语法说明

①table_reference:指定要查询的表或视图。 ②tbl_name:指定要查询的表名。

与列别名一样,可以使用关键字AS选项为表指定别名,其中tbl_name_alias为表指定别名。表别名主要用于相关子查询或连接查询中。如果在FROM子句中指定了表别名,那么它所在的SELECT语句中其他子句都必须使用表别名来代替原始的表名。当同一个表在SELECT语句中多次被引用时,必须使用表别名加以区分。

③{USE |IGNORE |FORCE}INDEX

关键字USE INDEX用于指示MySQL选择一个索引来查找表中的行;关键字IGNORE INDEX用于指示MySQL不要使用某些特定的索引;关键字FORCE INDEX的作用与USE INDEX(index_list)类似,只有当无法使用一个给定的索引来查找表中的行时,才会使用全表扫描。

④ON子句:在子句中conditional_expr部分指定连接的条件。 ⑤USING子句

USING子句用于为一系列的列进行命名,这些列必须同时存在于所关联的两个表中,其中USING子句的column_list部分用于指定两表中相同的列名。如果要连接的两个表中有列名相同,并且连接的条件就是列名相等,那么ON子句可以换成USING子句。

2.连接表

(1)连接表的作用

①在关系数据库的设计中,为了减少数据的冗余,并增强数据库的稳定性和灵活性,通常会基于关系规范化原则将物理世界中的数据信息分解成多个表,实现一类数据一个表,并且在表与表之间通过设置“键”(如主键、外键)的方式来保持多表之间的关联关系。

②在关系数据库的应用中,通过对表对象的连接(join)运算,实现数据库中数据信息的组合。这种分解与组合数据的方法,使得数据库系统能够更有效地存储数据,更方便地处理数据,且可获得更大的可伸缩性。

③MySQL中的SQL语言支持连接运算,可实现当数据分别存储在多个表中时使用单条SELECT语句检索出所需数据,即在数据检索查询的执行中连接表。在FROM子句语法中的table_references部分,可以通过指定多个表来实现这种支持连接的多表查询,也称连接查询。

④当指定多个表时,SELECT操作会使用“连接”运算将不同表中需要查询的数据组合到一个结果集中,并同样以一个临时表的形式返回。

(2)常见的连接方式 ①交叉连接(cross join)

交叉连接又称笛卡儿积(Cartesian join),也称没有连接(no join)。它在FROM子句中使用关键字CROSS JOIN连接两张表,用于实现一张表的每一行与另一张表的每一行的笛卡儿乘积,返回两张表的每一行相乘的所有可能的搭配结果,供SELECT语句中其他语法元素使用。

【例5.4】假设数据库中有两张表,分别是tbl1和tbl2,现要求输出这两张表执行交叉连接后的所有数据集。 在MySQL的命令行客户端输入如下SQL语句即可: mysql>SELECT * FROM tbl1 CROSS JOIN tbl2;

在FROM子句中也可以省略关键字CROSS JOIN,而使用逗号分隔交叉连接的两张表。例5.4中的执行语句可改成下面等同的SQL语句形式:

mysql>SELECT * FROM tbl1,tbl2;

交叉连接返回的查询结果集的记录行数等于其所关联的两张表记录行数的乘积。对于存在大量数据的表,应该避免使用交叉连接。可以在FROM子句的交叉连接后面,通过添加WHERE子句设置判断条件的方法,来过滤返回的结果集。

②内连接(inner join)

内连接是通过在查询中设置连接条件的方式,来移除查询结果集中某些数据行后的交叉连接。内连接就是利用条件判断表达式中的比较运算符来结合两张表中的记录,其目的是为了消除交叉连接中的某些数据行,它在FROM子句中使用关键字INNER JOIN连接两张表,并使用ON子句来设置连接的条件。在MySQL中,INNER JOIN与CROSS JOIN从语法上来说是等同的,两者可以互换。

通常在使用内连接的过程中,其所对应的SQL语句结构形式为:

somecolumns为需要检索的列的名称或列别名,table1和table2是进行内连接的两张表的表名或表别名,somecondition是条件判断表达式,该式子中可采用任何一种比较运算符。

在内连接的FROM子句中可以省略关键字INNER,而只用关键字JOIN连接表。使用内连接后,FROM子句中的ON子句可用来设置连接表的条件,而其他不属于连接表的条件则可以在SELECT语句中的WHERE子句中进行指定。在FROM子句中,可以在多个表之间连续使用INNER JOIN或JOIN,如此可以同时实现多个表的内连接。

FROM子句中的关键字STRAIGHT_JOIN的连接用法与INNER JOIN基本相同。区别是STRAIGHT_JOIN后不可以使用USING子句,只能用ON子句设置连接条件。

③相等连接(equijoin) 相等连接是内连接的一种,主要用于关联具有一对一关系的两张表,即进行相等性测试的内连接。它在FROM子句中羼糕是使用关键字INNER JOIN或JOIN连接两张表,只是在ON子句的连接条件中使用运算符“=”,通常这样的条件会包含一个主键和一个外键。

④不等连接(non-equijion)

与相等连接相对应,不等连接也是内连接的一种、即进行不相等性测试的内链接。它在FROM子句中同样是使用关键字INNER JOIN 或JOIN连接两张表,只是在ON子句的连接条件中使用除运算符“=”之外的比较运算符。

⑤自连接(seIf-join)

作为特例,可以将一个表与它自身进行连接,这种连接成为自连接。它是内连接的一种,在FROM子旬中同样是使用关键字INNER JOIN或JOIN来进行连接。若需要在一个表中查找具有相同列值的行,则可以考虑使用自连接。使用自连接时,需要为指定两个不同的别名,且对所有查询列的引用均必须使用表别名限定,否则SELECT操作会失败。

⑥自然连接(natural join)

自然连接只有在连接的列在两张表中的名称都相同时才会有用,否则返回的是笛卡儿积的结果集。自然连接在FROM子句中使用关键字NATURAL JOIN。

⑦外连接(outer join)

内连接是在交叉连接的结果集上返回满足条件的记录;而外连接则是首先将连接的两张表分为基表和参考表,然后再以基表为依据返回满足和不满足条件的记录。

外连接可以在表中没有匹配记录的情况下仍返回记录。有可能对两张表分别使用内连接和外连接之后所返回的结果相同。但实质上这两类连接的操作语义是不同的,它们的差别在于外连接一定会提供数据行,无论该行能否在另外一个表中找出相匹配的行。

外连接要比前面所有的连接更加注重两张表之间的关系。根据连接表的顺序,可分为左外连接和右外连接两种。

a.左外连接

左外连接也称左连接。它在FROM子句中使用关键字LEFT OUTER JOIN(OUTER可省略),用于接收该关键字左边表(基表)的所有行,并用这些行与该关键字右边表(参考表)中的行进行匹配,即匹配左表中的每一行及右表中符合条件的行。这种连接方式特别适合当左表与右表具有一对多关系的情形。在左外连接的结果集中除了匹配的行之外,还包括左表中有的但在右表中不匹配的行,对于这样的行,从右表中被选择的列的值被设置为NULL。也就是说,左外连接的结果集中的NULL值表示右表中没有找到与左表相符的记录。

b.右外连接

右外连接也称右连接。它在FROM子句中使用关键字RIGHT OUTER JOIN(OUTER可省略)。右外连接是以右表为基表,其连接方法与左外连接完全一样。在右外连接的结果集中除了匹配的行之外,还包括右表中有的但在左表中不匹配的行,对于这样的行,从左表中被选择的列的值被设置为NULL。

四、WHERE子句

1.WHERE子句的作用

在SELECT语句中,可以使用WHERE子句,并可根据WHERE子句中指定的过滤条件(也称搜索条件或查询条件),从FROM子句的中间结果中选取适当的数据行,实现数据的过滤。

2.WHERE子句的语法格式

where_condition用于指定过滤条件,其语法格式为:

predicate是判定运算,其结果取值为TRUE、FALSE或UNKNOWN。 predicate的语法格式

3.predicate部分的语法解释 (1)比较运算

①比较运算的使用语法

expression用于指定表达式。 ②比较运算符的种类

MySQL支持表5-3列出的比较运算符。

表5-3 比较运算符 比较运算符 = <> != < <= > >= <=> 说明 等于 不等于 不等于 小于 小于等于 大于 大于等于 不会返回UNKNOWN ③比较运算符特别说明

比较运算用于比较两个表达式的值。当两个表达式的值均不为NULL时,除了“<=>”运算符,其他比较运算返回逻辑值TRUE(真)或FALSE(假);而当两个表达式值中有一个为空值或都为空值时,则将返回UNKNOWN。对于运算符“<=>”,当两个表达式彼此相等或都等于空值时.比较的结果值为TRUE:若其中有一个空值或者都是非空值但却不相等时,则为FALSE,不会出现值为UNKNOWN的情况。

(2)字符串匹配 ①字符串匹配的作用

字符串匹配是一种模式匹配,它通过使用运算符LIKE来指示MySQL:过滤条件是使用通配符进行匹配运算,而不是通过判断是否直接相等进行比较。相互间进行匹配运算的对象可以是CHAR、VARCHAR、TEXT、DATETIME等类型的数据,运算返回的结果是逻辑值TRUE或FALSE。

②LIKE运算使用的语法格式

利用通配符可以在不能完全确定比较值的情形下,创建一个用于比较特定数据的搜索模式,并置于关键字LIKE后。可以在搜索模式中任意位置使用通配符,并且可以同时使用多个通配符。

③MySQL所支持的常用通配符 a.百分号(%)

最常使用的通配符是百分号(%)。在过滤条件的待比较对象(搜索串)中,百分号(%)可表示任何字符串,并且该字符串可出现任意次数(包括0次)。

使用百分号(%)通配符,需要注意以下几点:

第一,MySQL默认是不区分大小写的,如若要区分大小写,则需更换字符集的校对规则。 第二,百分号(%)可代表搜索模式中给定位置的0个、1个或多个字符串。 第三,百分号(%)不能匹配空值NULL。

第四,尾空格可能会干扰通配符的匹配,所以一般可以在搜索模式的最后附加一个百分号(%)。 b.下画线(_)

下画线(_)通配符与百分号(%)用途一样,但下画线(_)只用于匹配单个字符,而不是多个字符,也不是0个字符。

在使用LIKE运算符进行字符串的匹配过程中,可以在搜索模式之后选用关键字ESCAPE和一个指定的转义字符,来临时改变通配符的作用和意义。当要匹配的字符串中含有与通配符(_或%)相同的字符时,此时应通过该字符(_或%)前面的一个转义字符,指示其为搜索模式中的一个匹配字符,而不再是通配符。

【例5.5】在数据库mysql_test的表customers中,查找客户地址中含有下画线“_”的所有客户地址。 在MySQL命令行客户端输入如下SQL语句即可实现: mysql>SELECT cust_address,FROM mysql_test.customers ->WHERE cust_address LIKE '%#_%' ESCAPE '# ';

1 row in set<0.00 sec>

④在MySQL中使用通配符的注意事项

a.不要过度使用通配符,因为对通配符检索的处理一般会比其他检索方式花费更长的时间。

b.在确实需要使用通配符时,除非绝对有必要,否则不要把它们用在搜索模式的开始处,因为这样会让检索变得更慢。

c.特别注意通配符的位置。若通配符放错位置则可能不会返回所需的数据结果。 (3)文本匹配 ①文本匹配的作用.

文本匹配也是一种模式匹配,它是使用正则表达式进行文本串的匹配比较,以满足定义一些复杂过滤条件的要求。正则表达式是用来匹配文本的特殊串或字符集合,是文本匹配运算中的一种搜索模式。正则表达式需要使用正则表达式语句来建立。MySQL提供了对正则表达式语言的初步支持,允许使用关键字REGEXP指定正则表达式,从而可以过滤SELECT语句检索出的数据。

②使用正则表达式进行文本匹配的语法格式

运算符RLIKE是REGEXP|RLIKE]match_expression用于文本匹配的语法置于SELECT关键字之后,就可以在不使用数据库表的情况下,进行简单的正则表达式测试。如果返回0,则表示没有匹配,如返回1,则表示匹配成功。

③常用的字符匹配 a.基本字符匹配

使用正则表达式可以匹配任意一个字符,从而进行基本字符的匹配捡索。

【例5.6】在数据库mysql_test的表customers中,分别使用字符串匹配和文本匹配的方式,查询客户地址中带有中文“市”的地址信息。

第一,使用关键字LIKE在MySQL命令行客户端输入如下SQL语句:: mysql>SELECT DISTINCT cust_address FROM mysql_test.customers ->WHERE cust_address LIKE‘市’; Empty set<0.03 sec>

第二,再次使用关键字LIKE在MySQL命令行客户端输入如下SQL语句: mysql>SELECT DISTINCT cust_address FROM mysql_test.customers ->WHERE cust_address LIKE‘%市%’;

4 rows in set<0.00 sec>

第三,使用关键字REGEXP在MySQL命令行客户端输入如下SQL语句: mysql>SELECT DISTINCT cust_address FROM mysql_test.customers ->WHERE cust_address PEGEXP '市';

4 rows in set<0.00 sec>

由例子可看出,尽管在匹配基本字符的过程中,分别使用关键字LIKE和REGEXP的SQL语句看上去十分相似,但其执行的结果是不同的。这是因为LIKE与REGEXP之间存在这样一个重要的差别:LIKE用于匹配整个列,如果被匹配的字符串在列值中出现,LIKE将不会找到它,相应的行也不会返回,除非是使用通配符;而REGEXP是在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP将会找到它,相应的行将被返回。

如若在使用正则表达式进行文本匹配中,需要区分大小写,则可在关键字REGEXP之后再加上关键字BINARY。

b.选择匹配

在搜索模式中使用“|”分隔每个供选择匹配的字符串可以实现待搜索对象的选择性匹配。从功能上,分隔符“|”类似于在SELECT语句中使用OR子句,多个OR条件可以并入单个正则表达式。

【例5.7】在数据库mysql_test的表customers中,查询带有“北京”、“武汉”或“上海”中文字符的所有客户地址信息。

在MySQL命令行客户端输入如下SQL语句即可:

mysql>SELECT DISTINCT cust_address FROM mysql_test.customers ->WHERE cust address REGEXT '北京|武汉|海';

4 rows in set<0.00 sec>

如果在搜索模式中使用“|”分隔的是多个字符,则可以将这些字符组成一个字符串,然后置于一个方括号“[]”中,这样构建的搜索模式与使用分隔符“|”构建的搜索模式的执行效果是一样的。

c.范围匹配

可以通过在正则表达式中指定一个由方括号“[]”所包含的字符或数字集合,用于在这个集合范围内查找某个匹配的字符或数字。

d.特殊字符匹配

当要查找匹配这些有着特殊含义的特殊字符时,可使用转义字符的方式,来临时改变这些特殊字符的特殊意义,使其变为一个普通字符。具体方法是在这些特殊字符前使用“\\\\”,作为前导。例如,正则表达式中如果出现“\\\\-”,则表示是查找字符“-”。

“\\\\”也可用来引用空白元字符(即含有特殊含义的字符)。例如,“\\\\f”表示换页,“\\\\n”表示换行,“\\\\r”表示回车,“\\\”表示制表,“\\\\v”表示纵向制表。

e.字符类匹配

为更加方便地查找,可以将经常使用的数字、字符等定义成一个预定义的字符集(也称字符类),然后在正则表达式中直接使用。例如,字符类“[:upper:]”表示任意大写字母,如同在正则表达式中使用“[A-Z]”。

f.重复匹配

有时需要在正则表达式中对要匹配的字符或字符串的数目进行更强的控制,这时可以使用表5-4列出的重复元字符来完成。

表5-4 重复元字符 元字符 * + ? {n} {n,} {n,m} 说明 0个或多个匹配 1个或多个匹配(等于{1,} 0个或1个匹配{0,1} 指定数目的匹配 不少于指定数目的匹配 匹配数目的范围(m不超过255) 为了匹配处于特定位置的文本,需要在正则表达式中使用表5-5列出的定位符。

表5-5 定位符 定位符 $ [[:<:]] [[:>:]] 说明 文本的开始 文本的结尾 词的开始 词的结尾 在MySQL的正则表达式中符号“^”有两种用法:在用方括号“[]”包含起来的集合中,可用它来否定该集合;而作为定位符时,它表示字符串的开始处。

(4)判定范围

在WHERE子句中,用于范围判定的关键字有BETWEEN和IN两个。 ①BETWEEN…AND

当查询的过滤条件被限定在值的某个范围时,可以使用关键字BETWEEN。其语法格式是:

表达式expressionl的值不能大于表达式expression2的值。当不使用关键字NOT时,如果表达式expression的值在表达式expression1与expression2之间(包括这两个值),则返回TRUE,否则返回FALSE;如果使用关键字NOT时,其返回值正好相反。

②IN

使用关键字IN可以指定一个值的枚举表,该表中会列出所有可能的值,其语法格式是:

当要判定的值能与该表中任意一个值匹配时,会返回结果TRUE,否则返回FALSE。注意,尽管关键字IN可用于范围判定,但其最主要的作用是表达子查询。

(5)判定空值

当需要判定一个表达式的值是否为空值时,可以使用关键字IS NULL来实现,其语法格式是:

当不使用关键字NOT时,如果表达式expression的值为空值,则返回TRUE,否则返回FALSE;而当使用关键字NOT时,其结果正好相反。

(6)子查询

在MySQL中,允许使用SELECT语句创建子查询(subquery),即可嵌套在其他SELECT查询中的SELECT

查询。

①MySQL中的四类子查询

a.表子查询:子查询返回的结果集是一个表。

b.行子查询:子查询返回的结果集是带有一个或多个值的一行数据。

c.列子查询:子查询返回的结果集是-一列数据,该列可以有一行或多行,但每行只有一个值。 d.标量子查询:子查询返回的结果集仅仅是一个值。 ②结合关键字IN使用的子查询

结合关键字IN所使用的子查询主要用于判定一个给定值是否存在于子查询的结果集中,其语法格式是:

语法说明如下:

a.subquery:用于指定子查询。通常,这里的子查询只能返回一列数据。另外,对于比较复杂的查询要求,可以使用SELECT语句实现子查询的多层嵌套。

b.expression:用于指定表达式。当表达式与子查询返回的结果集中某个值相等时,过滤条件返回TRUE,否则返回FALSE;若使用了关键字NOT,则返回的值正好相反。

③结合比较运算符使用的子查询

结合比较运算符所使用的子查询主要用于将表达式的值与子查询的结果进行比较运算,其语法格式是:

语法说明如下:

a.expression:用于指定要进行比较的表达式。 b.subquery:用于指定子查询。

c.ALL、SOME和ANY:这三个关键字为选择项,用于指定对比较运算的限制。关键字ALL用于指定表达式需要与子查询结果集中的每个值都进行比较,当表达式与每个值都满足比较关系时,会返回TRUE,否则返回FALSE;关键字SOME和ANY是同义词,表示表达式只要与子查询结果集中的某个值满足比较关系时,就返回TRUE,否则返回FALSE。

④结合关键字EXIST使用的子查询

结合关键字EXIST所使用的子查询主要用于判定子查询的结果集是否为空。其语法格式为:

如果子查询的结果集不为空,则返回TRUE,否则返回FALSE。

在实际应用中,子查询通常可以改成表的连接,只是两者的执行性能会有所差异。

五、GROUP BY子句与分组数据 1.GROUP BY子句的作用

在SELECT语句中,允许使用GROUP BY子句,将结果集中的数据行根据选择列的值进行逻辑分组,以便能汇总表内容的子集,即实现对每个组的聚集计算。因而,GROUP BY子句可指示MySQL分组数据,然后对每个组而不是对整个结果集进行聚合。

2.GROUP BY子句的语法格式

3.GROUP BY子句的语法说明

(1)col_name:指定用于分组的选择列。可以指定多个列,彼此间用逗号分隔。注意,GROUP BY子句中的各选择列必须也是SELECT语句的选择列表清单中的一项。

(2)expr:指定用于分组的表达式。该表达式通常与聚合函数一块使用,例如,可将表达式“COUNT(*)AS‘人数’”作为SELECT语句的选择列表清单中的一项。

(3)position:指定用于分组的选择列在SELECT语句结果集中的位置,通常是一个正整数。例如,使用GROUP BY 3表示根据SELECT语句中列清单上的第3列的值进行逻辑分组。

(4)ASC|DESC:关键字ASC表示按升序分组;关键字DESC表示按降序分组。默认值为ASC。这两个关键字必须位于对应的列名、表达式、列的位置之后。

(5)WITH ROLLUP:此关键字为可选项,用于指定在结果集中不仅包含由GROUP BY子句分组后的数据行,还包含各分组的汇总行,以及所有分组的整体汇总行。因此,使用该关键字,可以得到每个分组以及每个分

组汇总级别的值。

4.GROUP BY子句的实例

【例5.8】在数据库mysql_test的表customers中获取一个数据结果集,要求该结果集中包含每个相同地址的男性客户人数、女性客户人数、总人数,以及客户的总人数。

在MySQL命令行客户端输入如下SQL语句即可实现:

mysql>SELECT cust_address,cust_sex,COUNT(*)AS'人数' ->FROM mysql_test.customers

->GROUP BY cust_address.cust_sex ->WITH ROLLUP;

10 rows in set(0.00 sec)

从上述例子的执行结果可以看出,在GROUP BY子句中添加了可选项WITH ROLLUP后,将对GROUP BY子句中所制定各列再次生成会汇总行:其汇总规则是:按列的排列的逆序依次进行汇总,并且在生成的统一逻辑组的汇总行中,对于具有不同列值的字段值将被设置为NULL。

GROUP BY子句的需要事项 (1)GROUP BY子句可以包含任意数目的列,使得其客队分组进行嵌套,为数据分组提供更加细致的控制。 (2)如果在GROUP BY 子句中嵌套了分组,那么将按按GROUP BY 子句中列的排列顺序的逆序方式依次进行汇总,并将在最后规定的分组上进行一个完全汇总。

(3)GROUP BY子句列出的每个列都必须是检索列或有效的表达式,但不能是聚合函数。如果在SELECT语句中使用表达式,则必须在GROUP BY子句中指定相同的表达式。注意,不能使用别名。

(4)除聚合函数之外,SELECT语句中的每个列都必须在在GROUP BY子句中给出。 (5)如果用于分组的列中含有NULL值,则NULL将作为一个单独的分组返回;如果该列中存在多个NULL值,则将这些NULL值所在的行分为一组。

六、HAVING 子句 1.HAVING语句

(1)可以使用HAVING子句来过滤分组,在结果集中规定包含哪些分组和排除哪些分组。 (2)HAVING子句的语法格式为:

where_condition用于指定过滤条件。

2.HAVING和WHERE的比较

HAVING子句与WHERE子句非常相似,HAVING子句支持WHERE子句中所有的操作符和句法,但两者之间仍存在以下几点差异:

(1)WHERE子句主要用于过滤数据行,而HAVING子句主要用于过滤分组,即HAVING子句可基于分组的聚合值而不是特定行的值来过滤数据。

(2)HAVING子句中的条件可以包含聚合函数,而WHERE子句中则不可以。

(3)WHERE子句会在数据分组前进行过滤,HAVING子句则会在数据分组后进行过滤。因而,WHERE子句排除的行不包含在分组中,这就有可能改变计算值,从而影响HAVING子句基于这些值过滤掉的分组。

3.HAVING语句的实例

【例5.9】在数据库mysql_test的表customers中查找这样一类客户信息:要求在返回的结果集中,列出相同客户地址中满足客户人数少于3的所有客户姓名及其对应地址。

在MySQL命令行客户端输入如下SQL语句即可实现:

4 rows in set(0.00 sec)

七、ORDER BY子句 1.ORDER BY语句

(1)用于将ORDER BY子句将结果集中的数据行按一定的顺序进行排列。 (2)ORDER BY子句的语法格式为:

(3)语法说明

①col_name:指定用于排序的列。可以同时指定多个列,列名彼此问用逗号分隔。 ②expr:指定用于排序的表达式。 ③position:指定用于排序的列在SELECT语句结果集中的位置,通常是一个正整数。例如,使用ORDER BY 2表示对SELECT语句中列清单上的第2列进行排序。

(4)ASC|DESC:关键字ASC表示按升序排列;关键字DESC表示按降序排列。默认值为ASC。这两个关键字必须位于对应的列名、表达式、列的位置之后。

2.ORDER BY语句的实例

【例5.10】在数据库mysql_test的表customers中依次按照客户姓名和地址的降序方式,输出客户的姓名和性别。

在MySQL命令行客户端输入如下SQL语句即可实现:

mysql>SELECT cust_name, cust_sex FROM mysql_test.customers

->ORDER BY cust_name DESC, cust_address DESC;

3.ORDER BY语句的使用说明

(1)ORDER BY子句中可以包含子查询。

(2)当对空值进行排序时,ORDER BY子句会将该空值作为最小值来对待。也就是说,若按升序排列结果集,则ORDER BY子句会将该空值所在的数据行置于结果集的最上方;若是使用降序排序,则会将其置于结果集的最下方。

(3)若在ORDER BY子句中指定多个列进行排序,则MySQL会按照这些列从左至右罗列的次序依次进行排序。

(4)在使用GROUP BY子句时,通常也会同时使用ORDER BY子句。千万不要仅依赖GROUP BY子句排序数据。表5-6汇总了ORDER BY子句与GROUP BY子句的差别。

表5-6 ORDER BY子句与GROUP BY子句的差别 ORDER BY 子句 排序产生的输出 GROUP BY子句 分组行,单输出可能不是分组的排序

任意列都可以使用 不一定需要 只可能是用选择列或表达式列 若与聚合函数一起使用列或表达式,则必须使用

八、LIMIT子句 1.LIMIT语句

(1)LIMIT子句用来限制被SELECT语句返回的行数。 (2)LIMIT子句的语法格式为:

LIMIT{[offset,]row_count | row_count OFFSET offset} (3)语法说明如下:

①offset:为可选项,默认为数字0,用于指定返回数据第一行在SELECT语句结果集中的偏移量,其必须是非负的整数常量。SELECT语句结果集中第一行(初始行)的偏移量为0而不是1。

②row_count:用于指定返回数据的行数,其也必须是非负的整数常量。若这个指定行数大于实际能返回的行数时,MySQL将只返回它能返回的数据行。

③row_count OFFSET offset:MySQL 5.0开始支持的另外一种语法,即从第offset+1行开始,取row_count行。

2.LIMIT语句的实例

【例5.11】在数据库mysql_test的表customers中查找从第5位客户开始的3位客户的cost_id和姓名信息。 在MySQL命令行客户端输入如下SQL语句即可实现:

mysql>SELECT oust_id,oust_name FROM mysql_test.customers

->ORDER BY oust_id ->LIMIT 4,3;

3 rows in set<0.00 sec> 也可写成:

九、UNION语句与联合查询 1.并查询的概念

多数SQL查询都只包含可从一个或多个表中返回数据的单条SELECT语句。MySQL也允许同时执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回。这种查询方式称为并(union)或联合查询。

2.联合查询的适用情况

(1)在单条查询中,需要从不同的表中返回相似结构的数据。 (2)对单个表执行多条查询时,需要以单条查询的结果集返回。

3.UNION语句的语法格式

(1)UNION语句的使用非常简单,只需先给出每条SELECT语句,然后在各条SELECT语句之间加上关键字UNION即可。

(2)若希望联合查询的结果集中没有重复的数据行,可在关键字UNION之后添加关键字DISTINCT,实际上这也是UNION的默认行为。

(3)若希望联合查询的结果集中可以允许存在重复的数据行,则可以在关键字UNION之后直接添加关键字ALL。

4.UNION语句使用时的注意事项

(1)UNION语句必须由两条或两条以上的SELECT语句组成,且彼此间用关键字UNION (2)UNION语句中的每个SELECT查询必须包含相同的列、表达式或聚集函数。

(3)每个SELECT查询中对应的选择列的数据类型必须兼容。列类型不必完全相同,但必须是MySQL可以隐含转换的类型,如不同的数值类型或不同的日期类型。

(4)第一个SELECT语句中被使用的列名称会被作为UNION语句结果集的列名称。

(5)只能使用一条ORDER BY子句或LIMIT子句,且它们必须置于最后一条SELECT语句之后。因为对于UNION语句的结果集,不存在用一种方式排序或限制一部分数据,而又用另一种排序或限制另一部分数据的情况,因此不允许在UNION语句中使用多条ORDER BY子句或LIMIT子句。

5.UNION语句的实例

【例5.12】使用UNION语句在数据库mysql_test的表customers中查找性别为“F”,或地址是“北京市”的cust_id和客户姓名。

在MySQL命令行客户端输入如下SQL语句即可实现:

由这个例子可看出,使用UNION语句进行联合查询与在单条SELECT语句使用多个WHERE子句的执行结果是相同的。

6.UNION语句和WHERE语句的区别

(1)在有些应用情景中,它们的执行性能会有所不同。

(2)UNION ALL是UNION语句中的一种,它可以完成WHERE子句完成不了的工作。如果需要每个条件的匹配行在最终的查询结果集中全部出现,并允许包含重复行,则必须使用UNION ALL而不是WHERE。

第6章 索 引

一、索引概述

在数据库中访问表中的行的方式。 1.顺序访问

在表中从头至尾逐行遍历,实现全表扫描,直至在一个无无序的行集中访问到所需数据的方式。这种方式执行时非常简单,但当表中的行数相当多时使得数据的遍历访问非常浪费时间,并且大大降低数据库的查询效率。

2.索引访问 (1)索引访问

通过遍历索引来直接访问表中记录行的方式。这种方式的使用,需要表自身至少有一个对应的索引。 (2)索引

根据表中的一列或若干列按照一定顺序建立的列值与记录行之间的对应关系表,因而索引实质上是一张描述索引列的列值与原表中记录行之间一一对应关系的有序表。在列上创建了索引之后,查找数据时可以直接根据该列上的索引找到对应记录行的位置,从而快速地查找到数据。

二、索引的存储与分类 1.索引与存储引擎的关系 索引是在存储引擎中实现的,因此每种存储引擎所支持的索引类型不一定完全相同,而且并非所有的存储引擎都会支持所有的索引类型。

2.MySQL在物理上的索引分类 (1)B-树索引 ①B-树的相关概念

大部分索引都是以B-树方式来存储的。这类索引也称BTREE索引,就是将索引采用树的数据结构形式存储在文件中。

BTREE索引是在文件中创建一棵包含多个结点的树。其中,树的顶部结点作为索引的起始点,称为根;树中每个结点包含索引列中若干个值,结点中每个值又都指向另一个结点或者直接指向表中的一个行记录,同时每个结点中的值是有序排列的;直接指向表中一行记录的结点称为叶子结点或叶子页,叶子页之间彼此连接,即一个叶子页有一个指向下一个叶子页的指针。正是基于这种树形数据结构,表中的每一行都会在索引中有一个对应值。在表中进行数据查询时,只需根据索引值就可以直接定位到数据所在的行。

②B-树索引的功能

由于BTREE索引存储的值按索引列中的顺序排列,并且B-树中的结点都是顺序存储的,所以可以利用BTREE索引进行全键值、键值范围和键值前缀查询,也可以对查询结果进行ORDER BY排序。但是,BTREE索引的使用必须遵循最左边前缀(leftmost prefix of the index)原则。

③B-树索引使用时的约束

a.查询必须从索引的最左边的列开始。

b.查询不能跳过某一索引列,必须按照从左至右的顺序进行匹配。 c.存储引擎不能使用索引中范围条件右边的列。 (2)哈希索引 ①哈希索引的介绍

哈希索引也称散列索引或HASH索引。在MySQL中,目前仅有MEMORY存储引擎和 HEAP存储引擎支持这类索引。其中,MEMORY存储引擎除了还可支持BTREE索引外,是将HASH索引作为默认索引。这类索引不是基于树形的数据结构查找数据,而是根据索引列对应的哈希值的方法来获取表中的记录行,因此HASH索引非常快。

②哈希索引的使用限制:

a.尽管HASH索引只包含哈希值和记录指针,但MySQL仍需读取表中索引列的值来参与散列计算,因而可能会影响到系统的性能。

b.不能使用HASH索引排序。

c.HASH索引不支持键的部分匹配,因为HASH值是通过整个索引值来计算的。

d.HASH索引只支持等值比较。

3.逻辑上索引的分类

(1)普通索引(INDEX)

最基本的索引类型,没有任何限制。创建普通索引时,通常使用的关键字是INDEX或KEY。 (2)唯一性索引(UNIQUE)

这类索引和普通索引基本相同,只是有一点区别,即索引列中的所有值都只能出现一次,必须是唯一的。创建唯一性索引时,通常使用关键字UNIQUE。

(3)主键(PRIMARY KEY)

主键是一种唯一性索引。创建主键时,必须指定关键字PRIMARY KEY,且不能有空值。主键一般是在创建表的时候指定,也可以通过修改表的方式添加主键,并且每个表只能有一个主键。

(4)全文索引(FULLTEXT)

全文索引只能在VARCHAR或TEXT类型的列上创建,并且只能在MyISAM表中创建。 (5)空间索引

MyISAM存储引擎支持空间索引,即RTREE索引。这种索引主要用于地理空间数据类型,如GEOMETRY。

4.实际使用中索引的分类 (1)单列索引

单列索引就是一个索引只包含原表中的一个列。 (2)组合索引

组合索引也称复合索引或多列索引,就是原表中多个列共同组成一个索引。一个表可以有多个单列索引,但这些索引不是组合索引。按照最左边前缀的法则,一个组合索引实质上为表的查询提供了多个索引,以此来加快查询速度。

5.按索引策略分类

为提高索引的应用性能,MySQL中的索引可根据具体应用采用不同的索引策略。这些索引策略所对应的索引类型有聚集索引、次要索引、覆盖索引、符合索引、前缀索引、唯一索引等,而它们在物理上默认都是B-树索引。其中:

(1)聚集索引

聚集索引是保证键值相近的记录元组存储的物理位置也相同,并且一个表只能有一个聚集索引。因而,字符串类型不适合建立聚集索引,尤其是随机字符串,会使得系统进行大量的移动操作。并非所有的MySQL存储引擎都支持聚集索引,目前只有solidDB和InnoDB支持聚集索引。

(2)覆盖索引

①如果索引包含满足查询的所有数据,称为覆盖索引。覆盖索引是一种非常强大的工具,由于只需要读取索引而不用读取数据,所以覆盖索引能大大提高查询性能。

②覆盖索引的优点:

a.索引项通常比记录要小,所以MySQL访问更少的数据。

b.索引都按值的大小顺序存储,相对于随机访问记录,需要更少的I/O。 c.大多数据引擎能更好地缓存索引,如MyISAM只缓存索引。

d.覆盖索引对于InnoDB表尤其有用,因为InnoDB使用聚集索引组织数据,如果二级索引中包含查询所需的数据,就不再需要在聚集索引中查找了。

③不同的存储引擎实现覆盖索引的方式不相同,而且并非所有存储引擎都支持覆盖索引。

三、索引的创建

1.使用CREATE INDEX语句创建索引

(1)CREATE INDEX语句创建索引的语法格式

①index_type的格式为:

②index_col_name的格式为:

③index_option的格式为:

(2)CREATE INDEX语句创建索引的语法说明 UNIQUE:可选项,用于指定创建唯一性索引。 FULLTEXT:可选项,用于指定创建全文索引。

SPATIAL:可选项,用于指定创建空间索引,即可以用来索引几何数据类型的列。

index_name:用于指定索引名。一个表可以创建多个索引,但每个索引在该表中的名称必须是唯一的。 index_type:指定索引类型。可选用的索引类型有BTREE和HASH两种。如果不指定,MySQL会默认创建BTREE索引。

tbl_name:指定要建立索引的表名。

index_col_name:索引列的描述。其中,它可包含以下三个语法要素: a.col_name

用于指定要创建索引的列名。通常可考虑将查询语句中在WHERE子句和JION子句里出现的列作为索引列。 b.length:可选项

用于指定使用列的前length个字符来创建索引。使用列的一部分创建索引有利于减小索引文件的大小,节省磁盘空间。在某些情况下,只能对列的前缀进行索引。例如,由于索引列的长度有一个最大上限,所以如果索引列的长度超过了这个上限,那么此时就需要利用前缀来进行索引。另外,BLOB或TEXT类型的列也必须使用前缀索引。前缀最长为255个字节,但对于MyISAM和InnoDB表,前缀最长为1000个字节。

c.ASC|DESC:可选项。用于指定索引按升序(ASC)还是降序(DESC)来排列,默认时为ASC。 CREATE INDEX语句不能创建主键。

(3)CREATE INDEX语句创建索引的实例

【例6.1】在数据库mysql_test的表customers上,根据cust_name和cust_id采用BTREE的索引类型创建一个复合索引index_cust。

【答】在MySQL的命令行客户端上输入如下SQL语句即可:

2.使用CREATE TABLE语句创建索引

(1)CREATE TABLE语句创建索引的语法格式 可在建表的同时建立索引。

在CREATE TABLE语句语法中的create_definition部分添加以下语法成分中的某一项或几项: ①在创建新表的同时创建该表的主键

②在创建新表的同时创建该表的索引

③在创建新表的同时创建该表的唯一性索引

④在创建新表的同时创建该表的全文索引或空间索引

⑤在创建新表的同时创建该表的外键

(2)CREATE TABLE语句创建索引的语法格式 语法及使用说明如下:

①关键字KEY:通常是关键字INDEX的同义词。

②CONSTRAINT[symbol]:为主键、UNIQUE键、外键定义一个名字。

③在使用CREATE TABLE语句定义列选项的时候,可以通过直接在某个列定义后面添加关键字PRIMARY KEY的方式来创建主键,而当主键是由多个列组成的多列索引时,则不能使用这种方法,只能通过在语句最后加上一个PRIMARY KEY(col_name,…)子句的方式来实现。

(3)CREATE TABLE语句创建索引的语法格式 【例6.2】在已有数据库mysql_test上新建一个包含产品卖家id号、姓名、地址、联系方式、售卖产品类型、当月销量等内容的产品卖家信息表seller,要求在创建表的同时,为该表添加由卖家id号和售卖产品类型组成的联合主键,并在当月销量上创建索引。

【答】在MySQL的命令行客户端上输入如下SQL语句即可:

【说明】MySQL可以在一个表上同时创建多个索引,并且使用PRIMARY KEY的列必须是一个具有NOT NULL属性的列。

3.使用ALTER TABLE语句创建索引

(1)ALTER TABLE语句创建索引的语法格式

使用ALTER TABLE语句修改表的同时,可以向已有的表中添加索引。可在ALTER TABLE语句语法中的alter_specification部分添加以下语法成分中的某一项或几项:

①在修改表的同时为该表添加索引

②在修改表的同时为该表添加主键

③在修改表的同时为该表添加唯一性索引

④在修改表的同时为该表添加全文索引

⑤在修改表的同时为该表添加空间索引

⑥在修改表的同时为该表添加外键

(2)ALTER TABLE语句创建索引的实例

【例6.3】使用ALTER TABLE语句在数据库mysql_test中表seller的姓名列上添加一个非唯一的索引,取名为index_seller_name。

在MySQL的命令行客户端上输入如下SQL语句即可:

四、索引的查看

1.使用SHOW INDEX语句查看索引的语法格式

运行该语句对应的SQL语句,系统就会返回一张结果列表。

2.使用SHOW INDEX语句查看索引的返回结果说明 Table列:用于显示索引所在表的名称。

Non_unique列:用于显示该索引是否不是唯一性索引。如果不是唯一性索引,则该列的值显示为1;如果是唯一性索引,则该列的值显示为0。

Key_name列:用于显示索引的名称。如果是在创建索引的语句中通过使用PRIMARY KEY关键字指定的索引,那么该索引在索引创建语句中是没有明确给出索引名的,但系统会为其默认指定一个索引名称,即“PRIMARY”。

Seq_in_index列:用于显示索引中列所对应的序列号。序列号计数从数字1开始。 Column_name列:用于显示索引中列的名称。

Collation列:用于显示列以何种顺序(升序或降序)存储在索引中。如果是升序,则该列的值显示为A;如果该列的值显示为NULL,则表示无分类。

Cardinality列:用于显示索引中唯一值数目的估计值。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。

Sub_part列:用于显示索引列被编入索引的情况。如果索引列只是被部分地编人索引,则该列的值显示为被编人索引的字符的数目;如果是整列被编入索引,则该列的值显示为 NULL。

Packed列:用于显示关键字如何被压缩。如果没有被压缩,则该列的值显示为NULL。

Null列:用于显示索引列是否包含有NULL。如果含有,则该列的值显示为YES;如果不含有,则该列的值显示为NO。

Index_type列:用于显示索引使用的类型或方法,如BTREE、HASH等。

Comment列:用于显示评注。

五、索引的删除

1.使用DROP INDEX语句删除索引

该语句的使用非常简单,其语法格式为:

其中,index_name指定要删除的索引名,tbl_name指定该索引所在的表。

2.使用ALTER TABLE语句删除索引

将ALTER TABLE语句的语法中alter_specification部分指定为以下子句中的某一项:

(1)DROP PRIMARY KEY:选用该子句表示ALTER TABLE语句将用于删除表中的主键。一个表中只有一个主键,主键也是一个索引。

(2)DROP INDEX index_name:选用该子句表示ALTER TABLE语句将用于删除各种类型的索引。 (3)DROP FOREIGN KEY fk_symbol:选用该子句表示ALTER TABLE语句将用于删除外键。 关于索引的删除,有这样两种情况需要注意:如果所删除的列是索引的组成部分,则该列也会从索引中删除;如果组成索引的所有列都被删除,则整个索引将被删除。

六、对索引的进一步说明 1.索引存在的弊端:

(1)索引在提高查询速度索引在提高查询速度的同时,却会降低更新表的速度。在更新表中索引列上的数据时,MySQL会自动地更新索引以确保索引树与表中的内容保持一致,这可能需要重新组织一个索引。

(2)索引是以文件的形式存储的,MySQL会将一个表的所有索引保存在同一个索引文件中,索引文件需要占用磁盘空间。如果有大量的索引,索引文件可能会比数据文件更快地达到最大的文件尺寸。特别是如果在一个大表上创建了多种组合索引,索引文件会膨胀得非常快。

索引只是提高效率的一个因素,如果MySQL中存在大数据量的表,则需要认真研究建立更加优秀的索引,或者优化查询语句。

2.索引使用的一些技巧和事项

(1)复合索引的使用会严格遵循最左前缀法则。

(2)当查询范围涉及的表中行数太多时,基于索引的查询优化将不会被使用。 (3)不要将索引列作为查询表达式的一部分。 (4)尽量使用覆盖索引。

(5)一般情况下不鼓励使用LIKE操作。“LIKE%aaa%”格式的子句会使索引失效,而“LIKE aaa%”格式的子句可以使用索引。

(6)不使用“NOT IN”和“<>”操作索引。

(7)索引不会包含有空值(NULL)的列。倘若列中包含有空值,则该列将不会被包含在索引中。复合索引中只要有一列含有空值,那么这一列对于该复合索引是无效的。在数据库设计时不要让字段的默认值为NULL。

(8)尽量使用短索引。由于短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作,所以在对字符串列进行索引时,如有可能,应该为该列指定一个前缀长度。

(9)由于使用索引方式排序是MySQL在扫描索引本身时即可完成排序,因而要比使用FileSort方式排序的效率高,所以在ORDER BY子句中,应尽量使用索引方式排序,避免使用FileSort方式排序。

第7章 视 图

一、视图概述 1.视图的概念

视图是从一个或多个表或者视图中导出的表,它也包含一系列带有名称的数据列和若干条数据行。

2.视图与数据库表的区别

(1)视图不是数据库中真实的表,而是一张虚拟表,其结构和数据是建立在对数据库中真实表的查询基础上的。

(2)视图的内容是由存储在数据库中进行查询操作的SQL语句来定义的,它的列数据与行数据均来自于定义视图的查询所引用的真实表(也称基础表、基表或源表),并且这些数据是在引用视图时动态生成的。

(3)视图不是以数据集的形式存储在数据库中,它所对应的数据实际上是存储在视图所引用的真实表(基础表)中。

(4)视图是用来查看存储在别处的数据的一种设施而其自身并不存储数据。尽管视图与数据库中的表存在着本质的不同,但视图一经定义后,可以如同使用表一样,对视图进行查询、修改、删除和更新等操作。

3.视图的优点 (1)集中分散数据

当用户所需的数据分散在数据库多个表中时,通过定义视图可以将这些数据集中在一起,以方便用户对分散数据的集中查询与处理。

(2)简化查询语句

通过定义视图可为用户屏蔽数据库的复杂性,使其不必详细了解数据库中复杂的表结构和表连接,因而能简化用户对数据库的查询语句。例如,即便是底层数据库表发生了更改,也不会影响上层用户对数据库的正常使用,只需数据库编程人员重新定义视图的内容即可。

(3)重用SQL语句

视图提供的是一种对查询操作的封装,它本身不包含数据,其所呈现的数据是根据视图的定义从基础表中检索出来的,如若基础表中的数据被新增或更改,视图所呈现的则是更新后的数据。通过定义视图,编写完所需查询后,可以方便地重用该视图,而不必了解它的具体查询细节。

(4)保护数据安全

通过只授予用户使用视图的权限,而不具体指定使用表的权限,来保护基础数据的安全性。 (5)共享所需数据

通过使用视图,每个用户不必都定义和存储自己所需的数据,可以共享数据库中的数据,从而同样的数据只需存储一次。

(6)更改数据格式

通过使用视图,可以重新格式化检索出的数据,并组织输出到其他应用程序中去。

二、创建视图

1.CREATE VIEW语句创建视图的语法格式

2.CREATE VIEW语句创建视图的语法说明 (1)OR REPLACE:可选项

用于指定OR REPLACE子句。该语句用于替换数据库中已有的同名视图,但需要在该视图上具有DROP权限。

(2)ALGORITHM子句:可选项

ALGORITHM子句是MySQL对标准SQL的扩展,它规定了MySQL处理视图的算法,这些算法会影响MySQL处理视图的方式。若没有给出ALGORITHM子句,则 CREATE VIEW语句的默认算法是UNDEFINED(未定义的)。

①MERGE

表示会将引用视图的SQL语句的文本与视图定义合并起来,使得视图定义的某一部分取代语句的对应部分。MERGE算法要求视图中的行和基础表中的行具有一对一的关系,如果不具有该关系,必须使用l临时表取而代之。

②TEMPTABLE

表示视图的结果将被置于临时表中,然后使用它执行语句。 ③UNDEFINED

表示MySQL将选择所要使用的算法。如果可能,它倾向于MERGE,而非TEMPTABLE,这是因为MERGE通常更有效,而且如果使用了临时表,则视图是不可更新的。

(3)view_name:指定视图的名称。该名称在数据库中必须是唯一的,不能与其他表或视图同名。 (4)column_list:可选项

可以为视图中的每个列指定明确的名称。列名的数目必须等于SELECT语句检索出的结果数据集的列数,并且每个列名间用逗号分隔。如若省略column_list子句,则新建视图使用与基础表或源视图中相同的列名。

(5)select_statement:用于指定创建视图的SELECT语句。这个SELECT语句给出了视图的定义,它可用于查询多个基础表或源视图。对于SELECT语句的指定,存在以下一些限制:

①定义视图的用户除了要求被授予CREATE VIEW的权限外,还必须被授予可以操作视图所涉及的基础表或其他视图的相关权限,

②SELECT语句不能包含FROM子句中的子查询。 ③SELECT语句不能引用系统变量或用户变量。 ④SELECT语句不能引用预处理语句参数。

⑤在SELECT语句中引用的表或视图必须存在。但是,创建完视图后,可以删除视图定义中所引用的基础表或源视图。若想检查视图定义是否存在这类问题,可使用CHECK TABLE语句。

⑥若SELECT语句中所引用的不是当前数据库的基础表或源视图时,需要在该表或视图前加上数据库的名称作为限定前缀。

⑦在由SELECT语句构造的视图定义中,允许使用ORDER BY子句。但是,如果从特定视图进行了选择,而该视图使用了具有自己ORDER BY语句,则视图定义中的ORDER BY子句将被忽略。

⑧对于SELECT语句中的其他选项或子句,若所创建的视图中页包含了这些选项,则语句执行效果未定义。 (6)WITH CHECK OPTION:可选子句

用于指定在可更新视图上所进行的修改都需要符合select_statement中所指定的限制条件,这样就可以确保数据修改后任然可以通过视图看到修改后的数据。当视图是根据另一个视图定义时,WITHCHECKOPTION 给出两个参数,即CASCADED和LOCAL,它们决定检查测试的范围。关键字CASCADED为选项默认值,它会对所有视图进行检查,而关键字LOCAL则使CHECK OPYION只对定义的视图进行检查。

3.CREATE VIEW语句创建视图的实例

【例7.1】在数据库mysql_test中创建视图customers_view,要求该视图包含客户信息表customers中所有男客户的信息,并且要求保证今后对该视图数据的修改必须符合客户性别为男性这个条件。

【答】在MySQL的命令行客户端入如下SQL语句,即可创建所需视图customers_view:

三、删除视图

1.DROP VIEW语句删除视图的语法格式

2.DROP VIEW语句删除视图的语法格式说明

(1)view_name:指定要被删除的视图名。使用DROP VIEW语句可以一次删除多个视图,但必须在每个视图上拥有DROP权限。

(2)IF EXISTS:关键字IF EXISTS为可选项,用于防止因删除不存在的视图而出错。若在DROP VIEW语句中没有给出该关键字,则当指定的视图不存在时,系统会发生错误。

四、修改视图定义

使用ALTER VIEW语句来对已有视图的定义(结构)进行修改,其语法格式为:

对于ALTER VIEW语句的使用,需要用户具有针对视图的CREATE VIEW和DROP权限,以及由SELECT语句选择的每一列上的某些权限。

修改视图的定义,也可以通过先使用DROP VIEW语句,再使用CREATE VIEW语句的过程来实现,还可以直接使用CREATE OR REPLACE VIEW语句来实现。若使用CREATE OR REPLACE VIEW语句,则当要修改的视图不存在时,该语句会创建一个新的视图,而当要修改的视图存在时,该语句会替换原有视图,重新构造一个修改后的视图定义。

五、查看视图定义

使用SHOW CREATE VIEW语句查看已有视图的定义(结构),其语法格式为:

view_name指定要查看视图的名称。

六、更新视图数据 1.视图更新的说明

视图是一个虚拟表,通过插入、修改和删除等操作方式来更新视图中的数据,实质上是在更新视图所引用的基础表中的数据。视图的更新操作是受一定限制的,并非所有的视图都可以进行INSERT、UPDATE或DELETE等更新操作,只有满足可更新条件的视图才能进行更新,否则可能会导致系统出现不可预期的结果。对于可更新的视图,需要该视图中的行和基础表中的行之间具有一对一的关系。

若视图中包含了下述任何一种SQL语句结构,那么该视图就是不可更新的: (1)聚合函数。

(2)DISTINCT关键字。 (3)GROUP BY子句。 (4)ORDER BY子句。 (5)HAVING子句。 (6)UNION运算符。

(7)位于选择列表中的子查询。 (8)FROM子句中包含多个表。

(9)SELECT语句中引用了不可更新视图。

(10)WHERE子句中的子查询,引用FROM子句中的表。

(11)ALGORITHM选项指定为TEMPTABLE,因为使用临时表时视图不可更新。

2.使用INSERT语句通过示图向基础表插入数据

【例7.2】在数据库mysql_test中,向视图customers_view插入下面一条记录: (909,’周明’,’M’,’武汉市’,’洪山区’)

【答】使用INSERT语句在MySQL的命令行客户端输入如下SQL语句即可插入数据: INSERT INTO mysql_test.customers_view

->VALUES(909,'周明 ','M','武汉市 ','洪山区'); Query OK,1 row affected(0.20 sec)

这条插入语句能够成功执行,是因为在创建视图customers_view的语句中加上了WITH CHECK OPTION子句。WITH CHECK OPTION子句会在更新数据时,检查新数据是否符合视图定义中WHERE子句的条件,并且WITH CHECK OPTION子句只能和可更新视图一起使用。

若插入的新数据不符合WHERE子句的条件,则数据插入操作无法成功,因而此时视图的数据插入操作受限。

当视图所依赖的基础表有多个时,也不能向该视图插入数据,这是因为MySQL不能正确地确定要被更新的基础表。

3.使用UPDATE语句通过视图修改基础表的数据

【例7.3】将视图customers_view中所有客户的cust_address列更新为“上海市”。

【答】使用UPDATE语句在MySQL的命令行客户端输入如下SQL语句进行数据更新:

若一个视图依赖于多个基础表,则一次视图数据修改操作只能改变一个基础表中的数据。

4.使用DELETE语句通过视图删除基础表的数据

【例7.4】删除视图customers_view中姓名为“周明”的客户信息。

【答】使用DELETE语句在MySQL的命令行客户端输入如下SOL语句删除指定数据;

对于依赖多个基础表的视图,不能使用DELETE语句。

七、查询视图数据

1.查询视图的适用情况

(1)利用视图简化复杂的表连接。

(2)使用视图重新格式化检索出的数据。 (3)使用视图过滤不需要的数据。

2.查询视图的实例

【例7.5】在视图customers_view中查找cust_id为905的客户姓名及其地址信息。 【答】在MySQL的命令行客户端输入如下SQL语句即可:

八、对视图的进一步说明

1.创建视图必须具有足够的访问权限。 2.对于可以创建的视图数目没有限制。

3.视图可以嵌套,即可以利用从其他视图中检索数据的查询来构造一个视图。 4.ORDER BY子句可以用在视图中,但如果从该视图检索数据的SELECT语句中也含有ORDER BY子句,那么该视图中的ORDER BY子句将被覆盖。

5.视图不能索引,也不能有关联的触发器、默认值或规则。

6.视图可以和表一起使用。例如,编写一条连接表和视图的SELECT语句。

7.由于视图不包含数据,所以每次使用视图时,都必须处理查询执行时所需的任何一个检索操作。倘若用多个连接和过滤条件创建了复杂的视图或者嵌套了视图,可能会发现系统运行性能下降得十分严重。在部署使用了大量视图的应用前,应该进行性能测试。

第8章 数据完整性约束与表维护语句

一、数据完整性约束 1.定义完整性约束

关系模型的完整性规则是对关系的某种约束条件。关系模型中有三类完整性约束,分别是实体完整性、参照完整性和用户定义的完整性。

(1)实体完整性

实体完整性规则(Entity Integrity Rule)是指关系的主属性,即主码的组成不能为空,也就是关系的主属性不能是空值NULL。

在MySQL中,实体完整性是通过主键约束和候选键约束来实现的。 ①主键约束

主键可以是表中的某一列,也可以是表中多个列所构成的一个组合。由多个列组合而成的主键也称复合主键。

a.MySQL中主键列遵守的规则: 第一,每一个表只能定义一个主键。

第二,主键的值,也称键值,必须能够唯一标识表中的每一行记录,且不能为NULL。也就是说,表中两个不同的行在主键上不能具有相同的值。这是唯一性原则。

第三,复合主键不能包含不必要的多余列。也就是说,当从一个复合主键中删除一列后,如果剩下的列构成的主键仍能满足唯一性原则,那么这个复合主键是不正确的。这是最小化规则。

第四,一个列名在复合主键的列表中只能出现一次。

b.在CREATE TABLE或ALTER TABLE语句中使用关键字PRIMARY KEY实现主键约束的方式 第一,作为列的完整性约束。此时只需在表中某个列的属性定义后加上关键字PRIMARY KEY即可。 第二,作为表的完整性约束。需要在表中所有列的属性定义后掭加一条PRIMARY KEY(index_col_name,…)格式的子句。

如果主键仅由一个表中的某一列所构成,上述两种方法均可以定义主键约束;如果主键是由表中多个列所构成的一个组合,则只能用上述第二种方法定义主键约束。定义主键约束后,MySQL会自动为主键创建一个唯一性索引,用于在查询中使用主键对数据进行快速检索,该索引名默认为PRIMARY,也可以重新自定义命名。

c.添加主键约束的实例

【例8.1】重新改写本书中的【例3.1】,使之在创建表的过程的完整性约束方式定义主键。 【答】只需在MySQL的命令行客户端输入如下SQL语句即可: mysql>USE mysql_test; Database changed

mysql>CREATE TABLE customers

->(

-> cust_id int NOT NULL AUTO_INCREMENT PRIMARY KEY, -> cust_name char(50) NOT NULL,

-> cust_sex int(1)NOT NULL DEFAULT 0, -> cust_address char(50) NULL, -> cust_contact char(50) NULL, ->)ENGINE=InnoDB;

Query OK,0 rows affected(0.10 sec) ②候选键约束

a.候选键可以是表中的某一列,也可以是表中多个列所构成的一个组合。 b.候选键的值必须是唯一的,且不能为NULL。

c.候选键可以在CREATE TABLE或ALTER TA BLE语句中使用关键字UNIQUE来定义,实现方法与主键约束相似,同样可作为列或者表的完整性约束方式。

d.MySQL中候选键与主键之间的区别

第一,一个表中只能创建一个主键,但可以定义若干个候选键。

第二,定义主键约束时,系统会自动产生PRIMARY KEY索引,而定义候选键约束时,系统自动产生

UNIQUE索引。

(2)参照完整性 ①参照完整性的介绍

a.在关系模型中实体及实体间的联系都是用关系来描述的,存在着关系与关系间的引用。

b.参照完整性规则(Referential Integrity Rule)就是定义外码和主码之间的引用规则,它是对关系间引用数据的一种限制。参照完整性的定义:若属性(或属性组)F是基本关系R的外码,它与基本关系s的主码K相对应,则对于R中每个元组在F上的值只允许两种可能,即要么取空值(F的每个属性值均为空值),要么等于S中某个元组的主码值。关系R与S可以是不同的关系,也可以是同一关系,而F与F是定义在同一个域中。

c.参照完整性是由系统自动支持的,即在建立关系(表)时,只要定义了“谁是主码”、“谁参照于谁”,系统将自动进行此类完整性的检查。

②参照完整性的定义方式

在MySQL中,参照完整性是通过在创建表(CREATE TABLE)或更新表(ALTER TABLE)的同时定义一个外键声明来实现的。外键声明有下列两种方式:

a.在表中某个列的属性定义后直接加上“reference_definition”语法部分。

b.在表中所有列的属性定义后添加“FOREIGN KEY(index_col_name,…)reference_defintion”子句的语法部分。

③reference_definition建立参照完整性的语法定义

a.index_col_name的语法格式为:

b.reference_option的语法格式为:

RESTRICT | EASCADE | SET NULL | NO ACTION

reference_definition的语法定义主要包含外键所参照的表、列、参照动作的声明和实施策略等四部分内容。 ④reference_definition建立参照完整性的语法说明: a.tbl_name

指定外键所参照的表名。这个表称为被参照表(或父表),而外键所在的表称作参照表(或子表)。 b.col_name

指定被参照的列名。外键可以引用被参照表中的主键或候选键,也可以引用被参照表中某些列的一个组合,但这个组合不能是被参照表中随机的一组列,必须保证该组合的取值在被参照表中是唯一的。外键中的所有列值在被参照表的列中必须全部存在,也就是通过外键来对参照表中某些列(外键)的取值进行限定与约束。

c.ON DELETE | ON UPDATE

指定参照动作相关的SQL语句。这里可为每个外键指定的参照动作分别对应于DELETE语句和UPDATE语句。

d.reference_option

指定参照完整性约束的实现策略。当没有明确指定参照完整性的实现策略时,两个参照动作会默认使用RESTICT。具体策略如下:

RESTRICT:限制策略,即当要删除或更新被参照表中被参照列上并在外键中出现的值时,系统拒绝对被参照表的删除或更新操作。

CASCADE:级联策略,即从被参照表中删除或更新记录行时,自动删除或更新参照表中匹配的记录行。 SET NULL:置空策略,即当从被参照表中删除或更新记录行时,设置参照表中与之对应的外键列的值为NULL。这个策略需要被参照表中的外键列没有声明限定词NOT NULL。

NO ACTION:不采取实施策略,即当一个相关的外键值在被参照表中时,删除或更新被参照表中键值的动作不被允许。该策略的动作语义与RESTRICT相同。

⑤参照完整性的实例

【例8.2】在数据库mysql_test中创建一个商品订单表orders,该表包含的订单信息有:订单号order_id、

订购商品名order_product、订购商品类型order_product_type、购客户id号cust_id、订购时间order_date、订购价格order_price、订购数量order_amount。要求商品订单表orders中的所有订购客户信息均已在表customers中记录在册。

【答】在MySQL的命令行客户端输入如下SQL语句即可:

例8.2通过使用关键字PRIMARY KEY定义了一个主键约束。同时,它通过定义外键创建了一个参照完整性约束,其作用是确保MySQL随时检测插入到外键中的每一个非空值是否都已经在被参照表中作为主键出现了。

⑥指定外键时需要遵守的规则

a.被参照表必须已经用一条CREATE TABLE语句创建了,或者必须是当前正在创建的表。如若是后一种情形,则被参照表与参照表是同一个表,这样的表称为自参照表)(self-referencing table),这种结构称为自参照完整性(self-referential integrity)。

b.必须为被参照表定义主键。

c.必须在被参照表的表名后面指定列名或列名的组合。这个列或列组合必须是这个被参照表的主键或候选键。

d.尽管主键是不能够包含空值的,但允许在外键中出现一个空值。只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。

e.外键中的列的数目必须和被参照表的主键中的列的数目相同。

f.外键中的列的数据类型必须和被参照表的主键中的对应列的数据类型相同。 (3)用户定义的完整性 ①用户定义的完整性的介绍

用户定义的完整性规则(User-defined Integrity Rule)是针对某一应用环境的完整性约束条件,它反映了某一具体应用所涉及的数据应满足的要求。

关系模型提供定义和检验这类完整性规则的机制,其目的是用统一的方式由系统来处理,而不再由应用程序来完成这项工作。

在实际系统中,这类完整性规则一般在建立数据库表的同时进行定义,应用编程人员不需再做考虑,如果某些约束条件没有建立在库表一级,则应用编程人员应在各模块的具体编程中通过程序进行检查和控制。

MySQL支持几种用户自定义完整性约束,分别是非空约束、CHECK约束和触发器。 ②非空约束与CHECK约束 a.非空约束

在MySQL中,非空约束可以通过在CRETE TABLE或ALTER TABLE语句中的某个列定义后面,加上关键字NOT NULL作为限定词,来约束该列的取值不能为空。

b.CHECK约束

与非空约束一样,CHECK约束也是在创建表(CREATE TABLE)或更新表(ALTER TABLE)的同时,根据用户的实际完整性要求来定义的。它可以分别对列或表实施CHECK约束,其使用的语法格式是:

CHECK(expr)

第一,expr是一个SQL表达式,用于指定需要检查的限定条件。在更新表数据时,MySQL会检查更新后的数据行是否满足CHECK约束中的限定条件。MySQL可以使用简单的表达式来实现 CHECK约束,也允许使用复杂的表达式作为限定条件,

第二,若将CHECK约束子句置于表中某个列的定义之后,则这种约束也称基于列的CHECK约束。 第三,若将CHECK约束子句置于表中所有列的定义以及主键约束和外键定义之后,则这种约束也称基于表的CHECK约束。该约束可以同时对表中多个列设置限定条件。

③用户定义的完整性的实例 【例8.3】改写【例8.2】,重新创建表orders,要求表orders中cust_id列的所有值均来源于表customers中的cust_id列。

【答】在MySQL的命令行客户端输入如下SQL语句即可: mysql>USE mysql_test; Database changed

mysql>CREATE TABLE orders

->(

-> order_id INT NOT NULL AUTO_INCREMENT, -> order_product CHAR(50) NOT NULL,

-> order_product_type CHAR(50) NOT NULL, -> cust_id INT NOT NULL,

-> CHECK(cust_id IN (SELECT cust_id FROM customers)), -> order_date DATETIME NOT NULL, -> order_price DOUBLE NOT NULL, -> order_amount INT NOT NULL, -> PRIMARY KEY(order_id), ->);

Query OK,0 rows affected(0.31 sec)

2.命名完整性约束

与数据库中的表和视图一样,可以对完整性约束进行添加、删除和修改等操作。为了删除和修改完整性约束,首先需要在定义约束的同时对其进行命名。

命名完整性约束的方法是在各种完整性约束的定义说明之前加上关键字CONSTRAINT和该约束的名字,其语法格式为:

CONSTRAINT [symbol]

symbol为指定的约束名字。这个名字是在完整性约束说明的前面被定义,其在数据库里必须是唯一的。若没有明确给出约束的名字,则MySQL自动创建一个约束名字。

【例8.4】改写【例8.2】,重新创建表orders,在原要求的基础上,将该表的主键约束命名为PRIMARY_KEY_ORDERS,并将它的外键说明命名为FOREIGN_KEY_ORDERS。

【答】在MySQL的命令行客户端输入如下SOL语句即可:

在定义完整性约束时,应当尽可能地为其指定名字,以便在需要对完整性约束进行修改或删除操作时,可以更加容易地引用它们。只能给基于表的完整性约束指定名字,而无法给基于列的完整性约束指定名字。

3.更新完整性约束

当对各种约束进行命名后,就可以使用ALTER TABLE语句来更新与列或表有关的各种约束。

若要添加约束,可在ALTER TABLE语句中使用ADD CONSTRAINT子句,实际上这也是定义约束的一种形式。需要注意以下两点:

(1)完整性约束不能直接被修改。若要修改某个约束,实际上是用ALTER TABLE语句先删除该约束,然后再增加一个与该约束同名的新约束。

(2)使用ALTER TABLE语句,可以独立地删除完整性约束,而不会删除表本身。若使用DROP TABLE语句删除一个表,则表中所有完整性约束都会自动被删除。

二、表维护语句

MySQL提供了一些可用于维护与管理数据库的SQL语句,统称表维护语句,是MySQL数据库优化的基础。

1.ANALYZE TABLE语句

(1)ANALYZE TABLE语句的作用

MySQL的优化元件Optimizer在优化SQL语句时,首先需要收集一些相关信息,其中包括表的索引散列程度Cardinality ,它表示表中某个索引所对应的列包含多少个不同的值。在MySQL中,可以使用SHOW INDEX FROM tbl_name语句查看索引的散列程度。

由于表中某个索引被创建时,对应索引上的散列程度。Cardinality不会立即被计算出来,此时就需要使用ANALYZE TABLE句来更新Cardinality;倘若Cardinality的值比数据的实际散列程度小许多,索引就会失效,那么此时也需要使用ANALYZE TABLE语句来修复Cardinality,以提高查询的效率。

(2)ANALYZE TABLE语句的语法格式

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE

tbl_name[,tbl_name]…

如果在MySQL上开启了二进制日志文件,那么ANALYZE TABLE语句执行操作的结果也会写入二进制日志文件中。也可以在ANALYZE TABLE语句中添加NO_WRITE_TO_BINLOG或LOCAL选项来取消写入,其中关键字NO_WRITE_TO_BINLOG与LOCAL同义。

(3)ANALYZE TABLE语句的实例

【例8.5】更新数据库mysql_test中表customers的索引散列程度,并查阅结果。

【答】在MySQL的命令行客户端输入如下SQL语句即可查阅到一张有关更新成功的结果表:

1 row in set(0.00 sec)

2.CHECK TABLE语句

(1)CHECK TABLE语句的作用

数据库在其运行过程中有可能会遇到错误,如数据写入磁盘时发生错误、索引没有同步更新或者数据库未关闭MySQL就停止工作等。遇到这些情形时,数据就可能发生错误。此时,可以使用CHECK TABLE语句来检查一个或多个表是否有错误,但该语句只对InnoDB、MylSAM、ARCHIVE和CSV表起作用。

(2)CHECK TABLE语句的语法格式

GHECK TABLE tbILname [tbl_name]…[option]… option的格式为:

option={FOR UPGRADE | OUICK | FAST | MEDIUM | EXTENDED | CHANGED} 使用CHECK TABLE语句,可以指定如下选项:

UPGRADE:用来测试在更早版本的MySQL中建立的表是否与当前版本兼容。

QUICK:这是速度最快的选项,在检查各列的数据时,不会检查链接的正确与否。如果没有遇到什么问题,可以使用这个选项。

FAST:只检查表是否正常关闭,如果在系统掉电之后没有遇到严重问题,可以使用这个选项。 CHANGED:只检查上次检查时间之后被更改的表以及没有被正确关闭的表。 MEDIUM:默认的选项,会检查索引文件和数据文件之间的链接正确性。

EXTENDED:这是最慢的选项,对每行的所有关键字进行全面的关键字查找。这可以确保表是完全一致的,但是花费的时间较长。

(3)CHECK TABLE语句的实例

【例8.6】使用CHECK TABLE语句检查数据库mysql_test中的表customers。

【答】在MySQL的命令行客户端输入如下SQL语句即可查阅到一张有关检查成功的结果表。

MySQL会在系统中保存表最近一次检查的时间,并且每次运行CHECK TABLE语句都会存储相关的记录信息。

3.CHECKSUM TABLE语句

(1)CHECKSUM TABLE语句的作用

数据在传输时,可能会发生变化,也有可能因为其他原因损坏。为了保证数据的一致,可以使用CHECKSUM TABLE语句对于数据库中的每一个表计算校验和。

(2)CHECKSUM TABLE语句的语法格式

CHECKSUM TABLE tbl_name [tbt_name]…[QUICK | EXTENDED] 使用说明如下:

①在CHECKSUM TABLE语句中可以指定选项QUICK或EXTENDED。 ②当指定选项QUICK时,表示返回已存储的校验和(也称活性表校验和),而如果没有已存储的校验和,则返回NULL,这个过程非常快。活性表校验和可以在使用CREATE TABLE语句创建表时,通过指定表选项“CHECKSUM=1”来启用,然而目前只被MyISAM表支持。

③当指定选项EXTENDED时,整个表会一行一行地被读取,并计算校验和,因而对于较大的表,这个过程可能会很慢。

④默认情况下,如果既没有指定QUICK,也没有指定EXTENDED,并且如果表的存储引擎支持,则MySQL返回一个活性校验和,否则会对表进行扫描。

⑤如果对一个不存在的表执行CHECKSUM TABLE语句,系统会返回NULL,并且产生一个警告。 (3)CHECKSUM TABLE语句的实例

【例8.7】对数据库mysql_test中的表customers使用CHECKSUM TABLE语句获取一个校验和。 【答】在MySQL的命令行客户端输入如下SQL语句即可得到该表的校验和:

4.OPTIMIZE TABLE语句

(1)OPTIMIZE TABLE语句的作用

如果用户不断地使用INSERT、DELETE和UPDATE语句更新一个表,特别是使用这些语句操作含有VARCHAR、BLOB或TEXT列的表时,表的内部结构会出现很多碎片和未利用的空间。为保证数据的读取效率,可以定期地使用OPTIMIZE TABLE语句来重新利用未使用的空间,并整理数据文件的碎片。

(2)OPTIMIZE TABLE语句的语法格式

OPTIZE [NO,WRITE_TO_BINLOG | LOCAL] TABLE

tbl_name [,tbl_name]… 使用说明如下:

①在OPTIMIZE TABLE语句的执行过程中,MySQL会锁定表。

②OPTIMIZE TABLE语句只对MyISAM、BDB和InnoDB表起作用。

③与ANALYZE TABLE语句一样,如果在MySQL上开启了二进制日志文件,那么OPTI_MIZE TABLE语句执行操作的结果也会写入二进制日志文件中。也可以在OPTIMIZE TA_BLE语句中添加

NO_WRITE_TO_BINLOG或LOCAL选项来取消写入,其中关键字NO_WRITE_TO_BINLOG与LOCAL同义。

(3)OPTIMIZE TABLE语句的实例

【例8.8】优化数据库mysql_test中的表customers。 在MySQL的命令行客户端输入如下SQL语句即可: mysql>OPTIMIZE TABLE mysql_test.customers;

5.REPAIR TABLE语句

(1)REPAIR TABLE语句的作用

可以使用REPAIR TABLE语句尝试修复一个或多个可能被损坏的表。REPAIR TABLE语句只对MyISAM和ARCHIVE表起作用。

(2)REPAIR TABLE语句的语法格式

REPAIR [NO_WRITE_TO_BINLOG|LOCAL] TABLE

tbl_name[,tbl_name]…

[QUICK] [EXTENDED] [USE_FRM] (3)REPAIR TABLE语句的语法说明

QUICK:最快的选项,若指定此选项,则REPAIR TABLE操作会尝试只修复索引树。 EXTENDED:最慢的选项,若指定此选项,则MySQL会逐行创建索引。

USE_FRM:只有当MYl索引文件丢失时才使用这个选项,全面重建整个索引。

NO_WRITE_TO_BINLOG或LOCAL:与ANALYZE TABLE语句一样,如果在MySQL上开启了二进制日志文件,那么REPAIR TABLE语句执行操作的结果也会写入二进制日志文件中。也可以在REPAIR TABLE语句中添加NO_WRITE_TO_BINLOG或LOCAL选项来取消写入,其中关键字NO_WRITE_TO_BINLOG与LOCAL同义。

第9章 触发器

一、触发器

触发器是一个被指定关联到一个表的数据库对象,当对一个表的特定事件出现时,它将会被激活。触发器具有MySQL语句在需要时才被执行的特点,即某条(或某些)MySQL语句在特定事件发生时自动执行。

触发器用于保护表中的数据。当有操作影响到触发器所保护的数据时,触发器就会自动执行,从而保障数据库中数据的完整性,以及多个表之间数据的一致性。

触发器就是MySQL响应INSERT、UPDATE和DELETE语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组MySQL语句)。其他MySQL语句是不支持触发器的。

二、创建触发器

1.CREATE TRIGGER语句创建触发器的语法格式

2.CREATE TRIGGER语句创建触发器的语法说明

(1)DEFINER从句:指定当触发器被触发时满足事件执行权限的安全上下文。 (2)trigger_name

触发器的名称,触发器在当前数据库中必须具有唯一的名称。如果要在某个特定数据库中创建,名称前面应该加上数据库的名称。

(3)trigger_time

触发器被触发的时刻,它有两个选项,即BEFORE和AFTER,用于表示触发器是在激活它的语句之前或者之后触发。如果希望验证新数据是否满足使用的限制,则使用 BEFORE选项;如果希望在激活触发器的语句执行之后完成几个或更多的改变,通常使用AFTER选项。

(4)trigger_event:触发事件,用于指定激活触发器的语句的种类,其可以是下述值之一: INSERT:将新行插入表时激活触发器。 UPDATE:更改表中某一行时激活触发器。 DELETE:从表中删除某一行时激活触发器。 (5)tbl_name

与触发器相关联的表名,必须引用永久性表,不能将触发器与临时表或视图关联起来。在该表上触发事件发生时才会激活触发器。同一个表不能拥有两个具有相同触发时刻和事件的触发器。例如,对于一张数据表,不能同时有两个BEFORE UPDATE触发器,但可以有一个BEFORE UPDATE触发器和一个BEFORE INSERT触发器,或一个BEFORE UPDATE触发器和一个AFTER UPDATE触发器。

(6)FOR EACH ROW

这个声明用来指定,对于受触发事件影响的每一行都要激活触发器的动作。例如,使用一条INSERT语句向一个表中插入多行数据时,触发器会对每一行数据的插入都执行相应的触发器动作。

(7)trigger_body 触发器动作主体,包含触发器激活时将要执行的MySQL语句。如果要执行多个语句,可使用BEGIN...END复合语句结构。这里可使用存储过程中允许的相同语句。

注意,在触发器的创建中,每个表每个事件每次只允许一个触发器。因此,每个表最多支持6个触发器,即每条INSERT、UPDATE和DELETE的之前与之后。单一触发器不能与多个事件或多个表关联,例如,需要一个对INSERT和UPDATE操作执行的触发器,则应该定义两个触发器。

3.SHOW TRIGGER语句查看触发器的语法说明

在MySQL中,如若需要查看数据库中已有的触发器,可以使用SHOW TRIGGERS语句。其语法格式为:

4.创建触发器的实例

【例9.1】在数据库mysql_test的表customers中创建一个触发器customers_insert_trigger,用于每次向表customers中插入一行数据时,将用户变量str的值设置为“one customer added!”。

【答】首先,在MySQL命令行客户端输入如下SQL语句:

然后,在MySQL命令行客户端使用INSERT语句向表customers中插入如下一行数据:

最后,在MySQL命令行客户端输入如下SQL语句验证触发器:

三、删除触发器

1.DROP TRIGGER删除触发器的语法格式

2.DROP TRIGGER删除触发器的语法说明

(1)IF EXISTS:可选项,用于避免在没有触发器的情况下删除触发器。

(2)schema_name:可选项,用于指定触发器所在的数据库的名称。若没有指定,则为当前默认数据库。 (3)trigger_name:要删除的触发器名称。 (4)DROP TRIGGER语句需要SUPER权限。

当删除一个表的同时,也会自动地删除该表上的触发器。另外,触发器不能更新或覆盖,为了修改一个触发器,必须先删除它,然后再重新创建。

四、使用触发器

MySQL所支持的触发器有三种:INSERT触发器、DELETE触发器和UPDATE触发器。 1.INSERT触发器

INSERT触发器可在INSERT语句执行之前或之后执行。使用该触发器时,需要注意以下几点:

(1)在INSERT触发器代码内,可引用一个名为NEW(不区分大小写)的虚拟表,来访问被插入的行。 (2)在BEFORE INSERT触发器中,NEW中的值也可以被更新,即允许更改被插入的值(只要具有对应的操作权限)。

(3)对于AUTO_INCREMENT列,NEW在INSERT执行之前包含的是0值,在INSERT执行之后将包含新的自动生成值。

2.DELETE触发器

DELETE触发器可在DELETE语句执行之前或之后执行。使用该触发器时,需要注意这样几点:

(1)在DELETE触发器代码内,可以引用一个名为OLD(不区分大小写)的虚拟表,来访问被删除的行。 (2)OLD中的值全部是只读的,不能被更新。

3.UPDATE触发器

UPDATE触发器在UPDATE语句执行之前或之后执行。使用该触发器时,需要注意如下几点:

(1)在UPDATE触发器代码内,可以引用一个名为OLD(不区分大小写)的虚拟表访问以前(UPDATE语句执行前)的值,也可以引用一个名为NEW(不区分大小写)的虚拟表访问新更新的值。

(2)在BEFORE UPDATE触发器中,NEW中的值可能也被更新,即允许更改将要用于UPDATE语句中的值(只要具有对应的操作权限)。

(3)OLD中的值全部都是只读的,不能被更新。

(4)当触发器涉及对触发表自身的更新操作时,只能使用BEFORE UPDATE触发器,而AFTER UPDATE触发器将不被允许。

4.触发器的执行过程错误处理的方式

(1)如果BEFORE触发程序失败则MySQL将不执行相应行上的操作。

(2)仅当BEFORE触发程序和行操作均已被成功执行,MySQL才会执行AFTER触发程序。 (3)如果在BEFORE或AFTER触发程序的执行过程中出现错误,将导致调用触发程序的整个语句的失败。 (4)对于事务性表,如果触发程序失败,以及由此导致的整个语句的失败,那么该执行语句所执行的所有更改将回滚;对于非事务性表,则不能执行这类回滚,因而即使语句失败,失败之前所作的任何更改会依然有效。

五、对触发器的进一步说明

1.与其他DBMS相比,目前MySQL版本所支持的触发器还较为初级。未来的MySQL版本中有一些改进和增强触发器支持的计划。

2.创建触发器可能需要特殊的安全访问权限,但是触发器的执行是自动的。也就是说,如果INSERT、DELETE和UPDATE语句能够执行,则相关的触发器也能执行。

3.应该多用触发器来保证数据的一致性、完整性和正确性。

4.触发器有一种十分有意义的使用模式—创建审计跟踪,也就是可使用触发器把表的更改状态以及之前和之后的状态记录到另外一张数据表中。

5.MySQL触发器不支持CALL语句。因此,不能在触发器代码内直接调用存储过程,只能手工地将所需的存储过程代码复制到触发器内。

第10章 事 件

一、事件

1.事件和触发器的联系

事件和触发器相似,都是在某些事件发生的时候启动,因此事件也可称为临时触发器(temporal trigger)。事件基于特定时间周期触发来执行某些任务,而触发器是基于某个表所产生的事件触发的,它们的区别也在于此。

2.查看和开启EVENT_SCHEDULER的方法

在使用事件调度器这个功能之前,必须确保MySQL中EVENT_SCHEDULER已被开启。这可通过执行如下MySQL命令语句来查看当前是否已开启事件调度器:

mysql> SHOW VARIABLES LIKE‘EVENT_SCHEDULER’; 或者,查看系统变量:

mysql>SELECT @@ EVENT_SCHEDULER;

如若没有被开启,可通过执行如下MySQL命令语句来开启该功能:

mysql>SET GLOBAL EVENT_SCHEDULER=1;

或者:mysql>SET GLOBAL EVENT_SCHEDULER=TRUE;

再或者,可以在MySQL的配置文件my.ini中加上EVENT_SCHEDULER=1或SET GLOBAL EVENT_SCHEDULER=ON来开启。

二、创建事件

1.CREATE EVENT语句创建事件的语法格式

(1)schedule的语法格式为:

(2)interval的语法格式为:

2.CREATE EVENT语句创建事件的语法说明

(1)event name:指定事件名,前面可以添加关键字IF NOT EXISTS来修饰。

(2)schedule:时间调度,用于指定事件何时发生或者每隔多久发生一次,分别对应下面两个子句: ①AT子句

用于指定事件在某个时刻发生。timestamp表示一个具体的时间点,后面可以加上一个时间间隔,表示在这个时间间隔后事件发生;interval表示这个时间间隔,由一个数值和单位构成;quantity是间隔时间的数值。

②EVERY子句

用于表示事件在指定时间区间内每间隔多长时间发生一次。STARTS子句用于指定开始时间;ENDS子句用于指定结束时间。

(3)event_body

DO子句中的event_body部分用于指定事件启动时所要求执行的代码。如果包含多条语句,可以使用BEGIN…END复合结构。

(4)ON COMPLETION[NOT]PRESERVE:可选项

表示事件的一种属性。若指定关键字NOT,则该选项表示事件最后一次调用后将自动删除该事件;若不指定关键字NOT,则该选项表示事件最后一次调用后将保留该事件。该选项默认时不指定关键字NOT。

(5)ENABLE | DISABLE | DISABLE ON SLAVE:可选项

表示事件的一种属性。关键字ENABLE表示该事件是活动的,活动意味着调度器检查事件动作是否必须调用;关键字DISABLE表示该事件是关闭的,关闭意味着事件的声明存储到目录中,但是调度器不会检查它是否应该调用;关键字DISABLE ON SLAVE表示事件在从机中是关闭的。如果不指定这三个选项中的任何一个,则在一个事件创建之后,它立即变为活动的。

3.CREATE EVENT语句创建事件的实例

【例10.1】在数据库mysql_test中创建一个事件,用于每个月向表customers中插入一条数据,该事件开始于下个月并且在2013年12月31日结束。

在MySQL命令行客户端输入如下SQL语句即可实现该事件:

三、修改事件

在MySQL 5.5中,事件被创建之后可以通过使用ALTER EVENT语句来修改其定义和相关属性,其语法格式为:

ALTER EVENT语句与CREATE EVENT语句使用的语法相似。用户可以使用一条ALTER EVENT语句让一个事件关闭或再次让其活动。

一个事件最后一次被调用后,它是无法被修改的,因为此时它已不存在了。

四、删除事件

在MySQL 5.5中,可以使用DROP EVENT语句删除已创建的事件,其语法较为简单,语法格式为: DROP EVENT [IF EXISTS] event_name

第11章 存储过程与存储函数

一、存储过程

1.存储过程的介绍 (1)存储过程的定义

存储过程是一组为了完成某特定功能的SQL语句集,其实质上就是一段存放在数据库中的代码,它可以由声明式的SQL语句(如CREATE、UPDSELECT等语句)和过程式SQL语句(如IF-THEN-ELSE控制结构语句)组成。

(2)存储过程和SQL语句效率比较 这组语句经过编译后会存储在数据库中。用户只需通过指定存储过程的名字并给定参数(如果该存储过程带有参数),即可随时调用并执行它,而不必重新编译,因此这种通过定义一段程序存放在数据库的方式,可加大数据库操作语句的执行效率。而前面介绍的各条MySQL数据库操作语句(SQL语句)在其执行过程中,需要首先编译,然后再执行。尽管这个过程会由DBMS自动完成,且对SQL语句的使用者透明,但每次执行之前都需要预先编译,就成为了数据库操作语句执行效率的一个瓶颈问题。

(3)存储过程的优点

①可增强SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

②良好的封装性。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句,并且数据库专业人员可以随时对存储过程进行修改,而不会影响到调用它的应用程序源代码。

③高性能。存储过程执行一次后,其执行规划就驻留在高速缓冲存储器中,在以后的操作中,只需从高速缓冲存储器中调用已编译好的二进制代码执行即可,从而提高了系统性能。

④可减少网络流量。由于存储过程是在服务器端运行,且执行速度快,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而可降低网络负载。

⑤存储过程可作为一种安全机制来确保数据库的安全性和数据的完整性。使用存储过程可以完成所有数据库操作,并可通过编程方式控制这些数据库操作对数据库信息访问的权限。

⑥存储过程既是一个可编程的函数,又是在数据库编程中对面向对象方法的模拟,它允许控制数据的访问方式。

2.创建存储过程

(1)使用CREATE PROCEDURE语句创建存储过程的语法格式

①proc_parameter的格式为:

②type的格式为:

③characteristic的格式为:

④routine_body的格式为:

(2)使用CREATE PROCEDURE语句创建存储过程的主要语法说明 ①sp_name

存储过程的名称,默认在当前数据库中创建。需要在特定数据库中创建存储过程时,则要在名称前面加上数据库的名称,即db_name.sp_name的格式。需要注意的是,这个名称应当尽量避免取与MySQL的内置函数相

同的名称,否则会发生错误。

②proc_parameter

存储过程的参数列表。param_name为参数名,type为参数的类型(可以是任何有效的MySQL数据类型)。当有多个参数时,参数列表中彼此间用逗号分隔。存储过程可以没有参数(此时存储过程的名称后仍需加上一对括号),也可以有1个或多个参数。MySQL存储过程支持三种类型的参数,即输入参数、输出参数和输入/输出参数,分别用IN、OUT和INOUT三个关键字标识。输入参数是使数据可以传递给一个存储过程;输出参数用于存储过程需要返回一个操作结果的情形;而输入/输出参数既可以充当输入参数也可以充当输出参数。需要注意的是,参数的取名不要与数据表的列名相同,否则尽管不会返回出错消息,但周存储过程中的SQL语句会将参数名看作是列名,从而引发不可预知的结果。

③characteristic:存储过程的某些特征设定,下面分别介绍。 a.COMMENT′string′ 用于对存储过程的描述,其中string为描述内容,COMMENT为关键字。这个描述信息可以用SHOW CREATE PROCEDURE语句来显示。

b.LANGUAGE SQL

指明编写这个存储过程的语言为SQL语言。目前而言,MySQL存储过程还不能用外部编程语言来编写,也就是说,这个选项可以不指定。今后MySQL将会对其扩展,最有可能第一个被支持的语言是PHP。

c.DETERMINISTIC

如若设置为DETERMINISTIC,表示存储过程对同样的输入参数产生相同的结果;若设置为NOT DETERMINISTIC,则表示会产生不确定的结果。默认为NOT DETERMINISTIC。

d.CONTAINS SQL|NO SQL|READS SQL DATA | MODIFIES SQL DATA

CONTAINS SQL表示存储过程包含读或写数据的语句;NO SQL表示存储过程不包含SQL语句;READS SQL DATA表示存储过程包含读数据的语句,但不包含写数据的语句;MODIFIES SQL DATA表示存储过程包含写数据的语句。若没有明确给定,则默认为CONTAINS SQL。

e.SQL SECURITY

这个特征用来指定存储过程使用创建该存储过程的用户(DEFINER)的许可来执行,还是使用调用者(INVOKER)的许可来执行。没有明确指定时,默认为DEFINER。

f.routine_body

存储过程的主体部分,也称为存储过程体,其包含了在过程调用的时候必须执行的SQL语句。这个部分以关键字BEGIN开始,以关键字END结束。如若存储过程体中只有一条SQL语句时,可以省略BEGIN–END标志。另外,在存储过程体中,BEGIN–END复合语句还可以嵌套使用。

第一,DELIMITER命令的作用

在MySQL中,服务器处理SQL语句默认是以分号作为语句结束标志。然而,在创建存储过程时,存储过程体中可能包含有多条SQL语句,这些SQL语句仍以分号作为语句结束符,那么MySQL服务器在处理时会以遇到的第一条SQL语句结尾处的分号作为整个程序的结束符,而不再去处理存储过程体中后面的SQL语句,这样显然不行。为解决这个问题,通常可使用DELIMITER命令,将MySQL语句的结束临时改为其他符号,从而使得MySQL服务器可以完整地处理存储过程体中的所有SQL语句

第二,DELIMITER 命令的语法格式 DELIMITER $$

第二,DELIMITER 命令的语法说明

$$是用户定义的结束符,通常这个符号可以是一些特殊的符号,如两个“#”或两个“¥”等。

当使用DELIMITER命令时,应该避免使用反斜杠(“\”)字符,因为它是MySQL的转义字符。 (3)CREATE PROCEDURE语句创建存储过程的实例

【例11.1】在数据库mysql_test中创建一个存储过程,用于实现给定表customers中一个cust_id即可修改表customers中该客户的性别为一个指定的性别。

【答】在MySQL命令行客户端输入如下SQL语句即可创建这个存储过程:

【使用说明】在MySQL 5.5中创建存储过程,必须具有CREATE ROUTINE权限。如若要查看数据库中存在哪些存储过程,可以使用SHOW PROCEDURE STATUS命令;若要查看某个存储过程的具体信息,则可以使用SHOW CREATE PROCEDURE sp_name命令,其中sp_name用于指定该存储过程的名称。

3.存储过程体

存储过程体可以使用各种SQL语句与过程式语句的组合,来封装数据库应用中复杂的业务逻辑和处理规则,以实现数据库应用的灵活编程。

(1)局部变量

用来存储存储过程体中的临时结果。

①DECLARE语句声明局部变量的语法格式

②DECLARE语句声明局部变量的语法说明 var_name:用于指定局部变量的名称。 type:用于声明局部变量的数据类型。

DEFAULT子句:用于为局部变量指定一个默认值。若没有指定,则默认为NULL。 ③DECLARE语句声明局部变量的使用说明:

a.局部变量只能在存储过程体的BEGIN…END语句块中声明。 b.局部变量必须在存储过程体的开头处声明。

c.局部变量的作用范围仅限于声明它的BEGIN…END语句块,其他语句块中的语句不可以使用它。

d.局部变量不同于用户变量,两者间的区别是:局部变量声明时,在其前面没有使用@符号,并且它只能被声明它的BEGIN…END语句块中的语句所使用;而用户变量在声明时,会在其名称前面使用@符号,同时已声明的用户变量存在于整个会话之中。

(2)SET语句

可以使用SET语句为局部变量赋值,其语法格式是:

(3)SELECT…INTO语句

可以使用SELECT…INTO语句把选定列的值直接存储到局部变量中,其语法格式是:

语法说明如下:

col_name:用于指定列名。

var_name:用于指定要赋值的变量名。

table_expr:表示SELECT语句中的FROM子句及后面的语法部分。

说明:存储过程体中的SELECT…INTO语句返回的结果集只能有一行数据。 (4)流程控制语句 ①条件判断语句

第一,IF–THEN–ELSE语句

IF–THEN–ELSE语句可以根据不同的条件执行不同的操作,其语法格式为:

语法及使用说明如下:

search_condition:用于指定判断的条件。

statement_list:用于表示包含了一条或多条的SQL语句。

只有当判断条件search_condition为真时,才会执行相应的SQL语句。 IF–THEN–ELSE语句不同于系统内置函数IF()。 第二,CASE语句

语法说明如下:

第一种语法格式中的case_value用于指定要被判断的值或表达式,随后紧跟的是一系列的WHEN–THEN语句块。每一个WHEN*THEN语句块中的参数when_value用于指定要与case_value进行比较的值。倘若比较的结果为真,则执行对应的statement_list中的SQL语句。如若每一个WHEN–THEN语句块中的参数when_value都不能与case_value相匹配,则会执行ELSE子句中指定的语句。该CASE语句最终会以关键字END CASE作为结束。

第二种语法格式中的关键字CASE后面没有指定参数,而是在WHEN–THEN语句块中使用search_condition指定了一个比较表达式。如若该表达式为真,则会执行对应的关键字THEN后面的语句。与第一种语法格式相比,这种语法格式能够实现更为复杂的条件判断,而且使用起来会更方便些。

②循环语句

第一,WHILE语句

WHILE语句的语法格式是:

语法说明如下:

WHILE语句首先判断条件search-condition是否为真,倘若为真,则执行statement_list中的语句,然后再次进行判断,如若仍然为真则继续循环,直至条件判断不为真时结束循环。

begin_label和end_label是WHILE语句的标注,且必须使用相同的名字,并成对出现。 第二,REPEAT语句

REPEAT语句的语法格式为:

语法说明如下:

REPEAT语句首先执行statement_list中的语句,然后判断条件search_condition是否为真,倘若为真,则结束循环,如若不为真,则继续循环。

REPEAT也可以使用begin_label和end_label进行标注。

REPEAT语句和WHILE语句的区别在于:REPEAT语句先执行语句,后进行判断;而WHILE语句是先判断,条件为真时才执行语句。

第三,LOOP语句

LOOP语句的语法格式为:

语法说明如下:

LOOP语句允许重复执行某个特定语句或语句块,实现一个简单的循环构造,其中statement_list用于指定需要重复执行的语句。

begin_label和end_label是LOOP语句的标注,且必须使用相同的名字,并成对出现。

在循环体statement_list中语句会一直重复被执行,直至循环使用LEAVE语句退出。LEAVE语句的语法格式为:LEAVE label,这里的label是LOOP语句中所标注的自定义名字。

另外,循环语句中还可以使用ITERATE语句,但它只能出现在循环语句的LOOP、REPEAT和 WHILE子句中,用于表示退出当前循环,且重新开始一个循环。其语法格式是:ITERATE label,这里的label同样是循环语句中自定义的标注名字。ITERATE语句与LEAVE语句的区别在于: LEAVE语句是结束整个循环,而ITERATE语句只是退出当前循环,然后重新开始一个新的循环。

(5)游标 ①游标的作用

在MySQL中,一条SELECT…INTO语句成功执行后,会返回带有值的一行数据,这行数据可以被读取到存储过程中进行处理。然而,在使用SELECT语句进行数据检索时,若该语句成功被执行,则会返回一组称为结果集数据行,该结果集中可能拥有多行数据,这些数据无法直接被一行一行地进行处理,此时就需要使用游标。游标是一个被SELECT语句检索出来的结果集。在存储了游标后,应用程序或用户就可以根据需要滚动或浏览其中的数据。

②使用游标的注意事项

第一,在MySQL对游标的支持是从MySQL5.0开始的,即之前的MySQL无法使用游标。 第二,游标只能用于存储过程或存储函数中,不能单独在查询操作中使用。

第三,在存储过程或存储函数可以定义多个游标,但是在一个BEGIN…END语句块中每一个游标的名字必须是唯一的。

第四,游标不是一条SELECT语句,是被SELECT语句检索出来的结果集。 ③使用游标的具体步骤 第一,声明游标

在使用游标之前,必须先声明(定义)它。这个过程实际上没有检索数据,只是定义要使用的SELECT语句。创建游标的语法格式为:

DECLARE cursor_name CURSOR FOR select_statement

语法说明如下:

cursor_name:指定要创建的游标的名称,其命名规则与表名相同。

select_statement:指定一个SELECT语句,其会返回一行或多行的数据。注意:这里的SELECT语句不能有INTO子句。

第二,打开游标 必须打开该游标,才能使用。这个过程实际上是将游标连接到由SELECT语句返回的结果集中。打开游标的语法格式是:

OPEN cursor_name

cursor_name用于指定要打开的游标。

在实际应用中,一个游标可以被多次打开,由于其他用户或应用程序可能随时更新了数据表,因此每次打开

游标的结果集可能会不同。

第三,读取数据

对于填有数据的游标,可根据需要取出数据。使用FETCH…INTO语句从中读取数据的语法格式为:

FETCH cursor_name INTO var_name[,var_name]…

语法说明如下:

cursor_name:用于指定已打开的游标。 var_name:用于指定存放数据的变量名。

FETCH…INTO语句与SELECT…INTO语句具有相同的意义,FETCH语句是将游标指向的一行数据赋给一些变量,这些变量的数目必须等于声明游标时SELECT子句中选择列的数目。游标相当于一个指针,它指向当前的一行数据。

第四,关闭游标

在结束游标使用时,必须关闭游标。关闭游标的语法格式为:

CLOSE cursor_name

cursor_name用于要关闭的游标。

每个游标不再需要时都应该被关闭,使用CLOSE语句将会释放游标所使用的全部资源。在一个游标被关闭后,如果没有重新被打开,则不能被使用。对于声明过的游标,则不需要再次声明,可直接使用OPEN语句打开。另外,如果没有明确关闭游标,MySQL将会在到达END语句时自动关闭它。

④使用游标的实例

【例11.2】在数据库mysql_test中创建一个存储过程,用于计算表customers中数据行的行数。 【答】首先,在MySQL命令行客户端输入如下SQL语句创建存储过程sp_sumofrow:

然后,在MySQL命令行客户端输入如下SQL语句对存储过程sp_sumofrow进行调用: mysql>CALL sp_sumofrow(@rows);

Query OK,0 rows affected,1 warning(0.00 sec)

最后,在MySQL命令行客户端输入如下SQL语句,并查看调用存储过程sp_sumofrow后的结果:

【例11.2】说明

第一,本例中定义了一个CONTINUE HANDLER句柄,它是在条件出现时被执行的代码,用于控制循环语句,以实现游标的下移。

第二,DECLARE语句的使用存在特定的次序。用DECLARE语句定义的局部变量必须在定义任意游标或句柄之前定义,而句柄必须在游标之后定义,否则系统会出现错误信息。

4.调用存储过程

使用CALL语句在程序,触发器或其他存储过程中调用它,其语法格式为

CALL sp_name([parameter[,…]])

CALL sp_name[()]

语法说明如下:

sp_name:指定被调用的存储过程的名称。如果要调用某个特定数据库的存储过程,则需要在前面加上该数据库的名称。

parameter:指定调用存储过程所要使用的参数。调用语句中参数的个数必须等于存储过程的参数个数。 当调用没有参数的存储过程时,使用CALL sp_name( )语句与使用CALL sp_name语句是相同的。

5.修改存储过程

可以使用ALTER PROCEDURE语句修改存储过程的某些特征,其语法格式为:

ALTER PROCEDURE proc_name[characteristic…]

characteristic的格式为:

这个语法中的characteristic部分用于指定要修改的存储过程的特征。在ALTER PROCEDURE语句中,只要设定了其中的值,存储过程的特征就会随之变化。另外,如若要修改存储过程的内容,可以先删除该存储过程,然后再重新创建。

6.删除存储过程

存储过程在被创建后,会被保存在服务器上以供使用,直至被删除。 (1)DROP PROCEDURE语句删除存储过程的语法格式

DROP PROCEDURE FUNCTION[IF_EXISTS]sp_name

(2)DROP PROCEDURE语句删除存储过程的语法说明

sp_name:指定要删除的存储过程的名称。注意,它后面没有参数列表,也没有括号。在删除之前,必须确认该存储过程没有任何依赖关系,否则会导致其他与之关联的存储过程无法运行。

IF EXISTS:指定这个关键字,用于防止因删除不存在的存储过程而引发的错误。

二、存储函数

1.存储函数和存储过程的相同点

都是由SQL语句和过程式语句所组成的代码片断,并且可以被应用程序和其他SQL语句调用。

2.存储函数与存储过程之间的区别

(1)存储函数不能拥有输出参数,这是因为存储函数自身就是输出参数;而存储过程可以拥有输出参数。 (2)可以直接对存储函数进行调用,且不需要使用CALL语句;而对存储过程的调用,需要使用CALL语

句。

(3)存储函数中必须包含一条RETURN语句,而这条特殊的SQL语句不允许包含于存储过程中。

3.创建存储函数

(1)CREATE FUNCTION语句创建存储函数的语法格式

①func_parameter的格式

param_name type

②type的格式

Any valid MySQL data type

③characteristic的格式

④routine_body的格式

Valid SQL routine statement

(2)CREATE FUNCTION语句创建存储函数的语法说明

sp_name:这里是用于指定存储函数的名称。注意,存储函数不能与存储过程具有相同的名字。 func_parameter:用于指定存储函数的参数。这里的参数只有名称和类型,不能指定关键字IN、OUT和INOUT。 RETURNS子句:用于声明存储函数返回值的数据类型。type用于指定返回值的数据类型。

routine_body:存储函数的主体部分,也称存储函数体。所有在存储过程中使用的SQL语句在存储函数中同样也适用,包括前面所介绍的局部变量、SET语句、流程控制语句、游标等。但是,存储函数体中还必须包含一个RETURN value语句,其中value用于指定存储函数的返回值。

(3)CREATE FUNCTION语句创建存储函数的实例

【例11.3】在数据库mysql_test中创建一个存储函数,要求该函数能根据给定的cust_id返回客户的性别,如果数据库中没有给定的cust_id,则返回“没有该客户”。

在MySQL命令行客户端输入如下SQL语句即可实现这个存储函数:

使用说明:在RETURN value语句中包含有SELECT语句时,SELECT语句的返回结果只能是一行且只能有一列值。另外,如若要查看数据库中存在哪些存储函数,可以使用SHOW FUNCTION STATUS语句;若要查看数据库中某个具体的存储函数,可以使用SHOW CREATE FUNCTION sp_name语句,其中sp_name用于指定该存储函数的名称。

4.调用存储函数

成功创建存储函数后,就可以如同调用系统内置函数一样,使用关键字SELECT对其进行调用,其语法格式是:

SELECT sp_name([func_parameter[,…]])

5.删除存储函数

存储函数在被创建后,会被保存在服务器上以供使用,直至被删除。删除存储函数的方法与删除存储过程的方法基本一样。在MySQL 5.5中,可以使用DROP FUNCTION语句来实现,其语法格式为:

DROP FUNCTION[IF EXISTS]sp_name

语法说明如下:

sp_name:指定要删除的存储函数的名称。注意,它后面没有参数列表,也没有括号。在删除之前,必须确认该存储函数没有任何依赖关系,否则会导致其他与之关联的存储函数无法运行。

IF EXISTS:指定这个关键字,用于防止因删除不存在的存储函数而引发的错误。

6.修改存储函数

在MySQL 5.5中,通过ALTER FUNCTION语句来修改存储函数的某些相关特征,其语法格式为:

ALTER FUNCTIN func_name[characteristic]

characteristic的格式为:

这个语法中的characteristic部分用于指定要修改的存储函数的特征。 若要修改存储函数的内容,则需要先删除该存储函数,然后重新创建。

第12章 访问控制与安全管理

一、用户账号管理 1.用户账号介绍

MySQL的用户账号及相关信息都存储在一个名为mysql的MySQL数据库中,这个数据库里有一个名为user的数据表,包含了所有用户账号,并且它用一个名为user的列存储用户的登录名。

一个新安装的系统,当前只有一个名为root的用户。root用户是在成功安装MySQL服务器后,由系统创建的,并且被赋予了操作和管理MySQL的所有权限。因此,root用户拥有对整个MySQL服务器完全控制的权限。

2.创建用户账号

(1)CREATE USER语句创建账户的语法格式

user_specification的格式为:

(2)CREATE USER语句创建账户的语法说明 ①user

指定创建用户账号,其格式为'user_name'@'host namel'。这里,user_name是用户名,host_name为主机名,即用户连接MySQL时所在主机的名字。如果在创建的过程中,只给出了账户中的用户名,而没指定主机名,则主机名会默认为是“%”,表示一组主机。

②IDENTIFIED BY子句

用于指定用户账号对应的口令,若该用户账号无口令,则可省略此子句。 ③可选项PASSWORD

用于指定散列口令,即若使用明文设置口令时,需忽略PASSWORD关键字:如果不想以明文设置口令,且知道PASSWORD函数返回给密码的散列值,则可以在此口令设置语句中指定此散列值,但需要加上关键字PASSWORD。

④password

指定用户账号的口令,在IDENTIFIED BY关键字或PASSWORD关键字之后。给定的口令值可以是只由字母和数字组成的明文,也可以是通过PASSWOED函数得到的散列值。

⑤IDENTIFIED WITH子句

用于指定验证用户账号的认证插件。

⑥auth_plugin:指定认证插件的名称,紧跟在IDENTIFIED WITH关键字之后。 (3)CREATE USER语句创建账户的实例

【例12.1】在MySQL服务器中添加两个新的用户,其用户名分别为zhangsan和lisi,他们的主机名均为localhost,用户zhangsan的口令设置为明文123,用户lisi的口令设置为对明文456使用PASSWORD( )函数加密返回的散列值。

【答】首先,在MySQL的命令行客户端输入下面的SQL语句,得到明文456所对应的PASSWORD( )函数返回的散列值:

(4)CREATE USER语句创建账户的使用说明

①要使用CREATE USER语句,必须拥有MySQL中mysql数据库的INSERT权限或全局CREATE USER权限。

②使用CREATE USER语句创建一个用户账号后,会在系统自身的mysql数据库的user表中添加一条新记录。如果创建的账户已经存在,则语句执行会出现错误。

③如果两个用户具有相同的用户名和不同的主机名,MySQL会将他们视为不同的用户,并允许为这两个用户分配不同的权限集合。

④如果CREATE USER语句的使用中,没有为用户指定口令,那么MySQL允许该用户可以不使用口令登录系统,然而从安全的角度而言,不推荐这种做法。

⑤新创建的用户拥有的权限很少。他们可以登录到MySQL,只允许进行不需要权限的操作,如使用SHOW语句查询所有存储引擎和字符集的列表等,不能使用USE语句来让其他用户已经创建的任何数据库成为当前数据库,因而无法访问相关数据库的表。

3.删除用户

(1)DROP USER语句删除用户的语法格式

DROP USER user[,user]…

(2)DROP USER语句删除用户的使用说明

①DROP USER语句可用于删除一个或多个MySQL账户,并消除其权限。

②要使用DROP USER语句,必须拥有MySQL中mysql数据库的DELETE权限或全局CREATE USER权限。

③在DROP USER语句的使用中,如果没有明确地给出账户的主机名,则该主机名会默认为是%。

④用户的删除不会影响到他们之前所创建的表、索引或其他数据库对象,这是因为MySQL并没有记录是谁创建了这些对象。

(3)DROP USER语句删除用户的实例 【例12.2】删除前面例子中的lisi用户。

【答】在MySQL的命令行客户端输入如下SQL语句: mysql>DROP USER lisi; ERROR 1396(HY000):Operation DROP USER failed for'lisi'@'%'

可以看到,该语句不能成功执行,并给出一个错误提示。原因在于,在DROP USER语句中只给出了用户名lisi,没有明确给出该账号的主机名,系统则默认这个用户账号是'lisi'@t'%',而该账户不存在,所以语句执行出错。这里,只需在MySQL的命令行客户端重新输入下面SQL语句即可成功执行:

mysql>DROP USER lisi@localhost; Query OK,0 rows affected(0.00 sec)

4.修改用户账号

(1)RENAME USER语句修改用户账号的语法格式

(2)RENAME USER语句修改用户账号的语法说明 ①old_user:系统中已经存在的MySQL用户账号。 ②new_user:新的MySQL用户账号。 (3)RENAME USER语句的使用说明

①RENAME USER语句用于对原有MySQL账户进行重命名。

②要使用RENAME USER语句,必须拥有MySQL中mysql数据库的UPDATE权限或全局CREATE USER权限。

③倘若系统中旧账户不存在或者新账户已存在,则语句执行会出现错误。

5.修改用户口令

(1)SET PASSWORD语句用户登录口令的语法格式

(2)SET PASSWORD语句用户登录口令的语法说明 FOR子句:指定欲修改口令的用户。该子句为可选项。 PASSWORD('new_password'):表示使用函数PASSWORD( )设置新口令new_password,即新口令必须传递到函数PASSWORD( )中进行加密。

encrypted password:表示已被函数PASSWORD( )加密的口令值。 (3)SET PASSWORD语句的实例

【例12.3】将前面例子中用户wangwu的口令修改成明文“hello”对应的散列值。

【答】首先,在MySQL的命令行客户端输入下面的SQL语句,得到明文hello所对应的PASSWORD( )函数返回的散列值:

接着,使用SET PASSWORD语句修改用户wangwu的口令为明文“hello”对应的散列值:

(4)SET PASSWORD语句的使用说明

①在SET PASSWORD语句中,若不加上FOR子句,表示修改当前用户的口令;若加上FOR子句,表示修改账户为user的用户口令,其中user的格式必须以'user_name'@'host_name'的格式给定,user_name为账户的用户名,host_name为账户所在的主机名。该账户必须在系统中存在,否则语句执行会出现错误。

②在SET PASSWORD语句中,只能使用选项PASSWORD('new_password')和encrypted pass-word中的一项,且必须使用其中的某一项。

二、账户权限管理

新创建的用户账号没有访问权限,只能登录MySQL服务器,不能执行任何数据库操作。 1.权限的授予

(1)GRANT语句授予权限的语法格式

①object_type的格式为:

TABLE |FUNCTION |PROCEDURE

②priv_level的格式为:

③user_specification的格式为:

④with_option的格式为:

(2)GRANT语句授予权限的语法说明

①priv_type:用于指定权限的名称,如SELECT、UPDATE、DELETE等数据库操作。 ②可选项column_list:用于指定权限要授予给表中哪些具体的列。 ③ON子句:用于指定权限授予的对象和级别,如可在ON关键字后面给出要授予权限的数据库名或表名等。 ④可选项Object_type:用于指定权限授予的对象类型,包括表、函数和存储过程,分别用关键字TABLE、FUNCTION和PROCEDURE标识。

⑤priv_level:用于指定权限的级别。可以授予的权限有如下几组: 列权限,和表中的一个具体列相关。

表权限,和一个具体表中的所有数据相关。

数据库权限,和一个具体的数据库中的所有表相关。 用户权限,和MySQL中所有的数据库相关。

对应地,在GRANT语句中可用于指定权限级别的值有这样几类格式: *:表示当前数据库中的所有表。 *.*:表示所有数据库中的所有表。

db_name.*:表示某个数据库中的所有表,db_name指定数据库名。

db_name.tbl_name:表示某个数据库中的某个表或视图,db_name指定数据库名,tb1_name指定表名或视图名。

tbl_name:表示某个表或视图,tbl_name指定表名或视图名。 db_name.routine_name:表示某个数据库中的某个存储过程或函数,routine_name指定存储过程名或函数名。 ⑥TO子句

用来设定用户的口令,以及指定被授予权限的用户user。若在TO子句中给系统中存在的用户指定口令,则新密码会将原密码覆盖;如果权限被授予给一个不存在的用户,MySQL会自动执行一条CREATE USER语句来创建这个用户,但同时必须为该用户指定口令。

由此可见,GRANT语句亦可以用于创建用户账号。 ⑦user specification:TO子句中的具体描述部分,其与CREATE USER语句中的user_specification部分一样。 ⑧WITH子句:GRANT语句的最后可以使用WITH子句,为可选项,其用于实现权限的转移或限制。 (3)GRANT语句授予权限的实例

【例12.4】授予用户zhangsan在数据库mysql_test的表customers上拥有对列cust_id和列cust_name的SELECT权限。

【答】使用root登录MySQL服务器,并在MySQL的命令行客户端输入下面的SQL语句:

这条权限授予语句成功执行后,使用用户zhangsan的账户登录MySQL服务器,可以使用SELECT语句来查看表customers中列cust_id和列cust_name的数据了,而且目前仅能执行这项操作,如果执行其他的数据库操作,则会出现错误。

(4)GRANT语句中priv_type的使用说明

①授予表权限时,priv_type可以指定为以下值:

SELECT:表示授予用户可以使用SELECT语句访问特定表的权限。

INSERT:表示授予用户可以使用INSERT语句向一个特定表中添加数据行的权限。 DELETE:表示授予用户可以使用DELETE语句从一个特定表中删除数据行的权限。 UPDATE:表示授予用户可以使用UPDATE语句修改特定数据表中值的权限。 REFERENCES:表示授予用户可以创建一个外键来参照特定数据表的权限。 CREATE:表示授予用户可以使用特定的名字创建一个数据表的权限。 ALTER:表示授予用户可以使用ALTER TABLE语句修改数据表的权限。 INDEX:表示授予用户可以在表上定义索引权限。 DROP:表示授予用户可以删除数据表的权限。 ALL或ALL PRIVILEGES:表示所有的权限名。

②授予列权限时,priv_type的值只能指定为SELECT、INSERT和UPDATE,同时权限的后面需要加上列名列表column_list。

③授予数据库权限时,Priv_type可以指定为以下值:

SELECT:表示授予用户可以使用SELECT语句访问特定数据库中所有表和视图的权限。 INSERT:表示授予用户可以使用INSERT语句向特定数据库中所有表添加数据行的权限。 DELETE:表示授予用户可以使用DELETE语句删除特定数据库中所有表的数据行的权限。 UPDATE:表示授予用户可以使用UPDATE语句更新特定数据库中所有数据表的值的权限。 REFERENCES:表示授予用户可以创建指向特定的数据库中的表外键的权限。

CREATE:表示授予用户可以使用CREATE TABLE语句在特定数据库中创建新表的权限。 ALTER:表示授予用户可以使用ALTER TABLE语句修改特定数据库中所有数据表的权限。 INDEX:表示授予用户可以在特定数据库中的所有数据表上定义和删除索引的权限。 DROP:表示授予用户可以删除特定数据库中所有表和视图的权限。

CREATE TEMPORARY TABLES:表示授予用户可以在特定数据库中创建临时表的权限。 CREATE VIEW:表示授予用户可以在特定数据库中创建新的视图的权限。

SHOW VIEW:表示授予用户可以查看特定数据库中已有视图的视图定义的权限。

CREATE ROUTINE:表示授予用户可以为特定的数据库创建存储过程和存储函数等权限。

ALTER ROUTINE:表示授予用户可以更新和删除数据库中已有的存储过程和存储函数等权限。 EXECUTE ROUTINE:表示授予用户可以调用特定数据库的存储过程和存储函数的权限。 LOCK TABLES:表示授予用户可以锁定特定数据库的已有数据表的权限。 ALL或ALL PRIVILEGES:表示以上所有的权限。

④最有效率的权限是用户权限。授予用户权限时,priv_type除了可以指定为授予数据库权限时的所有值之外,还可以是下面这些值:

CREATE USER:表示授予用户可以创建和删除新用户的权限。

SHOW DATABASES:表示授予用户可以使用SHOW DATABASES语句查看所有已有的数据库的定义的权限。

2.权限的转移与限制

权限的转移与限制可以通过在GRANT语句中使用WITH子句来实现。 (1)转移权限

如果将WITH子句指定为WITH GRANT OPTION,则表示TO子句中所指定的所有用户都具有把自己所拥有的权限授予其他用户的权利,而无论那些其他用户是否拥有该权限。

(2)限制权限

如果WITH子句中WITH关键字后面紧跟的是MAX_QUERIES_PER_HOUR count、MAX_UPDATES_PER_HOUR count、MAX_CONNECTIONS_PER_HOUR count或MAX_USER_CONNECTIONS count中的某一项,则该GRANT语句可用于限制权限。其中,MAX_QUERIES_PER_HOUR count表示限制每小时可以查询数据库的次数;MAX_UPDATES_PER_HOUR count表示限制每小时可以修改数据库的次数;MAX_CONNECTIONS_PER_HOUR count表示限制每小时可以连接数据库的次数;MAX_USER_CONNECTIONS count表示限制同时连接MySQL的最大用户数。这里,count用于设置一个数值,对于前三个指定,count如果为0则表示不起限制作用。

【例12.5】授予系统中的用户huang在数据库mysql_test的表customers上每小时只能处理一条DELETE语句的权限。

使用root登录MySQL服务器,并在MySQL的命令行客户端输入下面的SQL语句即可:

3.权限的撤销

(1)REVOKE语句撤销权限的语法格式

(2)REVOKE语句撤销权限的使用说明

①REVOKE语句和GRANT语句的语法格式相似,但具有相反的效果。 ②第一种语法格式用于回收某些特定的权限。 ③第二种语法格式用于回收特定用户的所有权限。

④要使用REVOKE语句,必须拥有mysql数据库的全局CREATE USER权限或UPDATE权限。 (3)REVOKE语句撤销权限的实例

【例12.6】回收系统中已存在的用户zhou在数据库mysql_test的表customers上的SELECT权限。 使用root登录MySQL服务器,并在MySQL的命令行客户端输入下面的SQL语句即可:

第13章 备份与恢复

一、数据备份与恢复

1.引起数据库损坏的可能因素

(1)计算机硬件故障。由于用户使用的不当,或者硬件产品自身的质量问题等原因,计算机硬件可能会出现故障,甚至不能使用,如硬盘损坏会导致其存储的数丢失。

(2)计算机软件故障。由于用户使用的不当,或者软件设计上的缺陷,计算机软件系统可能会误操作数据,从而引起数据破坏。

(3)病毒。破坏性病毒会破坏计算机硬件、系统软件和数据。 (4)人为误操作。例如,用户误使用了DELETE、UPDATE等命令而引起数据丢失或破坏;一个简单的DROP TABLE或者DROP DATABASE语句,就会让数据表化为乌有;更危险的是DELETE*FROM table_name能轻易地清空数据表,这些人为的误操作是很容易发生的。

(5)自然灾害。火灾、洪水、地震等这些不可抵挡的自然灾害会对人类生活造成极大的破坏,也会毁坏计算机系统及其数据。

(6)盗窃。一些重要数据可能会被窃或人为破坏。

2.数据备份和数据恢复的概念

数据库备份是指通过导出数据或者拷贝表文件的方式来制作数据库的副本。 数据库恢复则是当数据库出现故障或遭到破坏时,将备份的数据库加载到系统,从而使数据库从错误状态恢复到备份时的正确状态。

数据库的恢复是以备份为基础的,它是与备份相对应的系统维护和管理操作。系统进行恢复操作时,先执行一些系统安全性的检查,包括检查所要恢复的数据库是否存在、数据库是否变化及数据库文件是否兼容等,然后根据所采用的数据库备份类型采取相应的恢复措施。

通过备份和恢复数据库,也可以实现将数据库从一个服务器移动或复制到另一个服务器的目的。通过备份和恢复策略来保证数据库中数据的可靠性和完整性。

二、MySQL数据库备份与恢复的方法 1.使用SQL语句备份和恢复表数据

在MySQL 5.5中,可以使用SELECT INTO…OUTFILE语句把表数据导出到一个文本文件中进行备份,并可使用LOAD DATA…INFILE语句来恢复先前备份的数据。这种方法有一点不足,就是只能导出或导入数据的内容,而不包括表的结构,若表的结构文件损坏,则必须先设法恢复原来表的结构。

(1)SELECT INTO…OUTFILE语句

导出备份语句SELECT INTO…OUTFILE的语法格式为:

export_options的格式为:

语法说明如下:

①这个语句的作用是将表中SELECT语句选中的所有数据行写入到一个文件中,file_name指定数据备份文件的名称。文件默认在服务器主机上创建,并且文件名不能是已经存在的,否则可能会将原文件覆盖。如果要将该文件写入到一个特定的位置,则要在文件名前加上具体的路径。在文件中,导出的数据行会以一定的形式存放,其中空值是用“\N”表示。

②导出语句中使用关键字OUTFILE时,可以在export_options中加入以下两个自选的子句,它们的作用是决定数据行在备份文件中存放的格式:

第一,FIELDS子句

在FIELDS子句中有三个亚子句,分别是TERMINATED BY、[OPTIONAL-LY] ENCLOSED BY和ESCAPED BY。如果指定了FIELDS子句,则这三个亚子句中至少要求指定一个。其中,TERMINATED BY用来指定字段值之间的符号;ENCLOSED BY子句用来指定包裹文件中字符值的符号;ESCAPED BY子句用来指定转义字符。

第二,LINES子句。在LINES子句中使用TERMINATED BY指定一个数据行结束的标志。 如果FIELDS和LINES子句都不指定,则默认声明的是下面的子句: FIELDS TERMINATED BY'\'ENCLOSED BY\"ESCAPED BY'\\\\' LINES TERMINATED BY'\n'

③导出语句中使用的是关键字DUMPFILE,而非OUTFILE时,导出的备份文件里面所有的数据行都会彼此紧挨着放置,即值和行之间没有任何标记。

(2)LOAD DATA…INFILE语句

导入恢复语句LOAD DATA…INFILE的语法格式为:

语法说明如下:

①LOW_PRIORITY | CONCURRENT

若指定LOW_PRIORITY,则延迟该语句的执行;若指定CONCURRENT,则当LOAD DATA正在执行的时候,其他线程可以同时使用该表的数据。

②LOCAL

若指定了LOCAL,则文件会被客户主机上的客户端读取,并被发送到服务器。文件会被给予一个完整的路径名称,以指定确切的位置。如果给定的是一个相对的路径名称,则此名称会被理解为相对于启动客户端时所在的目录。若没有指定LOCAL,则文件必须位于服务器主机上,并且被服务器直接读取。与让服务器直接读取文件相比,使用LOCAL的速度会略慢些,这是由于文件的内容必须通过客户端发送到服务器上。

③file_name

待导人的数据库备份文件名,文件中保存了待载人数据库的所有数据行。输入文件可以手动创建,也可以使用其他的程序创建。导入文件时可以指定文件的绝对路径,则服务器会根据该路径搜索文件。若不指定路径,则服务器在默认数据库的数据库目录中读取。若文件为“./backupfile.txt”,则服务器会直接在数据目录下读取,也就是MySQL的data目录。出于安全考虑,当读取位于服务器中的文本文件时,文件必须位于数据库目录中,或者是全体可读的。注意,这里给出的路径为Windows下的路径。

④tbl_name

指定需要导人数据的表名,该表在数据库中必须存在,表结构必须与导入文件的数据行一致。 ⑤REPLACE|IGNORE 如果指定REPLACE,则当导入文件中出现与数据库中原有行相同的唯一关键字值时,输入行会替换原有行;如果指定IGNORE,则把与原有行有相同的唯一关键字值的输入行跳过。

⑥FIELDS子句

此处的FIELDS子句和SELECT…INTO OUTFILE语句中类似,用于判断字段之间和数据行之间的符号。 ⑦LINES子句

TERMINATED BY亚子句用来指定一行结束的标志;STARTING BY亚子句则指定一个前缀,导入数据行

时,忽略数据行中的该前缀和前缀之前的内容。如果某行不包括该前缀,则整个数据行被跳过。

⑧IGNORE number LINES

这个选项可以用于忽略文件的前几行。例如,可以使用IGNORE 1 LINES来跳过数据备份文件中的第一行。 ⑨col_name_or_user_var

如果需要载入一个表的部分列,或者文件中字段值顺序与原表中列的顺序不同时,就必须指定一个列清单,其中可以包含列名或用户变量,例如:

LOAD DATA INFILE'backupfile 'txt'

INTO TABLE backupfile(cust_id,cust_name,cust_address) ⑩SET子句:SET子句可以在导人数据时修改表中列的值。 【例13.1】备份数据库mysql_test中表customers的全部数据到C盘的BACKUP目录下一个名为backupfile.txt的文件中,要求字段值如果是字符则用双引号标注,字段值之间用逗号隔开,每行以问号为结束标志。然后,将备份后的数据导入到一个和customers表结构相同的空表customers_copy中。

【答】首先,使用下面语句导出数据:。

mysql>SELECT$FROM mysql_test.customers

->INTO OUTFILE‘C:/BACKUP/backupfile.txt’ ->FIELDS TERMINATED BY ','

->OPTIONALLY ENCLOSED BY‘''’ ->LINES TERMINATED BY'?'; Query OK,3 rows affected(0.00 sec)

导出成功后,可以使用Windows记事本查看C盘BACKUP文件夹下的backupfile.txt文件,文件内容如图13-1所示。

图13-1 备份数据文件的内容

然后,使用下面的语句将备份数据导人数据库mysql_test中一个和customers表结构相同的空表customers_copy中:

在导入数据时需要特别注意,必须根据数据备份文件中数据行的格式来指定判断的符号。

在多个用户同时使用MySQL数据库的情况下,为了得到一个一致的备份,需要在指定的表上使用LOCK TABLES_name READ语句做一个读锁定,以防止在备份过程中表被其他用户更新;而当恢复数据时,则需要使用LOCK TABLES table_name WRITE语句做一个写锁定,以避免发生数据冲突。在数据库备份或恢复完毕之后需要使用UNLOCK TABLES语句对该表进行解锁。

2.使用MySQL客户端使用程序备份和恢复数据 (1)使用MySQL客户端使用程序的方法

打开计算机中的DOS终端,进入MySQL安装目录下的bin子目录,如C:\\Program Files\\MySQL\\MySQL Server 5.5\\bin,出现如图13-2所示的MySQL客户端使用程序运行界面,由此可在该界面光标闪烁处输入所需的MysQL客户端实用程序的命令。

图13-2 MySQL客户端实用程序运行界面

(2)使用mysqldump程序备份数据

mysqldump程序可以备份数据库表的结构,还可以备份一个数据库,甚至整个数据库系统,只需在MySQL客户端实用程序的运行界面中输入mysqldump_help命令,即可查看到mysqldump程序分别对应如下三种命令:

①备份表

使用的命令格式为:

mysqldump[OPTIONS]database[tables]>filename

语法说明如下:

OPTIONS:mysqldump命令支持的选项,可以通过执行mysqldump--help命令得到mysql-dump选项表及更多帮助信息。

database:指定数据库的名称,其后面可以加上需要备份的表名。若在命令中没有指定表名,则该命令会备份整个数据库。

filename:指定最终备份的文件名,如果该命令语句中指定了需要备份的多个表,那么备份后都会保存在这个文件中。文件默认的保存地址是MySQL安装目录下的bin目录中。如果需要保存在特定位置,可以指定其具体路径。需要注意的是,文件名在目录中不能已经存在,否则新的备份文件会将原文件覆盖。

与其他的MySQL客户端实用程序一样,使用mysqldump备份数据时,需要使用一个用户账号连接到MySQL服务器,这可以通过用户手工提供参数或在选项文件中修改有关值的方式来实现。使用参数的格式是:-h[hostname]-u[username]-p[password]。其中,-h选项后面是主机名,如果是本地服务器,-h选项可以省略;-u选项后面是用户名;-p选项后面是用户密码,-p选项和密码之间不能有空格。

②备份数据库

mysqldump程序还可以将一个或多个数据库备份到一个文件中,其使用的命令格式为:

mysqldump[OPTIONS]—databses[OPTIONS]DB1[DB2 DB3…]>filename

③备份整个数据库系统

mysqldump程序还能够备份整个数据库系统,即系统中的所有数据库,其使用的命令格式为:

mysqldump [OPTIONS]--all-databse[OPTIONS]>filename

尽管使用:mysqldump程序可以有效地导出表的结构,但在恢复数据的时候,倘若所需恢复的数据量很大,备份文件中众多的SQL语句会使恢复的效率降低。因此,可以在mysqldump命令中使用“--tab=”选项来分开数据和创建表的SQL语句。“--tab=”选项会在选项中“=”后面指定的目录里,分别创建存储数据内容的.txt格式文件和包含创建表结构的SQL语句的.sql格式文件。另外,该选项不能与--data_bases选项或--all-databases选项同时使用,并且mysqldump必须运行在服务器主机上。

(3)使用mysql命令恢复数据

可以通过使用mysql命令将mysqldump程序备份的文件中全部的SQL语句还原到MySQL服务器中,从而恢复一个损坏的数据库。

【例13.2】假设数据库mysql_test遭遇损坏,试用该数据库的备份文件mysql_test.sql将其恢复。 【答】在MySQL客户端实用程序的运行界面中输入下面的恢复命令:

mysql -u root -p123456 mysql_test如果是数据库中表的结构发生了损坏,也可以使用mysql命令对其单独做恢复处理,但是表中原有的数据将会全部被清空。

(4)使用mysqlimport程序恢复数据

mysqlimport客户端实用程序可以恢复数据表中的数据。这个程序提供了LOAD DATA…INFILE语句的一个命令行接口,它发送一个LOAD DATA INFILE命令到服务器来运作,其大多数选项直接对应LOAD DATA…INFILE语句。

运行mysqlimport程序对应的命令格式为:

mysqlimport [OPTIONS]database textfile…

语法说明如下: ①OPTIONS

mysqlimport命令支持的选项,可以通过执行mysqlimport-help命令查看这些选项的内容和作用。常用的选项有:

-d,--delete:在导入文本文件之前清空表中所有的数据行。

-l,--lock-tables:在处理任何文本文件之前锁定所有的表,以保证所有的表在服务器上同步,但对于InnoDB类型的表则不必进行锁定。

--low-priority,--local,--replace,--ignore:分别对应LOAD DATA…INFILE语句中的LOW_PRIORITY、LOCAL、REPLACE和IGNORE关键字。

②database:指定欲恢复的数据库名称。 ③textfile

存储备份数据的文本文件名。使用mysqlimporl命令恢复数据肘,mysqlimport会剥去这个文件名的扩展名,并使用它来决定向数据库中哪个表导入文件的内容。

另外,在该命令中需要指定备份文件的具体路径,若没有指定,则选取文件的默认位置,即MySQL安装目录的DATA目录下。

④与mysqldump程序一样,使用mysqlimport恢复数据时,也需要提供-h、-u、-P选项来连接MySQL服务器。

3.使用MySQL图形界面工具备份和恢复数据 (1)备份数据库

首先,以Web的方式登录phpMyAdmin,出现如图13-3所示的phpMyAdmin管理界面。 在这个管理界面中,有一个“导出”选项,用于指定备份数据库的操作功能,同时还有一个格式选择下拉框,用于选择备份文件的文件格式。在界面的左边,可以对欲备份的数据库和表进行选定。最后,单击“执行”按钮,即可完成数据库的备份操作。

图13-3 phpMyAdmin管理界面

(2)恢复数据库

如图13-4所示,单击选取phpMyAdmin管理界面中的“导入”选择卡,并输入欲导入的备份文件名,单击“执行”按钮,即可开展数据库的恢复操作。

图13-4 phpMyAdmin的数据库导入界面

4.直接复制

MySQL的数据库和表是直接通过目录和表文件来实现的。 (1)直接复制文件的方法备份数据库的过程

①在复制之前确保数据表当前状态下没有被使用,最好方法是暂时关闭MySQL服务器。

②再复制待备份数据库所对应的文件目录下所有的表文件。其中,如果表使用的是MyISAM格式,则复制table_name.frm(表的描述文件)、table_name.MYD(表的数据文件)和table_name.MYI(表的索引文件)三类文件;如果表使用的是ISAM格式,则复制table_name.frm(表的描述文件)、table_name.ISD(表的数据文件)和table_name.ISM(表的索引文件)三类文件。

③重启服务器。

文件复制好之后,就可以将该文件拷贝到另外一个MySQL服务器的数据库目录下,此时该MySQL服务器就可以正常使用这个直接拷贝过来的数据库了;另外,还可以在数据库遭遇损坏时,将该文件直接覆盖到当前MySQL服务器的数据库目录下,实现数据库的恢复。

(2)在MySQL服务器间直接拷贝文件的注意事项 ①两个服务器必须使用相同或兼容的MySQL版本。

②两个服务器必须硬件结构相同或相似,除非要复制的表使用MyISAM存储格式,这是因为这种表为在不同的硬件体系中共享数据提供了保证。

三、二进制日志文件的使用 1.二进制日志文件的介绍

更新日志可以实时记录数据库中修改、插入和删除的SQL语句。

在MySQL 5.5中,更新日志已经被二进制日志取代。二进制日志以一种更加有效的格式,并且是事务安全的方式,包含了更新日志中可用的所有信息,如关于每个更新数据库的语句的执行时间信息,而不包含没有修改任何数据的语句。这些语句以“事件”的形式保存,描述数据的更改。

由于二进制日志包含了数据备份后进行的所有更新,因此二进制日志的主要目的就是在数据恢复时能够最大可能地更新数据库。

2.开启日志文件 具体操作如下:

(1)打开MySQL安装目录下的my.ini文件(若是Linux系统,则打开my.cnf文件)。 (2)找到[mysqld]这个标签,在此标签下面,添加以下格式的一行语句: log-bin[=filename]

其中,log-bin说明要开启二进制日志文件,可选项filename则是二进制日志文件的名字。加入该选项后,服务器启动时就会加载该选项,从而启用二进制日志。如果filename包含有扩展名,则扩展名将被忽略。MySQL服务器会为每个二进制日志文件名后面自动添加一个数字编号扩展名,每次启动服务器或刷新日志时,都会重新

生成一个二进制日志文件,其扩展名中的数字编号依次递增。如果filename未给出,则默认为主机名。

(3)保存修改,重启MySQL服务器。此时,在MySQL安装目录的DATA文件夹下就可以看到这样两个格式的文件:filename.数字编号、filename.index。其中,“filename.数字编号”是二进制日志文件,它以二进制形式存储,用于保存数据库更新信息,当这个日志文件的大小达到最大时,MySQL会自动创建一个新的二进制文件。“filename.index”是服务器自动创建的二进制日志索引文件,包含所有使用的二进制日志文件的文件名。

3.使用mysqibiniog实用工具处理日志 (1)查看二进制日志文件

可以使用mysqlbinlog查看二进制日志文件,其命令格式为:

mysqlbinlog [options] log_files…

其中,log_files是二进制日志的文件名。 (2)使用二进制日志恢复数据

可以使用mysqlbinlog恢复数据,其命令格式为:

mysqlbinlog[options]log_files…|mysql[options]

(3)使用二进制日志恢复数据的实例 【例13.3】假设系统管理员在本周一下午五点公司下班前,使用mysqldump工具进行了数据库mysql_test的一个完全备份,备份文件为alldata.sql。接着,从本周一下午五点开始启用日志,bin_log.000001文件保存了从本周一下午五点到本周三上午九点的所有更改信息,在本周三上午九点运行一条日志刷新语句,即“FLUSH LOGS;”,此时系统自动创建了一个新的二进制日志文件bin_log.000002,直至本周五上午十点公司数据库服务器系统崩溃。现要求将公司数据库恢复到本周五上午十点系统崩溃之前的状态。

【答】这个恢复过程可以分为三个步骤来完成。

①使用mysqldump工具将公司的数据库恢复到本周一下午五点之前的状态,即在MySQL客户端实用程序的运行界面中输入下面的命令:

mysqldump -u root -p123456 mysql_test②使用mysqlbinlog工具将公司的数据库恢复到本周三上午九点之前的状态,即在MySQL客户端实用程序的运行界面中输入下面的命令:

mysqlbinlog bin_log.000001| mysql -u root_p123456 按回车键执行这条命令。

③使用mysqlbinlog工具将公司的数据库恢复到本周五上午十点系统崩溃之前的状态,即在MySQL客户端实用程序的运行界面中输入下面的命令:

mysqlbinlog bin_log.000002 |mysql -u root -p123456 按回车键执行这条命令。

由此,就完成了整个数据库恢复的过程。 (4)清理二进制日志

由于二进制日志文件会占用很大的硬盘资源,所以需要及时清除没用的二进制日志文件。 ①清除所有的日志文件

RESET MASTER;

②删除部分日志文件

PURGE{MASTER|BINARY}LOGS TO'log_name'

PURGE{MASTER|BINARY}LOGS BEFORE 'date'

语法说明如下:

第一条语句用于删除指定的日志文件,其中log_name为文件名。第二条语句用于删除时间date之前的所有日志文件。

第14章 PHP的MySQL数据库编程

一、PHP概述

PHP是Hypertext Preprocessor(超文本预处理器)的递归缩写,它是一种在服务器端执行的嵌入HTML文档的脚本语言,语言风格类似于C语言,其独特的语法混合了C、Java、Perl以及PHP自创的新语法。PHP作为一种服务器端的脚本/编程语言,具有简单、面向对象、解释型、高性能、独立于框架、动态、可移植等特点。

二、PHP编程基础

下面通过PHP 5编写的示例程序hello.php来体会服务器端嵌入HTML脚本的含义。

【例14.1】编写一个可以通过浏览器网页显示“hello world”的PHP 5程序代码。首先,在文本编辑器(例如记事本)中输入如下PHP程序,并命名为hello.php:

然后,将程序hello.php部署在已开启的WAMP平台环境中,并在浏览器地址栏输入http://localhost/hello.php即可查看程序执行结果。若该程序成功地被执行,则会显示如图14-1所示的程序成功运行的结果。

图14-1 程序hello.php成功运行的结果

示例程序中,由PHP代码生成的页面输出将取代标记中的内容。通过浏览器查看图14-1运行结果的页面源文件,可看到如下所示内容:

由此可见,PHP 5程序是在Web服务器端运行的,且最终会以HTML文档的格式输出到客户端/浏览器。从语法上看,PHP语言是借鉴C语言的语法特征,由C语言改进而来的。在PHP程序的编写过程中,可以混合编写PHP 5代码和HTML代码,即不仅可以将PHP 5代码的脚本通过标签“”嵌入到HTML文件

中,还可以把HTML文件的标签嵌入到PHP 5的脚本里。

三、使用PHP进行MySQL数据库编程 1.PHP中操作MySQL的介绍

可以使用PHP内置的mysql函数库实现对MySQL数据库的各种操作。在使用mysql函数库访问MySQL数据库之前,需要在PHP的配置文件php.ini中将“;extension= php_mysql.dll”修改为“extension=php_mysql.dll”,即删除该选项前面的注释符号“;”,然后再重新启动Web服务器(例如Apache)。

2.基于B/S模式的Web应用程序的工作流程

(1)在用户计算机的浏览器中通过在地址栏中输入相应URI信息,向网页服务器提出交互请求。 (2)网页服务器收到用户浏览器端的交互请求。 (3)网页服务器根据请求寻找服务器上的网页。

(4)Web应用服务器(例如Apache)执行页面内含的PHP代码脚本程序。

(5)PHP代码脚本程序通过内置的MySQL API函数访问后台MySQL数据库服务器。 (6)PHP代码脚本程序取回后台MySQL数据库服务器的查询结果。

(7)网页服务器将查询处理结果以HTML文档的格式返回给用户浏览器端。 3.编程步骤

使用PHP进行MySQL数据库编程的基本步骤如下: (1)首先建立与MySQL数据库服务器的连接。 (2)然后选择要对其进行操作的数据库。

(3)再执行相应的数据库操作,包括对数据的添加、删除、修改和查询等。 (4)最后关闭与MySQL数据库服务器的连接。

以上各步骤,均是通过PHP 5内置函数库mysql中相应的函数来实现的。

4.建立与MySQL数据库服务器的连接

(1)使用函数mysql_connect()建立非持久连接 ①mysql_connect()的语法格式为:

mysql_connect([ servername [,username[,password ]]]) ②mysql_connect()的语法说明

servername:可选项,为字符串型,用于指定要连接的数据库服务器。默认值是“localhost:3306”。

username:可选项,为字符串型,用于指定登录数据库服务器所使用的用户名。默认值是拥有服务器进程的用户的名称,如超级用户root。

password:可选项,为字符串型,用于指定登录数据库服务器所用的密码。默认为空串。 函数mysql_connect()的返回值为资源句柄型(resource)。若其成功执行,则返回一个连接标识号;否则返回逻辑值FALSE。

通常是将mysql_connect()函数返回的连接标识号保存在某个变量中,以备PHP程序使用。 ③mysql_connect()的实例

【例14.2】编写一个数据库服务器的连接示例程序connect.php,要求以超级用户root及其密码123456连接本地主机中的MySQL数据库服务器,并使用变量$con保存连接的结果。

【答】首先,在文本编辑器(例如记事本)。串输入如下PHP程序。并命名为connect.php:(注意,PHP程序是被包含在标记符“”间的代码段,同时PHP程序中的变量名是以“$”开头) $con=mysql_connect(\"localhost:3306\); if(!$con) {

echo\"连接失败!
\";

echo\"错误编号:\".mysql_error().\"
; echo\"错误信息:\".mysql_error().\"
; die();//终止程序运行 }

echo\"连接成功!
\";

?>

然后,将程序connect.php部署在已开启的WAMP平台环境中,并在浏览器地址栏中输入

“http://localhost/connect.php”,按回车键即可查看程序执行结果:若连接成功,则显示“连接成功!”的信息,如图14-2所示;若连接失败,则显示相应的错误信息,同时会终止程序的运行,如图14-3所示,即为该程序连接密码不正确时的运行结果。

图14-2 程序connect.php成功运行的结果

图14-3 程序connect.php密码不正确时的运行结果

④连接判断即连接失败的处理

建立连接是执行其他MySQL数据库操作的前提条件,因此在执行函数mysql_connect()之后,应当立即进行相应的判断,以确定数据库连接是否已被成功建立。在PHP中,一切非0值会被认为是逻辑值TRUE,而数值0则被当作逻辑值FALSE。函数mysql_connect()执行成功后,所返回的连接标识号实质上是一个非0值,即被当作逻辑值TRUE来处理。因而,若要判断是否已成功建立与MySQL数据库服务器的连接,只需判断函数mysql_connect()的返回值即可。

如果连接失败,则可进一步调用PHP中的函数mysql_error()和mysql_error(),以获取相应的错误编号和错误提示信息。函数mysql_error()和mysql_error()的功能就是分别获取PHP程序中前一个MySQL函数执行后的错误编号和错误提示信息。当前一个MySQL函数成功执行后,函数mysql_errno()和mysql_error()会分别返回数值0和空字符串,因此,这两个函数也可用于判断函数mysql_connect()或其他MySQL函数的执行情况,即成功或失败。

(2)使用函数mysql_pconnect()建立持久连接 ①mysql_pconnect()的语法格式

mysql_pconnect([ servername [,username[,password]]])

②函数mysql_pconnect()与函数mysql_connect()的区别

第一,由函数mysql_connect()建立的连接,当数据库操作结束之后将自动关闭,而由函数mysql_pconnect()建立的连接会一直存在,是一种稳固持久的连接。

第二,对于函数mysql_peonneet()而言,每次连接前都会检查是否使用了同样的servername、username、password进行连接,如果有,则直接使用上次的连接,而不会重复打开。

第三,由函数mysql_connect()建立的连接可以使用函数mysql_close()关闭,而使用函数mysql_pconnect()建立起来的连接不能使用函数mysql_close()关闭。

5.选择数据库

(1)mysql_select_db()选择数据库的语法格式为:

mysql_select_db(database[,connection])

(2)mysql_select_db()的语法说明

database:必需项,为字符串型,用于指定要选择的数据库名称。

connection:可选项,为资源句柄型,用于指定相应的与MySQL数据库服务器相连的连接标识号。若未指定该项,则使用上一个打开的连接。若没有打开的连接,则会使用不带参数的函数mysql_connect()来尝试打开一个连接并使用之。

函数mysql_connect()的返回值为布尔型。若成功执行,则返回TRUE;否则返回FALSE。 (3)mysql_select_db()的实例

【例14.3】编写一个选择数据库的PHP示例程序selectdb.php,要求选定数据库mysql_test作为当前工作数据库。

【答】首先在文本编辑器(例如记事本)中输入如下PHP程序,并命名为selectdb.php;

然后,将程序selectdb.php部署在已开启的WAMP平台环境中,并在浏览器地址栏中输入“http://localhost/selectdb.php”,按回车键即可查看程序执行结果。若数据库选择成功,则会显示“数据库选择成功!”的信息,如图14-4所示。

图14-4 程序select.php成功运行的结果

6.执行数据库操作

(1)mysql_query()提交并执行SQL语句的语法格式

mysql_query(query[,connection])

(2)mysql_query()的语法说明

query:必需项,为字符串型,指定要提交的SQL语句。注意,SQL语句是以字符串的形式提交,且不以分号作为结束符。

connection:可选项,为资源句柄型,用于指定相应的与MySQL数据库服务器相连的连接标识号。若未指定该项,则使用上一个打开的连接。若没有打开的连接,则会使用不带参数的函数mysql_connect()来尝试打开一个连接并使用之。

函数mysql_query()的返回值是资源包柄型。对于SELECTSHOW、EXPLAIN或DESCRIBE语句,若执行成功,则返回相应的结果标识符,否则返回FALSE;而对于INSERT、DELETE、UPDATE、REPLACE、CREATE TABLE、DROP,TABLE或其他非检索语句,若执行成功,则返回TRUE,否则返回FALSE。

(3)数据的添加

在PHP程序中,可以将MySQL中用于插入数据的INSERT语句置于函数mysql_query()中,实现向选定的数据库表中添加指定的数据。

【例14.4】编写一个添加数据的PHP示例程序insert.php,要求可向数据库mysql_test中的表customers添加一个名为“李中华”的客户的全部信息。

【答】首先在文本编辑器(例如记事本)中输入如下PHP程序,并命名为insert.php:

然后,将程序insert.php部署在已开启的WAMP平台环境中,并在浏览器地址栏中输入“http://localhost/insert.php”,按回车键即可查看程序执行结果。若该客户的信息添加成功,则会显示“客户添加成功!”的信息,如图14-5所示。

图14-5 程序insert.php成功运行的结果

(4)数据的修改

在PHP程序中,可以将MySQL中用于更新数据的UPDATE语句置于函数mysql_query()中,实现在选定的数据库表中修改指定的数据。

(5)数据的删除

在PHP程序中,可以将MySQL中用于删除数据的DELETE语句置于函数mysql_query()中,实现在选定

的数据库表中删除指定的数据。

(6)数据的查询

在PHP程序中,可以将MySQL中用于数据检索的SELECT语句置于函数mysql_query()中,实现在选定的数据库表中查询所要的数据。当函数mysql_query()成功被执行时,其返回值不再是一个逻辑值TRUE,而是一个资源句柄型的结果标识符。结果标识符也称结果集,代表了相应查询语句的查询结果。每个结果集都有一个记录指针,所指向的记录即为当前记录。在初始状态下,结果集的当前记录就是第一条记录。

①读取结果集中的记录

在PHP 5中,可以使用函数mysql_fetch_array()、mysql_fetch_row()或mysql_fetch_assoc()来读取结果集中的记录。它们的语法格式分别为:

mysql_fetch_array(data[,array_type]) mysql_fetch_row(data) mysql_fetch_assoc(data) 语法说明如下:

data:为资源句柄型,用于指定要使用的数据指针。该数据指针可指向函数mysql_query()产生的结果集,即结果标识符。

array_type:可选项,为整型(int),用于指定函数返回值的形式,其有效取值为PHP常量MYSQL_NUM(表示数字数组)、MYSQL_ASSOC(表示关联数组)或MYSQL_BOTH(表示同时产生关联数组和数字数组)。其默认值为MYSQL_BOTH。

三个函数成功被执行后,其返回值均为数组类型(array)。若成功,即读取到当前记录,则返回一个由结果集当前记录所生成的数据,其中每个字段的值会保存到相应的索引元素中,并自动将记录指针指向下一个记录。若失败,即没有读取到记录,则返回FALSE。在使用函数mysql_fetch_array()时,若以常量MYSQL_NUM作为第二个参数,则其功能与函数mysql_fetch_row()的功能是一样的,所返回的数据为数字索引方式的数组,只能以相应的序号(从0开始)作为元素的下标进行访问;若以常量MYSQL_ASSOC作为第二个参数,则其功能与mysql_fetch_assoc()的功能是一样的,所返回的数组为关联索引方式的数组,只能以相应的字段名(若指定了别名,则为相应的别名)作为元素的下标进行访问;若未指定第二个参数,或以 MYSQL_BOTH作为第二个参数,则返回的数组为数字索引方式与关联索引方式的数组,既能以序号为元素的下标进行访问,也能以字段名为元素的下标进行访问。由此可见,函数mysql_fetch_ array()完全包含了函数mysql_fetch_row()和函数mysql_fetch_assoc()的功能。因此,在实际编程中,函数mysql_fetch_array()是最为常用的。

【例14.5】编写一个检索数据的PHP示例程序select.php,要求在数据库mysql_test的表customers中查询cust_id为916的客户的姓名。

【答】首先在文本编辑器(例如,记事本)中输入如下PHP程序,并命名为select.php:

然后,将程序select.php部署在已开启的WAMP平台环境中,并在浏览器地址栏中输入“http://localhost/select.php”,按回车键即可查看程序执行结果。若该客户的姓名被成功检索到,则会显示如图14-6所示的结果信息。

图14-6 程序select.php成功运行的结果

②读取结果集中的记录数

在PHP 5中,可以使用函数mysql_nun_rows()来读取结果集中的记录数,即数据集的行数。 其语法格式分别是:

mysql_num_rows(data)

语法说明如下:

data:为资源句柄型,用于指定要使用的数据指针。该数据指针可指向函数mysql_query()产生的结果集,即结果标识符。

函数mysql_nun_rows()成功被执行后,其返回值是结果集中行的数目。 ③读取指定记录号的记录

在PHP 5中,可以使用函数mysql_data_seek()在结果集中随意移动记录的指针,也就是将记录指针直接指向某个记录。其语法格式为:

mysql_data_seek(data,row)

语法说明如下:

data:必需项,为资源句柄型,用于指定要使用的数据指针。该数据指针可指向函数mysql_quelT()产生的结果集,即结果标识符。

row:必需项,为整型(int),用于指定记录指针所要指向的记录的序号,其中0指示结果集中第一条记录。

函数mysql_data_seek()返回值为布尔型(bool)。若成功执行,则返回TRUE;否则,返回FALSE。

7.关闭与数据库服务器的连接

函数mysql_close()来关闭由函数mysql_connect()所建立的与MySQL数据库服务器的非持久连接。 (1)mysql_close()函数的语法格式

mysql_close([connection])

(2)mysql_close()函数的语法说明

connection:可选项,为资源句柄型,用于指定相应的与MySQL数据库服务器相连的连接标识号。如若未指定该项,则默认使用最后被函数mysql_connect()打开的连接。若没有打开的连接,则会使用不带参数的函数mysql_connect()来尝试打开一个连接并使用之。如果发生意外,没有找到连接或无法建立连接,系统发出E_WARNING级别的警告信息。

函数mysql_close()的返回值为布尔型。若成功执行,则返回TRUE;否则返回FALSE。

函数mysql_close()仅关闭指定的连接标识号所关联的MySQL服务器的非持久连接,而不会关闭由函数mysql_pconnect()建立的持久连接。另外,由于已打开的非持久连接会在PHP程序脚本执行完毕后自动关闭,因而在PHP程序中,通常无需使用函数mysql_close()。

第15章 开发实例

一、需求描述

在实际使用中,用户管理系统(或模块)主要负责管理与维护本系统内部所有用户的个人基本信息以及每个用户在系统中所具备的操作权限。

二、系统分析与设计

用户管理系统主要供该系统的管理员进行操作和使用。根据用户管理系统的需求特征,一个简单的用户管理系统可设计为图15-1所示的用户管理、部门管理、用户组管理、权限管理等四个主要功能模块。

图15-1 用户管理系统功能模块示意图

1.用户管理模块

用户管理模块主要负责管理与维护系统中每个用户的个人基本信息。该模块供系统管理员使用,其具体功能操作主要包括对每个用户及其个人基本信息的添加、删除、修改和查看,其对应的UML用例图可如图15-2所示。

图15-2 用户管理模块的用例图

2.部门管理模块

部门管理模块主要负责管理与维护系统中用户所在部门(子单位)自身的各相关信息。该模块供系统管理员使用,其具体功能操作主要包括对每个部门及其相关信息的添加、删除、修改和查看,其对应的UML用例图可如图15-3所示。

图15-3 部门管理模块的用例图

3.用户组管理模块

用户组管理模块主要负责管理与维护系统中用户所属用户组自身的各相关信息。该模块供系统管理员使用,其具体功能操作主要包括对每个用户组及其相关信息的添加、删除、修改和查看,其对应的UML用例图可如图15-4所示。

图15-4 用户组管理模块的用例图

4.权限管理模块

权限管理模块主要负责管理与维护系统中所有操作权限的相关信息,例如,权限的名称、权限的具体操作对象、权限的具体操作行为等。该模块供系统管理员使用,其具体功能操作主要包括对各权限及其相关信息的添加、删除、修改和查看,其对应的UML用例图如图15-5所示。

图15-5 权限管理模块的用例图

三、数据库设计与实现 1.数据库表结构的设计

根据前面对用户管理系统基本功能的分析与设计,一个简单的用户管理系统数据库的E-R模型图可如图15-6所示。

图15-6 用户管理系统数据库的E-R模型图

通过使用E-R图转换为关系模型的方法,可将图15-6所示的E-R图转换为五种关系表,其表结构分别描述如下:

(1)用户信息表users

该表用于存储每个用户的个人基本信息、所在部门信息、所属用户组信息,其表结构如表15-1所示。

表15-1 表users的结构 编号 1 2 3 4 5 6 7 字段名称 user_id user_name user_psw user_sex user_age user_dept user_group 数据类型 INT CHAR(10) CHAR(10) CHAR(1) INT INT INT 说明 用户ID号,主键 用户名 口令 性别 年龄 所在部门,可作外键 所属用户组,可作外键

(2)部门表dept

该表用于存储每个部门的名称、领导所在地等信息,其表结构如表15-2所示。

表15-2 表dept的结构

编号 1 2 3 4 字段名称 dept_id dept_name dept_leader dept_location 数据类型 INT CHAR(20) CHAR(10) CHAR(50) 说明 部门ID号,主键 部门名称 部门领导; 部门所在地 (3)用户组表usergroup 该表用于存储每个用户组的名称及相关描述信息,其表结构如表15-3所示。

表15-3 表usergroup的结构

编号 1 2 3 字段名称 group_id group_name group_desc 数据类型 INT CHAR(20) CHAR(50) 说明 用户组ID号,主键 用户组的名称 用户组的描述 (4)权限表func 该表用于存储每个权限的名称及对应的操作对象与行为,其表结构如表15-4所示。

表15-4 表func的结构 编号 1 2 3 字段名称 func_id func_name func_link 数据类型 INT CHAR(20) CHAR(20) 说明 权限ID号,主键 权限的名称 权限的操作对象与行为 (5)用户组权限表groupfunc 该表用于存储每个用户组所对应的权限信息,其表结构如表15-5所示。

表15-5 表groupfunc的结构 编号 1 2 3 字段名称 id group_id func_id 数据类型 INT INT INT 说明 表ID号,主键 用户组ID号,可作外键 权限ID,可作外键

2.数据库表结构的实现

在实现本实例系统的数据库表结构之前,首先需要在MySQL数据库的命令行客户端中输入如下SQL语句,用以创建一个名为db_user的数据库,来存放上述五种关系数据表。

mysql>CREATE DATABASE db_user; Query OK,1 row affected(0.33sec)

接着,可在MySQL命令行客户端中分别输入下列SQL语句,逐个创建用户信息表users、部门表dept、用户组表usergroup、权限表func、用户组权限表groupfunc。

(1)用户信息表users的实现

(2)部门表dept的实现

(3)用户组表usergroup的实现

(4)权限表func的实现

(5)用户组权限表groupfunc的实现

四、系统实现

1.三层软件体系架构和Apache介绍

图15-7所示的三层软件体系架构由表示层、应用层和数据层构成。其中,表示层是本实例系统的用户接口(User Interface,UI),具体表现为Web页面,其主要使用HTML标签语言来实现(为便于简洁地描述所有构成表示层的Web页面的实现代码,本小节给出的各个页面实现代码均未添加CSS、JavaScript等脚本);应用层是本实例系统的功能层,表现为应用服务器,位于表示层与数据层之间,主要负责具体的业务逻辑处理,以及与表示层、数据层的信息交互,其所处理的各种业务逻辑主要由PHP语言编写的动态脚本来实现;数据层位于本实例系统的最底层,具体表现为MySQL数据库服务器,其主要通过SQL数据库操作语言,负责对MySQL数据库中的数据进行读写管理,以及更新与检索,并与应用层实现数据交互。

图15-7 本实例系统的三层架构示意图

本例选用Apache作为应用服务器,所有由PHP语言编写的业务逻辑处理代码,以及由HTML标签语言编写的Web页面代码,都将置于Apache安装目录的WWW子目录下。例如,对于本实例系统中用户管理模块的实现,WWW子目录下所包含的对应代码文件有:index.html、add_user.php、show_user.php、insert_user.php、select_user.php、change_user.php、update_user.php、delete_user.php,这些代码文件之间链接关系如图15-8所示。

图15-8 用户管理模块中所有实现代码文件间的关系图

下面以本实例系统中用户管理模块为例,介绍其所有Web页面及底层业务逻辑处理的代码实现。

2.实例系统的主页面设计与实现

图15-9所示为用户管理系统的主页面,其包含了系统设计中四个功能模块所对应的各操作页面超链接入口。

图15-9 用户管理系统的主页面

实例系统主页面文件index.html的实现代码描述如下,其中包含了本实例系统四个功能模块分别对应的操作页面超链接文件名:

3.公共代码模块的设计与实现

在用户管理模块中存在一些应用层的业务逻辑处理代码,它们经常需要使用相同的代码来实现与数据层MySQL数据库的连接,因此可将对数据库的连接操作编写成一个单独的公共代码文件common.php,以供那些应用层的业务逻辑处理代码在需要连接数据库时可直接通过PHP语言的require_once函数进行加载,而不必针对所有需要处理数据库连接的业务逻辑代码都重复编写相同的数据库连接代码。

公共代码模块common.php的实现代码描述如下:

4.添加用户的页面设计与实现

图15-10所示为用户管理模块中添加用户的Web页面。通过该页面,可以向用户管理系统添加一位新用户的个人信息。

图15-10 用户管理模块中添加用户的Web页面

添加用户的Web页面文件add_user.php的实现代码描述如下:

当在添加用户的web页面中输入用户的个人信息后,单击该页面中的“添加”按钮,即可调用应用层中用于执行添加用户操作的业务逻辑处理代码insert_user.php,该代码的文件内容描述如下:

当一个用户的个人信息通过添加用户操作成功添加后,实例系统的页面会自动跳转到图15-11所示的Web页面。

图15-11 用户管理模块中成功添加用户后的结果页面

5.查看用户的页面设计与实现

图15-12所示为用户管理模块中查看用户的Web页面。通过该页面,可以通过指定用户姓名或用户所属部门来查看该用户的全部个人信息。

图15-12 用户管理模块中查看用户的Web页面

查看用户的Web页面文件show_user.php的实现代码描述如下:

当在查看用户的Web页面中输入要查看的用户姓名及所属部门的信息后,单击该页面中的“查看”按钮,即可调用应用层中用于执行查看用户操作的业务逻辑处理代码select_user.php,该代码的文件内容描述如下:

例如,当在图15-12所示查看页面中的用户姓名输入框中输入一个用户姓名“张三”后,并单击“查看”按钮,即可进入图l5-13所示的用户查看结果页面。在该用户的查看结果页面中包含了执行修改该用户和删除该用户操作的超链接入口,分别对应链接文件change_user.php和delete_user.php。

图15-13 用户查看结果页面图

6.修改用户的页面设计与实现

图15-14所示为用户管理模块中修改用户信息的Web页面。通过该页面,可以在用户管理系统中修改一位已有用户的个人信息。

15-14 用户管理模块中修改用户信息的Web页面

修改用户的Web页面文件change_user.php的实现代码描述如下:

当在修改用户的Web页面中输入完新的个人信息后,单击该页面中的“修改用户信息”按钮,即可调用应用层中用于执行修改用户操作的业务逻辑处理代码update_user.php,该代码的文件内容描述如下:

7.删除用户的底层代码实现

通过单击图15-13所示用户查看结果页面中的超链接“删除用户”,即可调用应用层中用于执行删除用户操作的业务逻辑处理代码delete_user.php,从而实现对指定用户的删除。其中,代码delete_user.php的文件内容描述如下:

当一个指定用户被成功删除后,实例系统的页面会自动跳转到图15-15所示的web页面。

图15-15 用户成功删除的结果页面

第三部分 历年真题及详解

全国计算机等级考试《二级MySQL数据库程序设计》真题精选(一)

选择题精选

1.下列链表中,其逻辑结构属于非线性结构的是( )。 A.二叉链表 B.循环链表 C.双向链表 D.带链的栈 【答案】A

【解析】线性结构是指除了第一个和最后一个结点外,所有的元素都是首尾相连的,每一个结点只有一个前驱结点和一个后继结点。线性表、栈、队列都是线性结构,循环链表和双向链表是线性表的链式存储结构;带链的栈是栈的链式存储结构;只有二叉链表是二叉树的存储结构,而二叉树是非线性结构,因为二叉树有些结点有两个后继结点,不符合线性结构的定义。

2.设循环队列的存储空间为Q(1:35),初始状态为front=rear=35。现经过一系列入队与退队运算后, front=15,rear=15,则循环队列的元素个数为( )。

A.15 B.16 C.20

D.0或35 【答案】D 【解析】循环队列是指用一段地址连续的存储单元存储数据元素,定义两个游标:指向队头的游标(front)、指向队尾的游标(rear)。队首和队尾指针重叠时,说明队列为空或者为满。由题目可知,循环队列最多存储35个元素。front=rear=15时,循环队列可能为空,也可能为35。

3.下列关于栈的叙述中,正确的是( )。 A.栈底元素一定是最后入栈的元素 B.栈顶元素一定是最先入栈的元素 C.栈操作遵循先进后出的原则 D.以上三种说法都不对 【答案】C

【解析】栈是操作受限的线性表,栈只能在栈顶插入和删除元素,按照先进后出的原则组织数据。

4.在关系数据库中,用来表示实体间联系的是( )。 A.属性 B.二维表 C.网状结构 D.树状结构 【答案】B 【解析】关系数据库使用的是关系模型,用二维表来表示实体间的联系。在关系表中,每一行称为一个元组,对应表中的一条记录;每一列称为一个属性,对应表中的一个字段。网状结构和树状结构对应于实体间的逻辑关系模型。

5.公司中有多个部门和多名职员,每个职员只能属于一个部门,一个部门可以有多名职员。则实体部门和职员间的联系是( )。

A.1:1联系 B.m:1联系 C.1:m联系

D.m:n联系 【答案】C

【解析】实体集之间通过联系来建立连接关系,包括:一对一联系(1:1)、一对多联系(1:m)、多对多联系(m:n)。本题中,一个部门可以有多名职员,而每个职员只能属于一个部门,显然,部门和职员间是一对多的联系。

6.有两个关系R和S如下:

R A a b C

S A c B 3 C 1 B 1 2 3 C 2 1 1

则由关系R得到关系S的操作是( )。 A.选择 B.投影 C.自然连接 D.并 【答案】A 【解析】投影是从表中选出指定的属性值组成新表,是单目运算,选择是指按条件选取元组,是对行的操作。交与并是双目运算。由关系R得到关系S是一个单目运算,可以排除CD两项。关系S是由关系R的第3个元组组成,这是对关系R进行选择运算的结果。

7.数据字典(DD)所定义的对象包含于( )。 A.数据流图(DFD) B.程序流程图 C.软件结构图 D.方框图 【答案】A

【解析】数据字典是指对数据的数据项、数据结构、数据流、数据存储、处理逻辑、外部实体等进行定义和描述,其目的是对数据流程图中的各个元素做出详细的说明。数据字典是在需求分析阶段建立,在数据库设计过程中不断修改、充实和完善的。

8.软件需求规格说明书的作用不包括( )。 A.软件验收的依据

B.用户与开发人员对软件要做什么的共同理解 C.软件设计的依据

D.软件可行性研究的依据 【答案】D 【解析】需求分析阶段最终生成软件需要规格说明书是为了使用户和软件开发者双方对该软件的初始规定有一个共同的理解,使之成为整个开发工作的基础。其作用有:①有利于用户、分析人员和设计人员之间的交流;②可以直接支持目标确认;③可以作为控制软件开发进程的依据。可行性研究是在需求分析之前进行的,软件需求规格说明书不可能作为可行性研究的依据。

9.下列属于黑盒测试方法的是( )。

A.语句覆盖 B.逻辑覆盖 C.边界值分析 D.路径分析 【答案】C 【解析】黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用。仅着眼于程序外部功能,不考虑内部逻辑结构,主要针对软件界面和软件功能进行测试。黑盒测试的方法主要包括:等价类划分法、边界值分析法、错误推测法、因果图等。

10.下列不属于软件设计阶段任务的是( )。 A.软件总体设计 B.算法设计

C.制定软件确定测试计划 D.数据库设计 【答案】C

【解析】软件概要设计阶段的任务有:①软件系统的结构的设计;②数据结构和数据库设计;③编写概要设计文档;④概要设计文档评审。确认测试是依据需求规格说明书来验证软件的功能和性能,即确认测试计划是在需求分析阶段就制定了。

11.数据定义语言中的创建,修改,删除这三个英语单词下列完全正确的是( )。 A.创建(create),修改(alter),删除(update) B.创建(alter),修改(modify),删除(drop) C.创建(create),修改(alter),删除(drop) D.创建(alter),修改(create),删除(drop)

【答案】C

12.建表语句中的not null,该代码表示的含义是( )。

A.允许空格 B.非空约束

C.不允许写入数据 D.不允许读取数据

【答案】B

13.select * from student,该代码中的 * 号表示的正确含义是( )。 A.普通的字符*号 B.错误信息 C.所有的字段名 D.模糊查询

【答案】C

14.向数据表添加数据,添加的关键字是( )。 A.insert B.update C.delete D.select

【答案】A

15.函数max()表明这是一个( )函数。 A.求总值函数 B.求最小值函数

C.求平均值函数 D.求最大值函数

【答案】D

16.修改表记录的语句关键字是( )。 A.delete B.update C.insert D.select

【答案】B

17.删除表记录的语句关键字是( )。 A.insert B.update C.delete D.select

【答案】C

18.在语句select * from student where s_name like ’%晓%’,where关键字表示的含义是( A.条件 B.在哪里 C.模糊查询 D.逻辑运算

【答案】A

19.update student set s_name =’王军’ where s_d =1,该代码执行的操作是( )。 A.添加姓名叫王军的记录 B.删除姓名叫王军的记录 C.返回姓名叫王军的记录 D.更新姓名叫王军的记录

【答案】D

20.模糊查询的关键字是( )。 A.not B.and C.like D.or

【答案】C

。 )

全国计算机等级考试《二级MySQL数据库程序设计》真题精选(二)

选择题精选

1.下列数据结构中,属于非线性结构的是( )。 A.循环队列 B.带链队列 C.二叉树 D.带链栈 【答案】C

【解析】线性结构是指除了第一个和最后一个结点外,所有的元素都是首尾相连的,每一个结点只有一个前驱结点和一个后继结点。栈和队列均满足这两个条件,属于线性结构。二叉树属于非线性结构,因为除了叶子结点外,每个结点都可以有两个后件,不满足线性表的条件。

2.下列数据结构中,能够按照“先进后出”原则存取数据的是( )。 A.循环队列 B.栈 C.队列 D.二叉树 【答案】B

【解析】栈是操作受限的线性表,栈只能在栈顶插入和删除元素,按照先进后出的原则组织数据。

3.对于循环队列,下列叙述中正确的是( )。 A.队头指针是固定不变的 B.队头指针一定大于队尾指针 C.队头指针一定小于队尾指针

D.队头指针可以大于队尾指针,也可以小于队尾指针 【答案】D 【解析】循环队列是指用一段地址连续的存储单元存储数据元素,定义两个游标:指向队头的游标(front)、指向队尾的游标(rear)。在循环队列结构中,一般情况下rear>front,但是,当存储空间的最后一个位置已被使用,而要进行入队时,如果存储空间的第一个位置空闲,便可将元素加入到第一个位置,即将存储空间的第一个位置作为队尾。此时便有front>rear。

4.算法的空间复杂度是指( )。

A.算法在执行过程中所需要的计算机存储空间 B.算法所处理的数据量

C.算法程序中的语句或指令条数

D.算法在执行过程中所需要的临时工作单元数 【答案】A

【解析】算法的空间复杂度是对这个算法所需要的内存空间的量度,包括:①算法程序所占的空间;②输入的初始数据所占的存储空间;③算法执行中所需要的额外空间。

5.软件设计中划分模块的一个准则是( ) 。 A.低内聚低耦合 B.高内聚低耦合 C.低内聚高耦合 D.高内聚高耦合 【答案】B

【解析】模块独立性最大原则是模块划分的原则之一,高内聚低耦合是优秀软件设计应当遵循的规则,内聚度是一个模块内部各个元素间彼此结合的紧密程序的度量,耦合度是模块间互相连接的紧密程度的度量。

6.下列选项中不属于结构化程序设计原则的是( )。 A.可封装 B.自顶向下 C.模块化 D.逐步求精 【答案】A

【解析】结构化程序设计的基本原则包括:①模块化设计;②自顶向下;③逐步求精;④限制使用goto语句。

7.软件详细设计产生的图如下:

该图是( )。 A.N-S图 B.PAD图 C.程序流程图 D.E-R图 【答案】C

【解析】程序流程图基本图符有:①控制流(用箭头表示);②加工步骤(用方框表示);③逻辑条件(用菱形表示)。有5种控制结构:顺序、选择、多分支选择、后判断重复型和先判断重复型。N-S是盒图,所有内容均在方框中表示。PAD图是问题分析图,它用二维树形结构的图表示程序的控制流。E-R图是实体关系图,提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。

8.数据库管理系统是( )。 A.操作系统的一部分

B.在操作系统支持下的系统软件 C.一种编译系统 D.一种操作系统 【答案】B

【解析】数据库管理系统DBMS(Data Base Management System)是一种系统软件,负责数据库中的数据组织、数组操纵、数据维护、控制和保护以及数据服务等。数据库系统DBS(Data Base System,简称DBS)通常由软件、数据库和数据管理员组成。

9.在E-R图中,用来表示实体联系的图形是( )。 A.椭圆形 B.矩形 C.菱形 D.三角形 【答案】C

【解析】E-R图是实体联系模式图,E-R图的三要素:①实体,用矩形框表示,框内为实体名称;②属性,用椭圆形表示,并用线与实体连接;③实体间的联系,用菱形框表示,用线将菱形框与实体相连,并在线上标注联系的类型。

10.有三个关系R,S和T如下:

R A a b C

S A d

T A a b C d B 1 2 3 3 C 2 1 1 2 B 3 C 2 B 1 2 3 C 2 1 1

其中关系T由关系R和S通过某种操作得到,该操作为( )。 A.选择 B.投影 C.交 D.并 【答案】D 【解析】投影是从表中选出指定的属性值组成新表,是单目运算,选择是指按条件选取元组,是对行的操作。交与并是双目运算。并运算将结构相同的两个关系合并,合并后的关系包含两个关系中的所有元组。交运算的结果是既属于R又属于S的记录组成的集合。

11.select substring(’长江长城黄山黄河’,2,2),返回的是( )。 A.长江 B.江长 C.长城

D.长江长城

【答案】B

12.若student表中有一字段s_fenshu,数据类型为整型,保存每个学生的考试成绩,求全班平均分的正确做法是( )。

A.把每个学生的s_fenshu 手工进行相加,然后除以全班人数,得到平均分 B.使用select avg(s_fenshu) from student

C.使用select sum(s_fenshu) from student / select count(*) from student D.使用select sum(s_fenshu) from student % select count(*) from student

【答案】B

13.100/3 的结果是( )。 A.33.33 B.33.333333 C.33

D.无法执行

【答案】C

14.正确的like运算表达式( )。

A.select * from net_46 where s_name like ’#晓#’ B.select * from net_6 where s_name like ’&晓&’ C.select * from net_46 where s_name like ’$晓$’ D.select * from net_46 where s_name like ’%晓%’ 【答案】D

15.以下的数据库中,大型的数据库是( )。 A.MySql B.DB2 C.Oracle

D.MS Sql 2005 【答案】C

16.Create database MyDB该代码的功能是( )。 A.创建表 MyDB B.创建数据库 MyDB C.修改数据库 MyDB D.删除数据库 MyDB 【答案】B

17.Use MyDB该代码的功能是_。 A.修改数据库 MyDB B.删除数据库 MyDB C.使用数据库 MyDB D.创建数据库 MyDB 【答案】C

18.Alter Database MyDB Modify name=MyDB001该代码的功能是_。 A.修改数据库名为 MyDB001 B.删除数据库 MyDB001 C.使用数据库 MyDB001 D.创建数据库 MyDB001 【答案】A

19.drop database MyDB001该代码的功能是_。 A.修改数据库名为 MyDB001 B.删除数据库 MyDB001 C.使用数据库 MyDB001 D.创建数据库 MyDB001 【答案】B

20.sp_spaceused代码的功能是( )。 A.返回数据库的登录信息

B.返回数据库的使用和保留空间 C.返回数据库的创建信息 D.返回数据库的安全信息 【答案】B

第四部分 模拟试题及详解

全国计算机等级考试《二级MySQL数据库程序设计》模拟试题及详解(一)

选择题精选

1.下列关于栈叙述正确的是( )。 A.栈顶元素最先被删除 B.栈顶元素最后才能被删除 C.栈底元素永远不能被删除 D.以上三种说法都不对 【答案】A

【解析】栈是限定在一端进行插入删除的先入后出的线性数据结构,栈顶元素最后被插入到栈中,但是最先被删除;而栈底元素最先被插入,最后被删除。

2.下列叙述中正确的是( )。

A.有一个以上根结点的数据结构不一定是非线性结构 B.只有一个根结点的数据结构不一定是线性结构 C.循环链表是非线性结构 D.双向链表是非线性结构 【答案】D

【解析】线性表的特点:在数据元素的非空有限集合中,①存在唯一的一个被称为“第一个”的数据元素;②存在唯一一个被称为“最后一个”的数据元素;③除第一个以外,集合中的每个数据元素均只有一个后继;④除最后一个以外,集合中的每个数据元素均只有一个后继。B项,根结点可以看做线性表中唯一的一个被称为“第一个”的数据元素,但是根结点以及其他结点的后继并没有限定为仅有一个,所以该数据结构不一定是线性结构。

3.某二叉树共有七个结点,其中叶子结点只有一个,则该二叉树的深度为(假设根结点在第1层)( )。 A.3 B.4 C.6 D.7

【答案】D 【解析】对于任意一棵二叉树T,如果叶子节点数为n0,度为2的结点数为n2,二者之间的关系是n0=n2+1,该题中度为2的结点数为0,且只有一个叶子节点,因此,树中度为1的结点有6个,树的深度为7。

4.在软件开发中,需求分析阶段产生的主要文档是( )。 A.软件集成测试计划 B.软件详细设计说明书 C.用户手册

D.软件需求规格说明书 【答案】D

【解析】需求分析阶段只能生成需求分析规格说明书;测试说明书是软件测试阶段生成的;软件详细设计说明书是设计阶段生成的;用户手册是软件发布时随软件一同交付给用户的。

5.结构化程序所要求的基本结构不包括( )。 A.顺序结构 B.GOTO跳转

C.选择(分支)结构 D.重复(循环)结构 【答案】B

【解析】结构化程序设计的三种结构是顺序、分支和循环,不包括GOTO跳转,它只是分支结构的一种,也

是一个关键字。

6.下面描述中错误的是( )。

A.系统总体结构图支持软件系统的详细设计 B.软件设计是将软件需求转换为软件表示的过程 C.数据结构与数据库设计是软件设计的任务之一 D.PAD图是软件详细设计的表示工具 【答案】A

【解析】软件系统的总体结构图是软件架构设计的依据,它并不支持软件的详细设计。支持软件系统的详细设计的有:程序流程N-S图以及PAD图等。

7.负责数据库中查询操作的数据库语言是( )。 A.数据定义语言 B.数据管理语言 C.数据操纵语言 D.数据控制语言 【答案】C

【解析】数据库语言包括:数据定义语言、数据操纵语言、数据查询语言和数据控制语言。其中,数据定义语言负责数据的模式定义与数据的物理存取构建;数据库操纵语言负责查询增加、删除等数据操作;数据查询语言负责进行数据查询而不会对数据本身进行修改;数据控制语言负责数据完整性、安全性的定义与检查以及并发控制、故障恢复等。

8.一个教师可讲多门课程,一门课程可由多个教师讲授,则实体教师和课程间的联系是( )。 A.1:1联系 B.1:m联系 C.m:1联系 D.m:n联系 【答案】D

【解析】两个实体集间的联系可以以下几种:一对一(1:1)联系、一对多(1:m)或多对一(m:1)联系和多对多(m:n)联系。由于一个教师可以上多门课程,一门课程也可以由多个教师教授,因此属于多对多(m:n)联系。

9.有三个关系R、S和T如下:

则由关系R和S得到关系T的操作是( )。 A.自然连接 B.交 C.除 D.并 【答案】C

【解析】设有关系T和R,T能被除的充分必要条件是:T中的域包含R中的所有属性;T中有一些域不出现在R中。在除运算中S的域由T中那些不出现在R中的域所组成,对于S中任一有序组,由它与关系R中每个有序组所构成的有序组均出现在关系T中。

10.定义无符号整数为Uint,下面可以作为类Uint实例化值的是( )。 A.-369 B.369

C.0.369

D.整数集合{1,2,3,4,5} 【答案】B

【解析】类Uint表示的是无符号整数类,因此,它的每一个实例也应是无符号整数。A项是有符号数,C项是浮点数,D项是集合,并不是类的实例化对象。

11.表达式select (9+6*5+3%2)/5-3的运算结果是多少( )。 A.1 B.3 C.5 D.7

【答案】C

12.表达式select ((6%(7-5))+8)*9-2+(5%2)的运算结果是( )。 A.70 B.71 C.72 D.73

【答案】B

13.执行delete from student语句后的结果是( )。 A.删除表student

B.删除表student的所有记录 C.删除数据库student

D.语句不完整,不能执行 【答案】D

14.修改操作的语句update student set s_name =’王军’该代码执行后的结果是( A.只把姓名叫王军的记录进行更新 B.只把字段名s_name改成’王军’ C.表中的所有人姓名都更新为王军 D.更新语句不完整,不能执行

【答案】C

15.请把下划处的代码补充完整( )。

______ into student (s_name) ______(N’王大军’)s A.update, values B.insert, value C.insert, values D.delete, like

【答案】C 16.(@@error = 0)该代码表示的含义是( )。 A.找到至少一个错误 B.没有任何一个错误 C.错误的编号是0

D.发生了除数为0的错误

。 )

【答案】C

17.开始事务,提交事务,回滚事务的英语单词分别是( )。 A.begin transaction,rollback transaction,commit transaction B.commit transaction,rollback transaction,begin transaction C.rollback transaction,begin transaction,commit transaction D.begin transaction,commit transaction,rollback transaction 【答案】D

18.以下的标识符中,符合标识符命名规则的有几个( )。 3abc7, abc73, bc73a, c73ab,*73abc A.1 个 B.2 个 C.3 个

D.4 个 【答案】C

19.数据库系统的核心是( )。 A.数据模型

B.数据库管理系统

C.数据库

D.数据库管理员 【答案】B

20.下列语句中,不是表数据的基本操作语句的是( A.CREATE语句 B.INSERT语句 C.DELETE语句 D.UPDATE语句 【答案】A

)。

全国计算机等级考试《二级MySQL数据库程序设计》模拟试题及详解(二)

选择题精选

1.下列叙述中正确的是( )。

A.线性表的链式存储结构与顺序存储结构所需要的存储空间是相同的 B.线性表的链式存储结构所需要的存储空间一般要多于顺序存储结构 C.线性表的链式存储结构所需要的存储空间一般要少于顺序存储结构 D.上述三种说法都不对 【答案】B

【解析】线性表的顺序存储结构使用一组地址连续的存储单元,而链式存储结构除了存放数据之外,还需要存放指向下一个元素的指针。因此,线性表的链式存储结构所需要的存储空间一般要多于顺序存储结构。

2.下列叙述中正确的是( )。

A.在栈中,栈中元素随栈底指针与栈顶指针的变化而动态变化 B.在栈中,栈顶指针不变,栈中元素随栈底指针的变化而动态变化 C.在栈中,栈底指针不变,栈中元素随栈顶指针的变化而动态变化 D.上述三种说法都不对 【答案】C

【解析】栈是一种先进后出的数据结构,入栈和出栈都是对栈顶指针操作,因此栈中保存的元素也随着栈顶指针的变化而变化。

3.软件测试的目的是( )。 A.评估软件可靠性

B.发现并改正程序中的错误 C.改正程序中的错误 D.发现程序中的错误 【答案】D

【解析】软件测试是程序的执行过程,目的在于发现错误。

4.下面描述中,不属于软件危机表现的是( )。 A.软件过程不规范 B.软件开发生产率低 C.软件质量难以控制 D.软件成本不断提高 【答案】A

【解析】较件危机主要表现在:①软件需求的增长得不到满足;②软件开发成本和进度无法控制;③软件质量难以保证;④软件不可维护或维护程度非常低;⑤软件的成本不断提高;⑥软件开发生产率的提高赶不上硬件的发展和应用需求的增长。

5.软件生命周期是指( )。

A.软件产品从提出、实现、使用维护到停止使用退役的过程 B.软件从需求分析、设计、实现到测试完成的过程 C.软件的开发过程

D.软件的运行维护过程 【答案】A

【解析】软件生命周期是指将软件产品从提出、实现、使用维护到停止使用退役的过程。还可将软件周期分为三阶段:定义阶段、开发阶段和运行维护阶段。

6.面向对象方法中,继承是指( )。 A.一组对象所具有的相似性质

B.一个对象具有另一个对象的性质 C.各对象之间的共同性质 D.类之间共享属性和操作的机制 【答案】D 【解析】继承性机制使得子类不仅可以重用其父类的数据结构和程序代码,而且可以在父类代码的基础上方便地修改和扩充,这种修改并不影响对原有类的使用,即实现了类之间共享属性和操作。

7.层次型、网状型和关系型数据库划分原则是( )。 A.记录长度 B.文件的大小

C.联系的复杂程度 D.数据之间的联系方式 【答案】D 【解析】数据库是数据的集合,它具有统一的结构形式并存放于统一的存储介质内,是多种应用数据的集成。数据之间的关系或联系是划分数据库的主要依据。

8.一个工作人员可以使用多台计算机,而L台计算机可被多个人使用,则实体工作人员与实体计算机之间的联系是( )。

A.一对一 B.一对多 C.多对多 D.多对一 【答案】C

【解析】两个实体间的联系可分为3种类型:①一对一联系,表现为主表中的一条记录与相关表中的一条记录相关联;②一对多联系,表现为主表中的一条记录与相关表中的多条记录相关联;③多对多联系,表现为主表中的多条记录与相关表中的多条记录相关联。本题中,一个工作人员可以使用多台计算机,一台计算机可被多个人使用,因此为多对多的关系。

9.数据库设计中反映用户对数据要求的模式是( )。 A.内模式 B.概念模式 C.外模式 D.设计模式 【答案】C

【解析】模式的3个级别反映了模式的3个不同环境,以及对它们的不同要求。其中,①内模式处于最低层,它反映了数据在计算机物理结构中的实际存储形式;②概念模式处于中层,它反映了设计者的数据全局逻辑要求;③外模式是处于最高层,反映了用户对数据的要求。

10.有三个关系R、S和T如下:

则由关系R和S得到关系T的操作是( )。 A.自然连接 B.交

C.投影 D.并

【答案】A

【解析】自然连接是关系的横向结合,是将两个关系拼接成一个更宽的新关系,要求两个关系含有一个或多个共有的属性,生成的新关系中包含满足连接条件的元组。B项和D项,交和并运算要求参与运算的表有相同的属性,交运算的结果是两个表的公共部分,并运算是将两个表整合成一个表;C项,投影是从表中选出指定的属性值组成新表,是单目运算。

11.下列不是MySQL常用类型的是( )。 A.INT B.VAR C.TIME D.CHAR 【答案】B

12.SQL语句又称( )。 A.结构化定于语言 B.结构化控制语言 C.结构化查询语言 D.结构化操纵语言 【答案】C

13.在MySQL中,通常使用以下哪个语句来进行数据的检索、输出操作( )。 A.SELECT B.INSERT C.DELETE D.UPDATE 【答案】A

14.以下哪种方法不能用于创建索引( )。 A.使用CREATE INDEX语句 B.使用CREATE TABLE语句 C.使用ALTER TABLE语句

D.使用CREATE DATABASE语句 【答案】D

15.不可对视图进行操作的有( )。 A.SELECT B.INSERT C.DELETE

D.CREATE INDEX 【答案】D

16.E-R图是数据库设计的工具之一,它一般适用于建立数据库的( )。 A.概念模型 B.结构模型 C.物理模型 D.逻辑模型 【答案】A

17.在SELECT语句中,可以使用以下哪个字句,将结果集中的数据行根据选择列的值进行逻辑分组,以便能汇总表内容的子集,即实现每个组的聚集计算( )。

A.LIMIT

B.GROUP BY C.WHERE D.ORDER BY 【答案】B

18.在MySQL语句中,通常使用( )语句来指定一个已有数据库作为当前工作数据库。 A.USING B.USED C.USES D.USE 【答案】D

19.在CREATE TABLE语句中,通常使用( )关键字来指定主键。 A.INDEX B.UNIQUE C.NULL

D.PRIMARY KEY 【答案】D

20.在MySQL中,可以使用( )语句来修改、更新一个表或多个表中的数据。 A.DELETE B.REPLACE C.UPDATE D.TRANCATE 【答案】C

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuowenda.com 版权所有 湘ICP备2023022495号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务