ASP.NET 实用资料[转]
使用SqlBulkCopy类加载其他源数据到SQL表 在数据回发时,维护ASP.NET Tree控件的位置 vagerent的vs2005网站开发技巧 ASP.NET2.0小技巧--内部控件权限的实现 图片滚动代码。 css——之三行三列等高布局 Datagird TemplateColumn类型列中如何设定日期格式为yyyy-MM-dd格式? SQL Server各种日期计算方法 在sqlserver中如何根据字段名查找字段所在的表 [CommunityServer]看RBAC的一方景象 七招制胜ASP.NET应用程序开发 企业库之数据访问的一个小应用 SQL查找某一条记录的方法 简介微软发布的Data Access Application Block 把Excel表中的数据导入数据库(存储过程、数据库作业) 通过避免下列 10 个常见 ASP.NET 缺陷使网站平稳运行(转) 一个分组查询的SQL 常用算法(附源码可直接执行) 网络蜘蛛(crawlers) ,SEO,网络公关等相关资源与工具的收集与整理 最新版FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用简解(提供博客园本地下载) 经典数据库记录分页代码 [GridView控件]自定义分页 Web C#2.0 DataSet和Reader封装组件实现自动多数据库切换(含组件源码和实例) 为GridView删除添加提示 扩展GridView(五)——固定表头、指定行或指定列 Asp.net 2.0 Treeview 无限级无刷新示例 运用JAVASCRIPT,写一个类,类名:student,他的属性:name,age,tall,他的方法:getName,getAge,getTall SQL IF..ELSE..在存储过程的使用规范 sql server日期时间函数 页面自动刷新 css的一些基础的东西 利用css和js实现firefox和IE都支持的页面局部打印 总结一些js自定义的函数 從無到有實現一個xml數據庫登錄驗証 图片保存到数据库和从数据库读取图片并显示(C#) [转]FreeTextBox使用详解 将上传图片打上防伪图片水印并写入数据库 asp.net 2.0中一次性更新所有GRIDVIEW的记录 VS2005 TreeView 的 CheckBox 被点击时的引发页面回发事件 扩展GridView(四)——每行复选框的全选与取消全选 [翻译]开发一个HTML在线编辑器(一) Castle ActiveRecord(一)概述 用sql 得到某表下的列名 一个二级域名转向类(转) sql 分页存储过程 sql2000下 分页存储过程 回归命令行 SQLServer的命令行工具们(2) – sqlcmd.exe(中篇) 分页及页码导航 用户控件 十分钟内学会:根据数据库生成站点导航 自己写的几个高效,简洁的字符处理函数 用一句SQL取出第 m 条到第 n 条记录的方法 老问题:js实现gridview中的全选和反选 js取得gridview中获取checkbox选中的值,郁闷了半天 JavaScript 经典代码大全:有 目录 及 编号 的哦 ! 深入DML JavaScript 網頁打印處理 HTML语言:经典笔记'800')this.width='800';if(this.height>'600')this.height='600';" border=0> 员工管理系统(数据库部分)--一个老师很久就布置的作业 CSS 实用笔记 数据仓库自动抽取:通过 SQL Server 企业管理器中的数据转换服务 (DTS) 设计器 创建 Analysis Services 处理任务 SQL Server各种日期计算方法 如何创建类型FreeTextBox的编辑器 MemberShip(图) 让你的ASP.NET虚拟主机也支持子网站 使用 SqlBulkCopy 大量复制文字文件之 C# 程序代码 Community Server 2.1 安装到远程虚拟主机上常见问题解决 (摘)开源AJAX开发框架 继续发布VS2005下DataGridView 的多种样式列控件 sql server作业用法 SQL2000 和 SQL2005 下 行列转换 示例 使用批处理产生日期(时间)文件、文件夹 ASP.NET 2.0 Security FAQs 效果直逼flash的Div+Css+Js菜单 一个二级域名转向类(转) ASP.NET分页系列转载 (转载)基于.net开发平台项目案例集锦 轻松学DIV教程(div+css布局) 如何让SELECT 查询结果额外增加自动递增序号 导出sql server 数据库为Excel的数据字典的小工具 使用Gridview和ObjectDataSource轻松实现自定义分页 在数据回发时,维护ASP.NET Tree控件的位置 除非迫不得已不要用游标 基于.NET的CMS软件的选择 搜索引挚项目(附源码) 重写GridView分页样式! 重写GridView 开源代码生成器:SmartCode 构建基于ListView(Win)的数据绑定对象 随心所欲的Web页面打印技术 扩展GridView控件(上) Gridview动态隐藏空字段 ASP.NET组件DataGrid的分页实用方法 基于角色-功能-资源的权限控制模型的设计与实现 asp.net 2.0 权限树的控制(多处转载) Castle ActiveRecord Hands On Lab(1):基本数据访问 如何在数据层分页以提高性能 为gridview添加删除提示。 解决ASP 2.0中GridView控件的删除、插入、编辑命令操作客户端确认问题的另一方法 基于.net开发平台项目案例集锦 EnterPrise应用(5) Security Application Block应用程序块 授权处理(VB.NET) Ajax实现无刷新三联动下拉框 ASP.NET 2.0打造购物车和支付系统之 一 ASP.NET 2.0打造购物车和支付系统之二 通过样式表实现固定表头和列 数字转换为大写人民币(附源码)_AX 使用RewritePath方法实现【不同路径+任意URL后缀重写到指定页面且URL地址不变】(附源码)_AX 基于.net开发平台项目案例集锦 效果直逼flash的Div+Css+Js菜单 一段非常简单的让图片自动切换js代码 ASP.NET弹出一个对话框 通过样式表实现固定表头和列 在VS2005中 GridView导入Excel的两点小技巧-附源码 asp.net 2.0 中GridView里设置日期格式 针对Enterprise Library 2.0的框架:OFrame预览(代码和工具全部开源) {asp.net2.0}##一个关于GridView的网站 障眼法--如何去掉动网新闻系统的版权信息 ASP.NET简单分页 NQL.NET 数据库对象查询语言简介 2 Asp.Net 学习资源列表 asp.net身份验证和授权 在VS2005中 GridView导入Excel的两点小技巧-附源码 [转载]Asp.Net 2.0 发布问题 权限树中Checkbox的操作[Asp.Net2.0] 如何于DataGridView控件中以跨数据行方式显示数据 asp.net2.0中,实现treeview中选择父级checkbox时,子级连动 整理转载 自定义DataGrid控件开源 [视频讲解]GridView里做链接实现新闻列表到详细内容页的跳转 『原创』以学论道之ASP.NET中的文件流操作 GridView控件自定义分页详解 3-tier Architecture with ASP.NET 2.0 : Tutorial By Scott Mitchell TreeViewVisitor: 一个快捷访问 TreeView 控件节点的帮助类 基于功能(代码)的权限管理 一步一步学习ObjectDataSource控件--自定义分页排序 自己编写的操作实体类的分页控件, 实现页码层与数据库的具体的信息隔离 Alexa世界排名原理+作弊源码,为网站赢得好排名 Ajax实现无刷新树 GridView 批量删除,自定义分页,定位页码 关于GridView中自定义分页、单选、多选、排序、自增列的简单应用 Ajax实现无刷新三联动下拉框 GridView模版列嵌套GirdView显示主从表数据 Ajax无刷新实现图片切换特效 asp.net 2.0 用户管理功能结构 Asp.Net2.0权限树中Checkbox的操作 Membership学习(二)membership入门[xgluxv] Membership学习(三)Membership Providers介绍[xgluxv] Membership学习(一) Membership介绍[xgluxv] Membership学习(四)-自定义MembershipProvider Gridview中当设置自动生成列时对列中字段使用 html代码显示 一点一点学ASP.NET之示例——HttpModule 示例 一个三层架构的WinForms程序的完整范例(.NET 1.1/Northwind) 发布XenoCode 2006 for DotNet 2.0破解程序 一个简单的存储过程 Css2快速参考 在b/s开发中经常用到的javaScript技术 NHibernate的灵活配置 搭建基于ASP.NET 2.0的DNN 4.X模块开发环境及模块实例(2) 搭建基于ASP.NET 2.0的DNN 4.X模块开发环境及模块实例(1) 发布一个支持大量文本打印的PrintDocument派生对象,公开源代码。 史上最全的Windows进程详解! PetShop4.0学习第一天 删除前的确认窗口 我对图形变换滤镜的收集(CSS渐变滤镜大全) 2006年it人士必去的10个网站 DataReader应用小示例(数据库访问操作的基本过程2.0通过) (收藏)抓取Web网页数据分析 GridView/DataGrid单元格不换行的问题 如何在GridView中使用DataFromatString VS2005新控件之GridView 使用高级技巧系列[一][视频] VS2005新控件之GridView 使用高级技巧 几个.Net开源的CMS、Portal系统 gridview中加弹出窗口用例 GridView&DetailsView对XML文件增删改 [译]Scott Mitchell 的ASP.NET 2.0数据教程之十一: 基于数据的自定义格式化 初谈ADO.NET中利用DataAdapter进行数据操作 单一登录 Web 应用程序的企业级安全系统 发布XenoCode 2006 for DotNet 2.0破解程序 IBatisNet+Castle构架开发指南 IBatisNet+Castle构架开发指南 (续) 附代码生成模板 GridView根据值的变化改变行列样式 使用ASP.NET 2.0中的GridView控件 我积累的数据库操作类(ASP.NET) 我积累的数据库操作类(ASP.NET) 我积累的数据库操作类(ASP.NET) GridView 控件编程的事件 css+div布局总结--新手入门 15分钟内快速构建数据访问层(翻译) Transact_SQL小手册(各种sql语句大集合) Exports datatable to CSV or Excel format [转贴]开发VS2005下ComboBoxTreeView(下拉列表框弹出树) 与ToolStripComboBoxTreeView(下拉列表框工具条弹出树) 使用配制文件定制身份验证和基于角色的安全 一句SQL得出表中重复的数据(TMP) SQL精妙语句 Asp.net2.0:如何使用ObjectDataSource(配合ORM) Sql Server数据库的备份和恢复措施 SQL Server2000数据库文件损坏时如何恢复 存储过程编写经验和优化措施 (转) 征集佳句-精妙SQL语句收集 利用WebBrowser彻底解决Web打印问题 各种sql语句大集合 自定义用户访问权限 DataGrid导出excel和word的例子 具有滚动条的div SQL Server 2005 Express 附加的数据库为“只读”的解决方法 Sql 导入/导出Excel 不走寻常路 设计ASP.NET应用程序的七大绝招 ASP.NET性能优化 ASP.NET性能优化 对数据库Sql Server常用操作类库SQLHelper 如何取出treeview中checkbox的值 海量数据库的查询优化及分页算法方案 使用配制文件定制身份验证和基于角色的安全 VS2005新控件之GridView 使用高级技巧系列[二][视频] 一条经典的汇总的sql sql Server 索引优化 (转) Log4Net使用指南 一些有用的sql语句实例 Enterprise Library 2.0 -- Data Access Application Block 在Excel中将连续多列相同数据项合并 执行SQL存储过程事事例 SQL宝典 SQL语句导入导出大全(轉,收藏用)
gridview中手工排序 Asp.net 项目中引入Nhibernate 入门(一) 利用asp.net 2.0的客户端回调功能制作下拉框无限级联动 一个 NHIBERNATE+GRIDVIEW 添加删除修改的例子(单表) IBatisNet基础组件 用javascript将数字转换为中文大写 asp.net的TextBox回车触发事件 利用Sql作业在asp.net 里面实现异步调用存储过程. 抓取Web网页数据分析 VS2005中如何动态设置数据库连接信息? GridView控件修改、删除示例(修改含有DropDownList控件) JavaScript有用的代码,摘抄自:http://bbs.tech.163.com/board/rep.jsp?b=tech10&i=1296&p=0[转] 一些sql语句的详细解释 DataGrid使用心得(附大量代码) [转] SQL Server中各个系统表的作用 使用 Web Services Enhancements 2.0 的基于角色的安全性 Flash+asp.net打造FLASH首页新闻发布 SQL存储过程事务和优化方法(包括查询方式语句结合) 小记存储过程中经常用到的本周,本月,本年函数 GridView Css ASP.NET 2.0 Language Swithcer and Theme Swiche ASP.net2.0学习资料汇总 触发器与约束的适用条件 GRIDVIEW 中当数据行数未满时,填充空白行 ComponentArt Web.UI for ASP.NET 2.X序列号 创建用于监视对student表进行插入和更新操作的触发器 20060516: 实现圆角div效果 .net绝对技术资料 sql server2000中使用convert来取得datetime数据类型样式(全) 一些sql 语句(行列转换等) [转载] Owc的使用---自己封装好的类可以实现14种分析图 非常經典的WEB列印方案 CuteEditor 5.0 的使用 ASP.NET 2.0构建动态导航的Web应用程序(TreeView和Menu ) MD5算法的T-SQL实现 ASP.NET2.0中数据源控件之异步数据访问 DotNetGrid 控件下载 DotNetGrid 介绍 WEB打印-------我的搜集 在校生数据导入范例 关于多极分类的几个存储过程 一个 NHIBERNATE+GRIDVIEW 添加删除修改的例子(单表) 树形数据查询示例 转 SQL Server 数据库管理常用的SQL和T-SQL语句 IIS状态代码的含义 .NET平台下带权限控制的TreeView控件节点生成算法(转载) 实现HTTP内容的抓取 给SQL Server存储过程,传送数组参数的变通办法 在.net中使用Fckeditor [转] SQL的3种连接查询 海量数据库的查询优化及分页算法方案 [转] transact---sql高级查询(下) [转] transact---sql高级查询(上) SQL Server数据库开发的二十一条军规 Excel编程 存储过程语法 SQL 语法参考手册 ASP.NET之精通弹出窗口 在网页中插入视频播放代码全集 无限级分类的实现 资源名称资源名称取得汉字字符串的拼音首字母的mssql函数 树_ajax 树_ajax GridView与DataGrid中的数据项访问差别 Gridview中onmouseover的效果 ASP.NET2.0+SQL Server2005构建多层应用(转载) 修正过的通用分页存储过程 [推荐]网络上通用的调查答卷系统-XML做数据库(将DataSet转化成字符串) MS-SQL数据库开发常用汇总 在visualStudio里面使用SqlServer2000作为数据源 获取影响行数和ID的存储过程 C# .Net中的类型转换 C#.net常用函数 SQL注入 FCKeditor2.2+ASP.NET2.0不完全攻略 FCKeditor2.2+ASP.NET2.0不完全攻略 【转贴】datagrid数据导出到excel文件给客户端下载的几种方法 GridView动态生成模板列 关于树形控件 asp.net 备份和恢复SQL SERVER 数据库 Asp.net(C#)实现验证码功能 Asp.NET程序中常用的三十三种代码 分割以逗号作为分割符号的字符串并插入到表中 列出一个表中的某个字段重复的记录 DataGrid系列技巧(导出excel,事件,多种方式呈现数据,全选全删)等等等 把以"文本文件(制表符分割)"保存的EXCEL文件导进SQLSERVER2000的DEMO! 总结:ADO.NET在开发中的部分使用方法和技巧 (转贴) DATAGRID的全选/取消全选控制(CHECKBOX) 使用SqlBulkCopy类加载其他源数据到SQL表 使用SqlBulkCopy类加载其他源数据到SQL表 使用SqlBulkCopy类加载其他源数据到SQL表 一个调查实例<主要训练向panel中添加控件>包括全部代码 ASP.NET 2.0客户端回调的实现分析(3)[ZT] [原创]把SQL的动态查询改成SQL查询 SQL Server实用经验技巧集 使用 DataAdapter 执行批量更新 treeview的建立,更新,删除 C#实现web信息自动抓取 [收藏].net关于企业Excel报表的生成 将 ASP.NET 2.0 应用程序服务配置为使用 SQL Server 2000 或 SQL Server 2005(转) .NET进销存系统开发笔记------之Gridview应用 .net 2.0中GridView无限级嵌套的实现 导入Excel电子表格数据到SQLSever数据库的另一种方法 一个购物车的简单实现(多层开发) ASP.NET2.0中 TreeView 和ORACLE 数据绑定的一种方法 ASP.NET2.0 ObjectDataSource的使用详解(2) ASP.NET2.0 ObjectDataSource的使用详解(1) 将DataSet更新自动提交到数据库工具类实现 超强扩展性的DNN-DotNetNuke模块功能分类列表(from 中国DNN) 世界上主要的一些搜索引擎 Survey Admin 示例:实现 Microsoft .NET 基于角色的安全性(转) NHibernate Step by Step (四)Session、Query及HQL NHibernate Step by Step (三) Configuration和Sessionfactory Microsoft .NET Pet Shop 4 架构与技术分析 PetShop的系统架构设计 Asp.Net 2.0 TreeView的Checkbox级联操作 无废话-SQL Server 2005新功能(1) - TSQL 导出导入Excel(DataSet,DataGrid) DNN开发中的一些细节(1) DNN开发中的一些细节(2) ASP.NET2.0: Ilungasoft.Framework.Web之基于Callback的无刷新上传进度条控件[带源码] TreeView 爱恨之间 Transact SQL 常用语句以及函数 Transact SQL 常用语句以及函数 ASP.NET 2.0 正式版中无刷新页面的开发 DNN开发中的一些细节(1) ASP.NET2.0快速入门--高级数据方案(3) 结合CodeSmith开发和调试DNN3模块 SqlDataSource WEB控件:当DeleteCommandType="storedProcedure"时 关于TreeView控件专题 利用Treeview做权限树的一种方法 利用Treeview做权限树的一种方法 (新)在ASP.NET中调用存储过程传参数 ASP.NET2.0快速入门系列--高级数据方案(上) ASP.NET2.0快速入门--高级数据方案(中) asp/asp.net中遍历树型结构. ASP.NET 2.0中使用multiview控件 ASP.NET2.0快速入门系列--高级数据方案(上) DataGrid,GridView和DetailsView中添加删除确认提示 VS2005中用Code Snippets提高开发效率 IIS和ASP.NET2.0 关于vs 2005的一个问题, 解决The path "xxxx' maps to a directory outside this application, which is not supported. VS2005第一天 Failed to access IIS metabase 无ASPX文件部署(续) ASP.NET 2.0构建动态导航的Web应用程序(TreeView和Menu ) ASP.NET 2.0基于SQLSERVER 2005的aspnetdb.mdf部署 对vs2005生成dll文件的一点疑惑 ASP.NET 2.0 新特性 WEB Service 下实现大数据量的传输 switch your web application project to use development machine's IIS server [ASP.NET 2.0 Security FAQs]如何设置SQL Server或SQL Express数据库,使其支持Membership、Profiles和Role 将 ASP.NET 2.0 应用程序服务配置为使用 SQL Server 2000 或 SQL Server 2005(转载) GridView 控件使用不完全指南! 【原创】asp/asp.net中遍历树型结构. .NET Pet Shop 4.0案例研究预览篇 关于树形结构的研究的资料收集 单点登录(SSO)的核心--kerberos身份认证协议技术参考(三) Gridview:在进入编辑模式后动态添加控件 ASP.NET中大结果集的分页[翻译] Asp.Net Forums研究文章集合(收藏) ASP.NET2.0中Gridview中数据操作技巧 SQL Server中利用存储过程来高性能地进行分页 关于二级域名Cookie的问题及解决方法 一步一步建网-2-DotNetNuke4-5/6-杂项/感! 通过系统配置来提高ASP.NET应用程序的稳定性 GridView 控件使用不完全指南!(续一) ASP.NET应用程序的部署--兼谈aspnet_compiler.exe命令 RDLC报表(一) RDLC报表(七) GridView 控件使用不完全指南! DNN皮肤制作 一个登陆页面,包含了初始化用户,输入检测,错误处理等 DNN皮肤制作 基于dotnetnuke的网站全新上线! [导入]DotNetNuke Skin 與 Container 設計介紹 CodeSmith3.0开发资料下载 CodeSmith开发系列资料总结 提高SQL执行性能方案:如何让你的SQL运行得更快zt Visual Studio 2005 的101个示例下载 网络数据库挖掘程序的设计 对联广告代码效果大全 网站生成静态页面,及网站数据采集的攻、防原理和策略 [原创]终极防范SQL注入漏洞! 【先锋海盗类】Ver2005 完美版 拿别人的新闻来用,虽然我知道这样不好,还是用了。。。 网页小偷程序ASP.net 数据采集程序(网页小偷)点滴心得 部署安装时写入SQL SERVER和Web.config 将博客园程序从Visual Studio 2003迁移到Visual Studio 2005的尝试 开篇:Nhibernat.Test项目分析之:ConfigurationTest 基于NHibernate的三层结构应用程序开发初步 15分钟内快速构建数据访问层(翻译) Asp.net 2.0专题二:本地化(Localization) 数据库应用基础系列 深入了解 SQL Server 2000 与 ADO.NET 中的事务隔离及数据锁定 第2章 并发操作的一致性问题 (2) 在asp.net 2.0中使用SqlBulkCopy类迁移数据 使用asp.net 2.0和SQL SERVER 2005构建多层应用 推荐个关于 team system教学的好站点 推荐个关于 team system教学的好站点 DataList控件也玩分页- - SQL Server 两个触发器例子,大家看看怎么样? 发布一个原创的基于Ajax的通用(组合)查询(续) 在IIS6.0下ASP .NET 的版本冲突问题 FCKeditor应用小记--起步篇 WEB Service 下实现大数据量的传输 55种网页常用小技巧(转载) [转]Microsoft PetShop 3.0 [转载]用WSE在Web服务中验证用户身份 一次SQL Server 2000修复实践的说明 新数据网格DataGridView简介(转自MSDN) [转贴]Visual Studio 2005常用插件搜罗 第 4 章 构建以数据为中心的应用程序 网 站 策 划 [转载] 在.net安装程序部署SQL Server数据库 [转载] 在.net安装程序部署SQL Server数据库 ASP.NET程序中常用代码汇总(一)(转载) ASP.NET程序中常用代码汇总(二)(转载) ASP.NET程序中常用代码汇总(三)(转载) ASP.NET程序中常用代码汇总(四)(转载) ASP.NET程序中常用代码汇总(五)(转载) 露雨资源库(第一个.net2.0软件)二 ADO.NET 2.0 大批量数据操作和多个动态的结果集 继续发布VS2005下DataGridView 的多种样式列控件 一个支持asp.net2.0和Sql server及Access的免费空间 FAQ:关于aspspider.net的申请与使用(逐渐整理中) ASP.NET 2.0中的成员管理与角色管理 ASP.NET中用哪种方式表格化数据 DotNet软件开发框架 知识管理系统分析之一:网络蜘蛛的分析 如何实现在Asp.net下XP风格的下拉菜单 CodeSmith基础(二) CodeSmith开发系列资料总结 利用 SharpZipLib方便地压缩和解压缩文件 GridView控件使用经验 一个支持asp.net2.0和Sql server及Access的免费空间 新版XNet.SqlHelper 使用ASP.NET 2.0 Profile存储用户信息[翻译] Level 200 FreeTextBox使用详解 (版本3.1.1) Web Services的身份验证 [小结]关于asp.net个性化站点的设置 网络数据库挖掘程序的设计 使用企业程序库的两点体会 ASP.NET 2.0构建动态导航的Web应用程序(TreeView和Menu ) 如何使网站基于CA认证访问 体验 .net2.0 的优雅(2) -- ASP.net 主题和皮肤 一完美的关于请求的目录不存在而需要url重写的解决方案! 如何建立有效的.Net软件注册保护机制 常用CSS ASP.NET程序中常用代码汇总(五) ADO.NET 2.0 大批量数据操作和多个动态的结果集 在Apache环境下成功的运行ASP.NET 使用ADO.net转换数据到Excel格式并提供下载 打开一个Excel模板文件填充数据另存为一个文件 一个关于DataGrid的打印类,分享,感谢作者 把excel 数据导入数据库 NHibernate文档翻译 第5章 集合类(Collections)映射 NHibernate文档翻译 第4 章 O/R Mapping基础 关于能自定义格式的、支持多语言的、支持多数据库的代码生成器的想法 自动代码生成器 Enterprise Library Step By Step系列(十一):异常处理应用程序块——入门篇 Enterprise Library Step By Step系列(十):缓冲应用程序块——进阶篇 Asp.net中DataGrid利用DataRelation显示主从表信息(可控制从表信息隐藏和显示). Cookie 支持二级域名和FormsAuthentication 加强版 aspx->cs->dll 无aspx文件部署 无ASPX文件部署(续) asp.net报表解决方法(第一次使用cnblogs的blog) NHibernate文档翻译 第3章 持久化类(Persistent Classes) 《ASP.NET办公自动化系统开发实例导航》笔记三 人事管理模块 [转]Microsoft PetShop 3.0
《ASP.NET办公自动化系统开发实例导航》笔记二 系统管理模块设计 《ASP.NET办公自动化系统开发实例导航》笔记一 NHibernate文档翻译 第2章 ISessionFactory配置 TreeView常用操作 NHibernate文档翻译 第1章 体系结构 关于ASP.NET中调用Excel组件不能结束进程的解决方法 用ActiveX控件和JavaScript脚本实现基于Web的票据套打(源码下载) 搜索引擎, 请手下留情 我写的Asp.net操作Excel的一个类库ExcelHelper(源码下载) Enterprise Library Step By Step系列(八):日志和监测应用程序块——进阶篇 一个经典的ADO.NET入门例子(CSDN博客迁移) [源代码]系统框架NickLee.Framework.V1.X for asp.net asp.net利用OWC生成分析報表 把aspx文件编译成DLL文件 ADO.NET 2.0 大批量数据操作和多个动态的结果集 让.Text的搜索引擎支持二级域名 微软技术大会 Tech.Ed2005 所有讲义(ppt格式)下载地址 应用系统架构设计 应用系统架构设计-补全篇 简单实用的DATAGRID组件 .Text 支持二级域名之二 Cuyahoga的安装及结构 也nhibernate会遇到问题,还好找到原因了 [C#]NHibernate处理多帐套问题 滚动DataGrid 蛙蛙推荐:迎接web2.0:写一个RSS.HTC组件 分享:微软提供的一个开源控件treeview 的一小个用法 发布一个原创的基于Ajax的通用(组合)查询(续) 在ASP.NET页面中冻结DataGrid的列或头部 Cuyahoga代码的研究之一:Cuyahoga.Corel项目 Cuyahoga研究三:用户配置数据的处理 Cuyahoga研究之二:利用MD5CryptoServiceProvider返回字符串的MD5 Hash值 [精华&原创]可按任意字段排序的分页存储过程(不用临时表的方法,不看全文会后悔) Asp.net中把DataTable或DataGrid导出为Excel 技巧百问(5):打造超级浮动广告(不受屏幕限制) 使用HttpModule实现多个域名分别“绑定”到子目录 利用XML实现通用WEB报表打印 续:利用XML实现通用WEB报表打印(实现篇) 昨天的性能优化与今天的网站故障 一个关于DataGrid的打印类,分享,感谢作者 把文件上载到数据库中 .Text分页技术(1)分页的存储过程分析 Community Server专题十:MemberRole之RoleManager 构建动态导航的Web应用程序 SQL Server 用触发器实现表的历史记录 SQL Server 用触发器实现表的历史记录 WEB打印大全 asp.net操作Excel总结 VC++开发BHO插件——定制你的浏览器 作者 陆其明 如何实现在Asp.net下XP风格的下拉菜单 使用数据2分处理的通用分页存储过程 前半部分与后半部分数据访问时间相同(很久没来了 作为国庆礼物给大家了) Js控制ASPX页面刷新的土办法 代码生成工具之MyGeneration 初次体验.net Ajax无刷新技术 Community Server专题八:MemberRole之Membership 应用IBatisNet+Castle进行项目的开发 .Net PetShop3.0的数据访问技术及其改进 Community Server专题七: Job & Timer 使用企业库在某些站点会报试图执行安全策略不允许的操作异常的解决方法。 刚注册,先转发一片文章:在 ASP.NET 中执行 URL 重写 利用asp.net 2.0构建企业级门户平台(1、设计思想) 利用asp.net 2.0构建企业级门户平台(2、实现页面请求的调度) 报表的开发利器-ExcelQuicker ExcelQuicker模板功能的高级应用示例——薪资报表 SQL Server未公开的两个存储过程 WSE--简介(一) .net WebControl 处女作,用于导航的Tree控件(不敢说用起来最简单也算得上非常简单,呵呵) xml数据岛,xsl,javascript,asp.net 的结合使用 web 程序模仿 windows 资源管理器 用CodeSmith生成数据库实体类的代码 .NET中统一的存储过程调用方法(收藏) TreeView常用操作 NHibernate学习 NHibernate学习 给SQL Server存储过程,传送数组参数的变通办法 Community Server专题二:体系结构 权限设计(二) 通用分页存储过程 N-Tier Server/(Smart)Client 应用程序的设计和开发 基于身份验证票据的权限系统的实现之源代码篇 Enterprise LibraryV1.0-数据应用程序块 共享自动生成DTO/DataAccess/BizObject的CodeSmith模板 一个不错的SQL储存过程分页,储存过程+Repeater,如果只是浏览数据的话,快就一个字 Forms验证中的roles 跨页面的多选功能实现 简单说一下我对这个CRM系统的设计方案哦 把你的Access数据库嵌入到资源中发布 对象界面映射(UI Mapping)——Mustang1.0.0.0写完了!!! 蛙蛙推荐:利用OWC创建图表的完美解决方案 SQLServer 工具箱v1.3(SQL脚本排序,日志清除,数据导入导出)附完整源代码 从WEB SERVICE 上返回大数据量的DATASET 批量字符串替换程序 install shield X 打包 .net Framework ASP.NET直接下载一个文件,而不是在IE中打开它 实现GridView控件的删除多条记录功能系列(1) ComponentArt WebUI For asp.nET 2.1,So Good Asp.nET UI Control! 实现GridView控件的删除多条记录功能系列(2) 博客园 Google广告 开源项目 实现GridView控件的删除多条记录功能系列(3) ICSharpCode的SharpZipLib最新0.84版本 SmartDBForge-智能数据库工厂 2005预览版:自动化生成数据库文档、SQL脚本、实体类等,支持多种数据库 提供一个实体类生成工具. T-SQL 存储过程: (20050802修订版) 根据基本表结构及其数据生成 INSERT INTO ... 的 SQL 关于单点登陆的一些问题 蛙蛙推荐:微软MSDN导航菜单演示(Javascript+CSS2) 蛙蛙推荐:远程抓取网页到本地数据库.doc CuteEditor破解手记 [分享]FCKEDITOR范例及中文使用说明 [DNN模块开发]模块的文件结构及命名方法 用好CodeSmith,提高生产力,CodeSmith技术原理初探. Smart Client学习体会(一) 优秀.net 控件包介绍 应用系统架构设计 如何在删除并重新安装 IIS 之后修复 IIS 映射 五种常见的ASP.NET安全缺陷 “他说,你那样做,太累,而且如果字段变了,还要维护” 纯脚本搞掂DataGrid表表头不动,表身滚动。 DataGrid分页中文效果,与大家共享,顺便有能者把DropDownList的触发找到。我是放在呈现上。 基于文件格式的DataGrid多媒体播放示例(带表头自动排序,动态播放列表功能) Office自动化开发中的事件编程 ExcelQuicker模板功能的高级应用示例——薪资报表 抄:JavaScript实用技巧集锦 [分享]新封装的一个实现无刷新连动下拉列表类(最新版本) 新鲜出炉,几分钟以前刚刚完成,一个带自定义分页,排序功能的DATAGRID控件(公开源码) C#操作Excel,套用模板并对数据进行分页 Asp.Net Forums与现有系统整合方案示例 存储过程中的事务实现 基于Active Directory的用户验证 Sql server数据库记录修改追踪和恢复的解决方案 SQL Server最新补丁与工具大全--数据库管理员必看 介绍一种Web上打印技术 表单验证代码(转载) 在Webpart中以Post方式提交数据到SharePoint站点 ASP.NET2.0中用Gridview控件操作数据 一个有用的oracle数据库访问封装类 【经验分享】海量数据高性能分页新法 MSDN: 设计数据层组件并在层间传递数据 真的需要在.NET中使用WIN32 API的朋友,这里是你的宝库 服务器升级安装操作备忘[原创] WEB柱状图和折线图控件,大家应急时可以用用 RapidTier 1.0 beta2 发布 关于设置WebControls里的treeview控件的图片路径 两分钟让你明白什么是ERP! 权限控制理论及实现 纯脚本搞掂DataGrid表表头不动,表身滚动。 NHibernate 使用手迹(2nd) ASP.NET服务器控件开发简介: ComboBox [开放源代码] 用存储过程生成单据号 [开源论坛]StellaForum v 2.0 公开 NHibernate使用的问题 使用NHibernate时需要考虑的另一个问题 使用 DataAdapter 和 DataSet 更新数据库 绝对适合您的DataPropertyGrid! 关于BI Portal(一) 也谈log4net 1.2.9 beta的使用(web 项目) datagrid(webform)批量操作的一些思路。 将TreeView存储、写入数据库的扩展类TreeViewEx 一句SQL语句解决倒序数据分页提取 一个 TreeView 的派生类: TreeViewEx 实现 NodeShowToolTip、NodeDoubleClick 事件 解放程序员的验证输入(II) 用好CodeSmith,提高生产力,CodeSmith技术原理初探. 最近开发一个SQL server大数据量统计系统的经验总结 SQL语言高级技法演练 动态载入数据的无刷新TreeView控件(5) 动态载入数据的无刷新TreeView控件(4) 在ASP.Net中两种利用CSS实现多界面的方法. SQL Server数据汇总完全解析 asp.net学习资源列表 将TreeView存储、写入数据库的扩展类TreeViewEx .NET平台下WEB应用程序的部署(安装数据库和自动配置) 在sql语句中替换Not In 的方法 创建新的企业级模板 SQL Server游標應用技巧一例 送给所有还未买房的技术朋友们——住房按揭贷款计算器 基于Wiki的网络协作/知识积累试验平台 快过年回家了,发点实用的东西给大家 .NET商业应用架构所要解决的若干问题(原创) 企业设计模式读书笔记 Domain Model MAVERICK.NET初窥(原创) 再谈SQL Server表与Excel、Access数据互导 使用Singleton改善ASP.NET性能备注 石头.net [杨 云] 也来说说asp.net页面之间传递数据 Vs ColdFusion 一套可嵌入或独立使用的翻页控件: WebPager(附源码) Rainbow分页解决方案 我对多类型用户的设计想法...... 为什么叫“老师” 和 “学生” 生成工具-CodeSmith-享受编程的乐趣(三) 生成工具-CodeSmith-享受编程的乐趣(二) 生成工具-CodeSmith-享受编程的乐趣(一) 在ASP.NET中使用NHibernate 代码阅读总结之ASP.NET StartKit TimeTracker(角色权限之捉虫笔记) 一个NHibernate应用的实际例子(A good open source project to learn how to use NHibernate) 客户自行更改了aspnet用户权限,结果整个网站不能用。查找了资料记录下来 数据分页显示大搜索 CNBlogs引用第三方组(控)件明细^_^ 使用HttpContext的User属性来实现用户验证 近音搜索,比较输入Z就可以搜索到拼音Z开头的汉字,搜索"浙江",只要输入"ZJ"就可以了 看了下面那篇“Crack别人应用程序”的文章有感,简述.Net下的应用程序授权。 子查询基础知识 我用Rainbow做网站 将TreeView存储、写入数据库的扩展类TreeViewEx Dottext中的配置 提高ASP.NET应用程序性能的几招方法 一定要记住:Page.IsPostBack 不能忘。。。 log4net 配置与应用 浅析《ASP.Net Web 站点高级编程》的登录验证! 开源的数据库组件 代码阅读总结之ASP.NET StartKit TimeTracker(角色权限) 老猫的理想开源小范例 [精华&原创]可按任意字段排序的分页存储过程(不用临时表的方法,不看全文会后悔) IEWebcontrol webctrl_client目录配置 FMStocks7 , 不错的一个.NET 示例程序 感受DataGrid给数据操作带来的便利(4) 感受DataGrid给数据操作带来的便利(5) 中国DNN 的邀请 感受DataGrid给数据操作带来的便利(6) DotNetNuke(DNN)从入门到进阶(1)-怎样写自己的模块 如何实现文本框焦点自动跳转及通过回车键提交表单 如何使用一个不错的图表组件WebChart(免费) .NET下,你采用的是哪种方式进行数据操作? 两种不同情况的分页实现 .NET下,你采用的是哪种方式进行数据操作? 常用SQL说明 可以动态分页的存储过程 [专题]O/R 实体关系映射 我的IBatisNet的Demo DNN官方说明2 Duwamish代码分析篇 SQL Server数据库备份还原 通用分页SQL SQL过程自动C#封装,支持从表到基本存储过程生成, DNN的白皮书(官方说明) SQL Server自动备份的SP, 只要加上数据库名, 和路径即可. Rainbow中的不过期分页的文章Module 点击一个Button,来看Duwamish7的总体层次 我在研究的一些.net开源项目 回头看.Net的优点与进步 方便好用的 ASP.Net 错误记录发布模块 ELMAH (Error Logging Modules And Handlers) 我用Rainbow做网站 实现千万级数据的分页显示--整理资料并测试 小技巧之——服务器端变量与客户端JScript脚本变量的互操作。 Asp.net(C#)实现验证码功能 SQL 2000中的触发器使用 NHibernate 空气是哪么的清新,世界是多么的美好 NHibernate 做个小项目来试一下吧 三 NHibernate 做个小项目来试一下吧 四 (我们继续) 博客园的开源项目: Aop.NET DotNetAOP ibatis介绍[转贴] 使用open source产品组装你的web应用架构[转贴,只作为收藏,非本人原创] 发现不少免费、酷、强大组件(Win/Web) NHibernate 做个小项目来试一下吧 一 NHibernate 做个小项目来试一下吧 一 NHibernate 空气是哪么的清新,世界是多么的美好 用Nhibernate怎么实现数据的添加、删除、修改简单程序 利用webService做系统间数据整合 Rainbow的安装 我想问一下NHibernate的问题??? NHibernate学习第二天(在nhibernate中执行SQL语句 ) NHibernate学习第一天(数据的写入 Insert) 好久没有见到有人谈论代码生成器了 几个开源项目实体层实现方式比较 象使用DataGrid一样使用DataList(包含分页) 一个对众多CMS(内容管理系统)进行比较、评论的网站 在Windows下让不同用户使用不同的分辨率(C# 2005) 数据分页 DotNetNuke:如何创建自己的模块(FlashPlayer Module) SharpDevelop代码分析 (一、序+基本概念) 发布Asp.Net Forums V2 中文官方 10.1 国庆版 号外!激动人心的DotNetNuke(DNN)2.2x新特性最新汇报! DotNetNuke:制作属于我们自己的Skin sql server中分页获取数据的存储过程 轻量级的数据库访问类 DotNetNuke:自动升级功能(一) DNN第三方贡献 CodeProject上最近(2004-09-24)发现的几个好代码 使用Reflector工具解决问题 关于Rainbow的一些思考 FreeTextBox的ToolbarButton整理 web的用户验证方式 SqlServer通用存储过程的编写 我将msdn上一篇关于数据库打包的文章由vb改为cs拉,好久没发言了,希望这个东西对大家有用! DotNet(.Net)下构建高适应性的三层架构 DotNetNuke:自动升级功能(序) 关于PagedDataSource,非常好用的一个分页属性! IronPython的第一块鳞片 关于Rainbow的一些思考 柱状图改进版 CN.Text开发笔记—利用反射将数据读入实体类 布局和配色(Rainbow的Design目录) 存储过程编写经验三 存储过程经验二 扩展AdRotator控件,让它支持.SWF广告 (源码) 描述 Machine.Config 和 Web.Config(转载) sqlserver 海量数据导入的最快方法 Community 学习(C#版) DataGrid使用<2> 绑定checkbox [百万级]通用存储过程.分页存储过程. 实现千万级数据的分页显示! 今天把最近看DotNetNuke的心得写一些,希望对别人有所帮助 DNN(DotNetNuke)研究手札系列2-背景、现状 win2003优化大全 (转载) DNN(DotNetNuke)研究手札系列1-资源 DotNetNuke 2.1.2安装指南 DataGrid资料 DataGrid技巧大集合
asp.net速查手册
GridView/DataGrid单元格不换行的问题
如何在GridView中使用DataFromatString
VS2005新控件之GridView 使用高级技巧系列[一][视频]
VS2005新控件之GridView 使用高级技巧
几个.Net开源的CMS、Portal系统
gridview中加弹出窗口用例
GridView&DetailsView对XML文件增删改
[译]Scott Mitchell 的ASP.NET 2.0数据教程之十一: 基于数据的自定义格式化
初谈ADO.NET中利用DataAdapter进行数据操作
单一登录 Web 应用程序的企业级安全系统
发布XenoCode 2006 for DotNet 2.0破解程序
IBatisNet+Castle构架开发指南
IBatisNet+Castle构架开发指南 (续) 附代码生成模板
GridView根据值的变化改变行列样式
使用ASP.NET 2.0中的GridView控件
我积累的数据库操作类(ASP.NET)
我积累的数据库操作类(ASP.NET)
我积累的数据库操作类(ASP.NET)
GridView 控件编程的事件
css+div布局总结--新手入门
15分钟内快速构建数据访问层(翻译)
Transact_SQL小手册(各种sql语句大集合)
Exports datatable to CSV or Excel format
[转贴]开发VS2005下ComboBoxTreeView(下拉列表框弹出树) 与ToolStripComboBoxTreeView(下拉列表框工具条弹出树)
使用配制文件定制身份验证和基于角色的安全
一句SQL得出表中重复的数据(TMP)
SQL精妙语句
Asp.net2.0:如何使用ObjectDataSource(配合ORM)
Sql Server数据库的备份和恢复措施
SQL Server2000数据库文件损坏时如何恢复
存储过程编写经验和优化措施 (转)
征集佳句-精妙SQL语句收集
利用WebBrowser彻底解决Web打印问题
各种sql语句大集合
自定义用户访问权限
DataGrid导出excel和word的例子
具有滚动条的div
SQL Server 2005 Express 附加的数据库为“只读”的解决方法
Sql 导入/导出Excel
不走寻常路 设计ASP.NET应用程序的七大绝招
ASP.NET性能优化
ASP.NET性能优化
对数据库Sql Server常用操作类库SQLHelper
如何取出treeview中checkbox的值
海量数据库的查询优化及分页算法方案
使用配制文件定制身份验证和基于角色的安全
VS2005新控件之GridView 使用高级技巧系列[二][视频]
一条经典的汇总的sql
sql Server 索引优化 (转)
Log4Net使用指南
一些有用的sql语句实例
Enterprise Library 2.0 -- Data Access Application Block
在Excel中将连续多列相同数据项合并
执行SQL存储过程事事例
SQL宝典
SQL语句导入导出大全(轉,收藏用)
gridview中手工排序
Asp.net 项目中引入Nhibernate 入门(一)
利用asp.net 2.0的客户端回调功能制作下拉框无限级联动
给大家推荐一个我的开源项目: Permission Base
一个 NHIBERNATE+GRIDVIEW 添加删除修改的例子(单表)
IBatisNet基础组件
用javascript将数字转换为中文大写
asp.net的TextBox回车触发事件
利用Sql作业在asp.net 里面实现异步调用存储过程.
抓取Web网页数据分析
VS2005中如何动态设置数据库连接信息?
GridView控件修改、删除示例(修改含有DropDownList控件)
JavaScript有用的代码,摘抄自:http://bbs.tech.163.com/board/rep.jsp?b=tech10&i=1296&p=0
[转] 一些sql语句的详细解释
DataGrid使用心得(附大量代码)
[转] SQL Server中各个系统表的作用
使用 Web Services Enhancements 2.0 的基于角色的安全性
Flash+asp.net打造FLASH首页新闻发布
SQL存储过程事务和优化方法(包括查询方式语句结合)
小记存储过程中经常用到的本周,本月,本年函数
GridView Css
ASP.NET 2.0 Language Swithcer and Theme Swiche
ASP.net2.0学习资料汇总
触发器与约束的适用条件
GRIDVIEW 中当数据行数未满时,填充空白行
ComponentArt Web.UI for ASP.NET 2.X序列号
创建用于监视对student表进行插入和更新操作的触发器
20060516: 实现圆角div效果
.net绝对技术资料
sql server2000中使用convert来取得datetime数据类型样式(全)
一些sql 语句(行列转换等) [转载]
Owc的使用---自己封装好的类可以实现14种分析图
非常經典的WEB列印方案
CuteEditor 5.0 的使用
ASP.NET 2.0构建动态导航的Web应用程序(TreeView和Menu )
MD5算法的T-SQL实现
ASP.NET2.0中数据源控件之异步数据访问
DotNetGrid 控件下载
DotNetGrid 介绍
WEB打印-------我的搜集
在校生数据导入范例
关于多极分类的几个存储过程
一个 NHIBERNATE+GRIDVIEW 添加删除修改的例子(单表)
树形数据查询示例
转 SQL Server 数据库管理常用的SQL和T-SQL语句
IIS状态代码的含义
.NET平台下带权限控制的TreeView控件节点生成算法(转载)
实现HTTP内容的抓取
给SQL Server存储过程,传送数组参数的变通办法
在.net中使用Fckeditor
[转] SQL的3种连接查询
海量数据库的查询优化及分页算法方案
[转] transact---sql高级查询(下)
[转] transact---sql高级查询(上)
SQL Server数据库开发的二十一条军规
Excel编程
存储过程语法
SQL 语法参考手册
ASP.NET之精通弹出窗口
在网页中插入视频播放代码全集
无限级分类的实现
资源名称资源名称取得汉字字符串的拼音首字母的mssql函数
树_ajax
树_ajax
GridView与DataGrid中的数据项访问差别
Gridview中onmouseover的效果
ASP.NET2.0+SQL Server2005构建多层应用(转载)
修正过的通用分页存储过程
[推荐]网络上通用的调查答卷系统-XML做数据库(将DataSet转化成字符串)
MS-SQL数据库开发常用汇总
在visualStudio里面使用SqlServer2000作为数据源
获取影响行数和ID的存储过程
C# .Net中的类型转换
C#.net常用函数
SQL注入
FCKeditor2.2+ASP.NET2.0不完全攻略
FCKeditor2.2+ASP.NET2.0不完全攻略
【转贴】datagrid数据导出到excel文件给客户端下载的几种方法
GridView动态生成模板列
关于树形控件
asp.net 备份和恢复SQL SERVER 数据库
Asp.net(C#)实现验证码功能
Asp.NET程序中常用的三十三种代码
分割以逗号作为分割符号的字符串并插入到表中
列出一个表中的某个字段重复的记录
DataGrid系列技巧(导出excel,事件,多种方式呈现数据,全选全删)等等等
把以"文本文件(制表符分割)"保存的EXCEL文件导进SQLSERVER2000的DEMO!
总结:ADO.NET在开发中的部分使用方法和技巧 (转贴)
DATAGRID的全选/取消全选控制(CHECKBOX)
使用SqlBulkCopy类加载其他源数据到SQL表
使用SqlBulkCopy类加载其他源数据到SQL表
使用SqlBulkCopy类加载其他源数据到SQL表
一个调查实例<主要训练向panel中添加控件>包括全部代码
ASP.NET 2.0客户端回调的实现分析(3)[ZT]
[原创]把SQL的动态查询改成SQL查询
SQL Server实用经验技巧集
使用 DataAdapter 执行批量更新
treeview的建立,更新,删除
C#实现web信息自动抓取
[收藏].net关于企业Excel报表的生成
将 ASP.NET 2.0 应用程序服务配置为使用 SQL Server 2000 或 SQL Server 2005(转)
.NET进销存系统开发笔记------之Gridview应用
.net 2.0中GridView无限级嵌套的实现
导入Excel电子表格数据到SQLSever数据库的另一种方法
一个购物车的简单实现(多层开发)
ASP.NET2.0中 TreeView 和ORACLE 数据绑定的一种方法
ASP.NET2.0 ObjectDataSource的使用详解(2)
ASP.NET2.0 ObjectDataSource的使用详解(1)
将DataSet更新自动提交到数据库工具类实现
超强扩展性的DNN-DotNetNuke模块功能分类列表(from 中国DNN)
世界上主要的一些搜索引擎
SQL Server 数据库管理常用的SQL和T-SQL语句
Transact SQL 常用语句以及函数[个人推荐]
Survey Admin 示例:实现 Microsoft .NET 基于角色的安全性(转)
NHibernate Step by Step (四)Session、Query及HQL
NHibernate Step by Step (三) Configuration和Sessionfactory
Microsoft .NET Pet Shop 4 架构与技术分析
PetShop的系统架构设计
Asp.Net 2.0 TreeView的Checkbox级联操作
无废话-SQL Server 2005新功能(1) - TSQL
导出导入Excel(DataSet,DataGrid)
DNN开发中的一些细节(1)
DNN开发中的一些细节(2)
ASP.NET2.0: Ilungasoft.Framework.Web之基于Callback的无刷新上传进度条控件[带源码]
TreeView 爱恨之间
Transact SQL 常用语句以及函数
Transact SQL 常用语句以及函数
ASP.NET 2.0 正式版中无刷新页面的开发
DNN开发中的一些细节(1)
ASP.NET2.0快速入门--高级数据方案(3)
结合CodeSmith开发和调试DNN3模块
SqlDataSource WEB控件:当DeleteCommandType="storedProcedure"时
关于TreeView控件专题
利用Treeview做权限树的一种方法
利用Treeview做权限树的一种方法
(新)在ASP.NET中调用存储过程传参数
ASP.NET2.0快速入门系列--高级数据方案(上)
ASP.NET2.0快速入门--高级数据方案(中)
asp/asp.net中遍历树型结构.
ASP.NET 2.0中使用multiview控件
ASP.NET2.0快速入门系列--高级数据方案(上)
DataGrid,GridView和DetailsView中添加删除确认提示
VS2005中用Code Snippets提高开发效率
IIS和ASP.NET2.0
关于vs 2005的一个问题, 解决The path "xxxx' maps to a directory outside this application, which is not supported.
VS2005第一天 Failed to access IIS metabase
无ASPX文件部署(续)
ASP.NET 2.0构建动态导航的Web应用程序(TreeView和Menu )
ASP.NET 2.0基于SQLSERVER 2005的aspnetdb.mdf部署
对vs2005生成dll文件的一点疑惑
ASP.NET 2.0 新特性
WEB Service 下实现大数据量的传输
switch your web application project to use development machine's IIS server
[ASP.NET 2.0 Security FAQs]如何设置SQL Server或SQL Express数据库,使其支持Membership、Profiles和Role
将 ASP.NET 2.0 应用程序服务配置为使用 SQL Server 2000 或 SQL Server 2005(转载)
GridView 控件使用不完全指南!
【原创】asp/asp.net中遍历树型结构.
.NET Pet Shop 4.0案例研究预览篇
关于树形结构的研究的资料收集
单点登录(SSO)的核心--kerberos身份认证协议技术参考(三)
Gridview:在进入编辑模式后动态添加控件
ASP.NET中大结果集的分页[翻译]
Asp.Net Forums研究文章集合(收藏)
ASP.NET2.0中Gridview中数据操作技巧
SQL Server中利用存储过程来高性能地进行分页
关于二级域名Cookie的问题及解决方法
一步一步建网-2-DotNetNuke4-5/6-杂项/感!
通过系统配置来提高ASP.NET应用程序的稳定性
GridView 控件使用不完全指南!(续一)
ASP.NET应用程序的部署--兼谈aspnet_compiler.exe命令
RDLC报表(一)
RDLC报表(七)
GridView 控件使用不完全指南!
DNN皮肤制作
一个登陆页面,包含了初始化用户,输入检测,错误处理等
DNN皮肤制作
基于dotnetnuke的网站全新上线!
[导入]DotNetNuke Skin 與 Container 設計介紹
CodeSmith3.0开发资料下载
CodeSmith开发系列资料总结
提高SQL执行性能方案:如何让你的SQL运行得更快zt
Visual Studio 2005 的101个示例下载
网络数据库挖掘程序的设计
对联广告代码效果大全
网站生成静态页面,及网站数据采集的攻、防原理和策略
[原创]终极防范SQL注入漏洞!
【先锋海盗类】Ver2005 完美版
拿别人的新闻来用,虽然我知道这样不好,还是用了。。。
网页小偷程序ASP.net
数据采集程序(网页小偷)点滴心得
部署安装时写入SQL SERVER和Web.config
将博客园程序从Visual Studio 2003迁移到Visual Studio 2005的尝试
开篇:Nhibernat.Test项目分析之:ConfigurationTest
基于NHibernate的三层结构应用程序开发初步
15分钟内快速构建数据访问层(翻译)
Asp.net 2.0专题二:本地化(Localization)
数据库应用基础系列
深入了解 SQL Server 2000 与 ADO.NET 中的事务隔离及数据锁定
第2章 并发操作的一致性问题 (2)
在asp.net 2.0中使用SqlBulkCopy类迁移数据
使用asp.net 2.0和SQL SERVER 2005构建多层应用
推荐个关于 team system教学的好站点
推荐个关于 team system教学的好站点
DataList控件也玩分页- -
SQL Server 两个触发器例子,大家看看怎么样?
发布一个原创的基于Ajax的通用(组合)查询(续)
在IIS6.0下ASP .NET 的版本冲突问题
FCKeditor应用小记--起步篇
WEB Service 下实现大数据量的传输
菜单控件
55种网页常用小技巧(转载)
[转]Microsoft PetShop 3.0
[转载]用WSE在Web服务中验证用户身份
一次SQL Server 2000修复实践的说明
新数据网格DataGridView简介(转自MSDN)
[转贴]Visual Studio 2005常用插件搜罗
第 4 章 构建以数据为中心的应用程序
网 站 策 划
[转载] 在.net安装程序部署SQL Server数据库
[转载] 在.net安装程序部署SQL Server数据库
ASP.NET程序中常用代码汇总(一)(转载)
ASP.NET程序中常用代码汇总(二)(转载)
ASP.NET程序中常用代码汇总(三)(转载)
ASP.NET程序中常用代码汇总(四)(转载)
ASP.NET程序中常用代码汇总(五)(转载)
露雨资源库(第一个.net2.0软件)二
ADO.NET 2.0 大批量数据操作和多个动态的结果集
本文转自钢钢博客园博客,原文链接:http://www.cnblogs.com/xugang/archive/2008/01/20/1045957.html,如需转载请自行联系原作者
010_《Delphi6最佳专辑》
《Delphi6最佳专辑》
Delphi 教程 系列书籍 (010) 《Delphi6最佳专辑》 网友(邦)整理 EMail: shuaihj@163.com
下载地址:
Part1
Part2
书名: Delphi 6.0最佳专辑
原出版社:
作者: 潇湘工作室 邢增平 等
出版社: 人民邮电出版社
书号: 7115099669
出版日期:2002年1月
开本: 787*1092 1/16
页码: 493
版次: 2002年1月第一版北京第一次印刷
内容简介
本书结合大量的具体实例,全面系统地介绍了Delphi 6.0的相关知识、编程技术及技巧。全书分为3部分共15章:前3章为第1部分“基础篇”,介绍了Delphi的基础知识、Delphi 6刀的新特性和集成开发环境、Object PASCAL语言以及常用的 Delphi组件;第 4-10章为第 2部分“提高篇”,介绍了当今的热门技术,如 ActiveX、OLE、DLL、异常处理、多线程、图形图像处理及多媒体制作、自制组件;后5章为第3部分“精通篇”,详细讲述Delphi的高级数据库开发技术、Web应用开发、应用程序发布等。 本书内容全面而又重点突出,既涵盖了 Delphi 60的所有编程领域和技术而又详略得当,是一本学习Delphi编程的非常好的参考书。它适合于从事计算机软件开发人员、各类Delphi用户以及大专院校师生阅读参考。
目录
第1部分 基础篇 第1章 Delphi 6.0入门 1.1 Delphi 6.0的新特性 1.2 Delphi 6.0的开发环境 1.2.1 主窗口 1.2.2 对象监视器 1.2.3 窗体 1.2.4 代码编辑器 1.3 设计第一个Delphi程序 1.3.1 新建应用程序工程 1.3.2 生成新的窗体和组件 1.3.3 设置窗体和组件的属性 1.3.4 编写事件处理程序 1.3.5 编译执行 1.4 快速入门的方法与技巧 1.4.1 IDE最重要的10点功能 1.4.2 使用代码浏览器的技巧 1.4.3 使用代码编辑器的技巧 1.4.4 使用帮助系统的技巧 1.4.5 设置IDE桌面 1.5 小结 第2章 Object PASCAL语言基础 2.1 基本概念 2.1.1 基本字符和符号 2.1.2 数据类型 2.1.3 数据类型的转换 2.1.4 常量说明 2.1.5 变量说明 2.1.6 赋值语句 2.1.7 常用的运算符 2.1.8 程序模块 2.2 程序流程控制 2.2.1 if语句 2.2.2 case语句 2.2.3 repeat语句 2.2.4 while语句 2.2.5 for语句 2.3 过程和函数 2.3.1 标题部分 2.3.2 说明部分 2.3.3 语句部分 2.3.4 参数 2.4 定义新的数据类型 2.4.1 枚举型 2.4.2 子界型 2.4.3 数组型 2.4.4 字符串型 2.4.5 集合型 2.4.6 记录型 2.5 对象与类类型 2.5.1 类类型和对象 2.5.2 类的方法 2.5.3 类的特性 2.5.4 类成员的可见性 2.5.5 类类型的兼容性 2.5.6 VCL类结构 2.6 小结 第3章 常用组件 3.1 标签 3.2 编辑框 3.2.1 编辑框的常用属性 3.2.2 编辑框的常用方法 3.3 多行编辑框 3.4 命令按钮 3.5 位图按钮 3.6 快捷按钮 3.7 复选框 3.8 单选按钮 3.9 分组框 3.10 单选分组框 3.11 列表框 3.12 组合框 3.13 面板 3.14 框架 3.15 主菜单 3.15.1 建立主菜单 3.15.2 菜单项的命令 3.15.3 其他菜单项属性 3.15.4 MainMenu的属性 3.16 弹出菜单 3.17 通用组件属性 3.18 组件应用的方法与技巧 3.18.1 窗体与组件的使用原则 3.18.2 技巧1:应用消息对话框 3.18.3 技巧2:应用提示框 3.18.4 技巧3:自动切换输入方法 3.18.5 技巧4:系统字体添加到ComboBox组件 3.18.6 技巧5:在RichEdit组件中存取文件 3.18.7 技巧6:设置模态对话框的返回值 3.18.8 技巧7:确定事件处理的消息来源 3.18.9 技巧8:为控件生成多行提示信息 3.18.10 技巧9:移动无标题栏窗口 3.18.11 技巧10:制作动态字幕 3.18.12 技巧11:在窗体上动态设置背景画面 3.19 小结 第2部分 提高篇 第4章 图形和多媒体 4.1 处理图像格式 4.1.1 位图 4.1.2 JPEG 4.1.3 实例:位图转换为JPEG 4.2 图像显示效果 4.2.1 画布的属性 4.2.2 画布的方法 4.2.3 绘图程序简介 4.2.4 实例:特效显示 4.3 多媒体播放 4.3.1 多媒体软件开发概述 4.3.2 MediaPlayer组件 4.3.3 实例:制作媒体播放器 4.4 多媒体应用的方法与技巧 4.4.1 技巧1:指定播放的声音类型 4.4.2 技巧2:指定播放文件名 4.4.3 技巧3:获取CD信息和控制CD播放 4.5 小结 第5章 对象链接与嵌入 5.1 OLE客户 5.1.1 创建OLE客户程序 5.1.2 TOleContainer的属性 5.1.3 TOleContainer的方法和事件 5.1.4 实例:检测已注册的OLE对象类 5.2 OLE自动化 5.2.1 服务器的分类 5.2.2 操纵自动化对象 5.2.3 程序示例:OLE自动化 5.3 小结 第6章 COM、DCOM与ActiveX技术 6.1 COM、DCOM和ActiveX技术原理 6.1.1 技术背景 6.1.2 COM 6.1.3 DCOM 6.1.4 ActiveX及DAX 6.2 使用第三方ActiveX控件 6.3 创建自己的AcitveX控件 6.4 创建ActiveForm 6.5 将ActiveX发布到Web上 6.6 小结 第7章 DLL的创建和使用 7.1 DLL概述 7.1.1 DLL出现的背景 7.1.2 什么是DLL 7.1.3 DLL的使用原理 7.1.4 使用DLL的好处 7.2 DLL单元剖析 7.3 DLL编写基础 7.3.1 DLL中的函数和过程 7.3.2 exports关键字 7.3.3 DLLProc函数 7.4 加载DLL 7.4.1 静态加载 7.4.2 动态加载 7.5 调用DLL中的函数和方法 7.5.1 静态加载时的调用方法 7.5.2 动态加载时的调用方法 7.6 创建资源DLL 7.6.1 利用DLL实现窗体的重用 7.6.2 资源DLL 7.7 DLL应用的方法与技巧 7.7.1 技巧1:调试动态链接库 7.7.2 技巧2:在DLL中显示消息对话框 7.7.3 技巧3:动态装入DLL 7.7.4 技巧4:定制不同语言版本的应用程序 7.8 小结 第8章 多线程应用 8.1 基本概念 8.2 利用Windows API创建多线程 8.2.1 创建多线程简介 8.2.2 实例:编写多线程记数程序 8.3 多线程同步问题 8.3.1 多线程的问题示例 8.3.2 使用TRTLCriticalSection控制同步 8.3.3 使用Mutexes控制同步 8.4 TThread对象和VCL 8.4.1 添加TThread类 8.4.2 TThread类中重要方法的使用 8.4.3 TThread类提供使用局部变量的方法 8.4.4 线程的优先级 8.4.5 实例:数组排序 8.5 小结 第9章 异常处理 9.1 异常处理基础 9.1.1 异常的来源 9.1.2 异常的关键字 9.2 异常处理语句 9.2.1 try....except语句 9.2.2 try...finally语句 9.2.3 Try...except和Try.....Finally的嵌套使用 9.2.4 On...Do...Else语句 9.2.5 raise 语句 9.3 创建异常类 9.3.1 定制异常类 9.3.2 非派生异常类 9.4 小结 第10章 自制组件 10.1 组件设计基础 10.1.1 确定是否需要编写组件 10.1.2 编写组件的步骤 10.2 基类的选择 10.2.1 公共基类 10.2.2 现有的组件 10.2.3 自制组件模板 10.2.4 几点建议 10.3 编写自己的组件 10.3.1 建立组件框架 10.3.2 添加属性 10.3.3 添加方法 10.3.4 添加事件 10.4 安装组件 10.4.1 安装组件 10.4.2 为组件增加图标 10.4.3 包的说明 10.5 组件包 10.5.1 包的基础知识 10.5.2 使用包 10.5.3 设计自己的包 10.6 小结 第3部分 精通篇 第11章 Delphi数据库应用开发基础 11.1 数据库应用程序开发概述 11.1.1 数据库的基本概念 11.1.2 数据存取 11.1.3 数据库应用程序的开发步骤 11.1.4 数据库应用开发能力的增强 11.1.5 数据库系统概述 11.1.6 用Database Desktop创建第一个数据库 11.2 Delphi的数据库特性 11.2.1 Delphi的数据库特性及体系结构 11.2.2 Delphi数据库组件简介 11.3 创建第一个Delphi数据库应用程序 11.3.1 使用Database Form Wizard 创建数据库窗体 11.3.2 了解Database Form Wizard创建的窗体 11.3.3 运行程序 11.4 主要——明细型数据库应用程序实例 11.4.1 一对多关系的主要──明细型数据库应用程序 11.4.2 一对多——多关系的数据库应用 11.5 深入掌握Delphi数据库编程技术 11.5.1 字段类的使用 11.5.2 查询数据库中的记录 11.5.3 修改数据库中的记录 11.5.4 数据访问组件的应用及编程 11.5.5 TTable组件及应用 11.5.6 TDataSource组件及其应用 11.5.7 数据浏览组件的应用及编程 11.6 Delphi数据库应用实例 11.6.1 数据访问组件的应用实例 11.6.2 数据控制组件应用实例之一:TDBGrid组件 11.6.3 数据控制组件应用实例之二:TDBNavigator组件 11.6.4 数据控制组件应用实例之三:TDBText组件 11.6.5 Decision Cube组件应用实例 11.7 小结 第12章 Delphi数据库高级专题之一: 深入了解Delphi数据库组件 12.1 TSession组件及其应用 12.1.1 TSession组件的重要属性及作用 12.1.2 TSession组件的方法 12.1.3 TSession组件应用举例 12.2 输入数据的有效性验证 12.3 使用DataModule 12.3.1 使用DataModule的原因 12.3.2 使用DataModule的方式 12.3.3 使用DataModule的实例 12.4 使用QReport组件制作报表 12.4.1 快速生成报表 12.4.2 QReport组件及其应用 12.4.3 报表实例 12.5 SQL编程 12.5.1 SQL语言简介 12.5.2 TQuery组件简介 12.5.3 编写第一个简单的SQL程序 12.5.4 SQL语言编程概述 12.5.5 动态SQL编程 12.5.6 SQL编程实例 12.6 数据库应用程序综合实例——图书馆管理 12.6.1 程序功能及总体结构设计 12.6.2 数据模块的设计 12.6.3 用户登录功能的实现 12.6.4 图书馆管理系统功能的实现 12.6.5 图书馆服务系统功能的实现 12.7 小结 第13章 Delphi数据库高级专题之二: 客户/服务器应用开发 13.1 客户/服务器应用开发原理 13.1.1 客户/服务器体系结构 13.1.2 客户/服务器模型 13.1.3 客户/服务器与桌面数据库开发的比较 13.1.4 各种数据库服务器产品介绍 13.1.5 Delphi的客户/服务器解决方案——IDAPI 13.2 Delphi客户/服务器应用开发环境的构造 13.2.1 建立和管理数据库别名 13.2.2 配置SQL Link驱动程序默认设置的方法 13.2.3 连接SQL服务器 13.3 Delphi Client/Server数据库开发技术 13.3.1 数据库的管理和维护 13.3.2 使用TDatabase组件连接SQL服务器 13.3.3 处理Client/Server事务控制 13.3.4 使用存储过程 13.3.5 从开发平台到服务器的向上适化 13.3.6 实例:本地缓存 13.4 Delphi客户/服务器应用实例分析 13.4.1 数据库环境简介 13.4.2 应用程序分析 13.5 小结 第14章 Web编程 14.1 Web应用开发技术简介 14.1.1 CGI 14.1.2 Web Server API 14.1.3 ASP 14.1.4 JDBC 14.2 Delphi对Web服务器应用程序的支持 14.2.1 Delphi支持Web服务器应用程序的方式 14.2.2 Web服务器应用程序的结构 14.2.3 组件的协调工作 14.2.4 快速构建应用 14.2.5 用数据库组件响应用户请求 14.3 Web服务器应用程序实例 14.3.1 实例1:创建最简单的Web应用程序 14.3.2 实例2:表单信息保存到数据库 14.3.3 实例3:查找记录 14.4 综合实例:基于代理服务器的Internet计费系统 14.4.1 系统设计目标与主要功能 14.4.2 系统工作模型 14.4.3 系统实现 14.4 小结 第15章 发布应用 15.1 发布应用概述 15.2 完善应用 15.2.1 制作启动界面 15.2.2 读写注册表 15.2.3 制作Windows风格的联机帮助系统 15.3 制作专业化的Setup程序 15.4 小结
【OCP|OCM】Oracle培训考证系列
【OCP|OCM】Oracle培训考证系列
我的个人信息
网名:小麦苗
QQ:646634621
QQ群:618766405
我的博客:http://blog.itpub.net/26736162/abstract/1/
微信公众号:xiaomaimiaolhr,二维码如下:
小麦苗的微信二维码如下所示,加我时请备注相关信息:
我的微店地址:https://weidian.com/s/793741433?wfr=c&ifr=shopdetail
?小麦苗出版的数据库类丛书:http://blog.itpub.net/26736162/viewspace-2142121/
博客链接:http://blog.itpub.net/26736162/viewspace-2152182/
现有课程
课程名称
课时
上课时间(可根据情况调整)
OCP(从入门到专家)
每年1-2期,35课时左右/期
每周一、周三、周四、周六
20:00-22:00
OCM认证
每年N期,9课时/期
每周二、周五
20:00-22:00
高可用课程(rac+dg+ogg)
未定
未定
未定
注意:
每次上课前30分钟答疑。
OCM实时答疑,提供和考试一样的练习环境。
授课方式:YY语音直播 + QQ互动答疑 + 视频复习。
OCP课时可以根据大家学习情况进行增加或缩减。
OCP报名可以循环听课,但最多不得超过3期课。
12c OCM课程私聊
OCM
【OCM】想考11g和12c OCM的小伙伴可以和我(lhrbestxh)私聊,非诚勿扰。11g OCM可以保证最低学费、最快训练速度和100%的通过率,非诚勿扰。
11g OCM考试内容思维导图
第一场
第二场
第三场
第四场
第五场
第六场
第七场
第八场
第九场
12c OCM
若要考12C OCM请私聊。
OCM培训说明连接
OCM培训说明连接:https://mp.weixin.qq.com/s/7-R6Cz8RcJKduVv6YlAxJA
OCP
OCP培训说明网络连接
OCP培训说明连接:https://mp.weixin.qq.com/s/2cymJ4xiBPtTaHu16HkiuA
讲课资料及视频下载地址
小麦苗OCP课程讲课资料下载地址:https://share.weiyun.com/a218681375a20d9be37f626fded2d626
小麦苗分享的其它资料: https://share.weiyun.com/5UZtOLs
永久更新地址:http://blog.itpub.net/26736162/viewspace-1624453/
OCP讲课文档
OCP第1期相关视频说明
小麦苗OCP 11g课程第1节--RHEL5.5的安装和基本配置(使用逻辑卷):https://v.qq.com/x/page/u0534y1g6u3.html
小麦苗OCP 11g课程第2节--数据库软件的图形化安装和静默安装,MD5,配置YUM源,安装rlwrap软件:https://v.qq.com/x/page/m05348z2s4v.html
小麦苗OCP 11g课程第3节--图形化建库、静默建库、静默删库、干净地卸载数据库软件、配置数据库资源开机启动、pmap、判断数据库位数等:https://v.qq.com/x/page/x0535r1ucah.html
【已加密】小麦苗OCP 11g课程第4节--SQL语句的分类,如何查看在线和离线文档、sqlplus的使用和设置(导出csv和html文件)、ERRORLOGGING的作用
【已加密】小麦苗OCP 11g课程第5节--基本SELECT语句的写法,NULL的注意事项,Quote (q)语法、模糊查询、WHERE子句和排序
小麦苗OCP 11g课程第6节--IS NULL走索引,LIKE模糊查询走索引,DUAL表详解(包括恢复),Oracle中的函数、隐式类型转换:https://v.qq.com/x/page/s0540b5ih94.html
小麦苗OCP 11g课程第7节--函数的高级应用,组函数,COUNT的用法和区别,MAX和MIN优化写法:http://v.qq.com/x/page/l0540f9nhgh.html
【已加密】小麦苗OCP 11g课程第8节--多表连接、笛卡儿积、层次查询(树形查询)、WITH语法、子查询、合并查询(集合查询)、connect by和笛卡儿积快速构造大表
【已加密】小麦苗OCP 11g课程第9节--创建和管理表、数据字典、数据类型介绍、操作数据(INSERT、UPDATE、DELETE、MERGE)、DML语句优化的方法
【已加密】小麦苗OCP 11g课程第10节--约束、视图、外键约束必须创建索引(死锁)、Top-N 分析、物化视图简介
【已加密】小麦苗OCP 11g课程第11节--序列、索引、同义词、DBLINK、为什么索引没有被使用、哪些操作会导致索引失效、监控索引的使用、预估索引的大小、索引的选择性
【已加密】小麦苗OCP 11g课程第12节--匿名块、存储过程、函数、包的开发、异常处理、自治事务、分批提交DML、利用触发器完成一些监控功能、存储过程和函数返回集合类型
小麦苗OCP 11g课程第13节--ASM的安装和配置、磁盘组的简单维护、创建ASM磁盘的几种常见方式(asmlib)、静默安装GRID软件、EM的创建和使用、如何查看磁盘是否包含数据、如何让crs_stat命令显示完整、kfod命令等:http://v.qq.com/x/page/s0560te3pju.html
【已加密】小麦苗OCP 11g课程第14节--体系结构(内存结构、进程结构、存储结构)--内存组件(SGA+PGA)、数据库和实例的区别、ASMM和AMM、归档模式的切换、多路复用控制文件等
小麦苗OCP 11g课程第15节--EM的维护、参数文件(spfile和pfile)、启动和关闭、告警日志、Oracle Restart(重点)等:http://v.qq.com/x/page/j06000r2u4a.html
【已加密】小麦苗OCP 11g课程第16节--ASM相关维护(磁盘组、OS和ASM文件格式转换)等
【已加密】小麦苗OCP 11g课程第17节--Oracle网络管理(动态注册和静态注册、限定IP访问、sqlnet.ora、listener.ora、tnsnames.ora文件的作用、TWO_TASK、SYS登录报权限不足、ORA-12547等)
【已加密】小麦苗OCP 11g课程第18节--表空间和数据文件管理(bigfile、OMF、表空间大小查询、表空间扩展、表空间配额、移动数据文件、如何删除表空间数据文件)
【已加密】小麦苗OCP 11g课程第19节--数据库用户管理、权限和角色、密码文件(Oracle的两种认证方式等等)
【已加密】小麦苗OCP 11g课程第20节--锁和会话(视图之间的关联关系、如何彻底杀掉会话等)、Undo(作用,存储内容、快清除、ORA-01555)、审计(分类,FGA审计、sysdba审计、AUD$表迁移等)
【已加密】小麦苗OCP 11g课程第21节--AWR(如何获取和阅读)、ASH(如何诊断系统问题)、ADDM、统计信息(学好SQL优化必修的一节课)等
【已加密】小麦苗OCP 11g课程第22节--exp、imp(从dmp文件获取相关信息,例如查看字符集,延迟段创建等)、数据泵expdp和impdp(彻底停止expdp,exclude、include,TTS,network_link,expdp卡死等)等
【已加密】小麦苗OCP 11g课程第23节--sqlldr(各种错误处理、酒店开房数据导入)、外部表(字符集设置)、补丁集更新(PSU、one-off补丁、热补丁)
【已加密】小麦苗OCP 11g课程第24节--故障类别、SCN(系统检查点SCN、文件检查点SCN、开始SCN和结束SCN)、实例恢复(前滚和回滚)、闪回体系(包括7种闪回技术及其原理)、DBA_SOURCE的使用
【已加密】小麦苗OCP 11g课程第25节--延迟段创建导致不能导出空表(只在11.2.0.1中存在)、RMAN简介及其常用命令(show all的配置、list、report、delete等)、备份恢复的类型
【已加密】小麦苗OCP 11g课程第26节--catalog库、RMAN备份(累积和差异增量备份)、块改变跟踪、备份脚本分享、定时任务(crontab + windows下的任务计划)
【已加密】小麦苗OCP 11g课程第27节--密码文件恢复、spfile恢复、控制文件恢复、在线redo和归档文件的恢复、v$archived_log的清理
【已加密】小麦苗OCP 11g课程第28节--数据文件恢复、表空间恢复(Undo表空间的恢复)、DRA(数据恢复顾问)、rm -rf误操作的恢复过程、TRUNCATE恢复方法、在丢失归档的情况下如何进行数据文件的恢复
【已加密】小麦苗OCP 11g课程第29节--日志挖掘logminer、bbed简介、坏块的检测(dbv、rman等)和恢复(BMR、bbed等)、如何确定坏块的对象名、OS备份(冷备和热备及其恢复)、非归档模式备份和恢复、RESETLOGS和NORESETLOGS区别、跨版本恢复、只存在备份片的恢复、恢复流程图
【已加密】小麦苗OCP 11g课程第30节--实验课(数据泵之NETWORK_LINK、duplicate from active复制数据库ASM到FS、TSPITR(表空间基于时间点恢复)、TTS(传输表空间))、测试库搭建等
【已加密】小麦苗OCP 11g课程第31节--JOB(DBMS_JOB、DBMS_SCHEDULER、创建删除JOB、是否正在运行、运行日志、故障处理)、分区表(分区类型、分区表查询优化、索引失效、普通表转换为分区表有哪些办法、压缩分区、分区表收集统计信息)
OCP培训课程大纲
注:
1学时=1小时
1课时=1次课=2学时=2小时
安装与卸载
课程模块
培训要点
学时
VMware Workstation虚拟机的相关知识
安装和卸载
版本介绍(32位和64位)
网络配置(配置固定IP地址并且可以上外网)
快照的介绍
VMware Tools
主机和虚拟机资源共享
主机和虚拟机时间同步
虚拟机的配置文件
0.5
Linux的安装(RHEL 5.5)
逻辑卷的管理方式
用户的环境变量配置
PS1环境变量的作用
su - oracle和su oracle的区别
网络环境的简单配置(配置固定IP地址并且可以上外网)、防火墙的配置
学会修改主机名
MD5值的简介和计算
其它OS知识
1.5
Oracle软件单机安装
让Oracle DB、监听和oem开机启动(dbstart)
配置sudo
图形界面和静默方式安装单机软件
1
Oracle ASM的安装
GI的基本安装和配置(图形界面+静默安装)
创建ASM磁盘的几种方式演示
Faking方式
/etc/sysconfig/rawdevices配置raw
Udev方式
ASMLIB方式
如何查看磁盘是否包含数据(lquerypv、hexdump)
添加loop设备的方法
如何让crs_stat命令显示完整
静默创建ASM实例和grid用户的监听
命令创建OEM:emca -config dbcontrol db -repos recreate
2
Oracle监听和TNS的简单配置
学会使用netmgr
静默创建监听
0.1
删除数据库的几种方式
dbca -silent
DROP DATABASE;
0.2
创建数据库
DBCA图形创建
静默创建
如何设置静默创建数据库为归档模式
静默建库常见问题的处理
手动创建数据库
0.5
管理工具介绍
PLSQL Developer软件使用
学会安装Windows和Linux下的绿色版的Oracle客户端软件
绿色版SecureCRT和SecureFX
Xshell调用图形界面
0.5
Oracle软件的卸载
Windows平台(主要是清理注册表)
Linux平台
0.5
其它内容
如何判断Oracle是32位还是64位?
在多个不同版本的数据库情况下,如何确定实例的ORACLE_HOME地址?
0.5
SQL基础部分
课程模块
培训要点
学时
SQL简介及分类
SQL语句的分类
COMMIT的类型
教会如何查看在线和离线官方文档
0.5
SQL*Plus
如何导出csv、xls文件
如何导出漂亮的html文件
如何使用上下左右方向键
执行脚本时的搜寻路径
@与@@、&与&&的区别
glogin.sql文件的作用,如何修改命令提示符?
ERRORLOGGING的作用
sqlplus调用SQL脚本
shell、bat调用sqlplus命令执行SQL命令
把sqlplus执行结果传递给shell
把shell程序参数传递给sqlplus
为了安全要求每次执行shell都手工输入密码
为了安全从文件读取密码
sqlplus中将行转为列输出
登录SQL*Plus的几种方式(EZCONNECT方式)
安装SQL*Plus的帮助脚本
0.5
基本SELECT语句
语法
别名
运算符
去重
空值
NULL的注意事项,例如如果子查询结果中包含NULL值,那么NOT IN (NULL、AA、BB、CC)返回为空。
IS NULL 走索引
Quote (q)语法
Oracle特殊字符的处理
0.5
WHERE条件和排序
条件
条件中使用字符串和日期
比较条件
模糊查询
1.LIKE模糊查询如何使用索引
2.如何搜索包括%和_符号的行
IN和OR(IN中最多支持1000个列举项)
BETWEEN(between包括边界值)
使用NULL/NOT NULL条件
逻辑条件(AND、OR 、NOT)--注意添加括号,防止形成笛卡儿积
排序
升序(ASC)
降序(DESC)
列别名排序
多列排序
0.5
连接类型
交叉连接(笛卡儿积)
内连接(简单连接)
等值连接
自然连接
自连接
非等值连接
外连接
左外连接
右外连接
全外连接
0.2
查询分类
子查询
主查询和子查询的关系
标量子查询---性能问题
关联子查询(标准子查询)
相关子查询
非相关子查询(独立子查询)
返回的行数
单行子查询
多行子查询
返回的列数
单列子查询
多列子查询
子查询中的IN和EXISTS
主查询
0.2
合并查询(集合查询)
UNION
UNION ALL
INTERSECT
MINUS
应用
0.2
函数
单行函数
字符函数
数字函数
日期函数
转换函数(隐式类型转换(字符列的值应该加上单引号))
通用函数
条件表达式有 CASE表达式、DECODE 函数
多行函数(组函数)
组函数的概念及应用
AVG、SUM、MAX、MIN(MAX和MIN的优化写法)
COUNT
DISTINCT
GROUP BY和HAVING
嵌套组函数
扩展内容
如何将一个数字转换为字符串并且按照指定格式显示?
ORA-00904: "wm_concat":invalid identifier错误解决
如何判断一个字符串是否含有中文汉字?
如何让日期显示为"年-月-日时:分:秒"的格式?
NLS_LANGUAGE的使用
如何判断当天是否月份最后一天?
COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)、COUNT(允许为空列)、COUNT(DISTINCT 列名) 的区别(结果和效率)
2
dual表
基本使用
删除后的恢复(若被删除则数据库不能启动,需要设置REPLICATION_DEPENDENCY_TRACKING=FALSE)
扩展
0.2
操作数据
INSERT
插入特殊值
插入指定日期
插入可输入变量
从另外一个表复制
在INSERT语句中使用子查询
DELETE
一道OCM考题
记得加WHERE条件
查找和删除重复的记录
UPDATE
关联更新一定要加WHERE条件
优化写法
MERGE(数据合并)
语法、概念
MERGE语句在优化中的巨大作用
提高DML语句性能的写法
0.5
存储过程、函数、包的开发
PL/SQL块
分支
循环(游标FOR循环)
控制
存储过程
编写
存过中捕获异常的行号
存储过程和函数的区别是什么?
存过中的动态执行语句(动态sql)
存过返回集合
函数
函数返回集合
函数返回系统游标
函数返回索引表
包
一个项目一个包,或一个系统一个包
异常处理
分类
预定义异常
非预定义异常
自定义异常
抛出异常
通过PL/SQL运行时引擎
使用RAISE语句
调用RAISE_APPLICATION_ERROR存储过程
SQLCODE和SQLERRM
如何捕获错误并记录到表中?
存过中捕获异常的行号(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE)
Oracle分批提交DML
分批 update
分批 delete
分批 insert
2
基本对象的管理
课程模块
培训要点
学时
DBLINK
概念、分类、创建语法(2种方式)、删除
相关权限、数据字典
讲解一道OCM的考题
0.2
约束
约束的概念和原则
定义约束
几种常见的约束
NOT NULL约束
UNIQUE约束
PRIMARY KEY约束(非空且唯一)
FOREIGN KEY约束
1.外键列需创建索引,否则易引起锁问题,导致死锁的产生
2.找出没有建立索引的外键
CHECK约束
管理约束
添加约束
删除约束
级联约束
查看约束
禁用、启用约束
0.5
视图
视图的概念和优势
分类
视图中的规则
管理视图
TOP-N分析
物化视图简介
对比"有无物化视图"前后执行计划的区别
扩展
DBA_UPDATABLE_COLUMNS的作用
在什么情况下可以对视图执行增、删、改操作?
0.3
其它数据库对象
序列
讲解一道OCP和OCM的考题
概念、语法、修改、删除
性能问题
索引
概念、作用、创建、删除
分类
复合索引
函数索引
位图索引
分区索引
全文索引
虚拟索引
不可见索引
重点:不能使用索引的情况
扩展
哪几种情况不能使用索引
如何预估即将创建索引的大小?
如何监控索引的使用状况?
哪些操作会导致索引失效?
什么是索引的选择性(Index Selectivity)?
IS NULL如何用到索引?
同义词
概念、创建、删除
扩展
PLAN_TABLE表的真谛
0.5
创建和管理表
表的分类
普通堆表(heap table)---最多包含1000列
全局临时表
会话级
事务级
分区表
范围分区
列表分区
HASH分区
组合分区
索引组织表(IOT)
簇表
外部表
数据字典(dict和tab)
创建表
CTAS及其优化
default选项
数据类型
删除表
引用表
修改表alter
重命名(rename)表或字段的名称
添加、修改、删除列
SET UNUSED及其恢复
移动表所在的表空间
修改表的存储特征
truncate
DELETE、DROP和TRUNCATE的区别
给表和列添加注释(COMMENT语句)
提供一个SQL生成开发语句
0.5
数据库管理
体系结构和Oracle Restart
课程模块
培训要点
学时
DB 服务器体系结构
内存结构
SGA
共享池(Shared Pool)
库缓存(Library Cache)
共享SQL区(Shared SQL Area)
私有SQL区(Private SQL Area)
共享PL/SQL区(Shared PL/SQL Area)
控制结构区(Control Structure Area)
数据字典缓存(Data Dictionary Cache)
保留池(Reserved Pool)
结果缓存(Result Cache)
数据缓冲区(Database Buffer Cache)
回收池(Recycle Pool)
保留池(Keep Pool)
默认池(Default Pool)
Redo日志缓冲区(Redo Log Buffer)
大池(Large Pool)
Java池(Java Pool)
流池(Streams Pool)
PGA
Private SQL Area(私有SQL区)
Cursor and SQL Areas(游标和SQL区)
Session Memory(会话内存)
Work Area(工作区)
AMM和ASMM
进程结构
USER PROCESS(用户进程)
SERVER PROCESS(服务器进程)
LOCAL=NO
LOCAL=YES
BACKGROUND PROCESSES(后台进程)
守护程序/应用程序进程
存储结构(物理结构)
数据文件
控制文件---新增控制文件
联机Redo日志文件
参数文件
归档日志文件
归档和非归档的区别
归档和非归档模式互相切换
密码文件
备份文件
告警日志和跟踪文件
2
体系结构部分扩展
AMM和ASMM
区别
互换
自动PGA内存管理
UGA介绍
SHOW SGA和V$SGA的结果区别
0.5
Oracle Restart
简介
Oracle Restart进程启动顺序
控制Oracle Restart
选择正确的SRVCTL实用程序
Oracle Restart配置
使用SRVCTL实用程序
获取有关SRVCTL实用程序的帮助
使用SRVCTL实用程序启动和关闭组件
查看组件状态
显示组件的Oracle Restart配置
手动向Oracle Restart配置添加组件
1
Oracle DB 系统
Oracle DB
物理结构
数据文件(Data files)
控制文件(Control files)
联机Redo日志文件(Online Redo log files)
参数文件(Parameter file)
归档日志文件(Archive log files)
密码文件(Password file)
逻辑结构
表空间(Tablespace)
段(Segment)
数据段
索引段
还原段
临时段
区(Extent)
块(Block)
数据块dump文件详解
数据库实例
OS分配的一块内存
SGA
PGA
一些后台进程(PMON、SMON、LGWR、CKPT、DBWn等)
实例和数据库的区别
2
管理数据库实例
课程模块
培训要点
学时
管理数据库实例
OEM
简介和分类
Database Control(数据库控制)
Grid Control(GC,网格控制)
维护
卸载:emca -deconfig dbcontrol db -repos drop
单机重建:emca -config dbcontrol db -repos recreate
集群重建:emca -config dbcontrol db -repos recreate -cluster
OEM的运行日志路径:$ORACLE_HOME/$HOSTNAME_$ORACLE_SID/sysman/log
OEM的安装日志路径:$ORACLE_HOME/cfgtoollogs/emca/
启动:emctl start dbconsole
关闭:emctl stop dbconsole
运行状态:emctl status dbconsole
OEM的界面地址:https://192.168.59.128:1158/em/
端口的配置文件:$ORACLE_HOME/install/portlist.ini
初始化参数文件
初始化参数值的类型
系统使用情况
普通参数
非凡参数
过时参数
强调参数
隐含参数--隐含参数的设置方法
推导参数
生效时间
动态参数
立即生效
延迟生效
静态参数----SPFILE
简化初始化参数
初始化参数:示例
使用SQL*Plus查看参数
更改初始化参数值
PFILE和SPFILE的区别是什么?
数据库启动和关闭
启动Oracle DB实例
启动Oracle DB实例:NOMOUNT
启动Oracle DB实例:MOUNT
启动Oracle DB实例:OPEN
关闭Oracle DB实例
SHUTDOWN NORMAL
SHUTDOWN TRANSACTIONAL
SHUTDOWN IMMEDIATE
SHUTDOWN ABORT
数据库处于RESTRICT、QUIESCE和SUSPEND状态的区别是什么?
数据库的启动经历几个过程
告警日志
Oracle 10g和11g告警日志文件的位置在哪里?
告警日志的包含内容
管理告警日志
V$DIAG_ALERT_EXT
①使用外部表方式
②视图V$DIAG_ALERT_EXT
③利用SHELL脚本
使用跟踪文件
2
ASM
课程模块
培训要点
学时
ASM
简介
ASM对于管理员的好处
ASM是什么?它有哪些优点?
ASM实例
主要进程
ASM实例初始化参数
数据库实例与ASM之间的交互
ASM相关动态性能视图
系统权限
SYSASM、SYSDBA或SYSOPER
使用OEM管理ASM用户
启动和停止ASM实例
SQL*Plus
srvctl
asmcmd
ASM磁盘
创建ASM磁盘的几种方法
ASM文件和FS文件转换的几种方法
分配单元(AU)
ASM磁盘有几种冗余方式?
ASM 磁盘的相关视图
ASM磁盘组
ASM故障组
管理磁盘组
创建和删除磁盘组
向磁盘组添加磁盘
从磁盘组删除磁盘
再平衡(Rebalance)
ASM磁盘组兼容性
ASM磁盘组属性
检索ASM元数据
视图
asmcmd
与ASM相关的有哪些进程?
ASMLIB是什么?常用命令有哪些?其运行日志路径在哪里?
在采用asmlib时,确认物理磁盘的方法
udev是什么?如何配置udev?
多路径(multipath)是什么?如何配置多路径?
asmcmd工具详细介绍
asm相关的OCP题目讲解
ASM管理命令行三工具:KFOD、KFED和AMDU
2
网络管理
课程模块
培训要点
学时
网络管理
监听
配置
管理
静态监听和动态监听
listener.ora
服务名
tnsnames.ora
简便连接(EZCONNECT方式)
测试Oracle Net连接
tnsping
其它实用内容
动态注册和静态注册有什么区别?
在Oracle中,如何限定特定IP访问数据库?
如何跟踪tnsping过程?
如何启动Oracle数据库的监听日志?
解释GLOBAL_NAMES设为TRUE的用途。
tnsnames.ora文件的作用是什么?
sqlnet.ora文件的作用是什么?
TWO_TASK环境变量的作用是什么?
在Windows环境下,错误"ORA-12560: TNS: 协议适配器错误"的常见原因有哪些?
Oracle的SYS用户登录报权限不足(ORA-01031: Insufficient Privileges)的常见原因有哪些?
在没有配置ORACLE_HOME环境变量的情况下,如何快速获取数据库软件的ORACLE_HOME目录?
造成错误"ORA-12547: TNS:lost contact"的常见原因有哪些?
2
管理数据库存储结构(表空间和数据文件)
课程模块
培训要点
学时
管理数据库存储结构(表空间和数据文件)
表空间和数据文件
表数据的存储方式
浏览存储结构
表空间的存储
预配置的数据库中的表空间
变更表空间
表空间操作
Oracle管理的文件(OMF)
数据文件的OMF管理
日志文件的OMF管理
使用OMF管理控制文件
使用OMF 创建ASM文件涉及的一些参数
扩大数据库
改变数据文件的名称和位置、移动数据文件
什么是用户的表空间配额(User tablespace Quota)
如何正确的删除表空间数据文件?
表空间管理
表空间大小查询
创建新的表空间
表空间大小为空的原因
扩展表空间
表空间收缩
修改表空间名称
表空间的管理方式
数据文件管理
DBA_DATA_FILES
数据文件大小查询
设置数据文件为自动增长
改变数据文件的大小
数据文件的大小为空
什么是大文件表空间(Bigfile Tablespace)?
1.5
用户、密码文件、权限及角色
课程模块
培训要点
学时
数据库事务处理
数据库事务的开始与结束
COMMIT和ROLLBACK语句
事务控制
事务的控制示例
隐式事务处理
用户及其密码文件
创建、密码
如何重建SCOTT用户
使用工具来创建用户
修改密码
Oracle用户密码含特殊字符时的登陆问题
密码文件
创建、作用
Oracle的两种认证方式
OS验证
密码文件验证
PROFILE管理密码
账户锁定
给账户(用户)解锁
终止密码
密码历史
修改密码为永不过期
Oracle用户被锁原因及办法
用户的状态(ACCOUNT_STATUS的九种状态)
基本状态
正常(OPEN)
锁定状态
LOCKED
LOCKED(TIMED)
过期状态
EXPIRED
EXPIRED(GRACE)
组合状态
EXPIRED & LOCKED(TIMED)
EXPIRED(GRACE) & LOCKED(TIMED)
EXPIRED & LOCKED
EXPIRED(GRACE) & LOCKED
在不知道用户密码的情况下如何更改密码
用原密码的密文来更改密码
直接更新USER$基表
user$.lCOUNT列记录了失败的登陆次数
11g密码区分大小写--sec_case_sensitive_logon
密码延迟验证
哪些用户密码没有被修改过
密码复杂性校验
删除用户
扩展
SCHEMA和USER的区别
重建scott用户
使用工具来创建用户
使用profile管理口令
什么是用户的表空间配额(User tablespace Quota)
回收DBA角色时需要注意什么问题
权限
概念、视图、基本权限
Oracle权限分类
系统权限(System Privilege)--DBA_SYS_PRIVS
对象权限(Object Privilege)--DBA_TAB_PRIVS
角色权限(Role Privilege)--DBA_ROLE_PRIVS
列权限--DBA_COL_PRIVS
如何获取用户的权限
DBMS_METADATA.GET_GRANTED_DDL
通过数据字典来获取
通过exp或expdp来获取
扩展
如何让普通用户可以TRUNCATE其他用户的表?
关于UNDER ANY TABLE/VIEW权限的解释
用户的权限分为哪几类?如何导出用户的权限?
角色
DBA、SYSDBA和SYSOPER的区别
概念、创建、删除
分类
预定义角色
DBA
CONNECT
RESOURCE
Oracle有哪些预定义角色?
自定义角色
角色生效和失效
锁和会话
课程模块
培训要点
学时
锁
锁的概念、作用
并发和并行
锁的分类
操作/保护对象不同
DML锁
行锁(TX,事务锁)
表锁(TM)
0:NONE
1:NULL
2:SS(Row-S)
3:SX(Row-X)
4:S(Share)
5:SSX(S/Row-X)
6:X(Exclusive)
死锁
行级死锁
1、主键、唯一索引的死锁
2、外键未加索引
3、位图索引遭到并发更新
4、常见事务引发的死锁
5、自治事务引发的死锁
块级死锁
ITL死锁
DDL锁(字典锁)
排它DDL锁(XDDL)
共享DDL锁(SDDL)
分析锁、可中断解析锁
系统锁
闩锁(Latches)
互斥体(Mutexes)
内部锁(Internal Locks)
用户与系统
自动锁(隐式锁)
显式锁
锁的兼容性
锁的数据字典---字段之间的关联关系
新建或重建索引过程中的锁信息的变化
SELECT ... FOR UPDATE
DML_LOCKS和DDL_LOCK_TIMEOUT参数
在编译存储过程、函数等对象时无响应-
新建或重建索引的锁信息
对于错误"ORA-08104: this index object 68111 is being online built or rebuilt",应该如何处理?
1
会话
V$SESSION视图
如何查看某一个会话是否被其它会话阻塞?
如何查到会话正在执行的SQL语句?
如何彻底杀掉会话?V$SESSION的STATUS为KILLED的情况下如何找到相关的后台OS进程?
如何让普通用户可以杀掉自己用户的会话?
SESSIONS和PROCESSES的关系
如何根据OS进程快速获得DB进程信息与正在执行的语句?
怎么杀掉特定的数据库会话?
如何快速的清理Oracle的进程?
1
审计和Undo
课程模块
培训要点
学时
审计
责任分离
数据库安全性
监视合规性
标准数据库审计
配置审计线索
统一审计线索
默认审计
什么是审计(Audit)?
审计如何分类
迁移SYS.AUD$表到其它表空间
审计中BY ACCESS和BY SESSION的区别是什么?
如何对SYSDBA和SYSOPER进行审计?
什么是细粒度审计?
FGA审计和标准审计有什么区别?
1
Undo
还原数据
事务处理和还原数据
存储还原信息
还原数据与重做数据
管理还原
配置还原保留时间
保证还原保留时间
将还原表空间改为固定大小
一般还原信息
使用还原指导
0.5
Undo和Redo
Undo的作用
Undo段存储的内容
块清除:
快速块清除(Fast Commit Cleanout)
延时块清除(Delayed Block Cleanout)
Undo表空间
系统回滚段(System Rollback Segment)与延迟回滚段(Deferred Rollback Segment)
ORA-01555
Redo日志文件(Redo Log Files)的作用是什么?
如何管理联机Redo日志组与成员?
在Oracle中,如果联机Redo日志文件损坏,那么如何恢复?
1
AWR、ASH、ADDM和统计信息
课程模块
培训要点
学时
AWR、ASH、ADDM和统计信息
统计信息(学习SQL优化的必修课)
统计信息的简介和分类
索引统计信息
表统计信息
列统计信息
系统统计信息
内部对象统计信息
自动收集统计信息
统计信息何时变为陈旧状态(10%的含义)?
修改自动收集统计信息的时间
DBA_TAB_MODIFICATIONS
怎样收集表的统计信息?怎样收集分区表的统计信息?
什么是动态采样(Dynamic Sampling)?
如何锁住统计信息?
什么是待定的统计信息(Pending Statistic)?
什么是直方图(Histogram)?
什么是多列统计信息(Extended Statistics)?
基表COL_USAGE$的作用是什么?
新建索引后统计信息是否自动收集?
什么是基数反馈(Cardinality Feedback)?
如何查询表和索引的历史统计信息
Oracle如何并发地收集统计信息?
当收集表的统计信息时应该注意哪些问题?
什么是基数(Cardinality)和可选择率(Selectivity)?
使用SPLIT来拆分某个分区的时候,其拆分出来的新分区的统计信息行数是多少?
当自动收集任务运行时,哪些对象会被收集?
分区表统计信息的更新机制是怎样的?
如何查询表的DML操作数据变化量?
对表执行TRUNCATE操作会将表的统计信息也清除掉吗?
自动负载信息库(AWR)
AWR 基础结构
AWR 基线
Enterprise Manager 和 AWR
管理 AWR
统计级别
什么是AWR?
如何获取AWR报告?
定时生成AWR报告
AWR报告中主要关注哪些方面内容?
ASH
什么是ASH?
如何获取ASH报告?
如何查看过去某一段时间数据库系统的会话是否有问题?
自动数据库诊断监视器 (ADDM)
什么是ADDM?
如何获取ADDM报告?
自动维护任务
简介
自动维护任务配置
服务器生成的预警
设置阈值
创建和测试预警
预警通知
对预警作出响应
2
JOB和分区
课程模块
培训要点
学时
JOB
DBMS_JOB
创建、删除
后台进程
dbms_job package 用法介绍
杀JOB
删除其它用户下的job用 sys.dbms_ijob.remove()
杀会话+杀后台进程
what的写法
存储过程
匿名块
数据字典
所有job(dba_jobs)
正在运行(dba_jobs_running)
RAC中指定dbms_job运行在指定实例(instance)
权限
PL/SQL工具创建和管理job
DBMS_SCHEDULER
DBMS_JOB和DBMS_SCHEDULER之间的区别
创建、删除
带参数
不带参数
通过dbms_scheduler去执行shell脚本
权限
轻量级job(Lightweight Jobs)
PL/SQL工具创建和管理job
RAC中如何指定JOB的运行实例
如何判断SCHEDULER JOB是否正在运行?
DBA_SCHEDULER_JOBS视图的STATE列
DBA_SCHEDULER_RUNNING_JOBS
如何查询SCHEDULER JOB的运行日志?
DBA_SCHEDULER_JOB_LOG和DBA_SCHEDULER_JOB_RUN_DETAILS
通过DBMS_SCHEDULER如何调用SHELL脚本?-
如何批量删除JOB?
数据字典
1
分区
分区表简介
何时考虑分区?
分区表有什么优点
有哪些类型的分区?如何选择用哪种类型的分区表?
范围分区(RANGE PARTITION)
哈希分区(HASH PARTITION)
列表分区(LIST PARTITION)
引用分区(REFERENCE PARTITION)
复合分区(组合分区)
INTERVAL分区(间隔分区)
月分区
天分区
系统分区
分区模板
分区表的维护
添加分区(add partition)
收缩表分区(coalesce partitions)
删除分区和删除子分区(drop partition)
添加子分区
截断表分区(Truncate Partition)--截断一个分区表中的一个分区的数据
截断分区表的子分区
截断带有约束的分区表
注意事项
移动表分区(Move Partition)
将一个表的分区从一个表空间移动到另一个表空间
压缩表Move--compress
合并分区(Merge Partitions)
重命名某一个分区(Rename Partition)
交换表分区(Exchange Partitions)
修改 list 表分区
修改 list 表分区--Add Values
修改list 表分区--Drop Values
拆分表分区(Split Partition)--分区切割
修改分区表属性
修改表分区默认属性(Modify Default Attributes)
修改表分区当前属性(Modify Partition)
修改分区表的logging属性
并行度
修改表子分区模板(Set Subpartition Template)
分区表的查询优化
单分区查询
跨分区查询
分区表常用数据字典视图有哪些?
Oracle之INTERVAL分区的STORE IN属性存储在哪张表中?
如何查询某个分区是否是INTERVAL分区表?
分区表的压缩
分区表压缩
含有子分区的分区表压缩
分区表哪些分区被压缩了
解压缩
分区表单个分区分析(分区表收集统计信息)
指定partname和GRANULARITY
普通表转换为分区表有哪些办法?
(1)导出/导入方法(Export/Import Method)
(2)子查询插入方法(Insert With a Subquery Method)
(3)分区交换方法(Partition Exchange Method)
(4)在线重定义方法(DBMS_REDEFINITION Method)
分区表中lob类型的字段
分区表性能注意事项
索引失效的情况
分区表
非分区表
1
备份和恢复(包括闪回)
课程模块
培训要点
学时
备份和恢复的概念
故障类别
语句失败
用户进程失败
网络故障
用户错误
介质故障
实例恢复
实例故障
了解实例恢复:检查点 (CKPT) 进程
实例恢复的阶段
优化实例恢复
使用 MTTR 指导
实例恢复和介质恢复的区别
配置可恢复性
配置快速恢复区
0.5
SCN
SCN的组成
SCN的分类
系统检查点SCN(System Checkpoint SCN)
文件检查点SCN(Datafile Checkpoint SCN)
开始SCN(Start SCN)
结束SCN(Stop SCN)
如何查看系统当前SCN
SCN与时间的相互转换
0.3
备份
rman 连接数据库
RMAN数据字典
rman命令
列出备份信息(list)
删除备份(delete)
报告命令(report)
可以报告哪些文件需要备份
报告不可恢复的备份集
报告数据库的信息
交叉检查(crosscheck)
VALIDATE DATABASE
RMAN的配置
CONFIGURE RETENTION POLICY 配置备份保留策略
CONFIGURE BACKUP OPTIMIZATION 配置备份优化
CONFIGURE DEFAULT DEVICE TYPE 配置 IO 设备类型
CONFIGURE CONTROLFILE AUTOBACKUP 配置控制文件自动备份
CONFIGURE DEVICE TYPE 设置并行备份
CONFIGURE DATAFILE BACKUP COPIES 设置备份文件冗余度
CONFIGURE MAXSETSIZE 配置备份集的最大尺寸
CONFIGURE ARCHIVELOG DELETION POLICY
RMAN中关于备份或归档文件状态OBSOLETE和EXPIRED的区别是什么?
物理备份和逻辑备份分别是什么?
差异增量备份和累积增量备份的区别是什么?
什么是块改变跟踪?
完全备份
全库备份脚本分享
增量备份
文件备份
数据文件备份
控制文件
spfile
表空间备份
1
恢复
TRUNCATE恢复方法
TSPITR(表空间基于时间点恢复)
rm -rf误操作的恢复过程
在丢失归档的情况下如何进行数据文件的恢复
数据文件OFFLINE之后必须要做的一件事是什么?
什么是DRA(Data Recovery Advisor,数据恢复指导)?
list failure:列出DRA记录的故障
advise failure:显示建议修复的选项
repair failure:使用RMAN的建议和关闭故障
rm -rf 误操作的恢复过程
丢失了控制文件(多种恢复方法演示)
丢失了在线重做日志文件
数据文件恢复
在NOARCHIVELOG模式下丢失了数据文件
在ARCHIVELOG模式下丢失了非关键数据文件
在ARCHIVELOG模式下丢失了系统关键数据文件
数据故障
只存在备份片如何恢复数据库
spfile恢复(多种恢复方法演示)
表空间恢复
Undo表空间
SYSTEM表空间
其它表空间
归档日志的恢复
restore archivelog 的各种选项
怎样清除v$archived_log视图中的过期信息
1
闪回
闪回的分类
闪回删除(Flashback DROP)--10g,基于回收站(Recycle Bin)特性实现
闪回数据库(Flashback Database)--基于闪回恢复区(Flash Recovery Area)中的闪回日志;10g开始引入,后台进程为:RVWR(Recovery Writer)
闪回数据归档(Flashback Data Archive)--基于闪回归档区(Flashback Archive)中的数据,11g开始引入,进程fbda(Flashback Data Archiver Process)
闪回版本查询(Flashback Version Query),10g
闪回查询(Flashback Query),9i
闪回事务查询(Flashback Transaction Query),10g
闪回表(Flashback TABLE),10g
其它内容
什么是闪回?闪回有哪些分类?
Oracle的回收站是什么?
什么是闪回数据归档(Flashback Data Archive)?
什么是闪回数据库?
如何让普通用户可以对DBA_SOURCE视图进行闪回查询?
存储过程被覆盖了,如何恢复?
1
RMAN 高级应用之 Duplicate 复制数据库
Duplicating an Active Database
Cloning A Database On The Same Server Using Rman Duplicate From Active Database
Duplicating a Database with a Target Connection
Duplicating a Database with Recovery Catalog Without Target Connection
Duplicating a Database Without Recovery Catalog or Target Connection
1
bbed简介
bbed简介
0.1
rman之块介质恢复
坏块的简介
坏块的检测方法
BMR恢复坏块
如何确定坏块的对象名
如果发现有坏块,那么如何检索其它未坏的数据?
模拟坏块
blockrecover恢复坏块
创建演示环境
单块数据块损坏的恢复处理
多块数据块损坏的恢复处理
坏块的对象定位与影响
bbed模拟
bbed修复坏块示例
0.5
非归档模式备份恢复
非归档的备份方法
非归档模式下的恢复
非归档模式的备份与恢复示例
0.2
OPEN RESETLOGS
使用alter database open resetlogs的场合
为什么使用RESETLOGS?
RESETLOGS会执行什么操作?
0.1
4条RECOVER DATABASE命令的区别是什么?
1 RECOVER DATABASE USING BACKUP CONTROLFILE
2 RECOVER DATABASE UNTIL CANCEL
3 RECOVER DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL;
4 RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE;
0.1
日志挖掘logminer
日志挖掘logminer
0.1
利用增量数据库备份进行恢复
利用增量数据库备份进行恢复
0.1
跨版本恢复
RMAN可以跨版本或跨平台执行还原或复制命令吗?
跨大版本恢复
跨小版本恢复
1
OS备份(物理备份)和恢复
冷备份(一致性备份、脱机备份) --cool backup
冷备份的优缺点
冷备份一般步骤
冷备脚本的写法
存在冷备下的还原(非归档模式)
丢失数据文件
丢失system表空间
丢失sysaux
undo丢失
自己建立的表空间(如users,ts_test)
temp表空间
日志文件丢失
控制文件丢失
参数文件丢失
密码文件丢失
热备份(非一致性备份、联机备份) --只能用于归档模式
简介
热备的过程
基于数据库的热备
基于表空间的热备
控制文件的热备
参数文件的热备
临时表空间的数据文件、日志文件不需要备份
热备份的相关视图
存在热备下的还原
还原控制文件
还原数据文件
可以脱机的表空间文件
不可以脱机的表空间文件
0.5
移动数据(exp、expdp、sqlldr、外部表)
课程模块
培训要点
学时
exp和imp
EXP导出数据
导出表
导出方案
导出数据库
IMP导入数据
导入表
导入方案
导入数据库
imp导入常见问题处理
其它实用内容
可以从dmp文件获取哪些信息?
一、获取基本信息:导出的版本、时间、导出的用户
二、获取dmp文件中的表信息
三、解析dmp文件生成parfile文件
四、如何查看dmp文件的字符集
五、如何将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中?
exp的query参数
什么是延迟段创建(Deferred Segment Creation)?
Oracle 11g不能导出空表的三种解决方法
exp导出ASH数据
方法1:ctas建表导出,有的客户不让建表
方法2:导出基表的数据
常见错误
XP-00091: Exporting questionable statistics 问题处理方法
EXP-00026: conflicting modes specified
IMP-00013: only a DBA can import a file exported by another DBA
IMP-00031: 必须指定 FULL=Y 或提供 FROMUSER/TOUSER 或 TABLES 参数
IMP-00002: 无法打开要读取的imp D:/admin.dmp
EXP-00008: 遇到 ORACLE 错误 904
imp导入报错:IMP-00037: Character set marker unknown
IMP-00010: not a valid export file, header failed verification
imp-00051,imp-00008
IMP-00132: first file in the multi-file export is 32
0.5
数据泵(expdp和impdp)
Oracle 数据泵:概览
Oracle 数据泵:优点
Oracle Database 11g 中的数据泵增强功能
数据泵的目录对象
创建目录对象
数据泵导出与导入客户机:概览
数据泵实用程序:界面与模式
使用 Database Control 进行数据泵导出
数据泵导出示例
数据泵导出示例:基本选项
数据泵导出示例:高级选项
数据泵导出示例:文件
数据泵导出示例:调度
数据泵导出示例:复查
数据泵导入示例:impdp
其它实用内容
数据泵的一些常用语法命令
如何彻底停止expdp进程?
Oracle用户密码含特殊字符时如何登陆?
如何获取数据库DDL的创建语句
imp示例:
imp的indexfile选项(indexfile导出表和索引的ddl语句)
impdp示例:
expdp时显示时间 metrics
NETWORK_LINK 选项
只导出元数据
【IMPDP】使用 TRANSFORM选项去掉表空间和存储子句
如何导出存储过程、函数、包和触发器的定义语句?如何导出表的结构?如何导出索引的创建语句?
12c expdp VIEWS_AS_TABLES选项
过滤对象(exclude、include)
导出数据库连接
导出JOB
dba_export_objects
重定义表的Schema或表空间
优化导入/导出效率
impdp传输表空间(OCM考题)
expdp 导出sys用户下的表报错ORA-39165 和ORA-39166
数据泵导出导入卡死
使用隐含Trace参数诊断Oracle Data Pump故障
全库导出和导入演示
0.5
SQL*Loader
使用 SQL*Loader 加载数据
SQL*Loader 控制文件
直接路径加载与常规路径加载的比较
如何将文本文件或Excel中的数据导入数据库?
4G大文件导入示例。
0.2
外部表
外部表的优点
使用ORACLE_LOADER定义外部表
使用ORACLE_DATAPUMP填充外部表
使用外部表
基础
只有1列
外部表的parallel
利用外部表查看告警日志
先来个最简单的使用方法
再来个稍微复杂点的
0.2
管理补丁程序
课程模块
培训要点
学时
管理补丁程序
PSU、SPU(CPU)、BP、one-off patch等概念简介
什么是Metalink或MOS
Upgrade与Update
如何查找最新的PSU?
如何确认当前数据库已经安装了什么PSU?
如何安装PSU?
PSU安装演示
11.2.0.3.0升级到11.2.0.3.1
热补丁安装演示( One-off Patch)
一道OCM考题
0.5
实验课
课程模块
培训要点
学时
实验课
数据泵之NETWORK_LINK
Duplicating an Active Database(duplicate复制数据库)
Duplicating a Database Without Recovery Catalog or Target Connection
Duplicating a Database Without Recovery Catalog or Target Connection
TSPITR(表空间基于时间点恢复)
直接复制数据文件实现linux平台数据库复制到windows平台数据库
利用rman来实现linux平台数据库复制到windows平台数据库
热备下的测试库搭建
传输表空间(TTS)一例(linux asm -> win 文件系统)
传输表空间(TTS)一例(win文件系统 -> linux asm )
传输表空间(TTS)一例(AIX asm -> linux asm )
传输表空间(TTS)一例(linux asm -> AIX asm)
传输表空间(TTS)一例(linux asm -> AIX asm)--基于RMAN备份
传输表空间(TTS)一例(AIX asm -> linux asm )--基于RMAN
AIX平台数据库迁移到Linux--基于RMAN(真实环境)
2
OCP讲课内容思维导图
安装与卸载
SQL基础部分
基本对象的管理
数据库管理部分
体系结构和Oracle Restart
管理数据库实例
ASM
网络管理
表空间及数据文件
事务处理及用户
用户权限及角色
锁和会话
审计和Undo
AWR、ASH、ADDM、统计信息
JOB和分区
备份和恢复(包括闪回)
移动数据
管理补丁程序
实验课
OCP讲课文档目录
数据库安装部分的目录
第1章 安装Oracle软件 - 6 -
1.1 Oracle DB 管理员的任务 - 6 -
1.2 用于管理 Oracle DB 的工具 - 7 -
1.3 制定安装计划 - 8 -
1.4 Oracle Grid Infrastructure 和Oracle DB 安装:系统要求 - 9 -
1.5 准备操作系统 - 10 -
1.5.1 设置环境变量 - 11 -
1.5.2 检查系统要求 - 12 -
1.5.3 OUI - 13 -
1.5.4 GI安装 - 15 -
1.5.4.1 Installation Option(安装选项) - 15 -
1.5.4.2 选择产品语言 - 16 -
1.5.4.3 创建 ASM 磁盘组 - 17 -
1.5.4.4 定义 ASM 口令 - 17 -
1.5.4.5 定义已授权的操作系统组 - 19 -
1.5.4.6 指定安装位置 - 20 -
1.5.4.7 创建清单 - 21 -
1.5.4.8 执行先决条件检查 - 22 -
1.5.4.9 验证安装概要数据 - 23 -
1.5.4.10 监视安装进度 - 24 -
1.5.4.11 执行root配置脚本 - 25 -
1.5.4.12 执行 Configuration Assistant - 25 -
1.5.4.13 完成安装 - 27 -
1.5.4.14 配置 FRA 磁盘组 - 27 -
1.5.5 安装 Oracle DB 软件 - 30 -
1.5.5.1 选择安装类型 - 30 -
1.5.5.2 选择网格安装选项 - 31 -
1.5.5.3 选择语言设置 - 32 -
1.5.5.4 选择数据库版本 - 33 -
1.5.5.5 指定安装位置 - 34 -
1.5.5.6 选择操作系统组 - 35 -
1.5.5.7 执行先决条件检查 - 36 -
1.5.5.8 安装概要页 - 37 -
1.5.5.9 安装产品页 - 38 -
1.5.5.10 安装完成 - 39 -
1.5.5.11 安装选项:无提示模式 - 41 -
1.5.5.12 小测验 - 41 -
1.5.5.13 小结 - 42 -
1.5.6 使用DBCA创建Oracle DB - 42 -
1.5.6.1 计划数据库 - 42 -
1.5.6.2 选择适当的字符集 - 44 -
1.5.6.3 Database Configuration Assistant (DBCA) - 48 -
1.5.6.4 Database Templates(数据库模板) - 49 -
1.5.6.5 Database Identification(数据库标识) - 49 -
1.5.6.6 Management Options(管理选项) - 50 -
1.5.6.7 Database Credentials(数据库身份证明) - 50 -
1.5.6.8 Database File Locations(数据库文件位置) - 51 -
1.5.6.9 Recovery Configuration(恢复配置) - 52 -
1.5.6.10 Database Content(数据库内容) - 52 -
1.5.6.11 Initialization Parameters(初始化参数) - 53 -
1.5.6.12 Database Storage(数据库存储) - 54 -
1.5.6.13 Create Options(创建选项) - 54 -
1.5.7 创建数据库设计模板 - 57 -
1.5.8 使用 DBCA 删除数据库 - 58 -
1.5.9 小测验 - 60 -
1.5.10 小结 - 60 -
第2章 RHEL 5.5的OS版本 - 60 -
2.1 安装VMware Workstation 12 Pro - 60 -
2.1.1 校验MD5值 - 61 -
2.2 安装RHEL 5.5的OS版本 - 63 -
2.2.1 简易安装 - 63 -
2.2.2 一般安装过程 - 68 -
2.2.2.1 开始安装 - 83 -
2.2.2.2 建立自定义的分区结构 - 87 -
2.2.2.3 继续 - 92 -
2.3 其它软件安装 - 99 -
2.3.1 安装VMware Tools - 99 -
2.3.1.1 安装完成后设置共享文件 - 104 -
2.3.1.2 设置桌面背景和桌面的大小 - 105 -
2.3.2 设置主机IP地址 - 106 -
2.3.3 中文环境切换成英文环境 - 107 -
2.3.4 配置本地yum源(rhel 5.5) - 107 -
2.3.5 安装rlwrap - 108 -
2.4 对/dev/sdb进行分区 - 109 -
2.4.1 逻辑卷管理的命令 - 116 -
第3章 安装11.2.0.3 64位单机数据库软件 - 117 -
3.1 安装前的准备工作 - 117 -
3.1.1 软件准备 - 117 -
3.1.2 检查硬件 - 117 -
3.1.3 修改hosts文件、修改主机名 - 118 -
3.1.4 安装软件包检查 - 118 -
3.1.5 内核参数--shell限制 - 120 -
3.1.5.1 /etc/security/limits.conf - 120 -
3.1.5.2 /etc/pam.d/login - 121 -
3.1.5.3 /etc/profile - 121 -
3.1.5.4 /etc/sysctl.conf - 121 -
3.1.6 关闭防火墙 - 122 -
3.1.7 关闭耗费资源的服务 - 123 -
3.1.8 禁用selinux - 123 -
3.2 新建用户和组 - 124 -
3.2.1 配置用户的环境变量 - 124 -
3.3 新建安装目录 - 125 -
3.4 将oracle使用者加入到sudo群组中 - 125 -
3.5 准备oracle安装文件 - 125 -
3.5.1 拷贝安装文件 - 125 -
3.5.1.1 计算MD5值 - 128 -
3.5.2 解压安装文件 - 129 -
3.6 开始安装 - 130 -
3.6.1 安装前的检查 - 141 -
3.6.2 执行root.sh脚本 - 144 -
3.7 扩展(静默安装软件) - 145 -
第4章 创建数据库 - 148 -
4.1 DBCA图形创建 - 148 -
4.1.1 启动监听 - 159 -
4.2 DBCA静默方式建库(必会) - 161 -
4.2.1.1 什么是静默建库? - 161 -
4.3 CREATE DATABASE手动建库(OCM) - 163 -
4.4 删除数据库的几种方式 - 164 -
4.5 在多个不同版本的数据库情况下,如何确定实例的ORACLE_HOME地址? - 164 -
第5章 配置监听和TNS - 165 -
5.1 静默创建监听 - 167 -
第6章 其它 - 167 -
6.1 让Oracle DB、监听和oem开机启动(dbstart) - 167 -
6.1.1 方法1:配置Linux的service服务 - 168 -
6.1.2 方法2:配置/etc/rc.d/rc.local文件 - 170 -
6.1.3 总结 - 172 -
6.2 PLSQL Developer软件使用和Windows 下绿色版Oracle客户端的安装和使用 - 172 -
6.2.1 Linux下绿色版Oracle客户端的安装 - 172 -
6.3 配置glogin.sql - 173 -
6.4 如何判断Oracle是32位还是64位? - 173 -
第7章 数据库软件的卸载 - 176 -
第8章 安装grid软件 - 177 -
8.1 OS修改 - 177 -
8.1.1 编辑 /etc/security/limits.conf 文件,在文件尾部添加如下内容: - 177 -
8.1.2 添加grid用户 - 177 -
8.1.3 配置grid用户的环境变量 - 178 -
8.1.4 扩展磁盘空间 - 179 -
8.2 ASM磁盘准备(创建asm磁盘) - 179 -
8.2.1 创建ASM磁盘的方法1--Faking方式 - 179 -
8.2.2 创建ASM磁盘的方法2--直接修改/etc/sysconfig/rawdevices配置raw(rhel6之后不支持) - 182 -
8.2.3 创建ASM磁盘的方法3--Udev方式 - 184 -
一、 uuid方式 - 184 -
2、 配置 udev 绑定的 scsi_id - 187 -
3、 创建并配置udev rules文件 - 188 -
4、 udevadm进行测试 - 189 -
5、 添加完成后,重启 udev,不同 Linux 发行版本重启方式不一样。 - 189 -
6、 查看绑定的 asm,如果此时还是看不到 asm disk,请重启操作系统后再查看。 - 189 -
二、 raw方式 - 190 -
8.2.4 创建ASM磁盘的方法4--ASMLIB方式 - 191 -
一、 系统版本号 - 191 -
二、 Oracle asmlib下载 - 191 -
三、 上传并安装上述的三个rpm软件包 - 193 -
四、 配置ASM - 193 -
五、 系统添加磁盘 - 194 -
六、 grid软件安装完毕后配置asm_diskstring 路径 - 195 -
七、 测试 - 197 -
8.3 安装grid软件 - 198 -
8.3.1 解压软件 - 198 -
8.3.2 开始安装grid软件(图形界面) - 199 -
8.3.2.1 创建ASM磁盘组 - 203 -
8.3.2.2 执行root脚本 - 209 -
8.3.2.3 继续安装 - 210 -
8.3.2.4 测试ASM实例 - 211 -
8.3.3 静默安装grid软件(可选) - 212 -
8.3.3.1 安装grid软件 - 212 -
8.3.3.2 静默创建ASM实例 - 215 -
8.3.3.3 静默创建grid用户的监听 - 216 -
8.4 创建DATA和FRA的ASM磁盘组 - 218 -
8.5 创建asm管理的数据库 - 221 -
8.6 创建EM - 223 -
8.7 其它扩展 - 225 -
8.7.1 在AIX或Linux下,如何查看磁盘是否包含数据? - 225 -
8.7.2 如何让crs_stat命令显示完整 - 227 -
8.7.3 kfod命令 - 227 -
8.7.3.1 在采用asmlib时,确认物理磁盘的方法 - 228 -
Oracle基本SQL部分及其基本管理
目录 - 1 -
序言 - 12 -
第1章 SQL简介 - 12 -
1.1 SQL的起源和分类 - 13 -
1.1.1 SQL的起源 - 13 -
1.1.2 SQL的分类 - 13 -
1.2 提交(COMMIT)类型 - 15 -
1.3 如何查询在线和离线的官方文档 - 19 -
第2章 SQL*Plus工具 - 20 -
2.1 SQL 与 SQL*Plus - 20 -
2.2 SQL 语句与SQL*Plus - 20 -
2.2.1 关系对比 - 20 -
2.2.2 关系图 - 21 -
2.3 登录 SQL*Plus - 21 -
2.3.1 EZCONNECT方式 - 22 -
2.3.2 使用 SQL*Plus - 24 -
2.4 SQL*Plus和SQL Developer - 24 -
2.4.1 从Shell脚本调用SQL*Plus - 25 -
2.4.1.1 shell调用 - 25 -
一、 最简单的shell里调用sqlplus - 25 -
二、 把sqlplus执行结果传递给shell方法一 - 26 -
三、 把sqlplus执行结果传递给shell方法二 - 26 -
四、 把shell程序参数传递给sqlplus - 27 -
五、 为了安全要求每次执行shell都手工输入密码 - 27 -
六、 为了安全从文件读取密码 - 28 -
2.4.1.2 bat调用 - 28 -
2.4.2 从SQL*Plus调用SQL脚本 - 29 -
2.4.3 sqlplus中将行转为列输出 - 31 -
2.5 SQL*Plus的设置 - 34 -
2.5.1 显示表结构 - 35 -
2.5.2 SET TIMING ON; 和 SET TIME ON - 35 -
2.5.3 SQL*Plus编辑命令 - 35 -
2.5.4 使用 LIST, n, 和 APPEND - 36 -
2.5.5 SQL*Plus 文件命令 - 36 -
2.5.5.1 导出csv、和html文件 - 37 -
一、 导出csv文件格式 - 37 -
二、 导出html文件格式 - 38 -
2.5.6 如何使用上下左右方向键 - 40 -
2.5.7 设置执行脚本时的搜寻路径 - 41 -
2.5.8 SQL*Plus中@和@@的区别是什么? - 41 -
2.5.9 SQL*Plus中&与&&的区别是什么? - 41 -
2.5.10 glogin.sql脚本的作用是什么?如何修改命令的提示符? - 42 -
2.5.11 SQL*Plus的ERRORLOGGING的作用是什么? - 42 -
2.5.12 如何给SQL*Plus安装帮助? - 43 -
2.6 iSQL*Plus 简介 - 44 -
2.6.1 iSQL*Plus概览 - 46 -
2.6.2 SQL 和iSQL*Plus 交互作用 - 46 -
第3章 基本SELECT语句 - 46 -
3.1 SELECT语句的功能 - 47 -
3.2 选择所有列 - 48 -
3.3 选择指定的列 - 48 -
3.4 SQL语句的编辑 - 49 -
3.5 列标题默认属性 - 49 -
3.6 算术表达式 - 51 -
3.7 定义空值 - 52 -
3.7.1 NULL的注意事项 - 54 -
3.7.2 IS NULL 走索引 - 55 -
3.7.3 多表查询中的空值问题 - 56 -
3.7.3.1 情形一: - 57 -
3.7.3.2 情形二: - 58 -
3.8 定义列别名 - 59 -
3.9 连字运算符 - 61 -
3.9.1 文字字符串 - 62 -
3.10 相同的行--去重(distinct) - 62 -
3.11 Quote (q)--11g新增 - 64 -
3.12 Oracle特殊字符的处理 - 67 -
3.13 本章学习目的 - 68 -
第4章 条件和排序 - 69 -
4.1 用选择限定行 - 69 -
4.1.1 限定语法 - 70 -
4.1.2 使用WHERE子句 - 71 -
4.1.3 条件中使用字符串和日期 - 71 -
4.1.4 比较条件 - 72 -
4.1.4.1 使用比较条件 - 72 -
4.1.4.2 使用BETWEEN条件 - 73 -
4.1.4.3 使用IN条件 - 73 -
4.1.4.4 使用LIKE条件 - 75 -
一、 LIKE模糊查询如何使用索引 - 77 -
4.1.4.5 使用NULL/NOT NULL条件 - 79 -
4.1.5 逻辑条件(AND、OR 、NOT) - 81 -
4.1.5.1 注意问题 - 83 -
4.1.6 优先规则 - 84 -
4.2 排序 - 85 -
4.2.1 降序排序 - 86 -
4.2.2 用列别名排序 - 87 -
4.2.3 多列排序 - 88 -
4.3 总结 - 89 -
第5章 Oracle SQL 单行函数 - 89 -
5.1 学习目的 - 89 -
5.2 SQL函数介绍 - 89 -
5.3 SQL函数分类 - 90 -
5.3.1 单行函数 - 90 -
5.4 DUAL表介绍 - 91 -
5.4.1 扩展 - 92 -
5.5 字符函数 - 93 -
5.5.1 大小写处理函数 - 93 -
5.5.2 字符处理函数 - 94 -
5.6 数字函数 - 96 -
5.7 日期函数 - 97 -
5.7.1 系统日期 - 97 -
5.7.2 用日期计算 - 98 -
5.7.3 日期函数 - 99 -
5.7.4 转换函数 - 100 -
5.7.5 隐式数据类型转换 - 101 -
5.7.5.1 扩展 - 101 -
5.7.6 显式数据类型转换 - 103 -
5.7.6.1 日期格式模板 - 103 -
5.7.6.2 时间格式模板 - 104 -
5.7.6.3 数字格式模板 - 104 -
5.8 嵌套函数 - 104 -
5.9 通用函数 - 104 -
5.10 条件表达式 - 106 -
5.10.1 CASE表达式 - 106 -
5.10.2 DECODE函数 - 107 -
5.11 总结 - 108 -
5.12 扩展 - 109 -
5.12.1 如何将一个数字转换为字符串并且按照指定格式显示? - 109 -
5.12.2 ORA-00904: "wm_concat":invalid identifier错误解决 - 110 -
5.12.3 如何判断一个字符串是否含有中文汉字? - 115 -
5.12.4 在Oracle中,如何判断一个字符串是否为数字? - 117 -
5.12.5 在Oracle中,如何让日期显示为"年-月-日 时:分:秒"的格式? - 118 -
5.12.6 如何判断当天是否月份最后一天? - 119 -
第6章 用组函数合计数据 - 120 -
6.1 学习目的 - 120 -
6.2 组函数的概念 - 121 -
6.3 组函数使用 - 121 -
6.3.1 使用AVG、SUM、MAX、MIN - 122 -
6.3.1.1 MAX和MIN优化写法 - 122 -
6.4 使用COUNT - 124 -
6.4.1 使用COUNT(DISTINCT 列) - 125 -
6.4.2 COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)、COUNT(允许为空列)、COUNT(DISTINCT 列名) - 125 -
6.5 组函数与空值 - 126 -
6.6 GROUP BY 子句 - 127 -
6.7 HAVING 子句 - 128 -
6.8 嵌套组函数 - 128 -
6.9 总结 - 129 -
第7章 从多表中查询数据 - 129 -
7.1 从多表中查询数据 - 129 -
7.2 有效连接条件与笛卡儿积 - 130 -
7.2.1 笛卡尔积是什么? - 130 -
第8章 连接的类型 - 131 -
8.1 等值连接 - 132 -
8.1.1 等值连接中的列别名、表别名 - 134 -
8.1.2 多于两个表的等值连接 - 135 -
8.2 外连接 - 136 -
8.2.1 外连接(扩展) - 140 -
8.3 自连接 - 143 -
8.3.1 自连接(Self Join) - 144 -
8.4 SQL 1999 连接语法介绍 - 145 -
8.4.1 交叉连接 - 145 -
8.4.2 自然连接 - 145 -
8.4.3 ON子句 - 146 -
8.5 关于SQL Join 中 where和and的区别 - 147 -
8.6 层次查询 分层查询 树形查询 - 150 -
8.6.1 层次查询语法结构 - 151 -
8.6.2 分析 - 153 -
8.6.3 SYS_CONNECT_BY_PATH 用于 行列转换 - 166 -
8.6.4 层次查询进阶 - 167 -
8.6.5 综合案例 - 170 -
8.6.6 快速构造大表 - 173 -
8.7 WITH语法 - 174 -
8.8 总结 - 175 -
第9章 子查询 - 175 -
9.1 学习目的 - 176 -
9.2 子查询介绍 - 176 -
9.3 子查询分类 - 178 -
9.3.1 单行子查询 - 178 -
? ?单行子查询:子查询只返回一行 - 178 -
? ?针对单行子查询的条件和普通条件一样 - 178 -
? ?单行子查询中使用HAVING - 178 -
? ?可以把单行子查询想像作一个可变的值。它和一个单一值没什么区别 - 178 -
9.3.2 单行子查询错误 - 181 -
9.3.3 多行子查询 - 182 -
9.3.4 总结 - 184 -
9.3.5 子查询扩展 - 184 -
9.3.5.1 标量子查询和关联子查询 - 185 -
9.3.5.2 子查询中的IN和EXISTS - 186 -
9.3.5.3 多行子查询 - 187 -
9.4 一个案例 - 188 -
第10章 合并查询(集合查询) - 190 -
10.1 UNION - 190 -
10.2 UNION ALL - 191 -
10.3 INTERSECT(相交) - 191 -
10.4 MINUS(相减) - 192 -
第11章 数据字典 - 192 -
11.1 动态性能视图 - 193 -
11.1.1 动态性能视图:注意事项 - 195 -
11.2 数据字典 - 196 -
11.2.1 数据字典视图 - 197 -
11.3 扩展 - 199 -
第12章 创建和管理表 - 201 -
12.1 数据库对象及表介绍 - 201 -
12.2 有关表的最大列数 - 202 -
12.3 表的分类 - 203 -
12.3.1 Oracle的表可以分为哪几类? - 203 -
12.4 表和列的命名规则 - 204 -
12.5 CREATE TABLE语句创建表 - 205 -
12.5.1 用子查询语法创建表(CTAS) - 206 -
12.5.1.1 CTAS及其优化 - 207 -
12.6 DEFAULT选项 - 207 -
12.7 引用表 - 208 -
12.8 数据类型介绍 - 209 -
12.8.1 时间数据类型 - 210 -
12.8.1.1 TIMESTAMP类型 - 210 -
12.8.1.2 INTERVAL YEAR TO MONTH数据类型 - 212 -
12.8.1.3 INTERVAL DAY TO SECOND数据类型 - 213 -
12.9 ALTER TABLE语句 - 214 -
12.9.1 添加列 - 214 -
12.9.2 修改列 - 215 -
12.9.2.1 修改字段的类型、大小和默认值(不能有数据) - 215 -
12.9.3 删除列(删除一个字段或清空某一列的数据) - 215 -
12.9.3.1 SET UNUSED选项 - 216 -
12.9.4 修改表的存储特征 - 217 -
12.9.5 修改表的名字 - 217 -
12.9.6 修改字段的名字 - 217 -
12.9.7 移动表所在的表空间 - 218 -
12.10 删除表 - 218 -
12.11 改变对象名称 - 218 -
12.12 截断表(TRUNCATE) - 219 -
12.13 给表和列添加注释 - 219 -
12.13.1 利用SQL生成需要的SQL语句 - 220 -
12.14 总结 - 222 -
第13章 操作数据 - 222 -
13.1 学习目的 - 222 -
13.2 数据操纵语言 - 223 -
13.3 INSERT插入数据的语法 - 223 -
13.3.1 INSERT插入值的变化 - 225 -
13.3.1.1 插入特殊值 - 225 -
13.3.1.2 插入指定日期 - 226 -
13.3.1.3 插入可输入变量 - 226 -
13.3.1.4 从另外一个表复制 - 226 -
13.3.1.5 在INSERT语句中使用子查询 - 227 -
13.4 UPDATE更新数据的语法 - 227 -
13.4.1 UPDATE更新的例子和问题 - 228 -
13.4.2 用子查询更新两列 - 228 -
13.4.3 更新基于另一个表的行(多表关联更新--使用子查询更新数据) - 229 -
13.4.3.1 例子 - 230 -
13.4.4 更新导致完整性约束报错 - 232 -
13.5 DELETE删除数据的语法 - 233 -
13.5.1 TRUNCATE语句 - 234 -
13.5.2 DELETE更新的例子和问题 - 235 -
13.5.3 从表中删除行 - 235 -
13.5.4 删除基于另一个表的行 - 235 -
13.5.4.1 一道OCM题 - 236 -
13.5.5 删除数据导致的完整性约束 - 237 -
13.5.6 查找和删除重复的记录 - 237 -
13.6 显示默认值 - 238 -
13.7 MERGE合并语句语法 - 238 -
13.7.1 MERGE语句在优化中的巨大作用 - 242 -
13.7.2 DML语句优化的方法 - 243 -
13.8 DELETE、DROP和TRUNCATE的区别是什么? - 244 -
13.9 本章总结 - 245 -
第14章 约束 - 245 -
14.1 约束的概念和原则 - 245 -
14.1.1 约束的概念 - 246 -
14.1.2 约束的原则 - 246 -
14.2 定义约束 - 246 -
14.2.1 定义约束的语法 - 246 -
14.2.2 定义约束分类 - 247 -
14.3 几种常见的约束 - 248 -
14.3.1 NOT NULL约束 - 249 -
14.3.2 UNIQUE约束 - 249 -
14.3.3 PRIMARY KEY约束 - 251 -
14.3.4 FOREIGN KEY约束 - 251 -
14.3.4.1 外键列的索引 - 255 -
14.3.4.2 外键的死锁(外键未加索引) - 258 -
一、 脚本 - 263 -
二、 找出没有建立索引的外键 - 265 -
14.3.5 CHECK约束 - 266 -
14.4 管理约束 - 268 -
14.4.1 添加约束 - 268 -
14.4.2 删除约束 - 270 -
14.4.3 禁用、启用约束 - 271 -
14.4.4 级联约束 - 271 -
14.4.5 查看约束 - 272 -
14.5 ocp - 273 -
14.6 总结 - 274 -
第15章 视图 - 274 -
15.1 视图的概念和优势 - 274 -
15.2 视图的概念 - 275 -
15.2.1 使用视图的优势 - 275 -
15.3 创建简单视图 - 276 -
15.3.1 视图中查询数据 - 277 -
15.4 创建复杂视图 - 277 -
15.5 视图中DML操作的执行规则 - 277 -
15.5.1 With Check OPTION子句 - 278 -
15.5.2 With READ ONLY子句 - 278 -
15.6 管理视图 - 278 -
15.6.1 修改视图 - 279 -
15.6.2 删除视图 - 279 -
15.6.3 内建视图 - 279 -
15.7 视图扩展 - 280 -
15.7.1 Oracle中的视图 - 280 -
15.7.2 在什么情况下可以对视图执行增、删、改操作? - 281 -
15.8 Top-N 分析 - 282 -
15.8.1 扩展 - 283 -
15.9 物化视图简介 - 285 -
15.9.1 扩展 - 286 -
查询重写(QueryRewrite): - 287 -
15.10 总结 - 290 -
第16章 其他数据库对象 - 290 -
16.1 其他数据库对象的作用 - 291 -
16.2 序列 - 291 -
16.2.1 序列的语法 - 292 -
16.2.2 定义及查询序列 - 292 -
16.2.3 NEXTVAL和CURRVAL伪列 - 293 -
16.2.4 使用序列 - 293 -
16.2.5 修改序列 - 294 -
16.2.6 删除序列 - 295 -
16.2.7 麦苗扩展 - 295 -
16.2.7.1 注意内容 - 295 -
16.2.7.2 性能问题 - 296 -
16.2.7.3 OCP和OCM题举例 - 296 -
16.3 索引 - 297 -
16.3.1 索引的优缺点 - 297 -
16.3.2 索引的使用原则 - 298 -
16.3.3 创建索引 - 299 -
16.3.4 查询索引 - 300 -
16.3.5 基于函数的索引 - 300 -
16.3.6 删除索引 - 301 -
16.3.7 麦苗扩展 - 301 -
16.3.7.1 如何预估即将创建索引的大小? - 301 -
16.3.7.2 如何监控索引的使用状况? - 302 -
16.3.7.3 哪些操作会导致索引失效? - 305 -
16.3.7.4 什么是索引的选择性(Index Selectivity)? - 306 -
16.3.7.5 为什么索引没有被使用? - 307 -
16.3.7.6 IS NULL如何用到索引? - 310 -
16.3.7.7 LIKE模糊匹配如何选择索引? - 310 -
16.4 同义词 - 311 -
16.4.1 概念语法 - 311 -
16.4.2 创建和删除同义词 - 311 -
16.4.3 扩展 - 312 -
16.4.3.1 PLAN_TABLE表的真谛 - 312 -
16.5 数据库链接(dblink) - 313 -
16.5.1 dblink扩展 - 314 -
16.5.2 一道OCM考题 - 317 -
=================================================== - 317 -
存储过程、函数、包的开发 - 318 -
第17章 PL/SQL 块 - 318 -
17.1 PL/SQL 简介 - 318 -
17.2 程序形式 - 318 -
17.3 编写规范 - 318 -
17.3.1 注释 - 318 -
17.3.2 标志符号的命名规范 - 319 -
17.4 PL/SQL 块(匿名块)结构 - 319 -
17.4.1 声明部分 - 320 -
17.4.2 可执行部分 - 322 -
第18章 控制结构(分支,循环,控制) - 323 -
18.1 简介 - 323 -
18.2 条件分支语句 --if - 323 -
18.3 循环 - 326 -
18.3.1 loop - 326 -
18.3.2 while循环 - 328 -
18.3.3 for 循环 - 330 -
18.3.3.1 游标for循环 - 332 -
18.4 顺序控制 –goto,null - 333 -
18.4.1 goto 语句 - 333 -
18.4.2 null - 335 -
第19章 异常处理 - 337 -
19.1 概述 - 337 -
19.2 异常处理 - 337 -
19.2.1 预定义异常 ( Predefined ) - 337 -
19.2.2 非预定义异常(Non Predefined ) - 343 -
19.2.3 自定义异常(User_define) - 345 -
19.3 抛出异常 - 348 -
19.3.1 raise - 348 -
19.3.2 RAISE_APPLICATION_ERROR - 349 -
19.4 存过中捕获异常的行号 - 350 -
19.5 如何捕获错误并记录到表中? - 354 -
第20章 存储过程(Stored Procedure) - 359 -
20.1 存储过程和函数的区别是什么? - 359 -
20.2 示例 - 359 -
20.2.1 执行和调用存储过程 - 360 -
20.2.1.1 执行存过 - 360 -
20.2.1.2 存过调用存过 - 362 -
第21章 Oracle中的触发器 - 362 -
21.1 一些常用的监控 - 369 -
21.2 Oracle的自治事务是什么? - 374 -
第22章 Oracle中过程/函数返回集合 - 376 -
22.1.1 函数返回系统游标 - 376 -
第23章 Oracle分批提交DML - 377 -
23.1 分批update - 377 -
23.2 分批delete - 378 -
23.3 分批insert - 379 -
Oracle 备份恢复(rman、闪回、数据泵、exp、数据迁移等)
目录 - 1 -
第1章 备份和恢复的概念 - 15 -
1.1 故障类别 - 17 -
1.1.1 语句失败 - 17 -
1.1.2 用户进程失败 - 18 -
1.1.3 网络故障 - 19 -
1.1.4 用户错误 - 19 -
1.1.5 介质故障 - 20 -
1.2 Oracle的SCN是什么? - 20 -
1.2.1 SCN的组成 - 20 -
1.2.2 SCN的分类 - 21 -
1.2.3 如何查看系统当前SCN - 22 -
1.2.4 SCN与时间的相互转换 - 22 -
1.2.5 SYS.SMON_SCN_TIME字典基表 - 24 -
1.3 实例恢复(实例故障) - 25 -
1.3.1 实例故障 - 25 -
1.3.2 了解实例恢复:检查点 (CKPT) 进程 - 26 -
1.3.3 实例恢复的阶段 - 28 -
1.3.4 优化实例恢复 - 30 -
1.3.4.1 使用 MTTR 指导 - 31 -
1.3.5 麦苗扩展 - 32 -
1.3.5.1 实例恢复(前滚和回滚) - 32 -
1.4 配置可恢复性 - 35 -
1.5 配置快速恢复区 - 36 -
1.6 测验 - 37 -
1.7 小结 - 37 -
第2章 闪回体系 - 38 -
2.1 什么是闪回?闪回有哪些分类? - 39 -
2.1.1 闪回查询(Flashback Query) - 42 -
2.1.2 闪回版本查询(Flashback Version Query) - 44 -
2.1.3 闪回事务查询(Flashback Transaction Query) - 46 -
2.1.4 闪回表(Flashback TABLE) - 47 -
2.1.5 闪回删除(Flashback DROP) - 51 -
2.1.6 闪回数据库(Flashback Database) - 52 -
2.1.7 闪回数据归档(Flashback Data Archive) - 52 -
2.1.8 相关OCP题目 - 52 -
2.2 Oracle的回收站是什么? - 54 -
2.2.1 相关OCP题目 - 56 -
2.3 什么是闪回数据归档(Flashback Data Archive)? - 58 -
2.3.1 相关OCP题目 - 60 -
2.4 什么是闪回数据库? - 63 -
2.4.1 相关OCP题目 - 65 -
2.5 其它扩展 - 67 -
2.5.1 如何让普通用户可以对DBA_SOURCE视图进行闪回查询? - 67 -
第3章 执行数据库备份 - 68 -
3.1 课程目标 - 68 -
3.2 Oracle Secure Backup - 70 -
3.3 用户管理的备份 - 71 -
3.4 术语 - 72 -
3.5 Recovery Manager (RMAN) - 74 -
3.5.1 rman 连接数据库 - 75 -
3.5.2 RMAN数据字典 - 75 -
3.5.3 rman命令 - 76 -
3.6 RMAN简介 - 76 -
3.7 RMAN的配置 - 79 -
3.7.1 定义RMAN配置 - 79 -
3.7.2 显示RMAN默认配置 - 80 -
3.7.2.1 CONFIGURE RETENTION POLICY 配置备份保留策略 - 81 -
一、 设置 RMAN 备份的保存策略 - 84 -
3.7.2.2 CONFIGURE BACKUP OPTIMIZATION 配置备份优化 - 86 -
3.7.2.3 CONFIGURE DEFAULT DEVICE TYPE 配置 IO 设备类型 - 89 -
3.7.2.4 CONFIGURE CONTROLFILE AUTOBACKUP 配置控制文件自动备份 - 89 -
一、 控制文件快照自动备份 - 90 -
二、 11G新特性-控制文件延迟自动备份 - 90 -
3.7.2.5 CONFIGURE DEVICE TYPE 设置并行备份 - 96 -
3.7.2.6 CONFIGURE DATAFILE BACKUP COPIES 设置备份文件冗余度 - 97 -
3.7.2.7 CONFIGURE MAXSETSIZE 配置备份集的最大尺寸 - 98 -
3.7.2.8 CONFIGURE ARCHIVELOG DELETION POLICY - 98 -
3.7.3 FORMAT参数 - 102 -
3.7.4 配置备份设置 - 102 -
3.7.4.1 调度备份:策略 - 104 -
3.7.4.2 调度备份:选项 - 105 -
3.7.5 OCP - 110 -
3.8 rman 其它命令 - 113 -
3.8.1 列出备份信息(list) - 113 -
3.8.2 删除备份(delete) - 115 -
3.8.2.1 RMAN中关于备份或归档文件状态OBSOLETE和EXPIRED的区别是什么? - 118 -
3.8.3 报告命令(report) - 119 -
3.8.3.1 可以报告哪些文件需要备份 - 119 -
3.8.3.2 报告不可恢复的备份集 - 119 -
3.8.3.3 报告数据库的信息 - 120 -
3.8.4 交叉检查(crosscheck) - 125 -
3.8.5 show - 126 -
3.8.6 VALIDATE DATABASE - 126 -
3.9 批处理命令RUN - 126 -
3.10 物理备份和逻辑备份分别是什么? - 127 -
3.11 catalog库 - 128 -
3.11.1 恢复目录(Recovery Catalog)的概念 - 128 -
3.11.2 如何创建恢复目录(Recovery Catalog) - 129 -
3.11.2.1 例子 - 129 -
3.11.2.2 官网 - 131 -
一、 Prerequisites - 131 -
二、 基本恢复目录 - 133 -
三、 虚拟私有目录--RVPC(RMAN virtual private catalog) - 133 -
3.11.3 Recovery catalog resyncing 恢复目录同步 - 138 -
3.11.4 IMPORT CATALOG - 138 -
3.11.4.1 例子 - 141 -
3.11.5 Managing a Recovery Catalog - 142 -
3.11.6 OCP - 142 -
3.12 BACKUP命令---RMAN备份 - 151 -
3.12.1.1 whole backup - 153 -
3.12.1.2 full backup - 154 -
一、 完全备份示例 - 156 -
3.12.2 备份表空间 - 157 -
3.12.2.1 temp表空间 - 158 -
3.12.3 备份指定数据文件 - 158 -
3.12.3.1 system - 159 -
3.12.4 备份控制文件 - 159 -
3.12.4.1 在线镜像备份 - 162 -
3.12.4.2 自动备份 - 162 -
一、 显式自动备份 - 162 -
二、 隐式自动备份 - 163 -
3.12.4.3 手动备份 - 163 -
一、 备份集备份 - 163 -
二、 镜像复制备份 - 163 -
三、 重建脚本 - 164 -
3.12.4.4 控制文件快照 - 165 -
3.12.5 备份spfile - 172 -
3.12.6 备份归档日志文件 - 172 -
3.12.6.1 归档重做日志的备份与恢复 - 173 -
3.12.6.2 联机日志的备份 - 174 -
3.13 管理备份 - 175 -
3.13.1 查看备份报告 - 177 -
3.13.2 监视快速恢复区 - 178 -
3.13.3 使用 RMAN 命令行 - 179 -
3.14 麦苗扩展 - 180 -
3.14.1 差异增量备份和累积增量备份的区别是什么? - 180 -
3.14.2 什么是块改变跟踪(Block Change Tracking)? - 185 -
3.14.2.1 OCP - 186 -
3.15 我的备份脚本 - 188 -
3.15.1 linux - 189 -
3.15.1.1 nocatalog全备 - 189 -
一、 简易版-归档 - 191 -
二、 简易版-非归档mount全备 - 192 -
3.15.1.2 catalog增量备份脚本 - 193 -
一、 我自己的 - 195 -
3.15.1.3 Nocatalog增量备份脚本 - 198 -
一、 我自己的 - 211 -
3.15.2 windows - 213 -
3.15.2.1 全备--我自己的 - 215 -
3.15.2.2 增量备份 - 216 -
3.15.2.3 设置windows定时任务 - 219 -
一、 XP下设置 - 222 -
3.16 OCP - 224 -
3.17 小测验 - 234 -
3.18 小结 - 234 -
第4章 执行数据库恢复 - 234 -
4.1 课程目标 - 234 -
4.2 打开数据库 - 235 -
4.2.1 使数据库保持在打开状态 - 237 -
4.3 数据库归档恢复 - 238 -
4.4 对数据库进行完全介质恢复 - 238 -
4.5 物理文件恢复 - 239 -
4.5.1 口令文件(密码文件) - 239 -
4.5.2 spfile 丢失 - 239 -
4.5.2.1 数据库没有挂掉 - 239 -
4.5.2.2 数据库已经挂掉 - 240 -
一、 从rman的自动备份中找回 - 240 -
二、 手动创建 - 246 -
4.5.3 controlfile丢失 - 246 -
4.5.3.1 控制文件恢复前的准备 - 248 -
4.5.3.2 有备份情况下的恢复 - 251 -
一、 控制文件之一丢失(单个控制文件丢失或损坏) - 251 -
二、 各种情况下的丢失 - 252 -
三、 使用控制文件快照 - 275 -
4.5.3.3 重建控制文件---无备份情况下的恢复 - 278 -
一、 重建控制文件resetlogs和noresetlogs的区别 - 280 -
二、 在线日志无损情况下的重建 - 300 -
三、 在线日志损坏情况下的重建 - 301 -
四、 具有只读数据文件情况下的重建 - 303 -
4.5.3.4 控制文件不一致 - 307 -
4.5.3.5 OCP - 308 -
4.5.4 Redo文件丢失(online+archive) - 310 -
4.5.4.1 在线Redo日志 - 310 -
一、 查看日志文件的状态 - 312 -
二、 日志文件的恢复方法 - 313 -
三、 数据库归档/非归档模式下inactive redo异常ORA-00316 ORA-00327 - 315 -
四、 正常关闭数据库current redo异常ORA-00316 ORA-01623 - 318 -
五、 数据库异常关闭current/active redo异常ORA-00316 ORA-01624 ORA-01194 - 321 -
六、 Loss of a Redo Log File - 332 -
七、 Loss of a Redo Log Group - 337 -
八、 loss all online redo logs - 339 -
九、 数据库未挂掉的情况下的恢复 - 340 -
4.5.4.2 恢复归档日志archivelog - 341 -
一、 restore archivelog 的各种选项 - 341 -
二、 我的例子 - 351 -
三、 怎样清除v$archived_log视图中的过期信息 - 356 -
4.5.4.3 OCP - 358 -
4.5.5 datafile丢失 - 362 -
4.5.5.1 在NOARCHIVELOG模式下丢失了数据文件 - 364 -
4.5.5.2 在ARCHIVELOG模式下丢失了非关键数据文件 - 365 -
一、 在ARCHIVELOG模式下丢失了系统关键数据文件 - 366 -
4.5.5.3 open状态下可以脱机的文件(sysaux,user等等) - 367 -
一、 修改数据文件名称 - 368 -
4.5.5.4 open状态下不能脱机的文件(system,undo,temp) - 368 -
一、 undo文件丢失 - 373 -
4.5.5.5 Loss of a Noncritical Data File in ARCHIVELOG Mode - 374 -
4.5.5.6 Loss of a System-Critical Data File in ARCHIVELOG Mode - 374 -
一、 system数据文件丢失 - 375 -
二、 【RMAN】SYSTEM表空间数据文件丢失恢复模拟 - 380 -
三、 system - 395 -
4.5.5.7 非归档模式 - 397 -
4.5.5.8 如果删除表空间之前删除了表空间文件,解决办法: - 398 -
4.5.5.9 OCP - 398 -
4.5.5.10 数据文件没有备份的情况 - 399 -
4.5.6 表空间丢失 - 406 -
4.5.6.1 临时表空间数据文件(tempfile)丢失 - 408 -
4.5.6.2 Recovering from a Lost Index Tablespace - 411 -
4.5.6.3 Recovering a Read-Only Tablespace - 412 -
4.5.6.4 undo表空间 - 412 -
一、 有备份 - 426 -
二、 无备份 - 429 -
三、 使用bbed恢复 - 454 -
四、 数据库还没有挂掉的情况下 - 454 -
4.5.7 ORACLE丢失各种文件导致数据库不能OPEN恢复 - 455 -
4.6 麦苗扩展 - 458 -
4.6.1 恢复的分类 - 458 -
4.6.2 介质恢复(MEDIA RECOVERY) - 459 -
4.6.2.1 数据库还原(RESTORE)与数据库恢复(RECOVER) - 459 -
4.6.2.2 完全恢复和不完全恢复 - 462 -
4.6.2.3 完全恢复(Complete Recovery) - 463 -
一、 完全恢复的几种场景 - 465 -
4.6.2.4 不完全恢复的几种类型 - 475 -
4.6.2.5 实例恢复和介质恢复的区别 - 476 -
4.6.3 rm -rf误操作的恢复过程----数据库在无备份且open情况下的恢复 - 477 -
4.6.3.1 实验 - 479 -
4.6.3.2 登录SQLPLUS查看基本信息 - 479 -
4.6.3.3 模拟rm -rf误操作 - 481 -
4.6.3.4 开始恢复 - 483 -
一、 判断句柄位置 - 483 -
二、 恢复数据文件、控制文件、tmp文件和online log文件 - 485 -
三、 如果数据库还没有关掉则关闭数据库 - 489 -
4.6.3.5 总结 - 491 -
4.6.4 TRUNCATE恢复方法 - 491 -
4.6.5 TSPITR(表空间基于时间点恢复) - 492 -
4.6.6 在丢失归档的情况下如何进行数据文件的恢复 - 495 -
4.6.7 数据文件OFFLINE之后必须要做的一件事是什么? - 495 -
4.6.8 什么是DRA(Data Recovery Advisor)? - 498 -
4.6.8.1 Data Recovery Advisor(数据恢复指导) - 499 -
4.6.8.2 数据恢复指导 - 501 -
4.6.8.3 数据故障 - 503 -
一、 列出数据故障 - 504 -
二、 提供修复建议 - 505 -
4.7 基于用户管理恢复的方法 - 508 -
4.8 基于用户管理的完全恢复 - 508 -
4.9 小测验 - 510 -
第5章 日志挖掘logminer - 511 -
5.1 演示 - 515 -
第6章 利用增量数据库备份进行恢复 - 516 -
6.1 自己的脚本 - 516 -
第7章 RMAN高级应用之Duplicate复制数据库 - 519 -
7.1 简介 - 519 -
7.2 duplicate体系结构 - 520 -
7.2.1 Duplicating an Active Database - 521 -
7.2.1.1 Prerequisites Specific to Active Database Duplication - 525 -
7.2.1.2 自己的例子 - 525 -
7.2.2 Cloning A Database On The Same Server Using Rman Duplicate From Active Database - 526 -
7.2.2.1 Configure The Network - 527 -
7.2.2.2 Create A Password File For The New Database - 528 -
7.2.2.3 Create An Init.Ora For The New Database - 528 -
7.2.2.4 Create The Admin Directory For The New Database - 528 -
7.2.2.5 Shutdown And Startup Mount The Source Database - 528 -
7.2.2.6 Startup Nomount The New Database - 529 -
7.2.2.7 Connect To The Target (Source) And Auxiliary (New Clone)Databases Using Rman - 529 -
7.2.2.8 Execute The Duplicate Command - 529 -
7.2.2.9 Remove The Old Pfile - 535 -
7.2.2.10 Check The New Database - 535 -
7.2.3 Duplicating a Database with a Target Connection - 536 -
7.2.4 Duplicating a Database with Recovery Catalog Without Target Connection - 537 -
7.2.5 Duplicating a Database Without Recovery Catalog or Target Connection - 538 -
7.2.5.1 老师例子 - 539 -
7.3 Creating a Backup-Based Duplicate Database - 556 -
7.3.1 Creating an Initialization Parameter File for the Auxiliary Instance - 557 -
7.3.2 Specifying New Names for Your Destination - 558 -
7.3.2.1 SET NEWNAME - 559 -
7.3.3 Specifying Parameters for File Naming - 562 -
7.3.3.1 DB_FILE_NAME_CONVERT - 563 -
7.4 OCP - 563 -
第8章 BBED简介 - 567 -
第9章 rman之块介质恢复 - 568 -
9.1 坏块的简介 - 568 -
9.2 坏块的检测方法 - 569 -
9.3 BMR恢复坏块 - 571 -
9.4 如何确定坏块的对象名 - 571 -
9.5 如果发现有坏块,那么如何检索其它未坏的数据? - 572 -
9.6 模拟坏块 - 573 -
9.6.1 blockrecover恢复坏块 - 573 -
9.6.1.1 创建演示环境 - 573 -
9.6.1.2 单块数据块损坏的恢复处理 - 574 -
9.6.1.3 多块数据块损坏的恢复处理 - 575 -
9.6.1.4 坏块的对象定位与影响 - 577 -
9.6.2 bbed模拟 - 579 -
9.6.2.1 bbed修复坏块示例 - 580 -
9.7 坏块模拟脚本 - 584 -
9.8 OCP - 585 -
第10章 OS备份(物理备份)和恢复 - 587 -
10.1 操作系统备份(物理备份) - 587 -
10.1.1 冷备份(一致性备份、脱机备份) --cool backup - 587 -
10.1.1.1 冷备份的优缺点 - 588 -
10.1.1.2 冷备份一般步骤 - 588 -
10.1.1.3 冷备脚本的写法 - 589 -
一、 冷备脚本 - 592 -
10.1.1.4 存在冷备下的还原(非归档模式) - 592 -
一、 丢失数据文件 - 592 -
二、 日志文件丢失 - 608 -
三、 控制文件丢失 - 612 -
四、 参数文件丢失 - 616 -
五、 密码文件丢失 - 616 -
10.1.1.5 OCP - 617 -
10.1.2 热备份(非一致性备份、联机备份) --只能用于归档模式 - 617 -
10.1.2.1 简介 - 617 -
10.1.2.2 具体操作 - 618 -
一、 热备的过程 - 618 -
二、 基于数据库的热备 - 619 -
三、 基于表空间的热备 - 620 -
四、 控制文件的热备 - 621 -
五、 参数文件的热备 - 622 -
六、 临时表空间的数据文件、日志文件不需要备份 - 622 -
10.1.2.3 热备份的相关视图 - 622 -
10.1.2.4 热备ocp - 625 -
10.1.2.5 存在热备下的还原 - 629 -
一、 还原控制文件 - 629 -
二、 还原数据文件 - 632 -
第11章 非归档模式备份恢复 - 637 -
11.1 非归档的备份方法 - 640 -
11.1.1 非归档全备份 - 641 -
11.2 非归档模式下的恢复 - 643 -
11.3 非归档模式的备份与恢复示例(使用冷备) - 646 -
第12章 OPEN RESETLOGS - 650 -
12.1 使用alter database open resetlogs的场合 - 650 -
12.2 为什么使用RESETLOGS? - 650 -
12.3 RESETLOGS会执行什么操作? - 650 -
12.4 ocp - 651 -
第13章 其它 - 651 -
13.1 下列4条RECOVER DATABASE命令的区别是什么 - 651 -
13.2 RESETLOGS和NORESETLOGS的区别是什么? - 652 -
第14章 跨版本恢复 - 653 -
14.1 RMAN可以跨版本或跨平台执行还原或复制命令吗? - 653 -
14.2 跨小版本 - 655 -
14.3 跨大版本 - 656 -
第15章 只存在备份片的数据库恢复过程 - 656 -
15.1.1 总结 - 656 -
第16章 Oracle恢复流程图 - 656 -
第17章 移动数据 - 658 -
17.1 移动数据:一般体系结构 - 659 -
17.2 exp和imp - 660 -
17.2.1 EXP导出数据 - 661 -
17.2.1.1 导出表 - 664 -
17.2.1.2 导出方案 - 665 -
17.2.1.3 导出数据库 - 665 -
17.2.2 IMP导入数据 - 665 -
17.2.2.1 导入表 - 667 -
17.2.2.2 导入方案 - 668 -
17.2.2.3 导入数据库 - 668 -
17.2.2.4 imp导入常见问题处理 - 670 -
17.2.3 exp和imp的一些其它用法 - 671 -
17.2.4 其它实用内容 - 672 -
17.2.4.1 可以从dmp文件获取哪些信息? - 672 -
一、 获取基本信息:导出的版本、时间、导出的用户 - 672 -
二、 获取dmp文件中的表信息 - 672 -
三、 解析dmp文件生成parfile文件 - 673 -
四、 如何查看dmp文件的字符集 - 673 -
五、 如何将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中? - 674 -
17.2.4.2 exp的query参数和parfile的使用 - 675 -
一、 query和parfile示例 - 676 -
17.2.4.3 什么是延迟段创建(Deferred Segment Creation)? - 677 -
一、 Oracle 11g不能导出空表的三种解决方法 - 679 -
17.2.4.4 exp导出ASH数据 - 680 -
一、 方法1:ctas建表导出,有的客户不让建表 - 680 -
二、 方法2:导出基表的数据 - 682 -
17.2.5 常见错误 - 684 -
17.2.5.1 EXP-00091: Exporting questionable statistics 问题处理方法 - 684 -
17.2.5.2 EXP-00026: conflicting modes specified - 687 -
17.2.5.3 IMP-00013: only a DBA can import a file exported by another DBA - 689 -
17.2.5.4 IMP-00031: 必须指定 FULL=Y 或提供 FROMUSER/TOUSER 或 TABLES 参数 - 690 -
17.2.5.5 IMP-00002: 无法打开要读取的imp D:/admin.dmp - 692 -
17.2.5.6 EXP-00008: 遇到 ORACLE 错误 904 - 692 -
17.2.5.7 imp导入报错:IMP-00037: Character set marker unknown - 693 -
17.2.5.8 IMP-00010: not a valid export file, header failed verification - 696 -
17.2.5.9 imp-00051,imp-00008 - 698 -
17.2.5.10 IMP-00132: first file in the multi-file export is 32 - 699 -
17.2.6 注意事项 - 699 -
17.3 数据泵(expdp和impdp) - 699 -
17.3.1 Oracle 数据泵:概览 - 701 -
17.3.2 Oracle 数据泵:优点 - 702 -
17.3.3 Oracle Database 11g 中的数据泵增强功能 - 703 -
17.3.4 数据泵的目录对象 - 704 -
17.3.4.1 创建目录对象 - 705 -
17.3.5 数据泵导出与导入客户机:概览 - 706 -
17.3.6 数据泵实用程序:界面与模式 - 707 -
17.3.7 使用 Database Control 进行数据泵导出 - 708 -
17.3.8 数据泵导出示例 - 709 -
17.3.8.1 数据泵导出示例:基本选项 - 710 -
17.3.8.2 数据泵导出示例:高级选项 - 710 -
17.3.8.3 数据泵导出示例:文件 - 711 -
17.3.8.4 数据泵导出示例:调度 - 713 -
17.3.8.5 数据泵导出示例:复查 - 714 -
17.3.8.6 数据泵导入示例:impdp - 714 -
17.3.9 使用 Oracle Enterprise Manager 监视数据泵作业 - 715 -
17.3.10 以数据泵旧模式提供移植支持 - 716 -
17.3.11 数据泵旧模式 - 717 -
17.3.12 管理文件位置 - 719 -
17.3.13 麦苗扩展 - 720 -
17.3.13.1 数据泵的一些常用语法命令 - 720 -
17.3.13.2 如何彻底停止expdp进程? - 725 -
17.3.13.3 如何跟踪expdp和SQL*Plus命令? - 727 -
17.3.13.4 如何退出exp、imp、telnet等等交互窗口? - 727 -
17.3.13.5 Oracle用户密码含特殊字符时如何登陆? - 728 -
17.3.13.6 如何获取数据库DDL的创建语句 - 729 -
一、 imp示例(SHOW=Y) - 729 -
二、 imp的indexfile选项(indexfile导出表和索引的ddl语句) - 732 -
三、 impdp示例 - 734 -
四、 只导出元数据完整示例 - 737 -
五、 【IMPDP】使用 TRANSFORM选项去掉表空间和存储子句 - 737 -
17.3.13.7 过滤数据(exclude、include) - 738 -
一、 Exclude 反规则 - 739 -
二、 Include 正规则 - 740 -
三、 高级过滤CONTENT参数 - 741 -
四、 过滤已经存在的数据TABLE_EXISTS_ACTION参数 - 742 -
五、 导出job - 742 -
六、 导出dblink - 743 -
七、 导出公共同义词 - 743 -
17.3.13.8 重定义表的Schema或表空间 - 743 -
17.3.13.9 优化导入/导出效率(expdp/impdp) - 744 -
17.3.13.10 impdp传输表空间(OCM考题) - 748 -
17.3.13.11 注意事项 - 750 -
一、 expdp 导出sys用户下的表报错ORA-39165 和ORA-39166 - 750 -
17.3.13.12 impdp的一些选项 - 752 -
一、 NETWORK_LINK 选项 - 752 -
二、 oracle expdp时显示时间 metrics - 752 -
17.3.13.13 如何导出存储过程、函数、包和触发器的定义语句?如何导出表的结构?如何导出索引的创建语句? - 753 -
17.3.13.14 12c expdp VIEWS_AS_TABLES选项 - 766 -
17.3.13.15 其它错误 - 768 -
一、 数据泵导出出现ORA-31617错误 - 768 -
17.3.13.16 数据泵导出导入卡死 - 771 -
一、 AIX环境下EXPDP卡住问题处理 - 773 -
17.3.13.17 使用隐含Trace参数诊断Oracle Data Pump故障 - 775 -
17.4 SQL*Loader - 785 -
17.4.1 使用 SQL*Loader 加载数据 - 787 -
17.4.2 SQL*Loader 控制文件 - 787 -
17.4.3 直接路径加载与常规路径加载的比较 - 790 -
17.4.4 麦苗扩展 - 791 -
17.4.4.1 如何将文本文件或Excel中的数据导入数据库? - 791 -
一、 sqlldr高级用法 - 793 -
二、 sqlldr报错处理 - 795 -
17.4.4.2 简单示例 - 797 -
17.4.4.3 2000W酒店开房数据导入 - 798 -
17.5 外部表 - 803 -
17.5.1 外部表的优点 - 804 -
17.5.2 使用ORACLE_LOADER定义外部表 - 805 -
17.5.3 使用ORACLE_DATAPUMP填充外部表 - 806 -
17.5.4 使用外部表 - 807 -
17.5.5 麦苗扩展 - 807 -
17.5.5.1 基础 - 807 -
17.5.5.2 外部表示例 - 809 -
17.5.5.3 只有1列 - 809 -
17.5.5.4 外部表的parallel - 810 -
17.5.5.5 利用外部表查看告警日志 - 810 -
一、 先来个最简单的使用方法 - 810 -
二、 再来个稍微复杂点的 - 812 -
17.5.5.6 2000W酒店开房数据导入 - 814 -
17.6 有关sqlldr和外部表的一道OCM考题 - 815 -
17.7 小测验 - 820 -
17.8 小结 - 820 -
Oracle 管理部分(包括体系结构等内容)
目录 - 1 -
第1章 管理数据并发处理(锁和会话) - 14 -
1.1 课程目标 - 14 -
1.2 锁 - 15 -
1.2.1 显式锁定 - 17 -
1.2.2 隐式锁定 - 17 -
1.2.3 按照对象分类锁定 - 17 -
1.3 锁定机制 - 18 -
1.4 数据并发处理 - 19 -
1.5 DML 锁 - 21 -
1.6 入队机制 - 22 -
1.7 锁冲突 - 23 -
1.8 锁冲突的可能原因 - 24 -
1.9 检测锁冲突 - 25 -
1.10 解决锁冲突 - 26 -
1.10.1 使用 SQL 解决锁冲突 - 27 -
1.11 死锁 - 28 -
1.12 锁的扩展 - 28 -
1.12.1 分类 - 29 -
1.12.2 锁的兼容性 - 32 -
1.12.3 锁的数据字典视图 - 33 -
1.12.4 SELECT ... FOR UPDATE - 36 -
1.12.5 DML_LOCKS和DDL_LOCK_TIMEOUT参数 - 36 -
1.12.6 在编译存储过程、函数等对象时无响应 - 36 -
1.12.7 新建或重建索引的锁信息 - 36 -
1.12.8 对于错误"ORA-08104: this index object 68111 is being online built or rebuilt",应该如何处理? - 38 -
1.12.9 会话 - 39 -
1.12.9.1 V$SESSION视图 - 39 -
1.12.9.2 如何查看某一个会话是否被其它会话阻塞? - 42 -
1.12.9.3 如何查到会话正在执行的SQL语句? - 43 -
1.12.9.4 如何彻底杀掉会话?V$SESSION的STATUS为KILLED的情况下如何找到相关的后台OS进程? - 43 -
1.12.9.5 如何让普通用户可以杀掉自己用户的会话? - 44 -
1.12.9.6 SESSIONS和PROCESSES的关系 - 46 -
1.12.9.7 如何根据OS进程快速获得DB进程信息与正在执行的语句? - 47 -
1.12.9.8 怎么杀掉特定的数据库会话? - 48 -
1.12.9.9 如何快速的清理Oracle的进程? - 48 -
1.13 小测试 - 48 -
1.14 小结 - 49 -
第2章 管理还原数据 - 49 -
2.1 还原数据 - 50 -
2.2 事务处理和还原数据 - 52 -
2.3 存储还原信息 - 53 -
2.4 还原数据与重做数据 - 54 -
2.5 管理还原 - 55 -
2.5.1 配置还原保留时间 - 56 -
2.6 保证还原保留时间 - 57 -
2.7 将还原表空间改为固定大小 - 58 -
2.8 一般还原信息 - 59 -
2.9 使用还原指导 - 60 -
2.10 查看系统活动 - 61 -
2.11 扩展 - 62 -
2.11.1 Undo的作用 - 62 -
2.11.2 Undo段存储的内容 - 63 -
2.11.3 块清除 - 64 -
2.11.4 Undo表空间 - 65 -
2.11.5 系统回滚段(System Rollback Segment)与延迟回滚段(Deferred Rollback Segment) - 67 -
2.11.6 ORA-01555 - 67 -
2.11.7 Redo日志文件(Redo Log Files)的作用是什么? - 68 -
2.11.8 如何管理联机Redo日志组与成员? - 69 -
2.11.9 在Oracle中,如果联机Redo日志文件损坏,那么如何恢复? - 70 -
2.12 小测验 - 70 -
2.13 小结 - 71 -
第3章 实施Oracle DB审计 - 72 -
3.1 责任分离 - 73 -
3.2 数据库安全性 - 74 -
3.3 监视合规性 - 75 -
3.4 标准数据库审计 - 76 -
3.5 配置审计线索 - 78 -
3.6 统一审计线索 - 79 -
3.6.1 指定审计选项 - 80 -
3.7 默认审计 - 81 -
3.7.1 Enterprise Manager 审计页 - 82 -
3.7.2 使用和维护审计信息 - 83 -
3.7.3 基于值的审计 - 84 -
3.8 细粒度审计 - 86 -
3.8.1 FGA 策略 - 87 -
3.8.2 审计的 DML 语句: - 89 -
3.8.3 FGA 准则 - 90 -
3.9 SYSDBA审计 - 91 -
3.10 维护审计线索 - 92 -
3.11 Oracle Audit Vault - 93 -
3.12 麦苗扩展 - 94 -
3.12.1.1 什么是审计(Audit)? - 94 -
3.12.1.2 迁移SYS.AUD$表到其它表空间 - 95 -
3.12.1.3 审计如何分类 - 97 -
3.12.1.4 审计中BY ACCESS和BY SESSION的区别是什么? - 97 -
3.12.1.5 如何对SYSDBA和SYSOPER进行审计? - 97 -
3.12.1.6 什么是细粒度审计(精细化审计)? - 98 -
3.12.1.7 如何禁用或删除某个用户下的所有细粒度审计? - 100 -
3.12.1.8 FGA审计和标准审计有什么区别? - 100 -
3.13 小测验 - 101 -
3.14 小结 - 101 -
第4章 数据库维护(AWR、ASH、ADDM) - 102 -
4.1 数据库维护 - 103 -
4.2 查看预警历史记录 - 104 -
4.2.1 术语 - 105 -
4.3 Oracle 优化程序:概览 - 106 -
4.4 统计信息 - 107 -
4.4.1 优化程序统计信息 - 107 -
4.4.2 使用"管理优化程序统计信息"页 - 108 -
4.4.3 手动搜集优化程序统计信息 - 109 -
4.4.4 用于搜集统计信息的首选项 - 111 -
4.4.5 麦苗扩展 - 112 -
4.4.5.1 统计信息的简介和分类 - 112 -
4.4.5.2 索引统计信息 - 115 -
4.4.5.3 列的统计信息 - 115 -
4.4.5.4 系统统计信息 - 118 -
4.4.5.5 内部对象统计信息 - 120 -
4.4.5.6 自动收集统计信息 - 120 -
一、 统计信息何时变为陈旧状态(10%的含义)? - 122 -
二、 修改自动收集统计信息的时间 - 123 -
三、 DBA_TAB_MODIFICATIONS - 125 -
4.4.5.7 怎样收集表的统计信息?怎样收集分区表的统计信息? - 126 -
4.4.5.8 什么是动态采样(Dynamic Sampling)? - 126 -
4.4.5.9 如何锁住统计信息? - 130 -
4.4.5.10 什么是待定的统计信息(Pending Statistic)? - 132 -
4.4.5.11 什么是直方图(Histogram)? - 137 -
4.4.5.12 什么是多列统计信息(Extended Statistics)? - 151 -
4.4.5.13 基表COL_USAGE$的作用是什么? - 160 -
4.4.5.14 新建索引后统计信息是否自动收集? - 160 -
4.4.5.15 什么是基数反馈(Cardinality Feedback)? - 160 -
4.4.5.16 如何查询表和索引的历史统计信息 - 165 -
4.4.5.17 Oracle如何并发地收集统计信息? - 167 -
4.4.5.18 当收集表的统计信息时应该注意哪些问题? - 168 -
4.4.5.19 什么是基数(Cardinality)和可选择率(Selectivity)? - 170 -
4.4.5.20 使用SPLIT来拆分某个分区的时候,其拆分出来的新分区的统计信息行数是多少? - 177 -
4.4.5.21 当自动收集任务运行时,哪些对象会被收集? - 178 -
4.4.5.22 分区表统计信息的更新机制是怎样的? - 178 -
4.4.5.23 如何查询表的DML操作数据变化量? - 179 -
4.4.5.24 对表执行TRUNCATE操作会将表的统计信息也清除掉吗? - 181 -
4.5 自动工作量资料档案库 (AWR) - 182 -
4.5.1 AWR 基础结构 - 183 -
4.5.2 AWR 基线 - 184 -
4.5.3 Enterprise Manager 和 AWR - 185 -
4.5.4 管理 AWR - 186 -
4.5.5 统计级别 - 187 -
4.5.6 麦苗扩展 - 188 -
4.5.6.1 什么是AWR? - 188 -
4.5.6.2 如何获取AWR报告? - 189 -
一、 定时生成AWR报告 - 190 -
4.5.6.3 AWR报告中主要关注哪些方面内容? - 194 -
4.5.6.4 如何在AWR中查看每秒执行事务的个数? - 199 -
4.6 自动数据库诊断监视器 (ADDM) - 200 -
4.6.1 ADDM 查找结果 - 202 -
4.6.2 ADDM 建议 - 203 -
4.6.3 麦苗扩展 - 204 -
4.6.3.1 什么是ADDM? - 204 -
4.6.3.2 如何获取ADDM报告? - 205 -
4.7 ASH - 206 -
4.7.1 什么是ASH? - 206 -
4.7.2 如何获取ASH报告? - 207 -
4.7.3 如何查看过去某一段时间数据库系统的会话是否有问题? - 208 -
4.8 ASH、AWR、ADDM、AWRDDRPT、AWRSQRPT的比对 - 210 -
4.9 指导框架 - 212 -
4.9.1 Enterprise Manager 和指导 - 214 -
4.9.2 DBMS_ADVISOR程序包 - 215 -
4.10 小测验 - 215 -
4.11 自动维护任务 - 216 -
4.11.1 自动维护任务 - 216 -
4.11.2 自动维护任务配置 - 218 -
4.12 服务器生成的预警 - 219 -
4.12.1 设置阈值 - 220 -
4.12.2 创建和测试预警 - 221 -
4.12.3 预警通知 - 222 -
4.12.4 对预警作出响应 - 224 -
4.12.5 预警类型和清空预警 - 225 -
4.13 性能监视 - 226 -
4.13.1 Enterprise Manager 的性能页 - 227 -
4.13.2 细化到特定的等待类别 - 228 -
4.13.3 性能页:吞吐量 - 229 -
4.13.4 性能监视:顶级会话 - 230 -
4.13.5 性能监视:顶级服务 - 231 -
4.14 动态性能统计信息 - 232 -
4.15 故障排除和优化视图 - 233 -
4.16 无效和不可用对象 - 234 -
4.17 小测验 - 235 -
4.18 小结 - 236 -
第5章 JOB - 237 -
5.1 DBMS_JOB - 237 -
5.1.1 dbms_job package 用法介绍 - 241 -
5.1.1.1 DBMS_JOB包权限 - 242 -
5.1.1.2 DBMS_JOB后台进程 - 242 -
5.1.1.3 broken - 243 -
5.1.1.4 change - 244 -
5.1.1.5 interval - 244 -
5.1.1.6 isubmit - 244 -
5.1.1.7 next_date - 245 -
5.1.1.8 remove - 246 -
一、 杀job - 246 -
二、 删除其它用户下的job用 sys.dbms_ijob.remove() - 246 -
5.1.1.9 run - 251 -
5.1.1.10 submit - 252 -
5.1.1.11 user_export - 254 -
5.1.1.12 what - 254 -
一、 例子 - 255 -
5.1.2 RAC中指定dbms_job运行在指定实例 - 257 -
5.1.3 数据字典 - 259 -
5.1.4 OCP课堂 - 261 -
5.2 DBMS_SCHEDULER - 263 -
5.2.1 DBMS_JOB和DBMS_SCHEDULER之间的区别 - 264 -
5.2.2 各个组件(components) - 264 -
5.2.2.1 作业(job): - 264 -
5.2.2.2 时间表(schedule):--默认非禁用 - 264 -
5.2.2.3 程序(program): - 266 -
5.2.2.4 作业类(job_class): - 266 -
一、 管理JobClasses - 270 -
5.2.2.5 窗口(window): - 270 -
5.2.2.6 窗口组(window_group): - 272 -
5.2.3 参数设置 - 274 -
5.2.4 管理job - 278 -
5.2.4.1 启用Jobs - 278 -
5.2.4.2 禁用Jobs - 279 -
5.2.4.3 修改Jobs - 280 -
5.2.4.4 执行Jobs - 282 -
一、 dbms_scheduler.run_job报错 - 284 -
5.2.4.5 停止Jobs - 285 -
5.2.4.6 删除Jobs - 286 -
一、 批量删除job - 287 -
5.2.4.7 指定job的执行频率 - 288 -
5.2.5 创建job - 290 -
5.2.5.1 需要的权限 - 290 -
5.2.5.2 例子 - 291 -
5.2.5.3 通过dbms_scheduler去执行shell脚本 - 292 -
5.2.5.4 例子一 --- 不带参数 - 293 -
5.2.5.5 例子二 --- 带参数 - 295 -
5.2.5.6 含有参数 - 302 -
5.2.5.7 时间段内的job - 304 -
5.2.5.8 指定时间的一次性job - 305 -
5.2.5.9 批量创建job - 305 -
一、 创建job主进程 - 305 -
二、 创建job子进程 - 310 -
5.2.6 判断job是否正在运行 - 312 -
5.2.7 数据字典 - 312 -
5.2.8 Lightweight Jobs - 314 -
5.2.8.1 Persistent Lightweight Jobs - 320 -
5.2.9 OCP课堂 - 321 -
5.3 PL/SQL工具创建和管理job - 323 -
5.3.1 DBMS_JOB - 323 -
5.3.2 DBMS_SCHEDULER - 325 -
5.4 其它实用内容 - 325 -
5.4.1 RAC中如何指定JOB的运行实例? - 325 -
5.4.2 如何判断SCHEDULER JOB是否正在运行? - 328 -
5.4.3 如何查询SCHEDULER JOB的运行日志? - 329 -
5.4.4 通过DBMS_SCHEDULER如何调用SHELL脚本? - 330 -
5.4.5 如何批量删除JOB? - 330 -
5.4.6 已通知停止作业, 但是无法立即停止 - 331 -
5.5 OCP - 332 -
第6章 分区 - 333 -
6.1 分区表简介 - 334 -
6.2 分区表的一些限制条件 - 334 -
6.3 何时考虑分区? - 334 -
6.4 分区表有什么优点? - 334 -
6.5 有哪些类型的分区?如何选择用哪种类型的分区表? - 335 -
6.5.1 RANGE(范围)分区 - 335 -
6.5.2 HASH(哈希)分区 - 336 -
6.5.3 列表分区 - 338 -
6.5.4 复合分区 - 339 -
6.5.4.1 分区模板的应用 - 340 -
一、 分区模板数据字典 - 341 -
6.5.5 Interval分区 - 341 -
6.5.5.1 以月为间隔 - 342 -
6.5.5.2 以天为间隔 - 346 -
6.5.5.3 总结 - 350 -
6.5.5.4 interval分区重命名 - 353 -
一、 注意 - 357 -
6.5.6 System_partitioning - 357 -
6.5.6.1 Restrictions on System Partitioning - 358 -
6.5.6.2 Advantages of System Partitioned Tables - 359 -
6.5.6.3 Supporting Operations with System-Partitioned Tables - 361 -
6.6 分区表的维护 - 363 -
6.6.1 添加分区(add partition) - 364 -
6.6.2 收缩表分区(coalesce partitions) - 366 -
6.6.3 删除分区和删除子分区(drop partition) - 366 -
6.6.4 添加子分区 - 367 -
6.6.5 截断表分区(Truncate Partition)--截断一个分区表中的一个分区的数据 - 367 -
6.6.5.1 截断分区表的子分区 - 368 -
6.6.5.2 截断带有约束的分区表 - 368 -
6.6.5.3 注意事项 - 368 -
6.6.6 移动表分区(Move Partition) - 369 -
6.6.6.1 将一个表的分区从一个表空间移动到另一个表空间 - 370 -
6.6.6.2 压缩表Move--compress - 370 -
6.6.7 合并分区(Merge Partitions) - 371 -
6.6.8 重命名某一个分区(Rename Partition) - 374 -
6.6.9 交换表分区(Exchange Partitions) - 374 -
6.6.10 修改 list 表分区 - 378 -
6.6.10.1 修改 list 表分区--Add Values - 378 -
6.6.10.2 修改 list 表分区--Drop Values - 379 -
6.6.11 拆分表分区(Split Partition)--分区切割 - 380 -
6.6.12 修改分区表属性 - 382 -
6.6.12.1 修改表分区默认属性(Modify Default Attributes) - 382 -
6.6.12.2 修改表分区当前属性(Modify Partition) - 382 -
6.6.12.3 修改分区表的logging属性 - 383 -
6.6.12.4 并行度 - 383 -
6.6.13 修改表子分区模板(Set Subpartition Template) - 383 -
6.6.14 其它 - 385 -
6.7 分区表的查询优化 - 392 -
6.8 分区表常用数据字典视图有哪些? - 394 -
6.8.1 Oracle之INTERVAL分区的STORE IN属性存储在哪张表中? - 401 -
6.8.2 如何查询某个分区是否是INTERVAL分区表? - 402 -
6.9 分区表的压缩 - 402 -
6.9.1 分区表压缩 - 402 -
6.9.2 含有子分区的分区表压缩 - 403 -
6.9.3 分区表哪些分区被压缩了 - 403 -
6.9.4 总结 - 404 -
6.9.5 另一种办法:先置于compress状态后move - 404 -
6.9.6 解压缩 - 405 -
6.10 分区表单个分区分析(分区表收集统计信息) - 405 -
6.11 普通表转换为分区表有哪些办法? - 405 -
6.12 分区表查询 - 410 -
6.12.1 单分区查询 - 410 -
6.12.2 跨分区查询 - 411 -
6.13 分区表中lob类型的字段 - 412 -
6.14 分区表性能注意事项 - 412 -
6.15 索引失效的情况 - 420 -
6.16 OCP讲课 - 421 -
第7章 管理补丁程序 - 422 -
7.1 应用补丁程序版本 - 424 -
7.2 使用补丁程序指导 - 425 -
7.3 使用补丁程序向导 - 426 -
7.4 应用补丁程序 - 427 -
7.5 存放补丁程序 - 428 -
7.6 联机打补丁:概览 - 429 -
7.7 安装联机补丁程序 - 429 -
7.8 联机打补丁的优点 - 431 -
7.8.1 常规打补丁和联机打补丁 - 431 -
7.9 联机打补丁注意事项 - 432 -
7.10 麦苗扩展 - 433 -
7.10.1 PSU升级的过程 - 434 -
7.10.2 PSU(Patch Set Update)、CPU(Critical Patch Update)、BP(Bundle Patch)等概念 - 434 -
7.10.3 如何查找最新的PSU? - 435 -
7.10.4 如何确认当前数据库已经安装了什么PSU? - 435 -
7.10.5 如何安装PSU? - 436 -
7.10.6 Upgrade与Update - 437 -
7.10.7 注意问题 - 437 -
7.10.8 什么是Metalink或MOS? - 437 -
7.10.9 11.2.0.3.0升级到11.2.0.3.1 - 438 -
7.10.10 one-off patch - 439 -
7.10.11 一道OCM题 - 441 -
7.11 小测验 - 442 -
7.12 小结 - 442 -
第8章 使用技术支持(学员自行阅读) - 443 -
8.1 课程目标 - 443 -
8.2 使用支持工作台 - 443 -
8.3 在 Oracle Enterprise Manager 中查看严重错误预警 - 445 -
8.4 查看问题详细资料 - 446 -
8.4.1 查看意外事件详细资料:转储文件 - 447 -
8.4.2 查看意外事件详细资料:检查器查找结果 - 448 -
8.5 创建服务请求 - 449 -
8.6 将诊断数据打包并上载到 Oracle 技术支持 - 450 -
8.7 跟踪服务请求并实施修复 - 451 -
8.8 关闭意外事件和问题 - 453 -
8.9 意外事件打包配置 - 454 -
8.10 Enterprise Manager 针对 ASM 的支持工作台 - 456 -
8.11 使用 Oracle 技术支持 - 457 -
8.12 My Oracle Support 集成 - 458 -
8.12.1 使用 My Oracle Support - 459 -
8.13 调查问题 - 461 -
8.14 记录服务请求 - 463 -
8.15 小结 - 464 -
实验课
实验目录 - 11 -
第1章 数据泵之NETWORK_LINK - 11 -
1.1 博客地址 - 11 -
1.2 环境介绍 - 12 -
1.3 imp和exp简介 - 13 -
1.4 expdp不使用network_link - 15 -
1.5 expdp使用network_link - 18 -
1.5.1 目标数据库创建dblink - 18 -
1.5.2 client端或目标数据库执行 - 19 -
1.5.3 总结 - 21 -
1.6 impdp使用network_link - 21 -
1.6.1 目标数据库创建dblink - 21 -
1.6.2 client或目标端执行 - 22 -
1.6.3 总结 - 23 -
1.7 实验命令 - 23 -
第2章 Duplicating an Active Database(duplicate复制数据库) - 23 -
2.1 博客地址 - 23 -
1.1 duplicate体系结构 - 24 -
1.2 本次实验简介 - 25 -
1.3 本次实验原理 - 26 -
1.4 环境及搭建要求 - 26 -
1.4.1 对辅助数据库的要求 - 27 -
1.5 正式开始 - 28 -
1.5.1 duplicate database 设置 - 28 -
1.5.1.1 创建pfile 参数文件 - 28 -
1.5.1.2 创建密码文件 - 28 -
1.5.1.3 创建和source database的数据文件相关的目录结构 - 29 -
1.5.1.4 启动Auxiliary 到nomout 状态 - 29 -
1.5.2 在Target 和Auxiliary 都配置Oracle Net(Listener.ora and tnsnames.ora) - 30 -
1.5.2.1 测试网络是否配置好 - 33 -
1.5.3 开始RMAN duplicate from active database - 35 -
1.5.4 drop database - 41 -
2.2 OCP讲课(duplicate ACTIVE + ASM-->FS) - 42 -
1.5.5 duplicate database设置 - 42 -
1.5.5.1 创建pfile 参数文件 - 42 -
1.5.5.2 创建密码文件 - 43 -
1.5.5.3 创建和source database的数据文件相关的目录结构 - 43 -
1.5.5.4 启动Auxiliary到nomout状态 - 43 -
1.5.6 在Target和Auxiliary都配置Oracle Net(Listener.ora和tnsnames.ora) - 43 -
1.5.6.1 测试网络是否配置好 - 45 -
2.2.1 准备执行的RUN块 - 45 -
1.5.7 开始RMAN duplicate from active database - 46 -
2.2.2 测试一下dbid和dbname - 46 -
第3章 Duplicating a Database Without Recovery Catalog or Target Connection - 48 -
1.1 本次实验简介 - 48 -
1.2 环境及搭建要求 - 48 -
1.2.1 对辅助数据库的要求 - 48 -
1.3 正式开始 - 50 -
1.3.1 前期准备 - 50 -
1.3.1.1 建表 - 50 -
1.3.1.2 数据库归档模式 - 50 -
1.3.1.3 备份数据库 - 51 -
1.3.1.4 将备份内容拷贝到destination host - 55 -
1.3.1.5 创建pfile 参数文件 - 56 -
1.3.1.6 创建和source database的数据文件相关的目录结构 - 57 -
1.3.1.7 创建密码文件 - 58 -
1.3.2 实施数据库的复制 - 58 -
1.3.2.1 启动Auxiliary 到nomout 状态 - 58 -
1.3.2.2 连接到auxiliary instance并复制数据库 - 59 -
1.3.2.3 可能的报错 - 65 -
一、 fra满了 - 65 -
二、 备份位置 - 66 -
1.3.2.4 验证 - 66 -
1.3.3 drop database - 67 -
第4章 Duplicating a Database Without Recovery Catalog or Target Connection - 68 -
4.1 本次实验简介 - 68 -
4.2 本次实验原理图 - 69 -
4.3 环境及搭建要求 - 69 -
4.3.1 source database环境 - 69 -
4.3.2 对辅助数据库的要求 - 70 -
4.4 正式开始 - 71 -
4.4.1 前期准备 - 71 -
4.4.1.1 建表 - 71 -
4.4.1.2 数据库归档模式 - 73 -
4.4.1.3 备份数据库 - 74 -
4.4.1.4 将备份内容拷贝到destination host - 77 -
4.4.1.5 创建pfile 参数文件 - 77 -
4.4.1.6 创建和source database的数据文件相关的目录结构 - 78 -
4.4.1.7 创建密码文件 - 80 -
4.4.2 实施数据库的复制 - 81 -
4.4.2.1 启动Auxiliary 到nomout 状态 - 81 -
4.4.2.2 连接到auxiliary instance并复制数据库 - 83 -
一、 告警日志 - 93 -
4.4.2.3 可能的报错 - 119 -
二、 fra满了 - 119 -
三、 备份位置 - 120 -
1.1.1.2 验证 - 121 -
4.4.3 drop database - 122 -
第5章 TSPITR(表空间基于时间点恢复) - 124 -
5.1 博客地址 - 124 -
5.2 BLOG文档结构图 - 125 -
5.3 前言部分 - 125 -
5.3.1 导读 - 125 -
5.3.2 实验环境介绍 - 126 -
5.3.3 本文简介 - 126 -
5.4 TSPITR的相关知识点归纳 - 127 -
5.4.1 TSPITR简介 - 127 -
5.4.2 何时使用TSPITR - 127 -
5.5 实验部分 - 128 -
5.5.1 源库做备份操作 - 128 -
5.5.2 建立测试表并做truncate误操作 - 131 -
5.5.3 采用logminer找回误删除的时间点 - 133 -
5.5.4 执行TSPITR之前的检查 - 133 -
5.5.4.1 检查是否自包含 - 133 -
5.5.4.2 检查哪些对象执行TSPITR后将被删除 - 134 -
5.5.5 执行TSPITR - 135 -
5.5.6 online表空间并且导入丢失的对象 - 140 -
5.6 与TSPITR有关的OCP试题部分 - 142 -
5.7 总结 - 146 -
5.8 实验脚本 - 149 -
5.9 RMAN系列参考文章 - 151 -
第6章 直接复制数据文件实现linux平台数据库复制到windows平台数据库 - 152 -
6.1 平台环境概述 - 152 -
6.2 查看字节序 - 152 -
6.3 linux 下操作 - 154 -
6.3.1 linux下生成pfile和control file - 154 -
6.3.2 把linux上/u01/app/oracle/oradata/rman下的数据文件、重做日志文件、归档文件,还有刚才创建的pfile和控制文件及listener.ora、tnsnames.ora文件复制到windows平台上 - 155 -
6.4 windows 下操作 - 155 -
6.4.1 创建一个rman的实例,注意SID要与linux服务器中的相同 - 155 -
6.4.2 修改初始化参数文件,并创建相关目录 - 156 -
6.4.3 创建spfile并启动到nomount状态 - 157 -
6.4.4 将相应的数据文件拷贝到相关的目录然后重建控制文件(也别忘了更改文件路径) - 158 -
6.4.5 打开数据库并添加临时表空间数据文件 - 160 -
6.4.6 由于是64位到32位操作系统,所以需要编译一下内核代码 - 160 -
6.4.7 其它配置工作 - 163 -
6.4.8 测试OK - 163 -
6.4.9 删除数据库做其它测试 - 164 -
第7章 利用rman来实现linux平台数据库复制到windows平台数据库 - 165 -
7.1 平台环境概述 - 165 -
7.2 本次实验简介 - 165 -
7.3 本次实验原理图 - 165 -
7.4 查看字节序 - 165 -
7.5 source database 归档模式 - 167 -
7.6 linux 下操作 - 167 -
7.6.1 建表 - 167 -
7.6.2 rman备份 - 168 -
7.6.3 linux下生成pfile - 173 -
7.6.4 把linux上/home/oracle/oracle_bk/rman/下的所有备份文件复制到windows平台上 - 174 -
7.7 windows 下操作 - 174 -
7.7.1 创建一个rman的实例,注意SID要与linux服务器中的相同 - 174 -
7.7.2 修改初始化参数文件,并创建相关目录 - 175 -
7.7.3 创建spfile并启动到nomount状态 - 176 -
7.7.4 rman 进行数据文件的恢复 - 177 -
7.7.5 由于是64位到32位操作系统,所以需要编译一下内核代码 - 185 -
7.7.6 其它配置工作 - 188 -
7.7.7 测试OK - 188 -
7.7.8 删除数据库做其它测试 - 189 -
第8章 热备下的测试库搭建 - 190 -
8.1 基础知识 - 190 -
8.2 本次实验环境简介 - 190 -
8.3 源库生成热备份文件 - 190 -
8.4 传输备份文件到target库 - 194 -
8.4.1 传输数据文件 - 194 -
8.4.2 传输归档文件 - 194 -
8.5 修改target库的pfile文件并生成pfile文件中的路径 - 195 -
8.6 启动target数据库到nomount状态 - 196 -
8.7 开始创建控制文件 - 196 -
8.7.1 第一步,首先移动相应的数据文件到相应的控制文件记录的目录中 - 197 -
8.7.2 第二步,重新创建控制文件,控制文件创建完成后自动mount - 197 -
8.8 用rman注册一下 - 198 -
8.9 recover到指定的scn - 201 -
8.10 重建临时表空间并配置密码文件以及 TNS 和密码文件等 - 201 -
第9章 传输表空间(TTS)一例(linux asm -> win 文件系统) - 202 -
9.1 场景描述 - 202 -
9.2 环境准备 - 202 -
9.2.1 在源库上创建3个用户应用的表空间 - 202 -
9.2.2 在相应的表空间创建表和索引 - 203 -
9.3 判断平台支持并确定字节序 - 204 -
9.3.1 在源平台查询 - 204 -
9.3.2 在目标平台查询 - 204 -
9.4 选择自包含的表空间集(目前要传输app1tbs和idxtbs这2个表空间) - 205 -
9.4.1 进行检查 - 205 -
9.4.2 查看检查结果 - 205 -
9.5 产生可传输表空间集 - 206 -
9.5.1 使自包含的表空间集中的所有表空间变为只读状态 - 206 -
9.5.2 使用数据泵导出工具,导出要传输的各个表空间的元数据 - 206 -
9.5.2.1 确定导出目录 - 206 -
9.5.2.2 开始导出 - 207 -
9.5.3 生成数据文件 - 208 -
9.6 还原源库中的表空间为读/写模式 - 209 -
9.7 传输文件 - 210 -
9.7.1 传输转储元文件到目标库 - 210 -
9.7.2 查看目标库数据文件位置和目录 - 210 -
9.7.3 拷贝文件到目标库相应位置 - 210 -
9.8 开始导入 - 211 -
9.8.1 生成parfile文件 - 211 -
9.8.2 开始导入 - 211 -
9.8.3 查看目标平台信息 - 212 -
9.9 修改表空间对应的文件名 - 214 -
9.10 结束语 - 216 -
第10章 传输表空间(TTS)一例(win文件系统 -> linux asm ) - 216 -
10.1 场景描述 - 216 -
10.2 环境准备 - 217 -
10.2.1 在源库上创建3个用户应用的表空间 - 217 -
10.2.2 在相应的表空间创建表和索引 - 218 -
10.3 判断平台支持并确定字节序 - 219 -
10.3.1 在源平台查询 - 219 -
10.3.2 在目标平台查询 - 219 -
10.4 选择自包含的表空间集(目前要传输app1tbs和idxtbs这2个表空间) - 220 -
10.4.1 进行检查 - 220 -
10.4.2 查看检查结果 - 220 -
10.5 产生可传输表空间集 - 221 -
10.5.1 使自包含的表空间集中的所有表空间变为只读状态 - 221 -
10.5.2 使用数据泵导出工具,导出要传输的各个表空间的元数据 - 221 -
10.5.2.1 确定导出目录 - 221 -
10.5.2.2 开始导出 - 222 -
10.5.3 将数据文件拷贝到dpdump目录下 - 222 -
10.6 还原源库中的表空间为读/写模式 - 223 -
10.7 传输文件 - 223 -
10.7.1 利用ftp工具传输转储元文件到目标库 - 223 -
10.7.2 查看目标库数据文件位置和导入目录 - 223 -
10.7.3 拷贝文件到目标库相应位置并修改文件权限 - 224 -
10.8 开始导入 - 225 -
10.8.1 生成parfile文件 - 225 -
10.8.2 开始导入 - 225 -
10.8.3 查看目标平台信息 - 226 -
10.9 修改表空间对应的文件名 - 228 -
第11章 传输表空间(TTS)一例(AIX asm -> linux asm ) - 232 -
11.1 场景描述 - 232 -
11.2 环境准备 - 234 -
11.2.1 在源库上创建3个用户应用的表空间,并在相应的表空间创建表和索引 - 234 -
11.3 判断平台支持并确定字节序 - 236 -
11.4 选择自包含的表空间集 - 236 -
11.4.1 进行检查 - 236 -
11.5 产生可传输表空间集 - 237 -
11.5.1 使自包含的表空间集中的所有表空间变为只读状态 - 237 -
11.5.2 使用数据泵导出工具,导出要传输的各个表空间的元数据 - 238 -
11.5.2.1 确定导出目录 - 238 -
11.5.2.2 开始导出 - 239 -
一、 在source端转换(转换字节序可以在sorce端进行也可以在target端进行,我们选择在target端,这个步骤不执行) - 240 -
11.6 还原源库中的表空间为读/写模式 - 242 -
11.7 传输文件 - 243 -
11.7.1 查看目标库数据文件位置和导入目录 - 243 -
11.7.2 利用ftp工具传输转储元文件到目标库DATA_PUMP_DIR目录并修改权限 - 244 -
11.8 开始导入 - 245 -
11.8.1 转换字节序(转换字节序可以在sorce端进行也可以在target端进行,我们选择在target端执行) - 245 -
11.8.2 创建source库的2个用户并赋权限 - 246 -
11.8.3 开始导入 - 247 -
11.8.4 查看目标平台信息 - 247 -
第12章 传输表空间(TTS)一例(linux asm -> AIX asm) - 250 -
12.1 场景描述 - 250 -
12.2 环境准备 - 252 -
12.2.1 在源库上创建3个用户应用的表空间 - 252 -
12.2.2 在相应的表空间创建表和索引 - 253 -
12.3 判断平台支持并确定字节序 - 254 -
12.3.1 在源平台查询 - 254 -
12.3.2 在目标平台查询 - 254 -
12.4 选择自包含的表空间集 - 255 -
12.4.1 进行检查 - 255 -
12.4.2 查看检查结果 - 255 -
12.5 产生可传输表空间集 - 256 -
12.5.1 使自包含的表空间集中的所有表空间变为只读状态 - 256 -
12.5.2 使用数据泵导出工具,导出要传输的各个表空间的元数据 - 256 -
12.5.2.1 确定导出目录 - 256 -
12.5.2.2 开始导出 - 257 -
12.5.3 生成数据文件 - 258 -
12.5.3.1 在source端转换字节序(也可以在target端转换字节序,我们选择在target端转换) - 260 -
12.6 还原源库中的表空间为读/写模式 - 263 -
12.7 传输文件 - 263 -
12.7.1 传输转储元文件到目标库 - 263 -
12.7.2 查看目标库数据文件位置和目录 - 264 -
12.7.3 拷贝文件到目标库相应位置并修改权限 - 264 -
12.8 target端转换字节序 - 265 -
12.9 开始导入 - 266 -
12.9.1 创建source库的2个用户并赋权限 - 266 -
12.9.2 开始导入 - 267 -
12.9.3 查看目标平台信息 - 268 -
12.10 查看导入后结果 - 270 -
第13章 传输表空间(TTS)一例(linux asm -> AIX asm)--基于RMAN备份 - 271 -
13.1 场景描述 - 271 -
13.2 环境准备 - 272 -
13.2.1 在源库上创建3个用户应用的表空间 - 272 -
13.2.2 在相应的表空间创建表和索引 - 274 -
13.3 判断平台支持并确定字节序 - 274 -
13.3.1 在源平台查询 - 274 -
13.3.2 在目标平台查询 - 275 -
13.4 选择自包含的表空间集 - 276 -
13.4.1 进行检查 - 276 -
13.4.2 查看检查结果 - 276 -
13.5 产生可传输表空间集 - 277 -
13.5.1 rman全备份 - 277 -
13.5.2 生成结果集 - 280 -
13.6 传输文件 - 286 -
13.6.1 查看目标库数据文件位置和目录 - 286 -
13.6.2 拷贝文件到目标库相应位置并修改权限 - 287 -
13.7 target端转换字节序 - 287 -
13.8 target端开始导入数据 - 289 -
13.8.1 创建source库的2个用户并赋权限 - 289 -
13.8.2 开始导入 - 290 -
13.8.3 查看目标平台信息 - 290 -
13.9 查看导入后结果 - 291 -
第14章 传输表空间(TTS)一例(AIX asm -> linux asm )--基于RMAN - 293 -
14.1 场景描述 - 293 -
14.2 环境准备 - 294 -
14.2.1 在源库上创建3个用户应用的表空间,并在相应的表空间创建表和索引 - 294 -
14.3 判断平台支持并确定字节序 - 296 -
14.4 选择自包含的表空间集 - 297 -
14.4.1 进行检查 - 297 -
14.5 产生可传输表空间集 - 298 -
14.5.1 rman备份source库 - 298 -
14.5.2 transport tablespace 生成文件 - 300 -
14.6 传输文件到target端 - 305 -
14.6.1 查看目标库数据文件位置和导入目录 - 305 -
14.6.2 拷贝文件到目标库相应位置并修改文件权限 - 306 -
14.7 target端转换字节序 - 307 -
14.8 开始导入 - 307 -
14.8.1 创建source库的2个用户并赋权限 - 308 -
14.8.2 开始导入 - 308 -
14.8.3 查看目标平台信息 - 309 -
第15章 AIX平台数据库迁移到Linux--基于RMAN(真实环境) - 312 -
15.1 场景描述 - 312 -
15.2 源库信息收集 - 314 -
15.2.1 先跑一下健康检查(可选) - 314 -
15.2.2 表空间及数据文件情况 - 315 -
15.2.2.1 表空间大小 - 315 -
15.2.2.2 需要传输的数据文件大小 - 318 -
15.2.3 用户情况(密码、默认表空间、角色和权限,需迁移的schema对象大小、个数、列表) - 318 -
15.2.3.1 需要迁移的用户 - 318 -
15.2.3.2 用户权限 - 319 -
15.2.3.3 用户表大小 - 321 -
15.2.3.4 对象个数 - 322 -
15.2.3.5 对象详细信息 - 322 -
15.2.4 无效对象情况 - 326 -
15.2.5 索引情况 - 327 -
15.2.6 确定是否有业务数据、脚本在例如sys用户等的默认用户下 - 327 -
15.3 判断平台支持并确定字节序 - 327 -
15.4 判断表空间集是否自包含 - 328 -
15.5 产生可传输表空间集 - 329 -
15.5.1 rman备份source库 - 329 -
15.5.2 transport tablespace 生成文件 - 331 -
15.6 传输文件到target端 - 339 -
15.6.1 dbca创建target库 - 339 -
15.6.2 查看目标库数据文件位置和导入目录 - 340 -
15.6.3 利用ftp工具传输转储元文件到目标库 - 341 -
15.6.4 拷贝文件到目标库相应位置并修改文件权限 - 341 -
15.7 target端转换字节序 - 342 -
15.8 开始导入 - 344 -
15.8.1 创建source库的需要迁移的3个用户并赋权限(前边的脚本已经生成,直接拿过来执行) - 344 -
15.8.2 开始导入 - 345 -
15.8.2.1 报错:source和target的compatible参数不同引起ora-00721错误 - 346 -
15.8.3 查看目标平台信息 - 347 -
15.9 导入完成后的结果校验 - 348 -
15.9.1 校验用户情况(密码、默认表空间、角色和权限,需迁移的schema对象大小、个数、列表) - 348 -
15.9.1.1 校验用户 - 348 -
15.9.1.2 用户对象个数 - 349 -
15.9.1.3 对象详细信息 - 350 -
15.9.2 无效对象情况 - 353 -
15.9.3 索引情况 - 354 -
15.10 迁移后续收尾工作 - 354 -
15.11 TTS总结 - 354 -
第16章 只存在备份片的数据库恢复过程 - 354 -
16.1.1 原库备份并传输到测试库 - 355 -
16.1.2 测试库编辑pfile文件 - 359 -
16.1.3 备份集中含有控制文件备份的情况下的恢复--尝试法找回控制文件 - 359 -
16.1.3.1 方法一:采用dbms_backup_restore.restoreControlfileTo从备份片中来尝试找回控制文件 - 360 -
一、 启动数据库到mount状态 - 367 -
二、 重新注册备份集,还原spfile,还原数据库,不完全恢复数据库 - 368 -
16.1.3.2 方法二:尝试采用创建临时库来找回控制文件 - 374 -
一、 搭建临时库来注册备份集 - 374 -
1、 修改dbname和dbid - 377 -
2、 重新注册 - 379 -
二、 还原操作 - 381 -
1、 还原spfile - 381 -
2、 还原控制文件 - 381 -
3、 还原database - 381 -
16.1.3.3 方法三:直接通过restore命令尝试 - 400 -
16.1.3.4 采用os系统命令strings来判断 - 402 -
一、 判断备份集是否含有spfile - 403 -
二、 判断备份集中是否含有control file - 405 -
16.1.4 备份集中无控制文件情况下的数据库恢复--重建控制文件 - 405 -
16.1.5 总结 - 418 -
About Me
.............................................................................................................................................
● 本文作者:小麦苗,部分内容整理自网络,若有侵权请联系小麦苗删除
● 本文在itpub(http://blog.itpub.net/26736162/abstract/1/)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/
● 本文博客园地址:http://www.cnblogs.com/lhrbest
● 本文pdf版、个人简介及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/
● DBA宝典今日头条号地址:http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826
.............................................................................................................................................
● QQ群号:230161599(满)、618766405
● 微信群:可加我微信,我拉大家进群,非诚勿扰
● 联系我请加QQ好友(646634621),注明添加缘由
● 于 2018-03-01 06:00 ~ 2018-03-31 24:00 在魔都完成
● 最新修改时间:2018-03-01 06:00 ~ 2018-03-31 24:00
● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
.............................................................................................................................................
● 小麦苗的微店:https://weidian.com/s/793741433?wfr=c&ifr=shopdetail
● 小麦苗出版的数据库类丛书:http://blog.itpub.net/26736162/viewspace-2142121/
● 小麦苗OCP、OCM、高可用网络班:http://blog.itpub.net/26736162/viewspace-2148098/
.............................................................................................................................................
使用微信客户端扫描下面的二维码来关注小麦苗的微信公众号(xiaomaimiaolhr)及QQ群(DBA宝典),学习最实用的数据库技术。
小麦苗的微信公众号 小麦苗的DBA宝典QQ群2 《DBA笔试面试宝典》读者群 小麦苗的微店
.............................................................................................................................................
dba学习
第一章:数据库的启动和关闭
oracle server 由instance和database组成。
instance是一组后台进程/线程和一块共享内存区域。
database是存储在磁盘上的一组物理文件。
1.1 数据库的启动
启动的3个步骤:nomount、mount、open
1.1.1 启动数据库到nomount状态
oracle首先找到参数文件(spfile/pfile),根据参数文件中的设置创建实例,分配内存,启动后台进程。
这一步不需要控制文件和数据文件的参与。如果出现问题,肯定是内核参数(需要检查参数文件和系统配置)。
C:/> lsnrctl start --启动数据库监听程序
C:/> sqlplus /nolog --启动sqlplus
sql> conn sys/orcl as sysdba; --用管理员登录。 windows系统提示 "ora-12560: TNS: 协议适配器错误"
解决ORA-12560: TNS: 协议适配器错误,与大家共享
今天遭遇ORA-12560: TNS: 协议适配器错误的问题,经过一番努力问题已经解决,与大家共享。
造成ORA-12560: TNS: 协议适配器错误的问题的原因有三个:
1.监听服务没有起起来。windows平台个一如下操作:开始---程序---管理工具---服务,打开服务面板,启动oraclehome92TNSlistener服务。
2.database instance没有起起来。windows平台如下操作:开始---程序---管理工具---服务,打开服务面板,启动oracleserviceXXXX,XXXX就是你的database SID.
3.注册表问题。regedit,然后进入HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOME0将该环境变量ORACLE_SID设置为XXXX,XXXX就是你的database SID.或者右几我的电脑,属性--高级--环境变量---系统变量--新建
,变量名=oracle_sid,变量值=XXXX,XXXX就是你的database SID.或者进入sqlplus前,在command line下输set oracle_sid=XXXX,XXXX就是你的database SID.
经过以上步骤,就可以解决问题。
意思就是说:必须要在服务里启动oracleserviceXXXX,才能在在命令行中conn sys,这样在命令行中启动数据库就没有意义了。
sql> $net start oracleserviceorcl; --通过该命令启动数据库服务
sql> $net stop oracleserviceorcl; --通过该命令启动数据库服务
sql> startup nomount; --启动到nomount状态,使用参数文件spfile<sid>,输出警报日志alert_<sid>.log 可用视图:v$parameter
oracle选择参数文件的顺序:
首选spfile<sid>.ora,其次选择spfile.ora,最后选择init<sid>.ora,如果上述3个文件都不存在,oracle将无法启动。
show parameter命令:
show parameter 参数名; --返回参数名称、类型、参数值
例如:show parameter spfile; --从返回值可知使用的是spfile<sid>.ora文件。
show parameter dump_dest; --日志文件路径
show parameter control_files; --控制文件路径
参数文件中最少的参数是db_name,设置该参数后实例就可启动。Linux/UNIX下:
[]$ export ORACLE_SID=test --指定(创建)实例
[]$ sqlplus "/ as sysdba"
sql> startup nomount; --找不到参数文件
sql>! echo "db_name=test">/opt/oracle/product/9.2.0/dbs/inittest.ora
sql> startup nomount; --实例启动
1.1.2 启动数据库到mount状态
启动到nomount后,根据参数文件可找到控制文件,
alter database mount; --使用参数文件找到控制文件controlfile 可用视图:v$controlfile
oracle锁定控制文件,开始启动Heartbeat(心跳),每3秒更新一次控制文件。
alter session set events 'immediate trace name controlf level 10'; --每隔3秒转储2次控制文件信息
查询Heartbeat的值:select cphbt from x$kcccp;
等待事件control file heartbeat, select event#,name from v$event_name where name like '%heart%';
口令文件:$oracle_home/dbs/orapw<sid> 只找到orapw.exe可执行文件。
与口令相关的参数:select * from v$parameter where name='remote_login_passwordfile';
1.1.3 启动数据库到open状态
控制文件中记录了数据文件、日志文件、检查点信息,open数据库时包括两次检查,
第一次检查数据文件头中的检查点计数(checkpoint cnt)是否和控制文件中的检查点计数(checkpoint cnt)一致。用于确认数据文件是否来自同一版本。
检查点计数(checkpoint cnt)的作用:
alter session set events 'immediate trace name controlf level 10';--转储正常状态下的控制文件
alter tablespace system begin backup; --将system表空间置于热备份状态(热备份状态会冻结表空间数据文件的检查点),checkpoint加1
alter session set events 'immediate trace name controlf level 10';--再转储控制文件
alter system checkpoint; --手工执行检查点,checkpoint加1,SCN不变
alter session set events 'immediate trace name controlf level 10';--再转储控制文件
alter tablespace system end backup; --结束system表空间的热备份状态,checkpoint加1,SCN随之变化
alter session set events 'immediate trace name controlf level 10';--再转储控制文件
第二次检查数据文件头的开始SCN和控制文件中记录的该文件的结束SCN是否一致。
对每个数据文件都完成检查后,打开数据库,锁定数据文件,同时将每个数据文件的结束SCN设置为无穷大。
alter database open; --使用控制文件找到数据文件、日志文件、检查点信息,检查数据文件头中checkpoint cnt/system change number SCN是否与控制文件中的一致
shutdown immediate; --关闭数据库
startup force; --重启
1.2 进阶内容
1.2.1 SCN(system change number)系统改变号
SCN用于标识数据库在某个确切时刻提交的版本。事务提交时被赋予标识事务的scn,可作为内部时钟机制,全局唯一。
scn常见于事务表、控制文件、数据文件头、日志文件、数据块头等。
SCN的获取方式:
select dbms_flashback.get_system_change_number from dual; --9i之后
select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe; --9i之前
SCN的进一步说明:
SCN在事务提交或回滚是改变,在控制文件、数据文件头、数据块、日志文件头、日志文件change vector中的SCN作用各不相同。
数据文件头中包含了该数据文件的checkpoint SCN,表示该数据文件最近一次执行检查点操作时的SCN。
日志文件头中包含了Low SCN 和Next SCN,只日志文件包含介于Low SCN到Next SCN的重做信息,当前日志文件(redo logfile)Next SCN为无穷大。
select * from v$log;--查看日志文件
select dbms_flashback.get_system_change_number from dual; --获取SCN
alter system switch logfile; --切换日志文件
select * from v$log;--查看日志文件
控制文件的转储,不清楚有什么功能???
select * from v$logfile;--查看dump日志文件
alter system dump logfile 'C:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/REDO02.LOG';
1.2.2 检查点(Checkpoint)
检查点用于减少崩溃恢复(Cresh Recovery)时间。
修改数据时将数据读入内存,在内存中修改,记录重做(redo)信息,只有在提交时才将数据写回磁盘。redo可用于断电后,重启数据库时进行事务的重演(前滚操作),再对未提交的事务进行回滚。
检查点就是为了缩短前滚时间的。
当检查点发生时,oracle启用DBWR进程把修改过的数据写入磁盘,写完之后启用CKPT进程更新控制文件和数据文件头,记录检查点信息,标识已更改。
checkpoint scn查询
select file#,name,checkpoint_change#,to_char(checkpoint_time,'yyyy-mm-dd hh24:mi:ss') cpt from v$datafile;
select dbid,checkpoint_change# from v$database;
常规检查点与增量检查点
常规检查点(Conventional Checkpoint):oracle8之前的检查点,触发条件有log_checkpoint_interval、log_checkpoint_timeout参数设置及log switch等条件触发。
增量检查点(Incremental Checkpoint):oracle8之后引入的检查点队列(Checkpoint Queue)机制,每条脏数据被移动到检查点队列,按照Low RBA(redo byte address)的顺序排列,
当执行检查点时,DBWR从检查点队列按Low RBA顺序写出,ckpt进程更新将当前最低RBA写入控制文件。
增量检查点可以连续进行,检查点RBA更接近数据库最后的状态,可以减少恢复时间;DBWR可以持续写出,避免了常规检查点写出时的I/O征用。
select * from v$version;--版本信息
select * from v$option where parameter='Fast-Start Fault Recovery';
增量检查点组件(Fast-Start Fault Recovery)特性:
Fast-Start Checkpointing特性:参数fast_start_io_target(8i)/fast_start_mttr_target(9i)
Fast-Start On-Demand Rollback特性:
Fast-Start Paraller Rollback特性:
fast_start_mttr_target参数:定义数据库进行Crash恢复的时间,范围在0~3600s之间。
select * from v$parameter where name in ('fast_start_mttr_target','fast_start_io_target','log_checkpoint_interval','log_checkpoint_timeout');
建议用参数fast_start_mttr_target替换fast_start_io_target、log_checkpoint_interval、log_checkpoint_timeout
v$mttr_target_advice视图:select * from v$mttr_target_advice; --用于评估在不同的fast_start_mttr_target参数设置下,执行I/O的次数。
statistics_level参数:show parameter statistics_level;参数设置为typical或者all
v$statistics_level视图:select * from v$statistics_level where STATISTICS_NAME='MTTR Advice';
v$instance_recovery实例恢复状态视图:
select recovery_estimated_ios reio,actual_redo_blks arb,target_redo_blks trb,log_file_size_redo_blks lfsrb,log_chkpt_timeout_redo_blks lctrb,
log_chkpt_interval_redo_blks lcirb,fast_start_io_target_redo_blks fsiotrb,target_mttr "期望回复时间",estimated_mttr "平均回复时间",ckpt_block_writes "检查点已经写出的数据块的数量"
from v$instance_recovery;
一个例子:
执行查询,发现estimated_mttr>target_mttr ,estimated_mttr仍有上升趋势
select recovery_estimated_ios reio,actual_redo_blks arb,target_redo_blks trb,log_file_size_redo_blks lfsrb,log_chkpt_timeout_redo_blks lctrb,
log_chkpt_interval_redo_blks lcirb,fast_start_io_target_redo_blks fsiotrb,target_mttr "期望回复时间",estimated_mttr "平均回复时间",ckpt_block_writes "检查点已经写出的数据块的数量"
from v$instance_recovery;
查询等待事件:发现checkpoint incomplete等待
select sid,seq#,event from v$session_wait;
查询v$log视图:发现除当前组外,其余组处于active状态
select * from v$log;
通过os查看iostat状态信息,发现系统swap严重(si,sw),cpu等待io(wa)高:# vmstat 2
oracle 10g 自动检查点调整:
当fast_start_mttr_target参数未设置时,自动检查点调整生效。
v$instance_recovery实例恢复状态视图:
select recovery_estimated_ios reios,target_mttr "期望回复时间",estimated_mttr "平均回复时间",
writes_mttr wmttr,writes_other_settings woset,ckpt_block_writes "检查点已经写出的数据块的数量",
writes_autotune "自动调整检查点执行的写出次数",writes_full_thread_ckpt wftckpt
from v$instance_recovery;
从控制文件获取检查点信息:
在控制文件的转储中,可以看到关于检查点进程进度的记录.
low cache rba(recovery block address)指在Cache中,最低的RBA地址,在实例恢复或崩溃恢复中,从这里开始恢复。
on disk rba 是磁盘上的最高的重做值,在进行恢复时应用重做至少要达到这个值。
1.2.3 正常关闭数据库的状况
第二章 参数及参数文件 p62
2.1 初始化参数的分类
2.1.1 推导参数Derived Parameters
由其他参数计算得出,不需要设置。如:sessions=(1.1×processses)+5
2.1.2 操作系统依赖参数
受操作系统的限制。如:db_cache_size
2.1.3 可变参数
可以调整的参数。如:open_cursors
注:又可分为{静态参数、动态参数}、{显示参数、隐含参数} 显示参数在V$parameter视图中
2.1.4 初始化参数的获取
--获取显示参数
select * from v$parameter;
--获取隐含参数
select x.ksppinm name,y.ksppstvl value,y.ksppstdf isdefault,
decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM MOD','FALSE') ismod,
decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj
from sys.x$ksppi x,sys.x$ksppcv y
where x.inst_id=userenv('Instance') and y.inst_id=userenv('Instance') and
x.indx=y.indx and x.ksppinm like '%_&par%' order by translate(x.ksppinm,'_','');
2.2 参数文件
9i之前初始化参数文件,pfile文本文件。通过手工修改,实例重启后生效。
9i之后服务器参数文件,spfile二进制文件。通过alter system/alter session修改,动态参数立即生效,静态参数重启后生效。可以用RMAN备份。
2.2.1 创建数据库脚本
c:/oracle/product/10.2.0/admin/orcl2/scripts 数据库创建脚本
2.2.2 spfile的创建:
create spfile[='spfile路径及名称'] from pfile[='pfile路径及名称']; --需要sysdba权限
视图:v$spparameter
alter system set db_cache_size=24M scope=both/spfile;--设置参数
host rename spfileorcl.ora.bak spfileorcl.ora; --更名
2.2.3 spfile的搜索顺序
spfile<ORACLE_SID>.ora 目录 UNIX:$ORACLE_HOME/dbs/ NT:%ORACLE_HOME%/database C:/oracle/product/10.2.0/db_1/dbs/spfileorcl.ora
spfile.ora 目录 UNIX:$ORACLE_HOME/dbs/ NT:%ORACLE_HOME%/database C:/oracle/product/10.2.0/admin/orcl/pfile/init.ora.310201120914
init<ORACLE_SID>.ora 目录 UNIX:$ORACLE_HOME/dbs/ NT:%ORACLE_HOME%/database C:/oracle/product/10.2.0/db_1/database/initorcl.ora
2.2.4 使用pfile/spfile 启动数据库
sql> startup pfile='C:/oracle/product/10.2.0/db_1/database/initorcl.ora'; 在winxp上成功。
SQL> alter system set log_archive_start=true scope=spfile;
SQL> alter system set log_archive_start=false scope=spfile;
通过在pfile中调用spfile,使用后设置的参数覆盖spfile中的参数设置,是解决spfile中参数设置错误的一种方法。
2.2.5 修改参数 alter system
alter system命令的scope参数有三种取值:
memory:只改变当前实例,重启db后失效;spfile:只改变spfile的设置,不改变当前实例,重启db后生效;both:即改变当前实例,也改变spfile的设置,重启db后仍然有效。
alter system set db_cache_advice=off scope=memory; 重启startup force;后失效。
alter system set db_cache_advice=off scope=spfile; 重启startup force;后生效。静态参数只能指定scope=spfile进行修改。
alter system set db_cache_advice=on scope=spfile; 对当前实例无效,但可以通过v$spparameter试图查询。
alter system set db_cache_advice=on scope=both; 默认设置,与不加scope参数效果一致。
rac环境中的修改:
不指定SID名称,或者指定位“*”,对所有实例生效。alter system set open_cursors=500 SID='*' scope=memory;
指定SID参数,仅对指定的实例生效。alter system set open_cursors=150 scope=spfile sid='orcl';
通过:select sid,name,value from v$spparameter where name='×××'/'undo_tablespace';查询,对于非数值等值,修改时务必加上sid参数。
在关闭数据库状态修改spfile:
alter system set db_block_buffers=1000 scope=spfile; --错误的修改了参数
shutdown immediate; --停掉数据库
create pfile from spfile; 如:create pfile='C:/oracle/product/10.2.0/db_1/dbs/PFILEORCL.ORA' from spfile='C:/oracle/product/10.2.0/db_1/dbs/SPFILEORCL.ORA';
--将spfile复制到pfile,在pfile进行修改
connect sys/orcl as sysdba; --连接数据库
create spfile from pfile; 如:create spfile='C:/oracle/product/10.2.0/db_1/dbs/SPFILEORCL.ORA' from pfile='C:/oracle/product/10.2.0/db_1/dbs/PFILEORCL.ORA';
startup; --将修改後的pfile复制到spfile中,启动数据库
spfile的重要意义是将pfile文件中的静态参数区分为部分动态参数、部分静态参数,动态参数通过alter system命令可以直接生效,不用重启数据库。
限制:spfile是二进制文件,不能手工修改,否则将损坏spfile文件。
2.2.6 重置spfile中设置的参数
恢复参数的默认设置:alter system reset parameter名 <scope=memory|spfile|both> sid='sid名|*';
2.2.7 检查spfile是否使用
查询v$parameter动态试图,select name,value from v$parameter where name='spfile';为null则使用的是pfile
show命令,show parameter spfile;
查询v$spparameter试图,select count(*) from v$spparameter where value is not null;为0则使用的是pfile
select isspecified,count(*) from v$spparameter group by isspecified;TRUN为0则使用的是pfile
select decode(count(*),1,'spfile','pfile') used from v$spparameter where rownum=1 and isspecified='TRUE';
2.2.8 spfile的备份与恢复
用rman备份恢复spfile。当数据库发生重大变化时(如增减表空间),自动备份控制文件和spfile文件(需要配置控制文件自动备份)。
第三章 数据字典
3.1 数据字典概述
数据字典(Data dictionary)是oracle元数据(Metadata)的存储地点。
数据字典包括的内容:
所有数据库Schema对象的定义(表、视图、索引、聚簇、同义词、序列、过程、函数、包、触发器等);
数据库的空间分配和使用情况;
字段的缺省值;
完整性约束信息;
Oracle的用户名称、角色、权限等信息;
审计信息;
其他数据库信息。
数据字典的组成:内部RDBMS(X$)表、数据字典表、动态性能(V$)视图、数据字典视图。
3.2 内部RDBMS(X$)表
X$表是oracle的核心,用于跟踪内部数据库信息,维持数据库的正常运行。X$表被加密,建立的试图可用于查询,
X$表在数据库启动时由oracle应用程序动态创建,只能由sysdba用户访问,不能授权给其他用户。
常用到的X$表:X$BH、X$KSMSP、X$KSPPI、X$KSPPCV、X$KVIT(和实例相关的内部参数设置)
研究方法:可以通过autotrace或分析计划窗口查看视图以获知底层表的作用。
sql> set autotrace trace explain;
sql> select * from v$parameter; --底层表X$KSPPI、X$KSPPCV
sql> select * from X$KVIT; --和实例相关的内部参数设置
触发后台进程DBWR写动作的两个条件(X$KVIT):
脏缓冲(drity buffer)阀值(threshold)达到。kcbldq=25 large dirty queue if kcbclw reaches this。
no free buffer,当进程扫描LRU一定数量的Block后,没有足够的free空闲,则触发DBWR执行写出。kcbfsp=40 。
这两个阀值是数据库的内部限制,可以通过X$KVIT查询,不能调整。
3.3 数据字典表(Data Dictionary Table)
数据字典表用于存储表、索引、约束以及其他数据库结构的信息。表名以$结尾,如:tab$,obj$,ts$,bootstrap$,undo$等。数据字典表在创建数据库时通过运行sql.bsq脚本来创建。
sql.bsq包含数据字典表的定义及注释说明,存放在$oracle_home/rdbms/admin(c:/oracle/product/10.2.0/db_1/rdbms/admin/sql.bsq)目录下。
3.4 动态性能(V$)视图(Dynamic Performance View)
动态性能(V$)视图:记录db运行信息和统计数据,实时更新反映db的状态。
3.4.1 GV$和V$视图
在X$表的基础上创建GV$(global V$)和V$视图,大部分V$都有一个对应的GV$。
GV$和V$区别在于:GV$是多个实例的信息,V$是单个实例的信息。V$包含下列语句:where inst_id=USERENV('Instance')
select inst_id,instance_name,status,version from gv$instance;
select instance_number,instance_name,status,version from v$instance;
用于记录其他视图创建方式的视图,如:v$fixed_view_definition.
select view_definition from v$fixed_view_definition where view_name='V$FIXED_TABLE';
select view_definition from v$fixed_view_definition where view_name='GV$FIXED_TABLE';
可以看出V$视图是基于GV$视图创建的,GV$试图是基于X$表创建的。
3.4.2 GV_$、V_$视图和GV$、V$的同义词
X$表、GV$、V$试图只对sysdba开放,依据GV$、V$试图创建GV_$、V_$视图,然后再针对GV_$、V_$视图创建公共的同义词。
上述功能由catalog.sql脚本实现,脚本位置:$oracle_home/rdbms/admin(c:/oracle/product/10.2.0/db_1/rdbms/admin/catalog.sql)目录下。
create or replace view v_$sqlarea as select * from v$sqlarea; --创建v_$sqlarea视图
create or replace public synonym v$sqlarea for v_$sqlarea; --创建v_$sqlarea视图的同义词v$sqlarea
grant select on v_$sqlarea to select_catalog_role; --给同义词v$sqlarea授select_catalog_role角色的select权限。
其他用户访问的v$对象是V_$视图的同义词,而非v$试图。oracle的访问顺序是:表--》视图--》同义词。
验证如下:create table x$test_users as select username from dba_users; --创建x$表
create view v$test_users as select * from x$test_users; --创建v$试图
create view v_$test_users as select * from v$test_users; --创建v_$试图
create public synonym v$test_users for v_$test_users; --创建v_$试图的公共v$test_users同义词
connect tt/tt; --切换用户
create view v$test_users as select username,user_id from dba_users; --创建与同义词重名的视图v$test_users
select * from v$test_users; --访问的是本用户下的视图v$test_users
drop view v$test_users; --drop本用户下的视图v$test_users
select * from v$test_users; --访问的是sysy用户下的同义词v$test_users
3.4.3 进一步的说明 v$fixed_table, v$fixed_view_definition
v$fixed_table视图可以查看X$表、GV$和V$试图。
select count(*) from v$fixed_table where name like 'X$%'; --613张x$表
select count(*) from v$fixed_table where name like 'GV$%'; --372张gv$试图
select count(*) from v$fixed_table where name like 'V$%'; --396张v$试图
select count(*) from v$fixed_table; 总计1383, X$表、GV$和V$试图 合计 613+372+396=1381,相差了两条记录
select * from (select * from (select * from v$fixed_table where name not like 'X$%') where name not like 'GV$%') where name not like 'V$%'; --另外两条记录的查询
name: GO$SQL_BIND_CAPTURE ,O$SQL_BIND_CAPTURE (捕获动态绑定的参数)
type: view
v$fixed_view_definition视图可以查看GV$和V$试图的定义
select count(*) from v$fixed_view_definition where view_name like 'X$%'; --0 即该视图不包括x$表
select count(*) from v$fixed_view_definition where view_name like 'GV$%'; --372张gv$试图
select count(*) from v$fixed_view_definition where view_name like 'V$%'; --396张v$试图
select count(*) from v$fixed_view_definition; 总计770, GV$和V$试图 合计 372+396=768,相差了两条记录(视图的定义)
select * from (select * from v$fixed_view_definition where view_name not like 'GV$%') where view_name not like 'V$%'; --另外两条记录的查询
view_name:GO$SQL_BIND_CAPTURE,O$SQL_BIND_CAPTURE (捕获动态绑定的参数)
view_definition: 由定义可以看出看出O$SQL_BIND_CAPTURE是基于GO$SQL_BIND_CAPTURE创建的,带G是全局的,不带G是本实例的
select INST_ID,KQLFBC_PADD,KQLFBC_HASH,KQLFBC_SQLID,KQLFBC_CADD,KQLFBC_CHNO,substr(KQLFBC_NAME, 1, 30),KQLFBC_POS,to_number(decode(KQLFBC_DUPPOS, 65535, NULL, KQLFBC_DUPPOS)),KQLFBC_OACDTY,substr(KQLFBC_DTYSTR, 1, 15),decode(KQLFBC_OACCSI, 0, to_number(null), KQLFBC_OACCSI),decode(KQLFBC_OACPRE, 0, to_number(null), KQLFBC_OACPRE),decode(KQLFBC_OACSCL, 0, to_number(null), KQLFBC_OACSCL),KQLFBC_OACMXL,decode(KQLFBC_WCAP, 0, 'NO', 'YES'),decode(KQLFBC_WCAP, 0, to_date(NULL), KQLFBC_LCAP),KQLFBC_STRVAL,decode(KQLFBC_WCAP, 0, NULL,sys.sys$rawtoany(KQLFBC_BINVAL, KQLFBC_OACDTY,KQLFBC_OACCSF, KQLFBC_OACCSI)) from x$kqlfbc;
select ADDRESS, HASH_VALUE, SQL_ID, CHILD_ADDRESS,CHILD_NUMBER, NAME,POSITION, DUP_POSITION, DATATYPE, DATATYPE_STRING,CHARACTER_SID, PRECISION, SCALE, MAX_LENGTH, WAS_CAPTURED,LAST_CAPTURED, VALUE_STRING, VALUE_ANYDATA from go$sql_bind_capture where inst_id = USERENV('Instance');
3.5 数据字典视图
数据字典视图:是在X$表和数据字典表之上创建的视图,由catalog.sql创建,脚本位置:$oracle_home/rdbms/admin(c:/oracle/product/10.2.0/db_1/rdbms/admin/catalog.sql)目录下。
按前缀不同分为3类:user_(某个用户拥有的相关对象信息),all_(某个有权限访问的所有对象信息),dba_(数据库的所有相关对象信息).
user_tables (o.owner#=userenv('SCHEMAID')用来限制当前用户的schema对象信息)。
all_tables (o.owner# = userenv('SCHEMAID') or .. sys.objauth$ oa .. or ..v$enabledprivs .. 由or可以看出user_tables是all_tables的子集)。
dba_tables (没有了o.owner# = userenv('SCHEMAID')这一项,不仅仅限于当前用户,而是扩展的整个数据库)。
3.6 最后的验证 v$parameter
3.6.1 通过v$parameter视图追踪数据库架构。
select * from v$fixed_view_definition where lower(view_name)='v$parameter';
view_definition: select num,name,type,value,display_value,isdefault,isses_modifiable,issys_modifiable,isinstance_modifiable,ismodified,isadjusted,isdeprecated,description,update_comment,hash from gv$parameter where inst_id = userenv('Instance')
select * from v$fixed_view_definition where lower(view_name)='gv$parameter';
view_definition: select x.inst_id,x.indx+1,ksppinm,ksppity,ksppstvl,ksppstdvl,ksppstdf,decode(bitand(ksppiflg/256,1),1,'TRUE','FALSE'),decode(bitand(ksppiflg/65536,3),1,'IMMEDIATE',2,'DEFERRED',3,'IMMEDIATE','FALSE'),decode(bitand(ksppiflg,4),4,'FALSE',decode(bitand(ksppiflg/65536,3),0,'FALSE','TRUE')),decode(bitand(ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE'),decode(bitand(ksppstvf,2),2,'TRUE','FALSE'),decode(bitand(ksppilrmflg/64,1),1,'TRUE','FALSE'),ksppdesc,ksppstcmnt,ksppihash
from x$ksppi x,x$ksppcv y
where (x.indx = y.indx) and ((translate(ksppinm,'_','#') not like '##%') and ((translate(ksppinm,'_','#') not like '#%') or (ksppstdf = 'FALSE') or (bitand(ksppstvf,5) > 0)))
gv$parameter源自x$ksppi和x$ksppcv,x$ksppi和x$ksppcv用于包含所有的数据库参数,gv$parameter展现非隐含参数(非"_"开头的参数)。
3.6.2 视图还是同义词
sys用户访问v$parameter是访问的v$parameter视图;
非sys用户访问v$parameter是访问的v$parameter视图创建的v_$parameter视图的同义词。
3.6.3 oracle如何通过同义词定位对象
通过10046事件跟踪查询:
sql> connect sys/orcl as sysdba;
sql> grant alter session to tt; --给用户授session权限
sql> connect tt/tt;
sql> alter session set events '10046 trace name context forever,level 12';
sql> select * from v$test_users;
C:/oracle/product/10.2.0/admin/orcl/bdump/***.trc文件中记录:
首先,验证表和视图
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spare2 from obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is null and subname is null
bind 0: value=69 /0 owner#=69是tt用户,owner#=0是sys用户
bind 1: value="V$TEST_USERS"
bind 2: value=1
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spare2 from sys.obj$
where owner#=0 and name='V$TEST_USERS' and namespace=1 and remoteowner is null and linkname is null and subname is null;
这个查询owner#=69查不出结果,说明V$TEST_USERS不是tt用户下的对象Schema;owner#=0查出结果,说明V$TEST_USERS是sys用户下的对象Schema。
接着,验证同义词
select node,owner,name from syn$ where obj#=63261;
select obj#,node,owner,name from syn$ where name='V_$TEST_USERS';
obj#=63261
select object_name,object_id,object_type from dba_objects where object_name='V$TEST_USERS'
select object_name,object_id,object_type from dba_objects where object_name='V$TEST_USERS' and object_type='SYNONYM'
select text from view$ where rowid=:1;
select obj# from view$ where dbms_rowid.rowid_to_restricted(rowid,0)='000001CD.0013.0001';
select text from view$ where obj#=63260;
总结sql语句中oracle对于对象名的解析顺序:
oracle首先查看在发出命令的用户模式中是否存在表或视图;
如果表或视图存在,则使用该表或视图。
如果表或视图不存在,oracle检查私有同义词是否存在;
如果私有同义词存在,将使用这个同义词所引用的对象。
如果私有同义词不存在,oracle检查同名的公共同义词是否存在;
如果公共同义词存在,将使用这个公共同义词所引用的对象。
如果公共同义词不存在,oracle返回消息"ora-00942 table or view does not exist"。
10046事件的使用 http://www.eygle.com/case/ Use.sql_trace.to.Diagnose.database.html
第四章 内存管理
oracle实例启动时需要分配共享内存,启动后台进程。
4.1 SGA管理
4.1.1 什么是SGA
sga(system global area)系统全局区,是一块用于加载数据、对象并保存运行状态和数据库控制信息的一块内存区域,SGA隶属于实例,在实例启动时分配,实例关闭时释放。
在数据库启动到nomount状态时,SGA已经分配,
sql> show sga;
连接到数据库的用户可以共享SGA中的数据,加大SGA区的大小,可以有效地较少物理读,从而提高性能。
SGA的组成:
1).Buffer Cache 缓冲区高速缓存,用户存储最近使用的数据块。
9i前,Buffer Cache的设置:db_block_buffers设置Buffer Cache 缓冲区数量(block块的数量) 乘以 db_block_size(block块的大小设置) 才是Buffer Cache的大小。
sql> select name,value from v$parameter where name in ('db_block_buffers','db_block_size');
9i开始,引入的新的参数:db_cache_size(用于定义主block size的Default缓冲池的大小)。
SGA总大小由sga_max_size参数定义。
粒度(granule):是连续虚拟内存分配的单位,由SGA总大小(sga_max_size参数)确定。sga<128M,粒度=4M;否则粒度=16M.
sql> select name,value from v$parameter where name in ('db_cache_size','sga_max_size');
粒度大小受内部隐含参数_ksmg_granule_size的控制:
sql> select x.ksppinm name,y.ksppstvl value,x.ksppdesc describ from sys.x$ksppi x,sys.X$ksppcv y where x.inst_id=userenv('Instance') and y.inst_id=userenv('Instance') and x.indx=y.indx and x.ksppinm like '%&par%';
_ksmg_granule_size=4194304 4M 粒度的大小
多缓冲池技术:指根据不同数据的不同访问方式,将Buffer Cache分为Default(未指定存储池的数据)、keep(经常使用的数据)和Recycle(一次性读取的数据)池。
Default池大小参数db_cache_size(8i是 db_block_size * db_block_buffers),默认Default池的大小就是缓冲区Buffer Cache的大小。
建表时指定存储子句storage(buffer_pool keep),该表就使用keep缓冲区,初始参数db_keep_cache_size。
建表时指定存储子句storage(buffer_pool recycle),该表就使用recycle缓冲区,初始参数db_recycle_cache_size。
sql> show parameter cache_size; --db_cache_size =0 ???
sql> alter system set db_keep_cache_size=4M;
sql> show parameter cache_size; --db_keep_cache_size值由0更改为16M ???
缓冲区设置的查询:
sql> select id,name,block_size,current_size,target_size from v$buffer_pool;
该视图中查到的Default池为400M。
2).shared pool(共享池) 包含共享内存结构,如sql区等。sql区包含sql解析树、执行计划等信息,多次执行的sql可以在session间共享。
共享池大小由参数shared_pool_size定义,最小为1个粒度。
3).redo log buffer(日志缓冲区) 存储重做日志条目(redo entries),日志记录数据库变更,被写出到重做日志文件中,用于数据库恢复;
如果数据库运行在归档模式下,日志被写出到归档日志中,可用于数据恢复。
日志缓冲区大小由参数log_buffer定义.
4).large pool(大池) 用于共享服务器模式(MTS)、并行计算或RMAN的备份恢复等操作。参数:large_pool_size
5).java pool(java池) 用于jvm等Java选件。参数:java_pool_size
6).streams pool 为oracle的streams功能所使用,才从sgread pool中分出来。
通过视图v$sga查询sga大概设置:
sql> select * from v$sga;/show sga;
fixed size sga中的固定部分,包含数据库和实例的状态信息。不存储用户数据。
variable size 包括:shared_pool_size(共享池)、java_pool_size(java池)、large_pool_size(大池)
sql> select sum(value) from v$parameter where name in ('shared_pool_size','java_pool_size','large_pool_size');
database buffer 指Buffer Cache 包括:db_cache_size,db_keep_cache_size,db_recycle_cache_size
redo buffer 指日志缓冲区 log_buffers
通过试图v$sgastat查询sga具体信息:
sql> select * from v$sgastat;
sql> select * from v$sgainfo; resizeable为yes说明是可以调整大小的;为no的则不能调整。
4.1.2 SGA与共享内存
oracle SGA设置与操作系统的关联:
windows系统采用多线程服务器(即oracle server process是一个进程中的线程) ,不存在共享内存的问题,无需设置。
Linus/UNIX系统需要设置参数shmmax,参数的问题在不同的系统上可能不同,Solaris上/etc/system文件中shmsys:shminfo_shmmax定义;Linux上/proc/sys/kernel/shmmax参数定义。
shmmax内核参数定义的是系统允许的单个共享内存段的最大值,一般建议大于oracle SGA;如果小于oracle SGA,那么SGA被分配到多个共享内存段中。
Linus例子:shmmax默认32MB
[root]# more/proc/sys/kernel/shmmax --查看shmmax内核参数
33554432 =32M
[root]# cat/etc/sys/redhat-release
Red Hat Enterprise Linux AS release 3 --操作系统版本:红帽子3
[root]# uname -r
2.4.21-15.ELsmp
[root]# ipcs -sa --查看共享内存的分配,为创建oracle SGA分配了27个共享内存段
[root]# ps -ef|grep dbw --使用pmap工具查看共享内存段的地址空间
[root]# echo 1073741824 > /proc/sys/kernel/shmmax 为了避免多个共享内存段,可以修改shmmax内核参数为1G
[root]# more /proc/sys/kernel/shmmax --查看shmmax内核参数
1073741824 =1G --对shmmax文件的修改系统重启后复位,可以修改etc/sysctl.conf文件使更改永久化
在etc/sysctl.conf文件中添加一行 kernel.shmmax = 1073741824 重启系统生效,重启数据库
sql> shutdown immediate; --关闭数据库
[root]# ipcs -sa --查看共享内存的分配,共享内存段已经释放
没有修改shmmax参数,oracle在启动过程中就会在alert_<sid>.log文件中记录警告。
4.1.3 SGA管理的变迁
oracle 8i 静态SGA管理:
修改SGA参数,先关闭实例,修改参数文件init.ora,重启数据库才能生效。
oracle 9i 动态SGA管理:不需要重启数据库
第八章 等待事件 p354
通过等待事件发现性能瓶颈(从动态性能视图展现),进行性能分析和优化。
8.1 等待事件的起源
等待事件(v$event_name)的数目与数据库版本(v$version)相关。
select * from v$version;--查看数据库版本
select count(*) from v$event_name;--等待事件数量(oracle10gR2 := 872)
所有的800多等待事件分为12类:
select distinct wait_class#,wait_class from v$event_name order by wait_class#;
wait_class#=6,wait_class=idle 空闲等待事件:指oracle正在等待任务,与诊断和优化无关;其余等待事件则与诊断和优化相关。
各类等待事件的个数:
select wait_class#,wait_class,count(1) from v$event_name group by wait_class#,wait_class_id,wait_class order by wait_class#;
v$event_name中字段说明:
select event#,name,event_id,wait_class#,wait_class,wait_class_id,parameter1,parameter2,parameter3 from v$event_name where (parameter1 is not null or parameter2 is not null or parameter3 is not null) and wait_class#<>6;
event#,name,event_id 等待事件的编号、名称、序号;wait_class#,wait_class,wait_class_id 等待事件分类的编号、名称、序号;parameter1,parameter2,parameter3 参数值,非常重要的。
v$system_wait_class 获取每个等待事件分类的总计等待时间和次数:
select wait_class#,wait_class,wait_class_id,total_waits,time_waited from v$system_wait_class order by time_waited;
空闲等待事件:
select wait_class,event#,name,parameter1,parameter2,parameter3 from v$event_name e where wait_class='Idle';
8.2 从等待发现瓶颈
v$session :是数据库当前连接的session信息。
v$session_wait :是数据库当前连接的活动session正在等待的资源或事件信息。
v$system_event :是数据库启动以来所有等待事件的汇总信息。
8.2.1 v$session和v$session_wait
v$session_wait字段说明:
select event,p1text,p1,p1raw,seq#,wait_time,seconds_in_wait,state from v$session_wait w;
event 事件名;p1text,p1,p1raw 对应v$event_name中的参数值、十进制参数值、十六进制参数值;seq#,wait_time,seconds_in_wait,state 等待信息
oracle 10 R1 后 v$session_wait被整合到v$session中,此外还增加了blocking_session。R2 后增加:service_name,sql_trace,sql_trace_waits,sql_trace_binds用于显示当前session连接方式及是否启用sql_trace跟踪等。
8.2.2 v$sqltext
select sid,event,p1,p1text from v$session_wait order by event;
发现大量db file scattered read 及db file sequential read等待,全表扫描位于文件号为17的数据文件上。
db file scattered read(DB文件分散读取)与全表扫描相关的等待,将分散的数据读入Buffer Cache,没有创建索引或索引不合适导致。
v$sqltext的字段:
select address,hash_value,sql_id,command_type,piece,sql_text from v$sqltext t;
sql_text存放sql语句
8.2.3 捕获相关sql
v$sqltext与v$session的关联:
select sid, sql_text from v$sqltext t,v$session s where t.hash_value=s.sql_hash_value;
检查sql执行计划:在cmd中有效
C..>sqlplus /nolog --启动sqlplus
sql> connect tt/tt; --连接用户
sql> set autotrace trace explain; --启用执行计划
sql> select .. from .. where ..; --需要分析的sql
分析结果及展现方式与pl/sql developer下的Explain Plan Window 完全一致。
8.3 oracle 10g 的增加
v$session_wait会随session的消失而消失,即不保留历史信息。
8.3.1 v$session_wait_history视图:用以记录每个活动session最近10次的等待事件。
select sid,seq#,event#,event,wait_time,wait_count,p1text,p1,p2text,p2,p3text,p3 from v$session_wait_history;
sid :session编号;seq#:session下等待事件的编号;event#:等待事件的编号;event:等待事件的名称;wait_time:等待时间;wait_count:等待次数;p1text:参数值1;p1:十进制参数值1
每个sid下有10个seq#。
8.3.2 ASH新特性
Active Session History(ASH)活动session历史信息记录,记录活动会话等待的事件。每秒从v$session采样一次,采样由后台进程MMNL完成。
查看oracle内部隐含参数:不建议用户查询或者修改。
select x.ksppinm name,y.ksppstvl value,x.ksppdesc describ from sys.x$ksppi x,sys.x$ksppcv y
where x.inst_id=USERENV('Instance') and y.inst_id=USERENV('Instance') and x.indx=y.indx;
ASH功能是否启用由参数_ash_enable控制:
select x.ksppinm name,y.ksppstvl value,x.ksppdesc describ from sys.x$ksppi x,sys.x$ksppcv y
where x.inst_id=USERENV('Instance') and y.inst_id=USERENV('Instance') and x.indx=y.indx and x.ksppinm='_ash_enable';
ASH采样时间由参数_ash_sampling_interval控制:
select x.ksppinm name,y.ksppstvl value,x.ksppdesc describ from sys.x$ksppi x,sys.x$ksppcv y
where x.inst_id=USERENV('Instance') and y.inst_id=USERENV('Instance') and x.indx=y.indx and x.ksppinm='_ash_sampling_interval';
ASH记录通过视图v$active_session_history访问:
select * from v$active_session_history;
ASH信息被设计为在内存中滚动,在SGA(系统全局区域)中分配:
select * from v$sgastat where name like '%ASH%';
select * from v$sgastat; --SGA(系统全局区域)的内存分配
ASH buffers的大小算法:
Max(Min(cpu_count*2MB,5%*SHARED_POOL_SIZE,30MB),1MB) 即:最大30MB,最小1MB
如果SHARED_POOL_SIZE没有定义时,将5%*SHARED_POOL_SIZE替换为2%*SGA_TARGET
select name,value,display_value from v$parameter where name in ('shared_pool_size','cpu_count','sga_target');
生成ASH报告的两种方式:
1.调用$ORACLE_home/rdbms/admin/ashrpt.sql脚本,
sql> @?/rdbms/admin/ashrpt.sql;
文件类型:text,开始时间:-15,结束时间:当前时间,报表名称:
2.使用oem图形方式:性能页--》点击“运行ASH报告”即可生成。
ASH概况信息,等待事件信息,等待参数信息,TopSQL信息。
8.3.3 自动负载信息库AWR的引入(automatic workload repositoy)
AWR将数据库的操作统计信息和其他统计信息由每后台进程MMNL通过direct-path insert(直接路径插入)60分钟写入磁盘一次,并保存一周。
参数:statistics_level(basic,typical,all)统计信息的收集设置,_ash_disk_filter_ratio(隐含参数) ASH的写出比例.
select name,value,display_value from v$parameter where name in ('statistics_level');
select x.ksppinm name,y.ksppstvl value,x.ksppdesc describ from sys.x$ksppi x,sys.x$ksppcv y
where x.inst_id=USERENV('Instance') and y.inst_id=USERENV('Instance') and x.indx=y.indx and x.ksppinm='_ash_disk_filter_ratio';
AWR的基础表wrh$_active_session_history(分区表),视图dba_hist_active_sess_history.
V$session-->v$session_wait-->v$session_wait_history(记录了最近10次等待)-->v$active_session_history(记录1个小时的内容)-->wrh$_active_session_history(存储1星期)-->dba_hist_active_sess_history视图
sql> select occupant_name,occupant_desc,schema_name,space_usage_kbytes/1024 "MB" from v$sysaux_occupants where occupant_name like '%AWR%';
8.3.4 自动数据库诊断监控ADDM(automatic database diagnostic monitor)的引入
ADDM可以定期检查数据库的状态,确定性能瓶颈,提供调整建议。
8.4 顶级等待事件
视图v$system_event是数据库自启动以来等待事件的汇总,
sql> select * from (select event,time_waited from v$system_event order by time_waited desc) where rownum<10;
视图v$session_longops
sql> select opname from v$session_longops;
从中发现问题sql及问题sql查询的物理表,给表增加适当的索引即可。
8.5 重要等待事件
8.5.1 db file sequential read(数据文件顺序读取)
显示与单个数据块相关的读取操作,读取一个索引块或者通过索引块读取一个数据块时记录该等待事件。
sql> select name,wait_class,parameter1,parameter2,parameter3 from v$event_name where name='db file sequential read';
参数p1:要读取的文件的绝对文件号;参数p2:开始读取的数据块块号;参数p3:读取的BLOCK数量。
该等待事件显著表明:多表连接中连接顺序有误,索引使用有问题。
视图v$segment_statistics: 找出物理读取显著的索引段或者表段,通过重建或分区、调整存储参数等手段降低其I/O访问。
sql> select * from v$segstat_name;
sql> select * from v$segment_statistics;
8.5.2 db file scattered read(数据文件离散读取)
sql> select name,wait_class,parameter1,parameter2,parameter3 from v$event_name where name in ('db file sequential read','db file scattered read');
参数p1:文件号;参数p2:起始数据块号;参数p3:数据块数量。
第9章 性能诊断与sql优化
9.1 使用autotrace功能辅助sql优化
9.1.1 autotrace功能的启用(10g之前,autotrace功能并未打开,需要通过以下步骤手工启动)
1.创建基础表
运行$ORACLE_HOME/rdbms/admin/utlplan.sql脚本,用于创建plan_table表:
C:/> sqlplus /nolog
sql> connect / as sysdba;
sql> @?/rdbms/admin/utlplan.sql; --运行脚本创建plan_table表
sql> create public synonym plan_table for plan_table; --创建同义词
sql> grant all on plan_table to public; --授权
2.创建plustrace角色
运行$ORACLE_HOME/sqlplus/admin/plustrce.sql脚本,
sql> @?/sqlplus/admin/plustrce.sql; --运行脚本创建plustrace角色
3.一点增强
dba用户被授予了plustrace角色,在给其他用户也授权。
sql> grant plustrace to public; --授权后就可以使用autotrace功能
autotrace的选项说明:
set autotrace off : 不生成autotrace报告,默认设置 (查询结果)
set autotrace trace explain : (执行计划)
set autotrace trace statistics : (统计信息)
set autotrace on explain : autotrace只显示优化器执行路径报告 (查询结果+执行计划)
set autotrace on statistics : 只显示执行统计信息 (查询结果+统计信息)
set autotrace traceonly : 同set autotrace on,但不显示查询输出。(执行计划+统计信息)
set autotrace on : 包含执行计划和统计信息。 (查询结果+执行计划+统计信息)
9.1.2 oracle 10g autotrace功能的增强(良好的格式化及简要注解)
dbms_xplan用于格式化和查看sql的执行计划。
sql> select * from table(dbms_xplan.display(format=>'BASIC')); ???
sql> explain plan for select count(*) from dual;
sql> @?/rdbms/admin/utlxplp.sql;
select * from table(dbms_xplan.display());
oracle 10g autotrace 自动完成了输出的格式化,oracle 10g不需要创建基础表plan_table,在字典表中已经存在plan_table$,并存在同义词plan_table。
9.1.3 autotrace功能的内部操作(启动2个session连接,一个用于执行查询,一个用于记录执行计划和输出最终结果)
启用autotrace之前的session连接:
sql> set autotrace off; --关闭autotrace
sql> select sid,serial#,username from v$session where username is not null;
sql> set autotrace on; --启用autotrace,有两个session
sql> select a.sid,a.serial#,a.username,b.pid,b.spid from v$session a,v$process b where a.paddr=b.addr and a.username is not null;
v$process.spid是操作系统进程号,即一个进程在数据库中可能对应多个session.
p423
9.3 使用sql_trace/10046事件进行数据库诊断
sql_trace/10046事件是进行sql跟踪的手段,是强有力的辅助诊断工具。
9.3.1 sql_trace/10046事件的基础
1.sql_trace说明
sql_trace是静态参数,设置为true可以收集信息用于性能优化或问题诊断(dbms_system包功能与之类似),但会严重影响系统性能,只对特定session启用跟踪,可以使用alter session 或 dbms_system.set_trace_in_session;对数据库启用sql_trace则需满足:至少有25%的cpu idle,为user_dump_dest分配足够的空间,条带化磁盘以减轻IO负担。
使用alter session set sql_trace 来修改session级设置,不会更改v$parameter视图,所以说sql_trace是静态参数。
sql_trace启用前的设置:
timed_statistics设置为true,否则一些重要信息不会被收集。
MAX_DUMP_FILE_SIZE设置为unlimited(默认),sql> alter session set MAX_DUMP_FILE_SIZE=unlimited;
p440
本文转自东方之子736651CTO博客,原文链接:http://blog.51cto.com/ecloud/1389412 ,如需转载请自行联系原作者
PostgreSQL修炼之道:从小工到专家
数据库技术丛书
PostgreSQL修炼之道:从小工到专家
唐成著
图书在版编目(CIP)数据
PostgreSQL修炼之道:从小工到专家/唐成著. —北京:机械工业出版社,2015.4
(数据库技术丛书)
ISBN 978-7-111-49872-8
I. P… II. 唐… III. 关系数据库系统 IV. TP311.132.3
中国版本图书馆CIP数据核字(2015)第063966号
PostgreSQL修炼之道:从小工到专家
出版发行:机械工业出版社(北京市西城区百万庄大街22号 邮政编码:100037)
责任编辑:杨绣国陈佳媛 责任校对:董纪丽
印 刷: 版 次:2015年4月第1版第1次印刷
开 本:186mm×240mm 1/16 印 张:33.5
书 号:ISBN 978-7-111-49872-8 定 价:79.00元
凡购本书,如有缺页、倒页、脱页,由本社发行部调换
客服热线:(010)88378991 88361066 投稿热线:(010)88379604
购书热线:(010)68326294 88379649 68995259 读者信箱:hzjsj@hzbook.com
版权所有·侵权必究
封底无防伪标均为盗版
本书法律顾问:北京大成律师事务所 韩光/邹晓东
Preface 前 言
为什么要写这本书
PostgreSQL数据库是目前功能最强大的开源数据库,它基本包含了其他所有商业或开源的数据库中能找到的功能,甚至还包含了一些商业数据库中没有的功能。它是最接近工业标准SQL92的查询语言,并且正在实现新的功能以兼容最新的SQL标准:SQL2003。PostgreSQL也获得数个奖项,曾三次被评为Linux Journal杂志编辑评选的“最佳数据库奖”(2000年、2003年和2004年),并获2004年度的Linux新媒体最佳数据库系统奖。
PostgreSQL目前在国外很流行,特别是近两年,使用PostgreSQL数据库的公司越来越多,如提供网络电话功能的skype和著名的图片分享网站Instagram。2012年,美国联邦机构全面转向PostgreSQL阵营;法国也正推动政府机构积极采用PostgreSQL数据库取代商业数据库;世界最大的CRM软件服务提供商Salesforce同样开始大量使用 PostgreSQL。在DB-Engine 发布的历年数据库排名中,PostgreSQL自从2013年3月上升到第四名后,一直稳定在第四名,排在很多知名的商业数据库如DB2、Sybase之前,也排在所有NoSQL数据库如Cassandra、Redis等之前。
虽然在国外使用PostgreSQL 数据库的人很多,但在国内,PostgreSQL中文的学习资料并不多,因此我就想到写一本关于PostgreSQL的书,让国内更多的人加入到学习PostgreSQL数据库的队伍中来。
读者对象
适合阅读本书的用户:
数据库入门者。学习本书和相关的数据库知识,可以让一个对数据库了解不是很深的数据库爱好者成为数据库专家。
非PostgreSQL数据库的DBA。可以让非PostgreSQL的DBA 快速掌握PostgreSQL数据库相关知识,成为一名合格的PostgreSQL DBA。
PostgreSQL DBA。本书的一些章节对熟悉PostgreSQL数据库的DBA也有很大指导作用,可以使读者的知识更充实。
开发人员。通过此书可以快速掌握PostgreSQL数据库方面的知识,提高开发人员的数据库水平。
如何阅读本书
本书分为四大部分,分别为准备篇、基础篇、提高篇和第三方开源软件及架构篇。准备篇是为没有数据库基础的读者准备的,如果你已经具备了一定的数据库基础,可以跳过其中的一些内容。基础篇介绍了PostgreSQL数据库中的一些基础内容,学完此篇可以完成基本的PostgreSQL数据库的日常操作。提高篇讲解了一些更深的内容,如PostgreSQL的一些技术内幕、特色功能、优化等方面的内容,仔细阅读此篇可使你早日成为PostgreSQL数据库高手。第三方开源软件及架构篇讲解了与PostgreSQL数据库配套使用的一些常用的开源软件及架构设计方面的内容,通过阅读此篇,可以开阔大家的眼界,提高数据库架构设计能力。
本书中有大量的例子,读者边阅读此书边按例子进行实际的操作,将获得最佳的学习效果。
勘误和支持
由于作者的水平有限,编写的时间也很仓促,书中难免会出现一些错误或者不准确的地方,不妥之处恳请读者批评指正。你可以将书中的错误,遇到的问题及宝贵意见发送邮件至我的邮箱chengdata@gmail.com,我很期待听到你们的真挚反馈。
致谢
首先要感谢国内PostgreSQL数据库的爱好者,他们已经整理了很多PostgreSQL的文章,翻译了PostgreSQL的官方手册,让我可以站在前人的肩膀上。大家可以在PostgreSQL在中国的维基主页http://www.pgsqldb.org/mwiki/index.php/上看到前人的成果。
感谢机械工业出版社华章公司的编辑杨绣国老师,感谢她一年多来始终支持我的写作,她的鼓励和帮助引导我能顺利完成全部书稿。
最后要感谢我的妻子,她一直支持和鼓励我,让我能坚持把这本书写完。
谨以此书,献给众多热爱PostgreSQL的朋友们。
唐成(osdba)
中国,杭州,2015年1月
Contents 目 录
前言
第一篇准备篇
第1章PostgreSQL简介2
1.1什么是PostgreSQL2
1.1.1PostgreSQL概述2
1.1.2PostgreSQL的发展历史2
1.1.3 PostgreSQL数据库的优势3
1.1.4 PostgreSQL应用现状和发展趋势4
1.2 PostgreSQL数据库与其他数据库的对比4
1.2.1PostgreSQL与MySQL数据库的对比4
1.2.2 PostgreSQL与Oracle数据库的对比6
1.3 小结6
第2章PostgreSQL安装与配置7
2.1 从发行版本安装7
2.1.1 在Debian或Ubuntu下的安装7
2.1.2在Redhat、CentOS或Fedora下的安装9
2.1.3 在Windows下的安装12
2.1.4 发行版安装总结16
2.2 从源码安装16
2.2.1 编译安装过程介绍16
2.2.2 下载源代码17
2.2.3 编译及安装18
2.2.4 安装后的配置20
2.2.5 创建数据库簇21
2.2.6 安装contrib目录下的工具21
2.2.7 启动和停止数据库21
2.2.8 编译安装时的常见问题及解决方法22
2.3 安装技巧介绍24
2.3.1 在Redhat、CentOS下使用二进制包安装较新版本的方法24
2.3.2 如何使用较大的数据块提高I/O性能25
2.4 PostgreSQL的简单配置25
2.4.1 修改监听的IP和端口25
2.4.2 与数据库log相关的参数25
2.4.3 内存参数的设置26
2.5 小结26
第3章SQL语言入门27
3.1 SQL语句语法简介27
3.1.1 语句的分类27
3.1.2 词法结构27
3.2 DDL语句28
3.2.1 建表语句28
3.2.2 删除表语句30
3.3 DML语句30
3.3.1 插入语句30
3.3.2 更新语句31
3.3.3 删除语句31
3.4 查询语句31
3.4.1 单表查询语句31
3.4.2 过滤条件的查询32
3.4.3 排序32
3.4.4 分组查询33
3.4.5 表join34
3.5 其他SQL语句36
3.5.1 INSERT INTO... SELECT语句36
3.5.2 UNION语句36
3.5.3 TRUNCATE TABLE语句37
3.6 小结37
第二篇基础篇
第4章psql工具的使用介绍40
4.1 psql介绍40
4.2 psql的简单使用40
4.3 psql的常用命令42
4.3.1 \d命令42
4.3.2 指定字符集编译的命令45
4.3.3 \pset命令46
4.3.4 \x命令46
4.3.5 执行存储在外部文件中的SQL命令47
4.3.6 显示信息的命令48
4.3.7 更多的命令49
4.4 psql的使用技巧和注意事项50
4.4.1 历史命令与补全的功能50
4.4.2 自动提交方面的技巧50
4.4.3 如何得到psql中命令实际执行的SQL51
4.5 小结53
第5章数据类型54
5.1 类型介绍54
5.1.1 类型的分类54
5.1.2 类型输入与转换55
5.2 布尔类型56
5.2.1 布尔类型解释56
5.2.2 布尔类型的操作符58
5.3 数值类型59
5.3.1 数值类型解释59
5.3.2 整数类型 59
5.3.3 精确的小数类型59
5.3.4 浮点数类型60
5.3.5 序列类型61
5.3.6 货币类型61
5.3.7 数学函数和操作符62
5.4 字符串类型64
5.4.1 类型解释64
5.4.2 字符串函数和操作符65
5.5 二进制数据类型67
5.5.1 二进制数据类型解释67
5.5.2 二进制数据类型转义表示67
5.5.3 二进制数据类型的函数68
5.6 位串类型69
5.6.1 位串类型解释69
5.6.2 位串类型的使用69
5.6.3 位串的操作符及函数70
5.7 日期/时间类型71
5.7.1 日期/时间类型详解71
5.7.2 日期输入72
5.7.3 时间输入73
5.7.4 特殊值75
5.7.5 函数和操作符列表75
5.7.6 时间函数77
5.7.7 extract和date_part函数80
5.8 枚举类型81
5.8.1 枚举类型的使用81
5.8.2 枚举类型的说明82
5.8.3 枚举类型的函数83
5.9 几何类型84
5.9.1 几何类型概况84
5.9.2 几何类型的输入84
5.9.3 几何类型的操作符89
5.9.4 几何类型的函数97
5.10 网络地址类型98
5.10.1 网络地址类型概况98
5.10.2 inet与cidr类型98
5.10.3 macaddr类型101
5.10.4 网络地址类型的操作符101
5.10.5 网络地址类型的函数102
5.11 复合类型103
5.11.1 复合类型的定义103
5.11.2 复合类型的输入104
5.11.3 访问复合类型105
5.11.4 修改复合类型105
5.11.5 复合类型的输入与输出106
5.12 XML类型107
5.12.1 XML类型的输入107
5.12.2 字符集的问题108
5.12.3 XML类型的函数109
5.13 JSON类型114
5.13.1 JSON类型简介115
5.13.2 JSON类型的输入与输出115
5.13.3 JSON类型的操作符116
5.13.4 JSON类型的函数118
5.13.5 JSON类型的索引121
5.14 Range类型125
5.14.1 Range类型简介125
5.14.2 创建Range类型126
5.14.3 Range类型的输入与输出127
5.14.4 Range类型的操作符130
5.14.5 Range类型的函数130
5.14.6 Range类型的索引和约束131
5.15 数组类型132
5.15.1 数组类型的声明132
5.15.2 如何输入数组值133
5.15.3 访问数组135
5.15.4 修改数组137
5.15.5 数组的操作符138
5.15.6 数组的函数139
5.16 伪类型142
5.17 其他类型143
5.17.1 UUID类型143
5.17.2 pg_lsn 类型143
第6章逻辑结构管理145
6.1 数据库逻辑结构介绍145
6.2 数据库基本操作145
6.2.1 创建数据库145
6.2.2 修改数据库146
6.2.3 删除数据库147
6.2.4 常见问题及解答147
6.3 模式148
6.3.1 模式的定义148
6.3.2 模式的使用148
6.3.3 公共模式150
6.3.4 模式的搜索路径150
6.3.5 模式的权限151
6.3.6 模式的移植性151
6.4 表152
6.4.1 创建表152
6.4.2 表的存储属性154
6.4.3 临时表156
6.4.4 默认值158
6.4.5 约束159
6.4.6 修改表163
6.4.7 表继承及分区表167
6.4.8 分区表168
6.5 触发器173
6.5.1 创建触发器173
6.5.2 语句级触发器与行级触发器175
6.5.3 BEFORE触发器与AFTER触发器177
6.5.4 删除触发器178
6.5.5 触发器的行为179
6.5.6 触发器函数中的特殊变量180
6.6 事件触发器180
6.6.1 创建事件触发器183
6.6.2 修改事件触发器186
6.7 表空间186
6.7.1 表空间的定义186
6.7.2 表空间的使用186
6.8 视图187
6.8.1 视图的定义187
6.8.2 创建视图188
6.8.3 可更新视图189
6.9 索引191
6.9.1 索引简介191
6.9.2 索引的分类192
6.9.3 创建索引192
6.9.4 并发创建索引193
6.9.5 修改索引196
6.9.6 删除索引196
6.10 用户及权限管理197
6.10.1 用户和角色197
6.10.2 创建用户和角色198
6.10.3 权限的管理199
6.10.4 函数和触发器的权限202
6.10.5 权限的总结202
6.10.6 权限的示例202
6.11 事务、并发、锁203
6.11.1 ACID203
6.11.2 DDL事务204
6.11.3 事务的使用204
6.11.4 SAVEPOINT205
6.11.5 事务隔离级别206
6.11.6 两阶段提交207
6.11.7 锁机制209
6.11.8 死锁及防范212
6.11.9 表级锁命令LOCK TABLE213
6.11.10 行级锁命令213
6.11.11 锁的查看214
第7章PostgreSQL的核心架构221
7.1 应用程序的访问接口221
7.1.1 访问接口总体图221
7.1.2 不同编辑语言的PostgreSQL驱动介绍222
7.2 进程及内存结构223
7.2.1 进程和内存架构图223
7.2.2 主进程Postmaster224
7.2.3 SysLogger(系统日志)进程224
7.2.4 BgWriter(后台写)进程225
7.2.5 WalWriter(预写式日志写)进程225
7.2.6 PgArch(归档)进程225
7.2.7 AutoVacuum(自动清理)进程225
7.2.8 PgStat(统计数据收集)进程226
7.2.9 共享内存226
7.2.10 本地内存226
7.3 目录结构227
7.3.1 安装目录的结构227
7.3.2 数据目录的结构227
7.3.3 表空间的目录228
第8章服务管理229
8.1 服务的启停和创建229
8.1.1 启停方法229
8.1.2 pg_ctl230
8.1.3 信号234
8.1.4 postgres及单用户模式234
8.2 服务配置介绍235
8.2.1 配置参数235
8.2.2 连接配置项237
8.2.3 内存配置项240
8.2.4 预写式日志的配置项241
8.2.5 错误报告和日志项243
8.3 访问控制配置文件246
8.3.1 pg_hba.conf 文件247
8.3.2 认证方法介绍248
8.3.3 认证方法实战249
8.4 备份和还原249
8.4.1 逻辑备份249
8.4.2 pg_dump命令250
8.4.3 pg_restore命令254
8.4.4 pg_dump和pg_restore使用举例257
8.4.5 物理备份258
8.4.6 使用LVM快照进行热备份259
8.5 常用的管理命令261
8.5.1 查看系统信息的常用命令261
8.5.2 系统维护常用命令267
第三篇提高篇
第9章PostgreSQL中执行计划270
9.1 执行计划的解释270
9.1.1 EXPLAIN命令270
9.1.2 EXPLAIN输出结果解释271
9.1.3 EXPLAIN使用示例272
9.1.4 全表扫描275
9.1.5 索引扫描275
9.1.6 位图扫描275
9.1.7 条件过滤276
9.1.8 Nestloop Join277
9.1.9 Hash Join277
9.1.10 Merge Join278
9.2 与执行计划相关的配置项279
9.2.1 ENABLE_*参数 279
9.2.2 COST基准值参数279
9.2.3 基因查询优化的参数280
9.2.4 其他执行计划配置项281
9.3 统计信息的收集282
9.3.1 统计信息收集器的配置项282
9.3.2 SQL执行的统计信息输出283
9.3.3 手工收集统计信息283
第10章PostgreSQL中的技术内幕285
10.1 表中的系统字段285
10.1.1 oid286
10.1.2 ctid288
10.1.3 xmin、xmax、cmin、cmax289
10.2 多版本并发控制290
10.2.1 多版本并发控制的原理290
10.2.2 PostgreSQL中的多版本并发控制291
10.2.3 PostgreSQL多版本的优劣分析293
10.3 物理存储结构293
10.3.1 PostgreSQL中的术语293
10.3.2 数据块结构293
10.3.3 Tuple结构294
10.3.4 数据块空闲空间管理296
10.3.5 可见性映射表文件298
10.4 技术解密298
10.4.1 Index-only scans298
10.4.2 Heap-Only Tuples300
第11章PostgreSQL的特色功能302
11.1 规则系统302
11.1.1 SELECT规则302
11.1.2 更新规则303
11.1.3 规则和权限306
11.1.4 规则和命令状态307
11.1.5 规则与触发器的比较308
11.2 模式匹配和正则表达式308
11.2.1 PostgreSQL中的模式匹配和正则表达式介绍308
11.2.2 传统SQL的LIKE 操作符309
11.2.3 SIMILAR TO 正则表达式310
11.2.4 POSIX 正则表达式312
11.2.5 模式匹配函数 substring313
11.3 listen与notify315
11.3.1 listen与notify的简单示例315
11.3.2listen与notify的相关命令316
11.3.3 listen与notify的使用详解317
11.4 索引的特色320
11.4.1 表达式上的索引320
11.4.2 部分索引320
11.4.3 GiST索引323
11.4.4 SP-GiST索引325
11.4.5 GIN索引326
11.5 序列的使用328
11.5.1 序列的创建328
11.5.2 序列的使用及相关的函数329
11.5.3 常见问题及解答331
11.6 咨询锁的使用333
11.6.1 咨询锁的定义333
11.6.2 咨询锁的函数及使用333
11.6.3 常见问题及解答337
11.7 SQL/MED338
11.7.1 SQL/MED的介绍338
11.7.2 外部数据包装器对象339
11.7.3 外部服务器对象340
11.7.4 用户映射对象341
11.7.5 外部表对象341
11.7.6 file_fdw使用实例342
11.7.7 postgres_fdw使用实例345
第12章数据库优化347
12.1 优化准则和方法347
12.1.1 优化准则347
12.1.2 优化方法348
12.2 硬件知识348
12.2.1 CPU及服务器体系结构348
12.2.2 内存349
12.2.3 硬盘350
12.3 文件系统及I/O调优352
12.3.1 文件系统的崩溃恢复352
12.3.2 Ext2文件系统353
12.3.3 Ext3文件系统353
12.3.4 Ext4文件系统354
12.3.5 XFS文件系统355
12.3.6 Barriers I/O355
12.3.7 I/O调优的方法356
12.4 性能监控359
12.4.1 数据库性能视图359
12.4.2 Linux监控工具362
12.5数据库配置优化364
12.5.1内存配置优化364
12.5.2 关于双缓存的优化366
12.5.3 vacuum中的优化367
12.5.4 预写式日志写优化369
第13章Standby数据库的搭建371
13.1 Standby数据库原理371
13.1.1PITR原理371
13.1.2WAL日志归档372
13.1.3流复制372
13.1.4Standby的运行原理373
13.1.5 创建Standby的步骤373
13.2 pg_basebackup命令行工具374
13.2.1 pg_basebackup介绍374
13.2.2 pg_basebackup的命令行参数375
13.2.3 pg_basebackup使用示例376
13.3 异步流复制Hot Standby的示例377
13.3.1 配置环境377
13.3.2 主数据库的配置378
13.3.3 在Standby上生成基础备份378
13.3.4 启动Standby379
13.4 同步流复制的Standby数据库380
13.4.1 同步流复制的架构380
13.4.2 同步复制的配置381
13.4.3 配置实例381
13.5 检查备库及流复制情况383
13.5.1 检查异步流复制的情况383
13.5.2 检查同步流复制的情况384
13.5.3 视图pg_stat_replication详解385
13.5.4 查看备库的状态385
13.6 Hot Standby的限制387
13.6.1 Hot Standby的查询限制387
13.6.2 Hot Standby的查询冲突处理389
13.7 恢复配置详解390
13.7.1 归档恢复配置的配置项390
13.7.2 Recovery Target配置391
13.7.3 Standby Server配置 391
13.8 流复制的注意事项392
13.8.1 wal_keep_segments参数的配置392
13.8.2 vacuum_defer_cleanup_age参数的配置392
第四篇第三方开源软件及架构篇
第14章PgBouncer394
14.1 PgBouncer 介绍394
14.2 PgBouncer中的概念395
14.3 PgBouncer的安装方法395
14.4 PgBouncer的简单使用395
14.4.1 简单配置方法395
14.4.2 启动PgBouncer396
14.4.3 停止PgBouncer397
14.4.4 查看连接池信息397
14.5 PgBouncer的配置文件详解399
14.5.1 “[databases]”部分的配置项399
14.5.2 “[pgbouncer]”部分的配置项399
14.5.3 用户密码文件403
第15章Slony-I的使用404
15.1Slony-I中的概念404
15.1.1 集群404
15.1.2 节点405
15.1.3 复制集合405
15.1.4 数据原始生产者、数据提供者和数据订阅者405
15.1.5 slon守护程序405
15.1.6 slonik配置程序405
15.2 Slony-I复制的限制405
15.3 在Windows下使用pgAdminIII安装配置Slony-I406
15.3.1 Windows下安装Slony-I406
15.3.2Windows配置 Slony-I同步实例407
15.4在Linux下安装配置Slony-I419
15.4.1编译安装Slony-I419
15.4.2配置Slony-I复制421
第16章Bucardo的使用426
16.1Bucardo中的概念426
16.1.1Bucardo介绍426
16.1.2Bucardo FAQ426
16.1.3 Bucardo 同步中定义的概念427
16.2Bucardo的安装方法427
16.2.1Bucardo的安装步骤427
16.2.2安装Test-Simple、ExtUtils-MakeMaker、version428
16.2.3安装DBI及DBD::Pg428
16.2.4安装DBIx-Safe429
16.2.5安装Bucardo源码包429
16.3Bucardo同步配置429
16.3.1示例环境429
16.3.2配置同步的简要过程430
16.3.3 bucardo_ctl install431
16.3.4bucardo_ctl add db433
16.3.5 bucardo_ctl add table433
16.3.6 bucardo_ctl add herd433
16.3.7 bucardo_ctl add sync433
16.3.8 bucardo_ctl start434
16.4Bucardo的日常维护434
16.4.1Bucardo的触发器日志清理434
16.4.2临时停止和启动同步的方法435
16.4.3新增表到同步的方法435
16.4.4移除某个表或序列的方法435
第17章PL/Proxy的使用436
17.1PL/Proxy中的概念436
17.1.1PL/Proxy的定义436
17.1.2PL/Proxy的特性说明438
17.2PL/Proxy安装及配置438
17.2.1编译安装438
17.2.2安装规划439
17.2.3配置过程439
17.3PL/Proxy的集群配置详解443
17.3.1Cluster configuration API方式444
17.3.2SQL/MED方式配置集群446
17.4PL/Proxy语言详解446
17.4.1CONNECT447
17.4.2CLUSTER447
17.4.3RUN ON447
17.4.4SPLIT448
17.4.5TARGET448
17.5PL/Proxy的一个高可用方案448
17.5.1方案介绍448
17.5.2方案架构449
17.5.3具体实施步骤449
第18章pgpool-II的使用458
18.1 pgpool-II中的概念458
18.1.1 pgpool-II的定义458
18.1.2 pgpool-II的架构459
18.1.3 pgpool-II的工作模式460
18.1.4 pgpool-II的程序模块461
18.2 pgpool-II安装方法462
18.2.1 源码安装462
18.2.2 安装 pgpool_regclass463
18.2.3 建立 insert_lock 表463
18.2.4 安装C语言函数463
18.3 pgpool-II配置快速入门463
18.3.1 pgpool-II的配置文件及启停方法464
18.3.2 复制和负载均衡的示例466
18.3.3 使用流复制的主备模式的示例467
18.3.4 show命令468
18.4 pgpool-II高可用配置方法471
18.4.1 pgpool-II高可用切换及恢复的原理471
18.4.2 pgpool-II的健康检查473
18.4.3 复制和负载均衡模式的高可用示例473
18.4.4 使用流复制的主备模式下的高可用示例488
18.5 pgpool-II的总结492
第19章Postgres-XC的使用493
19.1 Postgres-XC中的概念493
19.1.1 Postgres-XC的定义493
19.1.2 Postgres-XC的特点493
19.1.3 Postgres-XC的性能494
19.1.4 Postgres-XC的组件494
19.2 Postgres-XC的安装495
19.2.1 源码安装方法495
19.2.2 Postgres-XC目录及程序说明496
19.3 配置Postgres-XC集群497
19.3.1 集群规划497
19.3.2 初始化GTM498
19.3.3 初始化GTM的备库498
19.3.4 初始化GTM Proxy499
19.3.5 初始化Coordinators、数据节点499
19.3.6 启动集群500
19.3.7 停止集群501
19.3.8 配置集群节点信息502
19.4 Postgres-XC的使用503
19.4.1 建表详解503
19.4.2 使用限制509
19.4.3 重新分布数据510
19.4.4 增加Coordinator节点的方法512
19.4.5 移除Coordinator节点的方法513
19.4.6 增加Datanode节点的方法513
19.4.7 移除Datanode节点的方法514
第20章高可用性方案设计516
20.1 高可用架构基础516
20.1.1 各种高可用架构介绍516
20.1.2 服务的可靠性设计517
20.1.3 数据可靠性设计517
20.2 基于共享存储的高可用方案517
20.2.1 SAN存储的方案517
20.2.2 DRBD的方案518
20.3 WAL日志同步或流复制同步的方案519
20.3.1 持续复制归档的standby的方法519
20.3.2 异步流复制的方案519
20.3.3 基于同步流复制方案519
20.4 基于触发器的同步方案520
20.4.1 方案的特点520
20.4.2 基于触发器方案的同步软件介绍520
20.5 基于语句中间件的高可用方案520
20.5.1 方案的特点520
20.5.2 基于语句中间件的开源软件介绍521
第一篇
准 备 篇
第1章PostgreSQL简介
第2章PostgreSQL安装与配置
第3章SQL语言入门
第1章
PostgreSQL简介
本章将着重介绍PostgreSQL数据库的相关知识,让没有接触过PostgreSQL的读者对它有一个初步的了解。
1.1什么是PostgreSQL
1.1.1PostgreSQL概述
PostgreSQL数据库是目前功能最强大的开源数据库,支持丰富的数据类型(如JSON和JSONB类型、数组类型)和自定义类型。而且它提供了丰富的接口,可以很容易地扩展它的功能,如可以在GiST框架下实现自己的索引类型等,它还支持使用C语言写自定义函数、触发器,也支持使用流行的语言写自定义函数,比如其中的PL/Perl提供了使用Perl语言写自定义函数的功能,当然还有PL/Python、PL/Tcl,等等。
1.1.2PostgreSQL的发展历史
前身Ingres:PostgreSQL的前身是伯克利源于1977 年的 Ingres 项目。这个项目是由著名的数据库科学家Michael Stonebraker领导的。1982年,Michael Stonebraker离开伯克利大学,把Ingres商业化,使之成为 Relational Technologies 公司的一个产品。后来 Relational Tecchnologies被Computer Associates(CA)收购。Ingres 是一个非关系型的数据库。
伯克利的 Postgres 项目:20世纪80年代,数据库系统中的一个主要问题是数据关系维护。在1985年Michael Stonebraker回到伯克利后,为了解决Ingres中的数据关系维护问题,启动了一个后Ingres(post-Ingres)的项目,这就是 POSTGRES 的开端。 POSTGRES项目是由防务高级研究项目局(DARPA)、陆军研究办公室(ARO)、国家科学基金(NSF) 以及 ESL公司共同赞助的。从1986年开始,Michael Stonebraker 教授发表了一系列论文,探讨了新的数据库的结构设计和扩展设计。第一个“演示性”系统在 1987 年便可使用了,并且在 1988 年的数据管理国际会议(ACM-SIGMOD)上展出。1989年6月发布了版本 1给一些外部的用户使用。由于源代码维护的时间日益增加,占用了太多本应用于数据库研究的时间,为减少支持的负担,伯克利的POSTGRES 项目在版本 4.2 时正式终止。
Postgres95:在 1994 年,来自中国香港的两名伯克利的研究生Andrew Yu 和 Jolly Chen 向 POSTGRES 中增加了现在SQL 语言的解释器,将Postgres改名为 Postgres95,随后将 Postgres95 源代码发布到互联网上供大家使用。它成为一个开放源码的POSTGRES 代码的继承者。
PostgreSQL6.X:到了 1996 年,很明显地看出“Postgres95”这个名字已经经不起时间的考验。于是起了一个新名字 PostgreSQL,为Postgres与SQL的缩写,即增加了SQL功能的Postgres的意思。同时版本号也沿用伯克利 POSTGRES 项目的顺序,从6.0开始。
PostgreSQL7.1:PostgreSQL 7.1是继6.5版本之后又一个有巨大变化的版本,首先它引入了预写式日志的功能。这样,事务就拥有了完善的日志机制,可以提供更好的性能,还可以实现更优良的备份和灾难恢复的能力(比如联机热备份和宕机后的自动恢复)。其次是不再限制文本类型的数据段长度,这从很大程度上解决了PostgreSQL大对象的问题。
Postgres8.X:该版本可以在Windows下运行,它具有一些新的特性。比如具有事务保存点功能、改变字段的类型、表空间、即时恢复(即时恢复允许对服务器进行连续的备份。既可以恢复到失败那个点,也可以恢复到以前的任意事务)等功能。并且开始支持Perl 服务器端编程语言。
PostgreSQL9.X:进入9.X版本,标识着PostgreSQL进入了黄金发展阶段。2010年9月20日发布了PostgreSQL 9.0,大大增强了复制的功能(replication),比如增加了流复制功能(stream replicaction)和HOT standby功能。从9.0开始,可以很方便地搭建主从数据库。2011年9月12日发布了PostgreSQL9.1,在该版本中增加了同步复制功能(synchronous replication);2012年9月10发布了PostgreSQL9.2,增加了级连复制的功能。
1.1.3 PostgreSQL数据库的优势
PostgreSQL有以下优势:
PostgreSQL数据库是目前功能最强大的开源数据库,它是最接近工业标准SQL92的查询语言,并且正在实现新的功能以兼容最新的SQL标准:SQL2003。
稳定可靠:PostgreSQL是唯一能做到数据零丢失的开源数据库。有报道称国外的部分银行也在使用PostgreSQL数据库。
开源省钱: PostgreSQL数据库是开源的、免费的,而且是BSD协议,在使用和二次开发上基本没有限制。
支持广泛:PostgreSQL 数据库支持大量的主流开发语言,包括C、C++、Perl、Python、Java、Tcl,以及PHP等。
PostgreSQL社区活跃:PostgreSQL基本上每三个月推出一个补丁版本,这意味着已知的BUG很快会被修复,有应用场景的需求也会及时得到响应。
1.1.4 PostgreSQL应用现状和发展趋势
PostgreSQL目前在国外很流行,特别是近几年使用PostgreSQL数据库的公司越来越多。比如,日本电信(NTT) 大量使用PostgreSQL替代Oracle数据库,并且在 PostgreSQL之上二次开发了Postgres-XC,Postgres-XC是对使用者完全兼容PostgreSQL接口的share-nothing 架构的数据库集群。网络电话公司Skype 也大量使用PostgreSQL,并贡献了一些与PostgreSQL数据库配套的开源软件:
PL/Proxy:PostgreSQL中的数据水平拆分软件
pgQ:使用PostgreSQL的消息队列软件
Londiste:用C语言实现的在PostgreSQL数据库之间进行逻辑同步的软件
全球最大的CRM软件服务提供商Salesforce也开始使用PostgreSQL,并招募了PostgreSQL内核开发者Tom lane。
2012年,美国联邦机构全面转向PostgreSQL阵营;法国也正积极推动政府机构采用PostgreSQL数据库,从而取代商业数据库。
在国内,越来越多的公司开始使用PostgreSQL,如斯凯网络(股票代码:MOBI)的后台数据库基本使用的都是PostgreSQL数据库,去哪儿网(qunar.com)也大量使用了PostgreSQL数据库。
主流的云服务提供商如亚马逊、阿里云的RDS(关系型数据库服务)同样提供了PostgreSQL的支持。
更多的使用PostgreSQL数据库的情况可以见PostgreSQL官方网站(http://www.postgresql.org/about/users/)。
1.2 PostgreSQL数据库与其他数据库的对比
1.2.1PostgreSQL与MySQL数据库的对比
可能有人会问,既然已经有一个人气很高的开源数据库MySQL了,为什么还要使用PostgreSQL?这主要是因为在一些应用场景中,使用MySQL有以下几个缺点:
功能不够强大:MySQL的多表连接查询方式只支持“Nest Loop”,不支持“hash join”和“sort merge join”。不仅如此,还有很多SQL语法它也不支持,子查询性能比较低。由于它不支持sequence,有公司还为此专门开发了统一序号分发中心的软件。
性能优化工具和度量信息不足:MySQL在运行过程中如果出现问题,只产生很少的性能数据,很难让维护人员准确定位问题产生的原因。MySQL的复制是异步的,无法通过Master/Slave做到数据零丢失。一些第三方公司也有改造MySQL源代码实现同步复制,但这些方案要么是没有开源,要么已开源却又不是很稳定,所以,对于普通大众来说,如何实现同步复制成了一个令人头疼的问题。
在线操作功能较弱:如果在MySQL表中加列,基本上是新建一个表,而且建索引时也会锁定整张表,即在建索引的过程中,表不能做任何操作。一些大的互联网公司或者是修改MySQL源码来实现在线DDL的功能,或者是通过上层架构来解决这个问题,如先在slave数据库上把DDL做完,然后把应用从master库切换到slave,再把原先的master上把DDL做完。第一种方法,需要公司有很强的MySQL研发能力,第二种方法需要公司有较强的开发能力,能设计出较强的应用架构。这对于一些中小型公司来说不太容易实现。
相对这些MySQL的弱点,PostgreSQL有以下几个优点:
PostgreSQL功能强大:支持所有主流的多表连接查询的方式(如:“Nest loop”、“ hash join”“sort merge join”等);支持绝大多数的SQL语法(如:with子句)。PostgreSQL是笔者见过的对正则表达式支持最强、内置函数也是最丰富的数据库。字段类型还支持数组类型。除了可以使用PL/PGSQL写存储过程外,还可以使用各种主流开发语言的语法(如:Python语言的PL/Python、Perl语言的PL/Perl来写存储过程)。这些强大的功能可以大大地节约开发资源。很多开发人员在PostgreSQL上做开发时,会发现数据库已帮自己实现了很多功能,甚至有一些业务功能都可直接使用数据库的功能解决,不再需要写代码来实现了。
性能优化工具与度量信息丰富:PostgreSQL数据库中有大量的性能视图,可方便地定位问题(比如:可看到正在执行的SQL,可通过锁视图看到谁在等待、哪条记录被锁定等)。PostgreSQL中设计了专门的架构和进程用于收集性能数据,既有物理I/O方面的统计,也有表扫描及索引扫描方面的性能数据。
在线操作功能好:PostgreSQL增加空值的列时,本质上只是在系统表上把列定义上,无须对物理结构做更新,这就让PostgreSQL在加列时可以做到瞬间完成。PostgreSQL还支持在线建索引的功能,建索引的过程可以不锁更新操作。
从PostgreSQL9.1开始,支持同步复制功能(synchronous replication),通过master和slave之间的复制可以实现零数据丢失的高可用方案。
另外,由于MySQL对SQL语法支持的功能较弱,基本上不适合做数据仓库。虽然也有些厂商开发了基于MySQL的数据仓库存储引擎(如Infobright),但这个方案只是解决了部分数据仓库的问题,SQL功能弱的问题仍无法完全解决。另外,Infobright的社区版本功能上还有很多的限制,如不支持数据更新,不支持太多的并发执行(最多支持十几个)等。而PostgreSQL不仅支持复杂的SQL,还支持大量的分析函数,非常适合做数据仓库。
PostgreSQL数据库中还有一些支持移动互联网时代的新功能,如空间索引。PostGIS是最著名的一个开源GIS系统,它是PostgreSQL中的一个插件,通过它可以很方便地解决LBS中的一些位置计算问题。
综上所述,PostgreSQL数据库是一个功能强大,又带有移动互联网特征的开源数据库。如果你仅仅是想把数据库作为一个简单的存储功能使用(如一些大的互联网公司),一些较复杂的功能都想放在应用中来实现,那么选择MySQL或一些NoSQL产品都是合适的;如果你应用的数据访问很简单(如大多数的blog系统),那么后端使用MySQL也是很合适的。但如果你的应用不像blog系统那么简单,而你又不想消耗太多的开发资源,那么PostgreSQL是一个明智的选择。最有说服力的例子就是图片分享公司instagram,在使用python+PostgreSQL架构后,只是十几个人就支持起了整个公司的业务。在数据库中使用PostgreSQL的感觉,就像在开发语言中使用python,会让你的工作变得简洁和高效。
1.2.2 PostgreSQL与Oracle数据库的对比
从功能上说,PostgreSQL要比Oracle数据库稍弱,如不支持索引组织表等。毕竟Oracle数据库是目前功能最强大的商业数据库,但PostgreSQL算是功能最强大的开源数据库。
PostgreSQL与Oracle有很多相似之处:都是使用共享内存的进程结构,客户端与数据库服务器建立一个连接后,数据库服务器就启动一个进程为这个连接服务,这与MySQL的线程模型不一样。此外,PostgreSQL的WAL日志与Oracle的Redo日志都是记录物理块数据变化的,这与MySQL的binlog也不同。
PostgreSQL与Oracle的不同之处在于:PostgreSQL有更多的支持互联网特征的功能。如PostgreSQL数据类型支持网络地址类型、XML类型、JSON类型、UUID类型,以及数组类型,有强大的正则表达式函数,where条件中可以使用正则表达式匹配,可以使用Python、Perl等语言写存储过程等。
另外,PostgreSQL更小巧。Oracle安装包动则几个GB以上,PostgreSQL安装包只有几十MB大小。在任何一个环境都可以容易地安装PostgreSQL。
1.3 小结
本章主要给大家介绍了什么是PostgreSQL数据库,它有哪些强大的功能,以及目前的一些应用情况,以便大家对PostgreSQL有一个初步的认识。
第2章
PostgreSQL安装与配置
本章将着重介绍PostgreSQL数据库的安装和配置方法。安装方法分为两类:一种是从二进制安装包进行安装,另一种是从源码安装。各个Linux的发行版本中,都内置了PostgreSQL的二进制安装包,但内置的版本可能较旧。二进制包安装的方法一般都是通过不同发行版本的Linux下的包管理器进行的,如在Redhat下是yum,在Ubuntu下是apt-get。使用源码安装更灵活,用户可以有更多的选择,可以选择较新的版本、配置不同的编译选项,编译出用户需要的功能。
2.1 从发行版本安装
2.1.1 在Debian或Ubuntu下的安装
在Debian和Ubuntu下一般使用apt-get命令或aptitude命令来安装软件,命令如下:
sudo apt-get install postgresql
安装完毕后,PostgreSQL数据库就启动了,如果想进入数据库,需要切换到postgres用户下:
su - postgres
然后使用psql连接到数据库中,从操作系统下的“postgres”用户(注意这里指的不是数据库中的postgres用户)连接数据库是不需要密码的,如下:
root@osdba-laptop:~# sudo su - postgres
postgres@osdba-laptop:~$ psql
psql (9.1.9)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access
privileges
-----------+----------+----------+------------+------------+--------------------
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres
+
| | | | |
postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres
+
| | | | |
postgres=CTc/postgres
(3 rows)
postgres=# \q
在上面的示例中,使用psql命令连接PostgreSQL数据库,psql是PostgreSQL中的客户端工具。“\l”是列出所有数据库的命令,“\q”是退出psql的命令,在后面的章节中还会详细介绍psql的使用方法。
在Debian或Ubuntu下,使用apt-get安装完成的PostgreSQL数据库的数据目录在/var/lib/postgresql/<dbversion>/main目录下:
postgres@osdba-laptop:~$ cd /var/lib/postgresql/9.1/main
postgres@osdba-laptop:~/9.1/main$ ls -l
total 56
drwx------ 5 postgres postgres 4096 Jun 29 11:55 base
drwx------ 2 postgres postgres 4096 Jun 29 11:55 global
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_clog
drwx------ 4 postgres postgres 4096 Jun 29 11:55 pg_multixact
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_notify
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_serial
drwx------ 2 postgres postgres 4096 Jun 29 12:00 pg_stat_tmp
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_subtrans
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_tblspc
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_twophase
-rw------- 1 postgres postgres 4 Jun 29 11:55 PG_VERSION
drwx------ 3 postgres postgres 4096 Jun 29 11:55 pg_xlog
-rw------- 1 postgres postgres 133 Jun 29 11:55 postmaster.opts
-rw------- 1 postgres postgres 100 Jun 29 11:55 postmaster.pid
lrwxrwxrwx 1 root root 36 Jun 29 11:55 server.crt ->
/etc/ssl/certs/ssl-cert-snakeoil.pem
lrwxrwxrwx 1 root root 38 Jun 29 11:55 server.key ->
/etc/ssl/private/ssl- cert-snakeoil.key
安装完成后,可以使用Linux下的服务管理命令service来启停数据库:
osdba@osdba-laptop:~$ sudo service postgresql status
9.1/main (port 5432): online
osdba@osdba-laptop:~$ sudo service postgresql stop
* Stopping PostgreSQL 9.1 database server
[ OK ]
osdba@osdba-laptop:~$ sudo service postgresql start
* Starting PostgreSQL 9.1 database server
[ OK ]
osdba@osdba-laptop:~$
2.1.2在Redhat、CentOS或Fedora下的安装
在Redhat、CentOS或Fedora下可使用yum工具来安装PostgreSQL,但这些系统的软件库中自带的PostgreSQL版本较低,其版本情况见表2-1。
表2-1Linux发行版本自带的PostgreSQL版本
Linux发行版本 自带的PostgreSQL版本
RHEL/CentOS/SL 5 8.1 (also supplies package postgresql84)
RHEL/CentOS/SL 6 8.4
Fedora 16、Fedora 17 9.1
Fedora 18 9.2
如果上面的PostgreSQL版本能满足你的需要,可按下面的步骤进行安装,否则就参照2.3.1节中的内容进行安装。
安装命令如下:
yum install postgresql-server.x86_64
具体安装过程如下:
[root@localhost ~]# yum install postgresql-server.x86_64
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.163.com
* extras: mirrors.163.com
* updates: mirrors.163.com
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package postgresql-server.x86_64 0:8.4.13-1.el6_3 will be installed
--> Processing Dependency: postgresql-libs(x86-64) = 8.4.13-1.el6_3 for package: postgresql-server-8.4.13-1.el6_3.x86_64
--> Processing Dependency: postgresql(x86-64) = 8.4.13-1.el6_3 for package: postgresql-server-8.4.13-1.el6_3.x86_64
--> Processing Dependency: libpq.so.5()(64bit) for package: postgresql-server-8.4.13-1.el6_3.x86_64
--> Running transaction check
---> Package postgresql.x86_64 0:8.4.13-1.el6_3 will be installed
---> Package postgresql-libs.x86_64 0:8.4.13-1.el6_3 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch
Version Repository Size
================================================================================
Installing:
postgresql-server x86_64
8.4.13-1.el6_3 base 3.4 M
Installing for dependencies:
postgresql x86_64
8.4.13-1.el6_3 base 2.8 M
postgresql-libs x86_64
8.4.13-1.el6_3 base 200 k
Transaction Summary
================================================================================
Install 3 Package(s)
Total size: 6.4 M
Installed size: 29 M
Is this ok [y/N]: Y
yum还会让你选择是否把一些依赖的包也安装上,当然要选择“Y”:
Downloading Packages:
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>
Package: centos-release-6-4.el6.centos.10.x86_64
(@anaconda-CentOS-201303020151.x86_64/6.4)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Is this ok [y/N]: Y
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : postgresql-libs-8.4.13-1.el6_3.x86_64
1/3
Installing : postgresql-8.4.13-1.el6_3.x86_64
2/3
Installing : postgresql-server-8.4.13-1.el6_3.x86_64
3/3
Verifying : postgresql-server-8.4.13-1.el6_3.x86_64
1/3
Verifying : postgresql-libs-8.4.13-1.el6_3.x86_64
2/3
Verifying : postgresql-8.4.13-1.el6_3.x86_64
3/3
Installed:
postgresql-server.x86_64 0:8.4.13-1.el6_3
Dependency Installed:
postgresql.x86_64 0:8.4.13-1.el6_3
postgresql-libs.x86_64 0:8.4.13-1.el6_3
Complete!
[root@localhost ~]#
这样就安装好了。
在RedHat下,安装好后,PostgreSQL服务并没有启动:
[root@localhost ~]# service postgresql status
postmaster is stopped
直接启动会报错:
[root@localhost ~]# service postgresql start
/var/lib/pgsql/data is missing. Use "service postgresql initdb" to initialize the cluster first.
[FAILED]
上面是在提示数据库还没有初使用化,请按提示把数据库初使用化:
[root@localhost ~]# service postgresql initdb
Initializing database: [ OK ]
再启动数据库:
[root@localhost ~]# service postgresql status
postmaster (pid 1345) is running...
切换到操作系统下的“postgres”用户,登录数据库:
[root@localhost ~]# su - postgres
-bash-4.1$ psql
psql (8.4.13)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collation | Ctype | Access
privileges
-----------+----------+----------+-------------+-------------+------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
:
postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
:
postgres=CTc/postgres
(3 rows)
postgres=#
这样就可以了。
也可以使用下面的命令把第三方贡献的软件包安装上:
yum install postgresql-contrib.x86_64
在RedHat或CentOS下,默认安装上的PostgreSQL的数据目录在/var/lib/pgsql/data目录下,如下:
-bash-4.1$ ls -l /var/lib/pgsql/data
total 80
drwx------. 5 postgres postgres 4096 Jun 30 11:07 base
drwx------. 2 postgres postgres 4096 Jun 30 11:08 global
drwx------. 2 postgres postgres 4096 Jun 30 11:07 pg_clog
-rw-------. 1 postgres postgres 3411 Jun 30 11:07 pg_hba.conf
-rw-------. 1 postgres postgres 1631 Jun 30 11:07 pg_ident.conf
图 2-1 PostgreSQL官方网站drwx------. 4 postgres postgres 4096 Jun 30 11:07 pg_multixact
drwx------. 2 postgres postgres 4096 Jun 30 11:13 pg_stat_tmp
drwx------. 2 postgres postgres 4096 Jun 30 11:07 pg_subtrans
drwx------. 2 postgres postgres 4096 Jun 30 11:07 pg_tblspc
drwx------. 2 postgres postgres 4096 Jun 30 11:07 pg_twophase
-rw-------. 1 postgres postgres 4 Jun 30 11:07 PG_VERSION
drwx------. 3 postgres postgres 4096 Jun 30 11:07 pg_xlog
-rw-------. 1 postgres postgres 16886 Jun 30 11:07 postgresql.conf
-rw-------. 1 postgres postgres 57 Jun 30 11:08 postmaster.opts
-rw-------. 1 postgres postgres 45 Jun 30 11:08 postmaster.pid
2.1.3 在Windows下的安装
在Windows安装时,先要到官网上下载PostgreSQL的Windows安装包,如图2-1所示。
图 2-1 PostgreSQL官方网站
点页面中的“download”,进入下载页面,如图2-2所示。
图2-2 PostgreSQL官方下载页面
然后选择下载安装包的类型为“Windows”,进入“Windows”安装包的下载界面,如图2-3所示。
图2-3 PostgreSQL Windows版本下载页面
这里需要根据你的Windows是32位的还是64位来选择下载合适的安装包,如图2-4所示。
图2-4 PostgreSQL Windows版本下的各种类型下载页面
因为Windows版本的安装包,是Enterprise DB公司制作的,所以下载时会显示EnterpriseDB公司的界面,如图2-5所示。
图2-5 PostgreSQL Windows版本下载转到EnterpriseDB公司页面
如果在可以下载时就选择运行,那么在下载后,就会直接运行安装程序,当然也可以在下载完后,再双击安装程序,如图2-6所示。
安装程序运行后,即会显示出安装向导,点“Next”即可,如图2-7所示。
进入选择安装目录界面,一般选择默认安装目录即可,可直接点“Next”,如图2-8所示。
进入选择数据目录的界面,根据实际需要,选择具体的目录,然后点“Next”,如图2-9所示。
进入数据库超级用户postgres的密码设置界面,以后可以使用这个超级用户增加更多的数据库用户,设置完后点“Next”,如图2-10所示。
然后进入选择数据库监听端口的界面,如果5432这个端口没有被别的应用程序占用,那么可使用这个默认端口,点“Next”,如图2-11所示。
选择语言,使用默认设置就可以了,点“Next”,如图2-12所示。
进入准备安装的界面,点“Next”,如图2-13所示。
开始安装,如图2-14所示。
安装完毕后,会问你是否需要使用“Stack Builder”安装一些附加的软件。Stack Builder是一个安装PostgreSQL附加软件的图形化工具。如果不需要,可以把选择框中的勾去掉,直接结束安装。
如果没有去掉,则会出现“Stack Builder”的界面,在该界面中会提示你为哪一个PostgreSQL安装附加软件(出现此提示的原因是可以安装多个不同版本的PostgreSQL),如图2-16所示。
这时会出现一个可以选择安装附加软件的界面,根据需要选择了附加软件后,点“Next”,如图2-17所示。
如果是第一次安装,不知道要安装哪些附加软件,可以点取消。以后需要时可以再次运行“Stack Builder”安装相应的附加软件。
2.1.4 发行版安装总结
Windows下的安装是比较简单的,只需要运行图形界面,基本上在安装的过程中点选“Next”项就可以完成安装。
Linux下各发行版本则使用相应版本的包管理器来进行安装即可。
前面曾提到,从发行版本安装PostgreSQL,所安装的一般不是最新版本,如果想安装最新版本的PostgreSQL,则要看下面介绍的方法或见2.3.1节的技巧。
2.2 从源码安装
2.2.1 编译安装过程介绍
这里先把大致的安装过程介绍一下。
第一步:下载源代码。
第二步:编译安装。过程与Linux下其他软件的编译安装过程相同,都是“三板斧”:
./configure
make
make install
第三步:编译安装完成后执行如下步骤。
1)使用initdb命令初使用化数据库簇。
2)启动数据库实例。
3)创建一个应用使用的数据库。
数据库簇是指数据库实例管理的系统文件和各个数据库文件的一个集合。
2.2.2 下载源代码
打开PostgreSQL的官方网站www.postgresql.org,如图2-18所示。
图2-18 PostgreSQL官方网站界面
点击网站菜单中的download,进入下载页面,如图2-19所示。
图2-19 PostgreSQL官方网站中的源代码下载界面
在下载页面中点左侧的“Source”,进入源代码下载页面,如图2-20所示。
图2-20 PostgreSQL官方源码下载中的选择版本界面
在源代码页面中选择合适的版本,比如v9.2.4,如图2-21所示。
图2-21 PostgreSQL官方源码下载中的选择v9.2.4版本界面
然后,在上面的页面中选择合适的压缩包下载就可以了,一般选择bz2的压缩包,因为这种格式体积较小。
2.2.3 编译及安装
默认情况下,安装会用到数据库中的压缩功能,而这个功能的实现需要第三方的压缩开发包zlib支持,在不同的Linux发行版本下,此包的名字会不太一样,但包的名字一般都含有“zlib”和“dev”两个字符串,“dev”是“develop”即开发包的意思。如在Ubuntu12.04下,可以使用下面的方法查找包的名称:
osdba@osdba-laptop:~$ aptitude search zlib |grep dev
p libghc-bzlib-dev - Haskell bindings to the bzip2 library
p libghc-bzlib-dev:i386 - Haskell bindings to the bzip2 library
v libghc-bzlib-dev-0.5.0.3-77459: -
v libghc-bzlib-dev-0.5.0.3-f7d98 -
p libghc-zlib-bindings-dev - low-level bindings to zlib
p libghc-zlib-bindings-dev:i386 - low-level bindings to zlib
v libghc-zlib-bindings-dev-0.1.0. -
v libghc-zlib-bindings-dev-0.1.0. -
p libghc-zlib-conduit-dev - streaming compression/decompression via co
p libghc-zlib-conduit-dev:i386 - streaming compression/decompression via co
v libghc-zlib-conduit-dev-0.4.0.1 -
v libghc-zlib-conduit-dev-0.4.0.1 -
p libghc-zlib-dev - Compression and decompression in the gzip
p libghc-zlib-dev:i386 - Compression and decompression in the gzip
v libghc-zlib-dev-0.5.3.3-78ddb:i -
v libghc-zlib-dev-0.5.3.3-7baa4 -
p libghc-zlib-enum-dev - enumerator interface for zlib compression
p libghc-zlib-enum-dev:i386 - enumerator interface for zlib compression
v libghc-zlib-enum-dev-0.2.2.1-16 -
v libghc-zlib-enum-dev-0.2.2.1-f8 -
p libghc6-bzlib-dev - transitional dummy package
p libghc6-zlib-dev - transitional dummy package
p lua-zlib-dev - zlib development files for the Lua languag
p lua-zlib-dev:i386 - zlib development files for the Lua languag
p zlib1g-dbg - compression library - development
p zlib1g-dbg:i386 - compression library - development
i A zlib1g-dev - compression library - development
p zlib1g-dev:i386 - compression library - development
从上面列出的包来看,只有“zlib1g-dev”的名称与我们需要的zlib开发包最接近,从而确定在Ubuntu12.10上(当然这还需要一些经验)应该安装这个包。
如果想要方便地在psql中使用上下键翻查历史命令,按照PostgreSQL官方手册的说明,还需要安装readline的开发包。与上面的方法类似,先查找包含“readline”和“dev”的包:
osdba@osdba-laptop:~$ aptitude search readline |grep dev
v lib32readline-dev -
p lib32readline-gplv2-dev - GNU readline and history libraries, develo
p lib32readline6-dev - GNU readline and history libraries, develo
v lib64readline-dev:i386 -
p lib64readline-gplv2-dev:i386 - GNU readline and history libraries, develo
p lib64readline6-dev:i386 - GNU readline and history libraries, develo
p libghc-readline-dev - Interface to the GNU readline library
p libghc-readline-dev:i386 - Interface to the GNU readline library
v libghc-readline-dev-1.0.1.0-52b -
v libghc-readline-dev-1.0.1.0-69f -
i libreadline-dev - GNU readline and history libraries, develo
p libreadline-dev:i386 - GNU readline and history libraries, develo
p libreadline-gplv2-dev - GNU readline and history libraries, develo
p libreadline-gplv2-dev:i386 - GNU readline and history libraries, develo
i A libreadline6-dev - GNU readline and history libraries, develo
p libreadline6-dev:i386 - GNU readline and history libraries, develo
从上面列出的包来看,只有“libreadline6-dev”的名称与我们需要的readline开发包最接近,所以应该安装这个包。
把前面下载的压缩包解压,如果该压缩包名称为postgresql-9.2.4.tar.bz2,解压命令则为:
tar xvf postgresql-9.2.4.tar.bz2
对于PostgreSQL8.X的版本,一般编译安装的第一板斧是使用configure命令,如下:
./configure --prefix=/usr/local/pgsql8.4.17 --enable-thread-safety --with-perl --with-python
对于PostgreSQL9.X的版本,一般编译安装的命令如下:
./configure --prefix=/usr/local/pgsql9.2.4 --with-perl --with-python
对比可以发现,在PostgreSQL8.X中,编译命令里有“--enable-thread-safety”选项,而在PostgreSQL9.X中没有这个选项。因为在日常使用中,一般要求客户端是线程安全的,PostgreSQL9.X考虑到这个问题,默认为线程安全的了,而PostgreSQL8.X没有,所以要加上这个选项。
再看看下面两个选项:
--with-perl: 加上这个选项,才能使用perl语法的PL/Perl过程语言写自定义函数,一般都需要。使用这个选项要求先安装perl开发包,该包在Ubuntu或Debian下的名称为:libperl-dev,可使用apt-get install libperl-dev安装。
--with-python:加上这个选项,才能使用python语法的PL/Python过程语言写自定义函数,一般都需要。使用这个选项要求先安装python-dev开发包,该包在Ubuntu或Debian下的名称为:python-dev,可使用apt-get install python-dev安装。
编译安装的第二板斧是运行make命令,这个命令没有什么好说的,直接运行就可以了:
make
按官方文档要求,使用make命令时,其版本要在gmake3.8以上,目前绝大多数的Linux发行版本都满足要求,所以在Linux下一般不需要检查make的版本,但如果是在其他非Linux的UNIX平台上,还是先检查一下make的版本比较好,命令如下:
osdba@osdba-laptop:~$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
在其他的UNIX平台上,有可能存在非GNU的make,这时GNU的make的名称会是gmake。
编译安装的第三板斧是运行make install命令。如果是在一般用户下进行编译的,可能对/usr/local目录没有写的权限,而运行make install命令时是需要使用root权限的,所以在Debian或Ubuntu下可以使用sudo:
sudo make install
在前面我们看到--prefix设置的路径为“/usr/local/pgsql9.2.4”,如果不设置这个路径,默认的路径将是“/usr/local”,为什么要在此路径上加上PostgreSQL的版本号呢?这是为了升级方便。make install命令运行完之后,还要进入/usr/local目录下,为/usr/local/pgsql9.2.4建立一个/usr/local/pgsql的链接:
cd /usr/localL9.2.
sudo ln -sf /usr/local/pgsql9.2.4 /usr/local/pgsql
如果PostgreSQL9.2.5发布了,在编译PostgreSQL9.2.5后,只需把现有的数据库停掉,然后把链接/usr/local/pgsql指向先前的版本/usr/local/pgsql9.2.5即可完成升级。是不是觉得很方便呢?
2.2.4 安装后的配置
安装完后,需要设置PostgreSQL可执行文件的路径:
export PATH=/usr/local/pgsql/bin:$PATH
还要设置共享库的路径:
export LD_LIBRARY_PATH=/usr/local/pgsql/lib
如果想让以上配置对所有的用户生效,可以把以上内容加到/etc/profile文件中,/etc/profile中的内容看起来类似如下:
...
...
...
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
export PATH=/usr/local/pgsql/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql/lib:$LD_LIBRARY_PATH
如果想让以上配置对当前用户生效,在Linux下可以把以上内容加到.bashrc文件中,在其他UNIX下可以加到.profile文件中。
有人问在Linux下为何不加到.profile文件或.bash_profile文件中,这是因为有时在图形界面下打开一个终端,.profile或.bash_profile不会生效。
2.2.5 创建数据库簇
先设定数据库中数据目录的环境变量:
export PGDATA=/home/osdba/pgdata
执行下面的命令创建数据库簇:
initdb
这样就完成了。
2.2.6 安装contrib目录下的工具
contrib下面有一些工具比较实用,一般都会安装上,其安装方法也与Linux下的编译过程相同,如下:
cd postgresql-9.2.3/contrib
make
sudo make install
2.2.7 启动和停止数据库
启动数据库的命令为:
pg_ctl start -D $PGDATA
其中,环境变量$PGDATA指向具体的PostgreSQL数据库的数据目录,看以下示例:
osdba@osdba-laptop:~$ pg_ctl start -D /home/osdba/pgdata
server starting
停止数据库的命令如下:
pg_ctl stop -D $PGDATA [-m SHUTDOWN-MODE]
其中-m是指定数据库的停止方法,有以下三种:
smart:等所有的连接中止后,关闭数据库。如果客户端连接不终止,则无法关闭数据库。
fast:快速关闭数据库,断开客户端的连接,让已有的事务回滚,然后正常关闭数据库。相当于Oracle数据库关闭时的immediate模式。
immediate:立即关闭数据库,相当于数据库进程立即停止,直接退出,下次启动数据库需要进行恢复。相当于Oracle数据库关闭时的abort模式。
PostgreSQL下的immediate关机模式是相当于Oracle中的Abort的关机模式,而Oracle下的immediate关机模式实际上对应的是PostgreSQL下的fast,Oracle DBA尤其要注意这一点。
其中,比较常用的关闭数据库的方法是“fast”方法。
2.2.8 编译安装时的常见问题及解决方法
问题一:./configure时报“error: zlib library not found”错误是怎么回事?报错信息如下:
osdba@ubuntu01:~/src/postgresql-9.2.3$ ./configure
--prefix=/usr/local/pgsql9.2.3 --with-perl --with-python
checking build system type... x86_64-unknown-linux-gnu
....
....
checking for inflate in -lz... no
configure: error: zlib library not found
If you have zlib already installed, see config.log for details on the failure. It is possible the compiler isn't looking in the proper directory.
Use --without-zlib to disable zlib support.
答:这是因为没有安装zlib开发包,安装后将不再报错。
问题二:已安装了“libreadline6”的包,但./configure时仍报“error: readline library not found”错误是怎么回事?报错信息如下:
osdba@ubuntu01:~/src/postgresql-9.2.3$ ./configure
--prefix=/usr/local/pgsql9.2.3 --with-perl --with-python
checking build system type... x86_64-unknown-linux-gnu
...
...
checking for library containing readline... no
configure: error: readline library not found
If you have readline already installed, see config.log for details on the failure. It is possible the compiler isn't looking in the proper directory.
Use --without-readline to disable readline support.
答:包安装错了,是需要安装开发包,即安装libreadline6-dev这个包,而不是libreadline6这个包。
问题三:在运行./configure命令时报以下警告,是否会导致编译出来的PostgreSQL的功能缺失?警告信息如下:
checking for bison... no
configure: WARNING:
*** Without Bison you will not be able to build PostgreSQL from Git nor
*** change any of the parser definition files. You can obtain Bison from
*** a GNU mirror site. (If you are using the official distribution of
*** PostgreSQL then you do not need to worry about this, because the Bison
*** output is pre-generated.)
checking for flex... no
configure: WARNING:
*** Without Flex you will not be able to build PostgreSQL from Git nor
*** change any of the scanner definition files. You can obtain Flex from
*** a GNU mirror site. (If you are using the official distribution of
*** PostgreSQL then you do not need to worry about this because the Flex
*** output is pre-generated.)
答:不会影响编译出来的PostgreSQL功能。这个警告的意思是没有bison和flex是无法使用git方式编译的。这里没有使用git,所以没有关系。bison是自动生成语法分析器的程序,flex则是自动生成词法分析器的程序,在PostgreSQL主要用于SQL的词法解析和语法解析。因为在源码包中已经生成了词法解析和语法解析的C源代码,所以没有bison和flex,也能正常编译。当然也可以把bison和flex这两个工具安装上,命令如下:
sudo aptitude install bison flex
问题四:在运行make时报“cannot find -lperl”的错误为什么?报错信息如下:
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith
-Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard
-fpic -shared -o plperl.so plperl.o SPI.o Util.o -L../../../src/port
-Wl,--as-needed -Wl,-rpath,'/usr/lib/perl/5.14/CORE',--enable-new-dtags
-fstack-protector -L/usr/local/lib -L/usr/lib/perl/5.14/CORE -lperl -ldl -lm
-lpthread -lc -lcrypt
/usr/bin/ld: cannot find -lperl
collect2: error: ld returned 1 exit status
make[3]: *** [plperl.so] Error 1
make[3]: Leaving directory `/home/osdba/src/postgresql-9.2.3/src/pl/plperl'
make[2]: *** [all-plperl-recurse] Error 2
make[2]: Leaving directory `/home/osdba/src/postgresql-9.2.3/src/pl'
make[1]: *** [all-pl-recurse] Error 2
make[1]: Leaving directory `/home/osdba/src/postgresql-9.2.3/src'
make: *** [all-src-recurse] Error 2
答:这是在./configure时加了--with-perl,却没有安装perl开发包导致的。注意,若没有安装perl开发包,在运行./configure时并不报错,而是到运行make命令的时候才报错。在Debian或Ubuntu下,只要安装libperl-dev包即可:
sudo aptitude install libperl-dev
2.3 安装技巧介绍
2.3.1 在Redhat、CentOS下使用二进制包安装较新版本的方法
如果认为Redhat或CentOS上自带的PostgreSQL版本太低,想要使用新版本,可以使用下面的方法安装。
使用PostgreSQL官方的RPM包,将新版本信息加到版本库中:
rpm -i
http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/pgdg-redhat92-9.2-7.noarch.rpm
然后使用yum install 命令安装新版本:
yum install postgresql92-server.x86_64
再使用1.1.2节介绍的方法安装新版本的PostgreSQL:
[root@localhost ~]# service postgresql-9.2 status
is stopped
[root@localhost ~]# service postgresql-9.2 initdb
Initializing database: [ OK ]
[root@localhost ~]# service postgresql-9.2 start
Starting postgresql-9.2 service: [ OK ]
登录数据库:
[root@localhost ~]# su - postgres
-bash-4.1$ psql
psql (9.2.4)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access
privileges
-----------+----------+----------+-------------+-------------+------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
+
| | | | |
postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
+
| | | | |
postgres=CTc/postgres
(3 rows)
postgres=# \q
使用下面命令把相关的第三方贡献包也安装上:
yum install postgresql92-contrib.x86_64
新版本的PostgreSQL的数据目录在/var/lib/pgsql/<version>/data目录下,“version”代表PostgreSQL的版本,如9.2版本就安装在/var/lib/pgsql/9.2/data目录下。
2.3.2 如何使用较大的数据块提高I/O性能
在数据仓库中使用PostgreSQL时,若希望使用较大的数据块提高I/O性能怎么办?要解决这类问题,只能采用从源码安装的方法,在执行./configure命令时指定较大的数据块,一般也需要指定较大的WAL日志块和WAL日志文件的大小。如想指定128KB的数据块、128KB的WAL日志块、64MB的WAL日志文件,则configure命令如下:
./configure --prefix=/usr/local/pgsql9.2.4 --with-perl --with-python
--with-blocksize=128 --with-wal-blocksize=128 --with-wal-segsize=64
使用此时编译出来的PostgreSQL程序创建的PostgreSQL数据库,不能使用其他块大小的PostgreSQL程序启动。
2.4 PostgreSQL的简单配置
本节将简单介绍PostgreSQL的配置方法,更具体的配置操作会在后面的章节中介绍。PostgreSQL数据库的配置主要是通过修改数据目录下的postgresql.conf文件来实现的。
2.4.1 修改监听的IP和端口
在数据目录下编辑postgresql.conf文件,找到如下内容:
#listen_addresses = 'localhost' # what IP address(es) to listen on;
#port = 5432 # (change requires restart)
其中,参数“listen_addresses”表示监听的IP地址,默认是在“localhost”处监听,也就是“127.0.0.1”的IP地址上监听,这会让远程的主机无法登录这台数据库,如果想从其他的机器上登录这台数据库,需要把监听地址改成实际网络的地址,一种简单的方法是,把这个地址改成“*”,表示在本地的所有地址上监听。
参数“port”表示监听的数据库端口,默认为“5432”,可以不更改。如果一台机器上安装了几个数据库实例(如安装了几个不同版本的PostgreSQL),可以设置为不同的端口。
修改了这两个参数后,需要重启数据库才能生效。
2.4.2 与数据库log相关的参数
来看看与log相关的几个参数:
日志的收集一般是要打开的,所以需要设置:
logging_collector = on
日志的目录一般使用默认值就可以了:
log_directory = 'pg_log'
日志的切换和是否选择覆盖则可以使用如下几种方案。
方案一:每天生成一个新的日志文件。
配置方法如下:
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_truncate_on_rotation = off
log_rotation_age = 1d
log_rotation_size = 0
方案二:每当日志写满一定的大小(如10MB空间),则切换一个日志。
配置方法如下:
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_truncate_on_rotation = off
log_rotation_age = 0
log_rotation_size = 10M
方案三:只保留7天的日志,进行循环覆盖。
配置方法如下:
log_filename = 'postgresql-%a.log' #
log_truncate_on_rotation = on
log_rotation_age = 1d
log_rotation_size = 0
2.4.3 内存参数的设置
PostgreSQL安装完毕后,可以修改以下两个主要内存参数。
shared_buffers:共享内存的大小,主要用于共享数据块。
work_mem:单个SQL执行时,排序、hash join所使用的内存,SQL运行完后,内存就释放了。
shared_buffers默认值为32MB,work_mem为1MB,如果你的机器上有足够的内存,可以把这个参数改得大一些,这样数据库就可以缓存更多的数据块,当读取数据时,就可以从共享内存中读,而不需要再从文件上去读取。
work_mem设置大一些,会让排序操作快一些。
2.5 小结
本章讲解了PostgreSQL在不同平台下的二进制安装方法,以及从源代码进行安装的方法。从前面的叙述中可以看出,在多数Linux发行版本中都自带了PostgreSQL的二进制安装包,可以直接使用Linux发行版本中的包管理器进行安装。不过这些自带的PostgreSQL版本都比较旧,如果想安装较新的PostgreSQL版本,可以从源代码进行编译安装。源代码编译安装也比较简单,要注意的是,需要先把一些依赖的开发包安装上。
第3章
SQL语言入门
SQL是结构化查询语言(STRUCTURED QUERY LANGUAGE)的简称,它是最重要的关系型数据库操作语言,并且它的影响已经超出了数据库领域。比如,在Hadoop中的Hive就是一个SQL接口。
本章将介绍一些通用的、最基础的SQL语法知识,以便于没有接触过数据库的读者能掌握最基础的数据库知识。这些使用语法不仅适用于PostgreSQL数据库,也适用于其他关系型数据库,如MySQL、Oracle。本章是为从没有接触过SQL的读者准备的,对于已有SQL基础的读者,可以略过此章。
3.1 SQL语句语法简介
3.1.1 语句的分类
SQL命令一般分为DQL、DML、DDL几类。
DQL:数据查询语句,基本就是SELECT查询命令,用于数据查询。
DML:Data Manipulation Language的简称,即数据操纵语言,主要用于插入、更新、删除数据,所以也分为INSERT、UPDATE、DELETE三种语句。
DDL:Data Definition Language的缩写,即数据定义语言,主要用于创建、删除,以及修改表、索引等数据库对象语言。
3.1.2 词法结构
每次执行的SQL可以由多条SQL命令组成。多条SQL命令之间由分号(“;”)分隔。
每个SQL命令由一系列的记号组成,这些记号可以由关键字、标识符、双引号包围的标识符、常量、单引号包围的文本常量和特殊的字符等组成。在 SQL 命令里可以有注释,这些注释在PostgreSQL中等效于空白。
举个例子,下面的命令从SQL的语法上来说是合法的:
SELECT * FROM OSDBA_TABLE01;
UPDATE OSDBA_TABLE SET COL1 = 614;
INSERT INTO OSDBA_TABLE VALUES (232, 'hello osdba');
该SQL由三条命令组成。在SQL中,多行命令可以在一行中,也可以在多行中。此外,单条命令也可以占用多行。
SQL命令并未严格地像计算机语言一样明确标识哪些是命令、哪些是操作数或参数。SQL的语法主要是让你比较直观地理解其意思。比如,查询一个表的数据,就是由“SELECT”+“要查询的各列”+“FROM 表”这样的语法组成的。后面的几节会详细叙述SQL的用法。
3.2 DDL语句
DDL语句是创建、修改和删除表的语句,想要掌握SQL语言,必须对它有一定的了解。
3.2.1 建表语句
表是关系型数据库中最基本的对象,数据库中的表与实际生活中的二维表格很相似,有很多列也有很多行,每一列有一个名称,不同的列有不同的数据类型,比如,列可能是数字、文本字符串,也可能是日期类型。建表语句的一个简单语法如下:
CREATE TABLE table_name (
col01_namme data_type,
col02_namme data_type,
col03_namme data_type,
col04_namme data_type,
};
其中“CREATE”、“TABLE”为关键字,是不变的,从字面上也很好理解,表示创建表。“table_name”表示表名,“col01_name”、 “col02_name”、 “col03_name”、 “col04_name”分别表示列名。“data_type”表示数据类型,不同的数据库系统有不同的数据类型名称,即使是相同意思的整数类型,在不同的数据库系统中也有不同的类型名称。变长的字符串在大多数数据库中都可使用 “varchar”类型,比如PostgreSQL、MySQL和Oracle数据库等。整形数据在PostgreSQL和MySQL都可以使用“int”类型。日期类型的名称一般为“date”。例如,要创建一张分数表score,包括“学生名称(student_name)”、“语文成绩(chinese_score)”、“数学成绩(math_score)”、“考试日期(test_date)”四列,则创建这个表的SQL如下:
CREATE TABLE score (
student_name varchar(40),
chinese_score int,
math_score int,
test_date date
);
如果按前面的安装步骤安装完了数据库,之后就可以使用psql工具连接到PostgreSQL数据库了,执行上面的建表语句,如下:
osdba=# CREATE TABLE score (
osdba(# student_name varchar(40),
osdba(# chinese_score int,
osdba(# math_score int,
osdba(# test_date date
osdba(# );
CREATE TABLE
osdba=#
在psql中,可使用\d显示数据库中有哪些表,如下:
osdba=# \d
List of relations
Schema | Name | Type | Owner
--------+-------+-------+-------
public | score | table | osdba
(1 row)
这样就看到了我们建的表。
使用“\d score”可以显示这张表的定义情况:
osdba=# \d score
Table "public.score"
Column | Type | Modifiers
---------------+-----------------------+-----------
student_name | character varying(40) |
chinese_score | integer |
math_score | integer |
test_date | date |
显示列的类型“character varying(40)”实际上与“varchar(40)”的意思是完全一样的,“int”与“integer”的意思也是一样的。
在建表的时候,可以指定表的主键,主键是表中行的唯一标识,这个唯一标识是不能重复的。在创建表的语句中,可以在列定义后面用“primary key”来指定这一列为主键,如下面的学生表:
CREATE TABLE student(no int primary key, student_name varchar(40), age int);
在该表中,学号(no)为主键,则在该列的定义后面加了“primary key”。在psql中演示如下:
osdba=# CREATE TABLE student(no int primary key, student_name varchar(40), age int);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "student_pkey" for table "student"
CREATE TABLE
细心的读者会注意到“NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "student_pkey" for table "student"”这句提醒,它表示系统为主键自动创建了一个隐含的索引“student_pkey”。
3.2.2 删除表语句
删除表的语法比较简单,如下:
DROP TABLE table_name;
其中“table_name”表示要删除的表名。假设要删除前面创建的表student,则可以使用下面的SQL:
DROP TABLE student;
3.3 DML语句
DML用于插入、更新和删除数据。主要包含INSERT语句、UPDATE语句和DELETE语句。
3.3.1 插入语句
可以使用下面的语句往前面创建的学生表(student)中插入数据:
INSERT INTO student VALUES(1, '张三', 14);
由此可以看出,INSERT语句的语法为:以“INSERT INTO”关键字为首,后面跟表名,然后再跟“VALUES”关键字,最后是由小括号包围起来的以逗号分隔的各列数据,数据的顺序与表定义时表列的顺序是一样的。当然也可以在表名后指定要插入数据列的顺序,如下所示:
INSERT INTO student(no, age, student_name) VALUES(2, 13, '李四');
在插入数据时,也可以指定某些列不插入数据,这时这些列的数据会被置为空,如下:
INSERT INTO student(no, student_name) VALUES(2, '王二');
如果在psql中执行了下面的语句,使用SELECT语句就可以查询出数据,查询的语句为:
SELECT * FROM student;
SELECT语句的具体用法会在后面的章节中介绍,现在只需要知道这么用就可以了。
我们查看到的数据如下:
osdba=# select * from student;
no | student_name | age
----+--------------+-----
1 | 张三 | 14
2 | 李四 | 13
3 | 王二 |
(3 rows)
从上面可以看出,在插入数据时,没有提供的列数据会被置为NULL。
3.3.2 更新语句
假设要把student表中所有学生的年龄(age)更新为“15”,则更新语句如下:
UPDATE student SET age = 15;
从上面的语句可以看出,更新语句以“UPDATE” 关键字开始,后面跟表名,然后是“SET”关键字,表示要设置的数据,再后面就是要设置的数据的表达式“age = 15”,设置数据的表达式也很简单,就是“列名=数据”的格式。
实际执行的效果如下:
osdba=# UPDATE student SET age = 15;
UPDATE 3
osdba=# select * from student;
no | student_name | age
----+--------------+-----
1 | 张三 | 15
2 | 李四 | 15
3 | 王二 | 15
(3 rows)
在更新数据时,还可以指定过滤表达式“WHERE”,从而指定更新哪条数据或哪些数据,比如,要更新学号(no)为3的学生年龄为14岁,则使用下面的语句:
UPDATE student SET age =14 WHERE no = 3;
在SET子句中,还可以同时更新多个列的值,如下所示:
UPDATE student SET age =13, student_name='王明充' WHERE no = 3;
3.3.3 删除语句
如果想删除学号(no)为3的记录,语句如下:
DELETE FROM student WHERE no = 3;
由此可见删除语句比较简单,以“DELETE FROM”开始,后面跟表名,然后加“WHERE”子句用于指定要删除的记录。
当然也可以没有“WHERE”子句,这表明要删除整个表的数据,删除表student中所有数据的语句如下:
DELETE FROM student;
3.4 查询语句
3.4.1 单表查询语句
查询student表中所有数据的语句为:
select no, student_name, age from student;
其中“SELECT”是关键字,表示要查询,后面跟多个列名,各列之间使用逗号分隔。其后的“FROM”是关键字,后面跟表的名称。各个列可以是表的列名,也可以是一个表达式,如下:
select age+5 from student;
表达式中可以包括表的列,也可以只是一个与表列无关的表达式,如下:
select no, 3+5 from student;
当表达式与表的列无关时,在PostgreSQL和MySQL中可以不使用“FROM 表名”,这样一来,就可以当作计算器使用了:
osdba=# select 55+88;
?column?
----------
143
(1 row)
osdba=# select 10*2,3*5+2;
?column? | ?column?
----------+----------
20 | 17
(1 row)
如果想查询表中所有列的数据,则可以使用“*”代表所有列,如下:
select * from student;
3.4.2 过滤条件的查询
SELECT语句后面可以通过指定WHERE子句来指定要查询哪条记录或哪些记录。比如,要查询学号为3的记录,其SQL语句为:
osdba=# SELECT * FROM student where no=3;
no | student_name | age
----+--------------+-----
3 | 王明充 | 13
(1 row)
在WHERE条件中也可以使用大于、小于的表达式。比如,想查询年龄大于等于15岁的学生,其语句如下:
osdba=# SELECT * FROM student where age >= 15;
no | student_name | age
----+--------------+-----
1 | 张三 | 15
2 | 李四 | 15
(2 rows)
3.4.3 排序
使用排序子句可以对查询出的数据进行排序,排序子句是在SELECT语句后面再加上“ORDER BY”子句。比如,希望查询出来的结果按年龄排序,则查询语句如下:
osdba=# SELECT * FROM student ORDER BY age;
no | student_name | age
----+--------------+-----
3 | 王明充 | 13
1 | 张三 | 15
2 | 李四 | 15
(3 rows)
排序子句“ORDER BY”应该在“WHERE”子句之前,如果顺序错了,会报错:
osdba=# SELECT * FROM student ORDER BY age WHERE age >= 15;
ERROR: syntax error at or near "WHERE"
LINE 1: SELECT * FROM student ORDER BY age WHERE age >= 15;
把“ORDER BY”子句放到“WHERE”子句后面就不报错了:
osdba=# SELECT * FROM student WHERE age >= 15 ORDER BY age;
no | student_name | age
----+--------------+-----
1 | 张三 | 15
2 | 李四 | 15
(2 rows)
还可以按多个列进行排序。比如,根据“age”和“student_name”两个列来排序:
osdba=# SELECT * FROM student ORDER BY age,student_name;
no | student_name | age
----+--------------+-----
3 | 王明充 | 13
2 | 李四 | 15
1 | 张三 | 15
(3 rows)
也可以在排序子句的列名后加“DESC”进行倒序排序:
osdba=# SELECT * FROM student ORDER BY age DESC;
no | student_name | age
----+--------------+-----
1 | 张三 | 15
2 | 李四 | 15
3 | 王明充 | 13
(3 rows)
osdba=# SELECT * FROM student ORDER BY age DESC,student_name;
no | student_name | age
----+--------------+-----
2 | 李四 | 15
1 | 张三 | 15
3 | 王明充 | 13
(3 rows)
3.4.4 分组查询
如果需要统计不同年龄的学生人数,可以使用分组查询,分组查询子句的关键字为“GROUP BY”,用法如下:
osdba=# SELECT age, count(*) FROM student GROUP BY age;
age | count
-----+-------
15 | 2
13 | 1
(2 rows)
从上面可以看出,使用“GROUP BY”语句时,需要使用聚合函数,常用的聚合函数为“count”、“sum”等。
3.4.5 表join
表join也称为多表关联查询。假设有一张班级表class,建表语句为:
CREATE TABLE class(no int primary key, class_name varchar(40));
表中的“no”表示班级编号,“class_name”表示班级名称。
插入一些测试数据:
osdba=# INSERT INTO class VALUES(1,'初二(1)班');
INSERT 0 1
osdba=# INSERT INTO class VALUES(2,'初二(2)班');
INSERT 0 1
osdba=# INSERT INTO class VALUES(3,'初二(3)班');
INSERT 0 1
osdba=# INSERT INTO class VALUES(4,'初二(4)班');
INSERT 0 1
osdba=# SELECT * FROM class;
no | class_name
----+------------
1 | 初二(1)班
2 | 初二(2)班
3 | 初二(3)班
4 | 初二(4)班
(4 rows)
还有另一张学生表student,建表语句为:
CREATE TABLE student(no int primary key, student_name varchar(40), age int, class_no int);
也插入一些数据:
osdba=# INSERT INTO student VALUES(1, '张三', 14, 1);
INSERT 0 1
osdba=# INSERT INTO student VALUES(2, '吴二', 15, 1);
INSERT 0 1
osdba=# INSERT INTO student VALUES(3, '李四', 13, 2);
INSERT 0 1
osdba=# INSERT INTO student VALUES(4, '吴三', 15, 2);
INSERT 0 1
osdba=# INSERT INTO student VALUES(5, '王二', 15, 3);
INSERT 0 1
osdba=# INSERT INTO student VALUES(6, '李三', 14, 3);
INSERT 0 1
osdba=# INSERT INTO student VALUES(7, '吴二', 15, 4);
INSERT 0 1
osdba=# INSERT INTO student VALUES(8, '张四', 14, 4);
INSERT 0 1
osdba=# SELECT * FROM student;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
2 | 吴二 | 15 | 1
3 | 李四 | 13 | 2
4 | 吴三 | 15 | 2
5 | 王二 | 15 | 3
6 | 李三 | 14 | 3
7 | 吴二 | 15 | 4
8 | 张四 | 14 | 4
若现在想查询出每个学生与班级的关系,那么此时就需要关联查询两张表:
SELECT student_name, class_name FROM student, class
WHERE student.class_no = class.no;
查询出来的结果如下:
osdba=# SELECT student_name, class_name FROM student, class
WHERE student.class_no = class.no;
student_name | class_name
--------------+------------
张三 | 初二(1)班
吴二 | 初二(1)班
李四 | 初二(2)班
吴三 | 初二(2)班
王二 | 初二(3)班
李三 | 初二(3)班
吴二 | 初二(4)班
张四 | 初二(4)班
(8 rows)
表关联查询就是在WHERE条件上加上需要关联的条件(两张表关联):
WHERE student.class_no = class.no;
由于在两张表中,有一些列的名称是重复的,如在表student中no表示学生号,而在表class中表示班级号,所以在关键条件中要明确使用“表名”加“列名”来唯一定位这个列。如果输入的表名比较长,不是很方便,这时可以给表起个别名,如下所示:
SELECT student_name, class_name FROM student a, class b
WHERE a.class_no = b.no;
上面的语句中,给表“student”起的别名为“a”,表“class”的别名为“b”,这时条件表达式中“b.no”就代表了表“class”中的“no”列。
在关联查询的WHERE子句中可以再加上其他的过滤条件,如下:
osdba=# SELECT student_name, class_name FROM student a, class b
WHERE a.class_no = b.no AND a.age > 14;
student_name | class_name
---------------+------------
吴二 | 初二(1)班
吴三 | 初二(2)班
王二 | 初二(3)班
吴二 | 初二(4)班
(4 rows)
3.5 其他SQL语句
3.5.1 INSERT INTO... SELECT语句
使用INSERT INTO... SELECT语句可以把数据从一张表插入到另一张表中,这个语句属于DML语句。
假设建了一张学生表的备份表:student_bak
CREATE TABLE student_bak(no int primary key, student_name varchar(40), age int, class_no int);
可以使用下面的语句把数据备份到下面这张备份表中:
INSERT INTO student_bak SELECT * FROM student;
实际演示如下:
osdba=# INSERT INTO student_bak SELECT * FROM student;
INSERT 0 8
osdba=# SELECT * FROM student_bak;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
2 | 吴二 | 15 | 1
3 | 李四 | 13 | 2
4 | 吴三 | 15 | 2
5 | 王二 | 15 | 3
6 | 李三 | 14 | 3
7 | 吴二 | 15 | 4
8 | 张四 | 14 | 4
(8 rows)
3.5.2 UNION语句
可以将从两张表查询出来的数据整合在一个结果集下,如:
SELECT * FROM student WHERE no = 1 UNION SELECT * FROM student_bak where no = 2;
这里的语法比较简单,把两个SQL用“UNION”关键字连接起来就可以了。
结果如下:
osdba=# SELECT * FROM student WHERE no = 1 UNION SELECT * FROM student_bak where no = 2;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
2 | 吴二 | 15 | 1
(2 rows)
注意,UNION可以把结果集中相同的两条记录合并成一条:
osdba=# SELECT * FROM student WHERE no = 1 UNION SELECT * FROM student_bak where no = 1;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
(1 row)
如果不想合并,请使用UNION ALL,如下:
osdba=# SELECT * FROM student WHERE no = 1 UNION ALL SELECT * FROM student_bak where no = 1;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
1 | 张三 | 14 | 1
(2 rows)
3.5.3 TRUNCATE TABLE语句
TRUNCATE TABLE语句的用途是清空表内容。不带WHERE条件子句的DELETE 语句也表示清空表的内容。从执行结果看,两者实现了相同的功能,但两者实现的原理是不一样的。
TRUNCATE TABLE是DDL语句,即数据定义语句,相当于用重新定义一个新表的方法把原先表的内容直接丢弃了,所以TRUNCATE TABLE执行起来很快,而DELETE 是DML语句,可以认为DELETE 是把数据一条一条地删除,若要删除很多行数据,就会比较慢。
如果想把表student_bak中的数据清理掉,则可以使用如下命令:
TRUNCATE TABLE student_bak;
3.6 小结
从前面的叙述可以看出,SQL语言是一种声明式编程语言,与命令式编程语言有较大的差异。声明式编程语言主要是描述用户需要做什么,需要得到什么结果的,不像命令式编辑需要描述怎么做,过程是什么。SQL语言能够智能地实现用户的需要,而不需要用户去关心具体的运行过程。完全用SQL写一个应用程序是不可能的,但非计算机专业人士也可以使用SQL,因为SQL是直观易懂的。
带你读《数据库与数据处理:Access 2010 实现 第2版》之一:数据处理与数据库
计算机基础课程系列教材点击查看第二章点击查看第三章数据库与数据处理:Access 2010 实现 第2版
张玉洁 孟祥武 编著
第1章
数据处理与数据库早期计算机主要用于科学计算,数据类型单一。随着计算机技术的发展以及计算机的益普及,计算机应用已经远远超出了这个范畴。如今面对各种类型的海量数据,利用计算机做得更多的是进行数据处理。数据处理不仅广泛应用于电信、银行、证券、航空、教育、出版、气象等领域,而且在地质勘探测绘、仓库管理、技术情报管理、销售、制造、智能交通、电子商务等领域也呈现出勃勃生机。数据处理离不开软件的支持,常用的数据处理软件包括:用于管理数据的文件系统和数据库管理系统,用于编写各种处理程序的高级程序设计语言及其编译、解释程序,以及各种数据处理方法的应用软件包等。
1.1 数据处理
数据和信息的关系非常密切,多数情况下没有严格的区分。信息处理从根本上离不开数据,因此信息处理实质上就是数据处理。而数据处理的最终结果是以信息或知识的方式展示给用户,所以数据处理也称为信息处理。但在某些特定的环境下,数据和信息还是两个不同的概念,不能混用,比如,不能将数据文件说成信息文件等。
1.1.1 数据与信息
1. 数据数据是对客观世界中各种事物的一种抽象、符号化的表示。它采用一种人为规定的符号来表示从现实世界中观察和收集到的现象和事实。数据的表现形式很多,可以是数字、文字、时间,也可以是图形、图像、动画、声音等多媒体形式。从计算机的角度看,数据泛指可以被计算机接受并能被计算机处理的符号。从数据库的角度看,数据就是数据库中存储的基本对象。数据有型与值之分。数据的型给出了该数据所属数据类型的说明,如整型、字符型、布尔型等;数据的值给出了符合给定型的数值,值是型的一个实例。数据的型相当于程序设计语言中变量的类型说明,数据的值相当于变量的取值。数据的型基本上相对稳定,数据的值则是不断变化的。2. 信息信息源于拉丁文“Information”,是指一种陈述或解释、理解等。数据经过解释并赋予一定的含义之后,就成为信息,即信息是根据需要对数据进行加工处理后得到的结果。3. 数据与信息的关系数据是信息的符号表示,是信息的具体表现形式,信息只有通过数据的形式表示出来才能被理解和接受。信息是数据的内涵,即数据的语义,信息在计算机中的存储即为数据。信息是观念上的,受制于人对客观事物变化规律的认知。例如,一个数字40的语义可能是年龄为40岁、体重为40公斤、价格为40元、考试成绩为40分、苹果为40个、书为40本等,也可能是高烧40度、水深40米、雨量达到40毫米、血压低压为40等。又比如,文字“黎明”的语义可能是一个词语,表示天快要亮或刚亮的时候,也可能是名称,如某人的姓名、壁画的名字、绘本的名字等。数据要符合其语义,数据与其语义是不可分的。数据库系统要保证数据库中的数据符合其语义。
1.1.2 数据处理与数据管理
数据处理的发展及应用的广度和深度,极大地影响着人类社会发展的进程。数据处理,也称信息处理,是将数据加工成信息的过程,具体指利用计算机对各种数据(包括数值数据和非数值数据)进行收集、整理、存储、分类、排序、检索、维护、加工、统计、传输等一系列活动的总和。数据处理的主要目的之一是从大量无序、难以理解的数据中,抽取并推导出有用的数据成分,作为行为和决策的依据。数据处理贯穿于社会生产和社会生活的各个领域。通常,数据处理的计算方法和过程比较简单,但处理的数据量通常很大,数据结构复杂,因此,数据处理的重点不是计算,而是数据管理。数据管理是数据处理的核心,主要功能包括数据的收集和分类、数据的表示和存储、数据的定位与查找、数据的维护和保护、提供数据访问接口和数据服务(如性能检测分析、可视化界面服务)等。数据处理与数据管理密切相关,数据管理技术的优劣直接影响数据处理的效果,数据库技术正是针对这一目标进行研究、发展并逐渐完善起来的专门技术。数据是数据库技术的研究目标,数据处理是数据库技术的应用方向,而数据管理则是数据库技术研究的主要内容。
1.1.3 数据管理简史
数据管理作为计算机应用领域中最大的一类应用,随着应用需求和计算机软硬件的发展,主要经历了人工管理、文件管理和数据库管理三个发展阶段。1. 人工管理阶段20世纪50年代中期之前,计算机主要用于科学计算。数据存储设备主要是卡片、纸带和磁带。没有操作系统和数据管理软件,数据需要人工管理。数据不保存,随用随丢。应用程序和数据不可分割,数据完全依赖于应用程序,不具有独立性,因而数据无法共享。该阶段应用程序与数据之间的对应关系如图l-1表示。
2. 文件管理阶段20世纪50年代后期至60年代中期,计算机技术有了很大的发展,开始广泛应用于信息处理。数据存储设备主要是磁盘、磁鼓。磁盘是一种随机存取设备,允许用户直接访问数据,摆脱了磁带顺序访问的限制。该阶段出现了操作系统,并使用专门的管理软件即文件系统(操作系统中的文件管理功能)来实施数据管理。数据可以长期保存在磁盘上,应用程序和数据有了一定的独立性,数据文件有了一定的共享性,但存在较大的数据冗余。在文件系统中,数据的逻辑结构和输入/输出格式由程序员在程序中进行定义和管理,数据的物理存储和存取方法则由文件系统提供。一个命名的数据集合称为一个文件,文件中的数据被组织成记录的形式,记录由字段组成。一个个文件彼此是孤立的,缺乏联系。应用程序只需使用文件名就可以与数据打交道,而不必关心数据的物理位置。图1-2给出了一个使用文件系统进行数据管理的示例。假设学生处应用程序需要学生文件F1,该文件包含了学生的基本信息。教务处应用程序需要学生信息文件F1、课程文件F21、选课文件F22、授课文件F23以及教工文件F3。人事处应用程序需要教工文件F3,该文件包含了教工的基本信息。这些文件的结构如下:F1:学号、姓名、性别、出生日期、所在院系、专业、班级、联系电话、宿舍地址F21:课程号、课程名、授课学期、学分、课程性质、开课学院F22:学号、姓名、所在院系、专业、班级、课程号、课程名、授课学期、学分、成绩F23:教师号、教师姓名、性别、职称、课程号、课程名、授课学期、学分、课程性质、授课年度F3:教工号、姓名、性别、出生日期、所在院系、最终学历、职称、联系电话、家庭住址
仔细分析这些数据的组织方式后发现,使用文件系统来管理数据存在如下一些缺点:(1)数据共享差,同样的数据在多个文件中重复存储,冗余较大学生的学号、姓名、所在院系、专业、班级等基本信息既保存在学生文件F1中,又保存在F22中;课程的课程号、课程名、授课学期、学分、课程性质既保存在F21中,又保存在F23中;教师的教师号、姓名、性别、职称等基本信息既保存在F3中,又保存在F23中。这样的数据组织方式使得相同数据重复保存,不能被共享,既浪费空间,又会影响数据的完整性。比如,某个学生转专业了,那么所有包含这些数据的文件都必须更新,以保持数据的完整性。然而,文件系统不具备维护数据一致性的功能,不会自动完成这些更新,需要人工完成,当数据重复存储在多处时,很难保证每一处都能及时更新,这样很容易造成数据的不一致,从而失去数据的可信性。(2)文件是孤立存在的,数据是分离的由于文件系统不具备自动实现数据之间关联的功能,无法反映现实世界事物之间的内在联系,文件之间相互独立,所以要建立文件之间的联系,必须通过应用程序来构造。比如,若查询某位教师所教授的某门课的学生信息,需要以某种方式将多个文件关联,以图1-2为例,至少需要将F1、F22、F23三个文件进行关联,从中提取需要的数据并组成一个新的文件。(3)数据的独立性差,程序和数据没有真正分离文件系统中,应用程序依赖文件的结构,每一次修改文件结构,都要修改相应的应用程序。例如,如果修改学生文件F1中专业的字段长度,或者在F1中增加或删除一个字段,那么所有使用F1文件的应用程序都必须修改。(4)文件系统提供的操作有限文件系统只提供了几个低级的文件操作命令,如果需要进行文件的查询、修改,则需要编写相应的应用程序来实现,而且功能相同的操作也很难共享应用程序。此外,文件系统很难控制用户的某些文件操作,比如,只能读写文件但不能删除文件,或者只能读文件中的部分数据等。3. 数据库管理阶段20世纪60年代后期,随着应用需求的增加、软硬件技术发展的日趋成熟,计算机用于信息处理的规模越来越大,对数据管理技术的要求也越来越高,原有的文件系统已经不能胜任数据管理的任务。与此同时,计算机网络系统和分布式系统的相继出现,导致急需一种新的能够在多用户环境下进行数据共享和处理的数据管理软件。在这个背景下,数据库管理系统(DataBase Management System, DBMS)应运而生。在数据库管理阶段,数据由DBMS统一管理和控制,包括数据的安全性控制、数据的完整性控制、并发控制以及数据库恢复等,实现整体数据的结构化,数据的结构使用数据模型来描述,无须程序定义和解释。数据面向整个系统,可以被多个用户或应用程序共享,提高了数据的共享性,减少了数据冗余,保证了数据的一致性和完整性。数据与应用程序相对独立,减少了应用程序开发和维护的成本。数据库管理阶段,应用程序与数据之间的对应关系如图l-3所示。
数据库管理系统的出现,使得以数据库为中心的数据库管理技术(简称数据库技术)成为计算机领域发展最快的技术之一。
1.1.4 数据库技术的发展和未来
1. 关系型数据库技术在数据库管理阶段,首先出现的是层次数据库管理系统和网状数据库管理系统,到了20世纪70年代出现了关系型数据库管理系统(Relational DataBase Management System, RDBMS),它基于E. F. Codd所提出的关系数据模型,这种数据模型最大的优点在于数据的逻辑结构简单,就是二维表(也称关系)。在目前使用的数据处理软件中,RDBMS占据了统治地位。从甲骨文公司的Oracle,到IBM的DB2和Informix、Sybase公司的Sybase、微软公司的SQL Server和Access,再到开源软件MySQL(Oracle公司)、PostgreSQL等,这些关系型数据库管理系统被广泛应用于各个不同的行业领域。关系型数据库技术的主要特点如下:
采用关系模型表示复杂的数据结构。关系型数据库将所有的数据以行和列的二元表现形式保存在一个规范的二维表中,有严格的字段定义和数据类型约束,对数据的读写以行(即记录)为单位。
采用SQL技术标准对数据库进行定义、操作和控制,增加了软件的可移植性。
在数据处理中严格遵守ACID原则,采用强事务保证数据的一致性和安全性。
可以对多个数据表进行JOIN操作,以完成复杂的查询任务。
尽可能解决尽可能多的数据处理和应用问题,因而常作为通用型的数据库技术。
关系型数据库技术也存在一些不足,比如,不适合大数据写入处理的场景,数据管理规模和访问速度受服务器物理性能(指硬盘、内存、CPU、主板总线等硬件最大性能指标)的限制,横向扩充(即构成多服务器集群)存在困难。随着数据库应用的日益复杂,比如对于计算机辅助设计和制造、数字出版、地理信息系统、动态的Web站点等需要处理多媒体数据并且能够根据用户要求进行交互式修改的复杂应用场景来说,RDBMS开始表现出一些不适应。此时出现了面向对象的数据库管理系统(Object-Oriented DataBase Management System, OODBMS),它将面向对象的概念与数据库系统相结合,可以为多种高级数据库应用提供适当的解决方案,目前多用于工程和设计领域。OODBMS存在的很多缺点使其占据的市场份额不多。比如,缺乏通用的数据模型;与RDBMS相比,OODBMS提供的功能比较复杂,难以使用;OODBMS面向程序员而不是非专业的最终用户,这使得设计和管理OODBMS的学习过程很艰难。这些都导致了人们对这种技术的排斥。进入20世纪90年代,Internet的兴起为商业智能提供了许多机会,DBMS开发商专注于数据仓库系统和数据挖掘产品的开发。数据仓库系统提供了数据分析机制,用户可以将分析结果用于决策支持。随着Web技术的迅猛发展以及XML的出现, 数据库与Web数据库集成环境的集成(简称Web数据库集成)以及XML与DBMS产品的集成呈现出高度发展的态势。Web数据库集成的方案的优点包括:具有简单性、平台无关性,使用Web浏览器轻松访问数据库,连接在Internet的所有机器上的文档都采用统一的标准HTML等。Web数据库集成的一些流行方案主要包括:使用脚本语言(如JavaScript、VBScript、PHP),扩展浏览器和Web服务器的能力,使其提供额外的数据库功能;使用JDBC,JDBC是Java 访问RDBMS最主要也是最成熟的方法,在JDBC中定义了数据库访问的API,Java可以作为编写数据库应用的宿主语言;Microsoft的ODBC技术(提供了访问多种SQL数据库的通用接口)以及Web解决平台,包括.NET、.ASP、ADO等。为使HTML文档具有动态特性,浏览器开发商引入了专用的HTML标记,这使开发Web文档变得复杂和困难。XML作为HTML的补充,使得不同类型的数据可以在网络上轻松交换。随着采用XML格式数据量的增大,对数据进行存储和查询的需求也日益增多。目前XML与DBMS产品的集成主要采用SQL/XML:2011数据模型,该模型在RDBMS中引入一种新的数据类型XML,并为该类型定义一组操作,将XML文档作为关系中的值,定义从关系数据到XML的一组映射。在存储了XML文档之后利用SQL:2011标准(扩展的SQL,用于发布XML)对数据进行查询。2. NoSQL(Not only SQL)数据库技术随着物联网、云计算、大数据技术的兴起,21世纪迎来了信息爆炸的时代,尤其是在21世纪前10年出现了大数据处理问题,推动了非关系型数据库技术尤其是NoSQL技术的发展。相比关系型数据库技术尽可能解决尽可能多的数据应用问题,NoSQL数据库技术只解决某一个方面或某一主题的问题。NoSQL重点关注“更快的处理速度”和“更恰当的存储”。NoSQL数据库没有固定的表结构,采用类似文档、键值、列族等非关系型数据模型,可以自由、灵活定义并在一个数据元素中存储各种不同类型的数据,支持海量数据存储,具有灵活的水平扩展能力,在处理数据库服务器大规模负载增加方面具有较高的性价比。但是为了提高操作性能,NoSQL放弃了很多像关系型数据库实施的规则约束,将本该数据库系统完成的功能交给了数据库程序员,不仅增加了数据库程序员的负担,也对他们的分析和编程能力提出了更高的要求。近些年,NoSQL数据库发展势头迅猛,数量上多达200多种,但归结起来通常分为键值数据库、文档数据库、列族数据库和图数据库4大类。这4类NoSQL数据库都是针对一种数据模型进行数据处理,各有特点和长处。(1)键值数据库(Key-Value Database)键值数据库的设计原则是以提高数据处理速度为目标,适合存在大量写操作的应用需求,擅长处理数组类型的数据。键值数据库运行在内存(它以内存或SSD为数据运行存储的主环境),采用定期向硬盘写数据的持久化策略,因此,键值数据库常被称为内存数据库。数据存储结构只有键(Key)和值(Value),并成对出现。在Value中可以保存任何类型的数据,通过Key来存储和检索具体的Value。键值数据库的优点是数据结构简单、提供分布式处理能力、高速计算和快速响应,只要配置更大容量、更快速度的内存就可以轻松应对海量数据访问的速度问题。缺点是无法存储结构化信息、在发生故障时不支持回滚操作,因此无法支持事务,不容易建立数据集之间复杂的横向关系,只限于两个数据集之间的有限计算。此外,对值进行多值查询的功能较弱。键值数据库产品有Redis、Memcached、Riak、BerkeleyDB、SimpleDB、DynamoDB以及甲骨文的Oracle NoSQL数据库等。作为键值数据库代表之一的Redis,使用C语言开发,提供了100多条命令,这些命令要比SQL语言简单很多。Redis支持的键值数据类型只有5种(字符串类型、散列类型、列表类型、集合类型、有序集合类型),并提供了几十种不同编程语言的客户端库,这使得在程序中与Redis的交互变得轻松容易。此外,Redis数据库中的所有数据都存储在内存中,并提供了持久化支持,将内存中的数据异步写入硬盘中,避免了程序退出而导致内存中数据丢失的问题。目前,Redis得到越来越多公司的青睐,百度、新浪微博、京东、阿里巴巴、腾讯、美团网、Twitter、Flickr、Stack Overflow、GitHub(Redis的开源代码就托管在其上)等都是Redis的用户。(2)文档数据库(Document Store Database)文档数据库是为解决大数据环境下的快速响应而设计的,擅长处理基于JSON、XML、BSON等格式的文档以及集合类型的数据。它具有强大的查询功能,看上去更接近于关系型数据库,并具有很强的可伸缩性,可以轻松解决PB级甚至EB级的数据存储需求,这给大数据处理带来了很多的方便。在文档数据库中,集合对应关系型数据库中的表,文档对应关系型数据库中的记录,是数据库的最小单位。每一条文档由大括号标识,其中包含若干个键值对(Key-Value Pair),键值对类似于关系型数据库中的字段值。文档数据库同关系型数据库一样,也是建立在对磁盘读写的基础上,对数据进行各种操作。但是为提高读写性能,文档数据库摒弃了关系型数据库规则的约束。对文档数据库的基本操作有读、写、修改和删除4种。最有名的文档数据库产品是MongoDB。百度云、腾讯云、新浪云、阿里云、华为、携程、中国银行、中国东方航空公司、Foursquare、eBay、MTV、MetLife等都是MongoDB的用户。(3)列族数据库(Column Family Database)在当今的大数据时代,列族数据库格外引人注目,它特别擅长PB、EB级别的大数据存储和几千或几万台级别的服务器分布式存储管理,具有丰富的查询功能以及高密集写入处理能力。列族数据库的数据存储模式比文档数据库和键值数据库的复杂,其存储结构由4部分组成:命名空间(相当于关系型数据库中的表名)、行键(相当于关系型数据库中的表的主键)、列族(相当于关系型数据库中的表结构)、列(相当于关系型数据库中的表的字段),列的每个值都附带一个时间戳。列族数据库的产品有BigTable、HBase、HadoopDB、Cassandra、HyperTable等。Twitter、eBay、Facebook、Netflix都是列族数据库产品的用户。(4)图数据库(Graph Database)图数据库专用于处理高度关联的数据,支持复杂的图算法,构建复杂的关系图谱,特别适合社交网络(QQ、微信)、推荐系统、模式识别、物流派送、规则推理等应用场景。图数据库以图论为基础,使用图作为数据模型来存储数据,节点、边、属性构成了图存储的三要素,凡是有类似关系的事物都可以使用图存储来处理。图存储数据本身非常简单,主要通过节点之间的关系发现有价值的数据规律。图数据库的产品有Neo4j、Infinite Graph、Allegro Graph、GraphDB等。其中,Neo4j是目前使用较多的产品,它无须事先定义存储结构,完全兼容关系型数据库的ACID特性,提供事务处理能力,为单个节点提供Create、Delete、Update、Remove、Merge等操作,为图提供图的交集、并集以及图的遍历等操作。Neo4j成功应用于eBay、Adobe、Cisco、T-Mobile等公司。3. NewSQL数据库技术近年来,出现了NewSQL数据库技术。NewSQL技术结合了关系型数据库与NoSQL数据库的优点,用于解决大数据环境下的数据存储和处理问题,是对各种新的可扩展、高性能数据库的统称。NewSQL数据库不仅具有NoSQL数据库良好的扩展性和灵活性,还保持了关系型数据库支持ACID和SQL等特性。NewSQL数据库产品有Spanner、SequoiaDB、VoltDB、Clustrix、GenieDB等。无论数据库技术如何发展,关系型数据库仍然是当今世界软件的基础,关系型数据库及其第三范式和SQL接口仍然在稳定地运行着。本书将详细介绍关系型数据库技术的相关概念、原理以及应用。
1.2 数据库与数据库管理系统
1.2.1 数据库
数据库(DataBase,DB)是指长期存储在磁带、磁盘、光盘或其他外存介质上,按照一定的结构组织在一起的相互关联的数据集合。从不同的角度看数据库有不同的理解,如图1-4所示。从用户的角度来看,数据库就是一种数据库应用软件;从数据模型的角度来看,数据库就是数据库管理系统;从数据的实际组织情况来看,数据库才是真正意义上的数据库。
数据库具有如下特征:1)在数据库中,不仅能够表示数据本身,还能够表示数据与数据之间的联系。比如,教学管理数据库中存放学生和课程的数据,学生数据通过选课与课程数据产生联系。2)数据通过一定的数据模型进行组织、描述和存储。数据模型包括层次模型、网状模型和关系模型等。3)具有较小的冗余度、较高的数据独立性和易扩展性。4)用户和应用程序可以共享数据。5)数据的各种操作如查询、修改、删除等都由一种专业软件统一进行管理。在当今数字时代,我们的数字交互,无论是信息检索、微博搜索和排序,还是社交、购物、评论、点赞,本质上都是在与数据库交互。
1.2.2 数据库管理系统
上述数据库的特征蕴藏在一种名为数据库管理系统(DBMS)的专业软件中。DBMS是一个与用户的应用程序和数据库相互作用的软件,它的目标是将数据作为一种可管理的资源来处理。如图1-5所示,DBMS是一种介于用户与操作系统之间,并在操作系统的支持下,专门用于数据管理的系统软件。它提供了有效建立、管理,并安全持久地保存大量数据的能力。DBMS是数据库系统的核心组成部分,它完成“科学组织和存储数据,高效获取和处理数据”的任务。
可以将DBMS看作某种数据模型在计算机系统上的具体实现。用户通过DBMS访问数据库中的数据,数据库管理员也通过DBMS进行数据库的维护工作。DBMS的主要功能包括:1)数据定义功能。通过DBMS提供的数据定义语言(Data Definition Language,DDL)及其翻译程序,定义数据库的结构、数据库中的各种数据对象,以及数据完整性和其他的约束条件。2)数据操纵功能。通过DBMS提供的数据操纵语言(Data Manipulation Language,DML)来完成对数据库中数据的插入、修改、删除和查询操作。3)数据控制功能。通过DBMS提供的数据控制语言(Data Control Language,DCL)对数据库进行统一管理和控制。比如,DBMS提供完整性控制,保证所存储数据的一致性;提供安全控制机制,禁止没有被授权的用户访问数据库;提供多用户环境下的并发控制机制,允许共享数据库。除了上述核心功能之外,DBMS还提供数据字典,用于存放数据库各级结构的描述;提供访问数据库的方法,即数据库接口以供用户或应用程序访问数据库;提供数据维护功能,比如数据库的数据装入、转换、存储、备份和发生故障后的系统恢复,以及数据库的性能分析和监测等。数据字典中存放的是数据库系统的一些说明信息,即数据的数据,称为元数据,如对各级模式的描述、索引、完整性约束、安全性要求、数据库的使用人员等说明信息。类似于日常生活中使用的字典或书的目录,它能够帮助DBMS按照用户指定的数据对象名称,快速找到所需要的信息。数据字典提供了对描述数据进行集中管理的手段,可以将它看成是数据库系统自身的小的、专门的数据库,区别于真正的物理数据库,常称之为描述数据库或数据库的数据库,只能由数据库系统本身来访问和修改。数据字典在数据库系统的设计、实现、运行和维护各阶段起着非常重要的作用,是数据管理和控制的有力工具。
1.2.3 认识Access 数据库管理系统
Access是一种小型的关系数据库管理系统。Access 2010是微软2010年推出的Microsoft Office 2010中的一员,它与Word、Excel和PowerPoint等有相同的操作界面和使用环境,具有存储方式单一、界面友好、易于操作以及强大的交互式设计功能等特点,很多中小型企业、大公司的部门,以及喜爱编程的开发人员专门利用它来制作处理数据的桌面应用系统。Access也常用于开发简单的Web应用程序,或作为客户/服务器系统中的客户端数据库,以及数据库相关课程的教学实践环境。Access通过数据库文件来组织和保存数据表、查询、报表、窗体、宏和模块等数据库对象,并提供了各种生成器、设计器和向导,以快速、方便地创建数据库对象和各种控件。此外,Access提供了丰富的内置函数和程序开发语言VBA(Visual Basic for Application),帮助数据库开发人员快捷开发数据库系统;还提供了与SQL Server、Oracle、MySQL等数据库的接口,实现数据共享和交换;可方便与Excel、Word等共享信息。1. Access 2010的操作环境启动 Access 2010成功后,首先看到的窗口就是 Backstage 视图,这里的视图是指界面。初次使用Access 2010时,首先要利用Backstage 视图创建数据库,然后再依次创建数据库中的各个对象。将创建数据库对象的界面称为Access 2010用户操作界面,该界面主要由快速访问工具栏、功能区、导航窗格和工作区组成。(1)Backstage 视图Backstage 视图也称为Access 2010的启动窗口,如图1-6所示。该视图替代了 Office 以前版本中的 Microsoft Office 按钮和“文件”菜单。因为通过该视图整合的各种文件级操作和任务都是在后台进行的,所以Backstage 视图也被称为后台视图。在实际的操作中,可以单击“文件”选项卡随时切换到 Backstage 视图。
Backstage 视图分为两个部分,左侧窗格由一些命令组成,右侧窗格显示不同命令的选择结果。命令包括新建、保存、打开、信息、保存并发布、帮助、选项、退出等。此外,与打印相关的命令和设置(如预览、打印、页面布局)也集中在Backstage 视图中。图1-6给出的是Backstage 视图的默认界面,左侧窗格中显示当前命令是“新建”数据库,在右侧窗格中显示“可用模板”和“空数据库”两个部分。利用它们既可以从头开始创建新数据库,也可以从专业设计的数据库模板库中选择数据库。“可用模板”中给出了当前Access系统中所有的数据库模板,包括12个样本模板(其中包含了5个Web数据库模板)、我的模板以及Office.com提供的“资产”“联系人”“问题&任务”“非盈利”和“项目”5个模板类别。单击“样本模板”可以看到当前Access系统所提供的12个样本模板,其中包含了预先建立的各种数据库对象。如果样本模板基本符合自己的设计要求,用户可以立即使用该模板或做简单修改后,快速建立起自己的数据库文件。如果没有合适的模板,可以在Office.com上搜索、下载由他人提供的模板,或者自己创建一个新的数据库文件。当新建一个空白数据库时,在界面右侧会显示将要创建的数据库的默认文件名和保存的位置,用户可以修改文件名和存放的位置。现在新建了一个数据库文件Database2.accdb。单击Backstage 视图中的“信息”命令,在视图的右侧窗格将出现如图1-7所示的界面,利用其中的命令选项可以对Database2.accdb进行压缩、恢复以及加密操作。此外,还可以查看和编辑该数据库文件的属性等。
Backstage 视图提供了上下文信息,根据不同的情况,“信息”窗格可能会显示数量不同的命令选项。例如,相对图1-7,在图1-8中增加了“启用内容”。这可能是因为存在禁用的宏,而系统阻止了该宏以保护计算机。这时可以通过“信息”窗格查看该宏的上下文信息,并启用宏。又如,某个在 Office 早期版本中创建的文档在兼容模式下打开,并且某些丰富的新功能被禁用的情况下,“信息”窗格中会出现版本转换功能等。
在Backstage 视图中,单击“保存并发布”后,右侧窗格如图1-9所示。“数据库另存为”功能可以将数据库文件保存为2003或2002等低版本的格式。例如,对于2010版本的Database2.accdb,将被保存为低版本的Database2.mdb文件。此外,可以将当前的数据库文件另存为扩展名为.accdt的数据库模板,可以将数据库打包、备份,还可以将数据库上传到SharePoint网站上实现共享,将包含VBA代码的数据库文件保存为扩展名为.accde的文件,该文件可以编译所有的VBA代码模块等。
“发布到Access Services”功能可以将数据库文件发布到SharePoint网站上,以便通过浏览器和Access共享数据库。当数据库发生变化时,需要重新发布到SharePoint网站上。重要提示
需要注意的是,Backstage 视图中的各种命令通常适用于整个数据库,而不是数据库中的某个对象。
可以通过自定义用户界面来扩展 Backstage视图,该用户界面使用 XML 来定义元素。
发布到SharePoint网站上的数据库文件只能是扩展名为.accdb的文件。(2)功能区
功能区取代了以往版本的传统菜单,将相关命令以选项卡的方式组织在一起,在同一时间只显示一个选项卡中的相关命令。如图1-10所示,Access 2010的功能区在默认情况下只有4个选项卡,分别是“开始”“创建”“外部数据”和“数据库工具”。每个选项卡又分为多个选项卡组(简称组)。在与选项卡平行的右侧有一个上箭头和一个问号,分别表示将功能区最小化和显示Access的帮助信息(也可以按F1键)。实际操作中遇到问题时,可随时查询系统帮助中的信息。
利用“开始”选项卡中的命令,可以进行视图的选择、数据的复制/粘贴、记录的排序与筛选,还可以对记录进行刷新、保存、删除、汇总、拼写检查,以及查找记录、设置字体格式和对齐方式等操作。“创建”选项卡中的命令主要用于创建Access 2010数据库对象。“外部数据”选项卡中的命令主要用于导入和导出各种数据。例如,导入外部数据或链接到外部数据,通过电子邮件收集和更新数据,导出数据到Excel、文本文件或电子邮件中,或以XML、PDF等格式保存等。“数据库工具”选项卡主要针对Access 2010数据库进行比较高级的操作,例如,压缩和修复数据库、启动VBA编辑器以创建和编辑VBA模块、运行宏、设置数据表之间的关系、显示或隐藏对象相关性、数据库性能分析、将部分或全部数据库移至SQL Server或SharePoint网站上,以及管理Access加载项等。除了上述4个默认的选项卡之外,还有一些隐藏的选项卡,称为上下文选项卡,它们只有在对特定对象进行特定操作时才会显示出来。例如,运行“创建”选项卡“表格”组中的“表”命令,在数据库Database2.accdb中创建一个数据表“表1”时,功能区中会自动出现黄色的“表格工具”选项卡组,其中包括“字段”和“表”两个选项卡。如图1-11所示。若采用表设计器来创建“表1”,则“表格工具”选项卡组中只有“设计”选项卡,如图1-12所示。
如果利用窗体设计器创建一个窗体,则功能区上会出现紫色的“窗体设计工具”选项卡组,其中包括“设计”“排列”和“格式”3个选项卡,如图1-13所示。
在 Access 2010中,可以自定义功能区中的选项卡,首先单击Backstage 视图中的“选项”命令,然后在“Access选项”对话框中选择“自定义功能区”。如图1-14所示。然后选择并添加选项卡、组和命令到功能区中,还可以进行删除、重命名、重新排列选项卡以及组合命令等操作。
(3)快速访问工具栏默认情况下,快速访问工具栏位于功能区上方应用程序标题栏左侧的Access标志的右边,也可以将其移到功能区的下方。快速访问工具栏将经常使用的功能集中在一起,如“保存”“恢复”“撤销”等。可以自定义快速访问工具栏以适应自己的工作环境,方法有以下两种。方法一:单击快速访问工具栏右侧的箭头,通过弹出的“自定义快速访问工具栏”菜单,在工具栏上添加其他命令,如图1-15所示。如果提供的命令不能满足需要,可以单击“其他命令”,直接跳转到如图1-16所示的界面进行设置。
方法二:单击Backstage 视图中的“选项”命令,在“Access选项”对话框中选择“快速访问工具栏”,如图1-16所示,然后选择要添加或从快速访问工具栏中移除的命令。(4)导航窗格与工作区导航窗格位于功能区下方的左侧,用于显示当前数据库中已经创建好的各种数据库对象。图1-17给出了利用样本模板创建的数据库文件“教职员.accdb”。通过窗口标题栏中央位置显示的内容可以知道,当前打开的是“教职员”数据库窗口。双击此处可以最大化或者还原该窗口。
在导航窗格中单击或(称为百叶窗开/关按钮),可以展开或折叠导航窗格。单击,可以在弹出的“浏览类别”菜单中选择查看对象的方式。图1-17显示的内容是按照对象类型进行排列的内容,可以看出“教职员”数据库中包含了表、查询、窗体和报表4类数据库对象。如果单击或,将折叠或展开每个数据库对象中包含的具体内容。右击导航窗格中的任何对象,将弹出相应的快捷菜单,可以从中选择相关命令执行操作。图1-18给出了右击数据库对象“窗体”时的快捷菜单。
在导航窗格中,双击某个对象,将打开该数据库对象,如表、窗体或报表,也可以右击数据库对象,然后单击“打开”。如果想了解更多导航窗格的详细内容,可以查看Access 2010的帮助信息。工作区是位于功能区下方、导航窗格右侧的区域。工作区用于对数据库对象进行设计、编辑、修改、显示,以及打开运行数据库对象。Access 2010采用了选项卡式文档来代替Access 2003中的重叠窗口以显示数据库对象。图1-17显示了“教职员列表”和“教职员电话列表”两个选项卡式文档,从文档名前面的图标可以识别出前者是窗体,后者是报表,并且当前文档是“教职员列表”。因为只是借助模板创建了“教职员”这个数据库,各个数据库对象中并没有数据,所以没有显示的内容。2. Access 2010的数据库对象(1)数据表数据表简称表,是数据库中最基本也是最重要的对象。Access 将数据组织成由行和列组成的二维表,每一行称为一条记录,每一列称为一个字段。需要为每个表指定主键来唯一标识每条记录,并确定各个表中的数据如何彼此关联,从而建立表间关系。表1-1给出了E-R模型、关系模型以及作为一种RDBMS的Access的术语对照。
图1-19给出了样本模板“罗斯文”数据库中的“客户”数据表的结构和内容。这是在Access 2010用户操作界面的工作区中展示的数据表。选项卡式文档包括了4个数据表,分别是“采购订单”“产品”“订单”和“客户”,当前显示的是“客户”数据表。
在Backstage 视图中创建数据库之后,首先要做的工作就是创建数据表。数据表是其他数据库对象的基础。在Access中,允许一个数据库中包含多个数据表,在不同的数据表中存储不同主题的数据。每个数据表都是由表结构和记录组成的。创建数据表首先要创建表结构,然后再创建表间关系,最后输入数据或将外部数据导入数据表中。有关数据表的相关概念和具体操作详见本书第四部分的第7章。(2)查询查询是数据库中应用最多的数据库对象。查询通常是指通过设置查询条件,从一个表、多个表或其他查询中选取全部或部分数据,以二维表的形式显示数据供用户浏览,或作为窗体、报表或其他查询的数据源。查询的结果虽然以二维表的形式展示,但查询不是数据表。每个查询只记录该查询的操作方式,并不真正保存查询结果数据,每进行一次查询,只是根据该查询的操作方式动态生成查询结果。因此,数据表是实表,查询是虚表。Access中,查询不仅可以从数据源中产生符合条件的动态数据集,还可以创建数据表,以及对数据源中的数据进行追加、删除、更新操作。Access 提供了5种查询类型,分别是选择查询、参数查询、交叉表查询、操作查询和SQL查询。通常使用查询向导和查询设计器两种方式创建查询。Access中的查询对象共有5种视图,分别是设计视图、数据表视图、SQL视图、数据透视表视图、数据透视图视图。图1-20给出了“罗斯文”数据库中的“现有库存”查询的数据表视图,图1-21给出了“现有库存”查询的设计视图。有关查询的相关概念和具体操作详见第四部分的第8章。
(3)窗体Access 提供了可视化的直观操作来设计数据输入、输出界面的结构和布局,即窗体数据库对象。窗体是用于处理数据的界面,通常包含了很多控件用于执行各种命令。通过设置控件的属性和编写宏或事件过程,可以确定窗体中要显示的内容、所打开的窗体和报表,以及执行其他各种任务。窗体为数据的输入和编辑提供便捷、美观的屏幕显示方式。其数据可以通过键盘直接输入,也可以来自数据表、查询或SQL语句。数据若来自数据表或查询,窗体中显示的数据将随表或查询中数据的变化而变化。Access中的窗体对象共有6种视图,分别是设计视图、 窗体视图、 数据表视图、布局视图、数据透视表视图、数据透视图视图,不同的窗体视图有不同的作用和显示效果。如图1-22所示,对于一个创建好的窗体,可以通过单击“开始”选项卡中的“视图”命令,从中选择其中的一种视图来查看窗体。
窗体作为用户与数据库交互的界面,在数据库应用程序中扮演着重要的角色。Access中的窗体类型主要有单个窗体、连续窗体、数据表窗体、分割窗体、多项目窗体、数据透视表窗体、数据透视图窗体、主/子窗体、导航窗体等。常用的创建方法有各种自动创建窗体的工具、窗体向导以及窗体设计器等。有关窗体的相关概念和具体操作详见第四部分的第9章。(4)报表报表主要用于数据的显示和打印,它的数据来源可以是表、查询,也可以是SQL语句。同窗体一样,报表本身不存储数据,只是在运行报表的时候才将信息收集起来。通过报表组织和显示Access中的数据,为打印或屏幕显示效果设置数据格式。利用报表提供的功能,可以对数据分组,进行数据的计算和统计,还可以打印输出标签、转换为PDF等其他格式的文件,以使报表便于阅读。此外,还可以运用报表创建标签并打印输出,以用于邮寄或其他目的等。图1-23给出了一个典型的报表例子。这是“罗斯文”数据库中的“年度销售报表”报表的报表视图,分别统计了各个产品在4个季度的销售金额。报表有4种视图,分别是设计视图、报表视图、布局视图、打印预览视图。一般采用报表向导、报表设计器来创建报表。报表的种类有纵栏式报表、表格式报表、图表报表和标签报表。有关报表的相关概念和具体操作详见第四部分的第9章。
(5)宏宏是由一个或多个宏操作命令组成的集合,主要功能是让程序自动执行相关的操作。Access 2010提供了大量的宏操作命令,每个宏操作命令都可以完成一个特定的任务。例如,宏操作OpenForm用于打开一个指定的窗体;宏操作MessageBox用于显示一个消息对话框,如图1-24所示,用户只需要输入相应的参数就可以创建一个简单宏。
宏与内置函数一样,可以为数据库应用程序提供各种基本功能。可以在窗体、报表、控件和模块中添加并使用宏以完成特定的功能。例如图1-25所示的“登录”窗体,若将“退出”命令按钮的“单击”事件与图1-24所示的“再见”宏相关联,则使得“登录”窗体运行时,单击“退出”命令按钮就执行MessageBox宏操作,即弹出如图1-26所示的对话框。使用宏非常方便,不需要记住语法,也不需要复杂的编程,只需利用几个简单的宏操作就可以对数据库进行一系列的操作。有关宏的相关概念和具体操作详见第四部分的第10章。(6)模块模块是Access中一个重要的对象,它比宏的功能更强大,运行速度更快,不仅能完成操作数据库对象的任务,还能直接运行Windows的其他程序。通过模块还可以自定义函数,以完成复杂的计算、执行宏所不能完成的复杂任务。
模块由VBA声明语句和一个或多个过程组成。过程由一系列VBA代码组成,并通过VBA语句执行特定的操作或计算数值。过程分为两类:事件过程和通用过程。通用过程分为Sub 过程和 Function 过程。Sub过程又称子程序,Function过程又称函数过程。事件过程是一种特殊的Sub过程,它由系统自动命名,事件过程名由指定的控件名和其所响应的事件名称构成。在Access中,模块分为两种基本类型:类模块和标准模块。窗体模块和报表模块都属于类模块,而且它们各自与某一个具体存在的窗体或报表相关联。标准模块是存放公共过程的模块,这些过程不与任何对象关联。任何模块都需要在VBA编辑器中编写相关代码。图1-27给出了VBA编辑器的界面。在左侧的工程窗口中可以看到名为“教学管理系统”的数据库中的所有模块。其中,类模块有7个,全部是窗体模块(以“Form_”开头),标准模块有3个。窗口右侧的代码区显示的是名为“模块2”的标准模块的代码,可以看出,“模块2”中只有一个名为sum的过程,功能是计算1~100之间的奇数和。执行这个过程的结果如图1-28所示。有关模块的相关概念和具体操作详见第四部分的第11章。
重要提示Access 2010数据库使用新格式来保存文件,创建扩展名为.accdb文件格式的数据库,而不是先前版本的.mdb文件格式。Access 2010向下兼容,在 Access 2010 中仍然可以打开和编辑低版本的数据库,但诸如文件菜单等各级菜单、数据库窗口以及工具栏等功能将被2010版本的用户界面所替代。
1.3 数据视图
数据库管理系统的主要目的之一是通过抽象来屏蔽数据存储和维护细节,为用户提供数据的抽象视图,以简化用户与数据库系统的交互。
1.3.1 数据抽象
1. 三个世界数据处理的过程会涉及三个不同的世界:现实世界、信息世界和计算机世界。现实世界是存在于人们头脑以外的客观世界,狭义上讲,现实世界就是客观存在的每个事物和现象。信息世界是现实世界在人们头脑中的反映和解释,它将现实世界的事物用文字和符号记录下来,是现实世界的概念化。信息世界是对现实世界的抽象,并从现实世界中抽取出能反映现实本质的概念和基本关系。信息世界作为现实世界通向计算机世界的桥梁,起着承上启下的作用。计算机世界是对信息世界的进一步抽象,反映数据特征和数据之间的联系,是信息世界的形式化和数据化。信息世界的信息在计算机世界中以数据的形式进行存储。有时也将计算机世界称为数据世界。上述三个世界中的常用术语对照如表1-2所示。
2. 抽象层次抽象层次由高到低依次划分为:视图层、逻辑层和物理层。1)视图层:因为大多数用户并不需要访问数据库中的全部数据,所以视图层仅描述整个数据库的部分数据,为用户提供屏蔽了数据类型等细节的一组应用程序。并且从安全性考虑,系统在视图层定义了多个不同的视图使不同的用户访问不同的数据。2)逻辑层:程序设计人员在这个抽象层次上使用某种高级程序设计语言进行工作。逻辑层描述整个数据库所存储的数据以及数据之间的关系。DBA通常在这个抽象层次上工作。3)物理层:描述数据的实际存储情况。DBA可能需要了解某些数据物理结构的细节,程序设计人员可能没有必要了解这些细节。数据库系统为数据库程序设计人员屏蔽了许多物理层的存储细节。
1.3.2 视图
视图的本意是指一个人看到某个物体所得到的图像。物体有全局的概念,而视图具有局部的含义。将视图的概念引入数据库,数据库相当于一个全局的事物,而每个用户从数据库中看到的数据就形成了视图。例如,从教务管理系统中查看成绩,每名学生登录系统后只能看到自己的课程成绩。视图相当于数据库的一个子集,它提供了一个保密级别,可以通过创建视图将用户不能查看的数据排除在外。图1-29给出了与三个抽象层次对应的视图:用户视图、概念视图和存储视图。用户视图也称外部视图,呈现的是数据库的局部结构。概念视图呈现的是数据库的全局结构。存储视图也称内部视图,呈现的是存储记录的物理顺序和彼此关联的方式。
1.3.3 模式与实例
对数据库的描述或者说对包含在一个数据库中所有实体的描述定义,称为数据库模式,简称模式。在多个抽象级别进行定义就形成了多个级别的模式。特定时刻存储在数据库中的数据集合称为数据库的一个实例。同一个模式可以有很多实例。通常情况下,模式在数据库设计阶段就要确定下来,一般不会频繁修改,因而是相对稳定的,而实例是变化的,因为数据库中的数据总是不断更新。模式反映的是数据的结构及其联系,而实例反映的是数据库某一时刻的状态。
1.4 数据库系统
1.4.1 数据库系统的组成
在具体应用中,最终用户实际面对的是数据库系统,而不是数据库或数据库管理系统。数据库系统(DataBase System,DBS)是基于数据库的计算机应用系统。如图1-30所示,DBS由计算机软硬件、数据库(包括物理数据库和描述数据库)、数据库管理系统、数据库应用系统、数据库管理员以及用户组成。其中,数据库应用系统是实现业务逻辑的应用软件,它通过向DBMS提出合适的请求(SQL语句)而与数据库进行交互。数据库应用系统是以操作系统、DBMS、高级程序设计语言和实用程序为软件环境,以某一领域的数据管理需求为应用背景,采用数据库概念和技术编写的一个可实际运行的计算机程序。它提供一个友好的图形用户界面,使用户可以方便地访问数据库中的数据。常见的数据库应用系统有信息管理系统、办公自动化系统、情报检索系统、高校教学管理系统、财务管理系统、商业交易系统等。数据库管理员(DataBase Administrator,DBA)是负责对数据库进行全面管理和控制的人员。数据库是共享资源,可以被多个用户和应用程序共享,需要统一规划、管理、协调、监控,同时,数据库也是重要的信息资源,需要对数据库中数据的并发性、安全性、完整性以及故障恢复进行维护,DBA就是完成上述工作的人员或机构。DBA可能是一个人,也可能是一组人。对于一个规模较大的数据库系统,DBA通常指数据库管理机构或部门。DBA的工作很繁重也很关键,所有与数据库有关的事宜一般均由DBA来决定。
重要提示数据库、数据库系统、数据库管理系统是三个不同的概念,在不引起混淆的情况下,数据库通常作为数据库系统或数据库管理系统的简称。比如,人们常说的数据库应用领域、数据库的三级模式结构,实际上是指数据库系统的应用领域、数据库系统的三级模式结构。又比如,甲骨文公司的Oracle是一款关系数据库管理系统产品,人们通常简称为 Oracle数据库。大学里常用的教学管理数据库系统,也常常称为教学管理数据库或教学管理系统。在实际学习中,到底是指哪一个概念,要根据上下文来理解。
1.4.2 数据库系统的特点
(1)数据的结构化数据的结构化是指数据之间相互联系,面向整个系统。具体来说,就是数据库系统不仅描述数据本身,而且还描述数据之间的联系,实现了整体数据的结构化。数据的结构化也是数据库系统与文件系统的主要区别之一。(2)数据共享程度高、易扩充、冗余度低共享是指数据可以被多个用户、多个应用程序使用。冗余度是指同一数据被重复存储的程度。共享程度高可以大大减少数据冗余,节约存储空间,避免数据的不一致性。此外,由于数据库设计是面向系统而不是面向某个应用,主要考虑的是数据的结构化,因而容易扩充。(3)数据的独立性高数据库系统的一个重要目标就是要使程序和数据真正分离,使它们能独立发展。数据的独立性就是指数据独立于应用程序,两者之间互不影响。数据的独立性包括逻辑独立性和物理独立性。(4)数据控制能力较强数据由DBMS统一管理和控制,包括数据的并发控制、安全性控制、完整性控制以及故障恢复等。
1.4.3 数据库系统的体系结构
数据库系统的体系结构分为外部体系结构和内部体系结构。外部体系结构是指从数据库最终用户的角度来看数据库系统,一般分为集中式结构、分布式结构、客户/服务器结构和并行结构。内部体系结构是指从数据库管理系统的角度来看数据库系统。本小节介绍数据库系统的内部体系结构,即三级模式结构。1. 数据库系统的三级模式结构根据美国国家标准化协会和标准计划与需求委员会提出的建议,将数据库系统的内部体系结构定义为三级模式和二级映像结构,如图1-31所示。数据库系统的三级模式之间的联系通过二级映像实现,实际的映像转换工作由DBMS完成。
与数据抽象的层次相对应,数据库系统的三级模式分别是外模式、模式和内模式,如图1-32所示。一个数据库只有一个模式、一个内模式,但可以有多个外模式。数据库系统的三级模式不仅可以使数据具有独立性,而且还可以使数据达到共享,使同一数据能够满足更多用户的不同要求。
(1)外模式外模式(External Schema)也称子模式或用户模式,是数据库在视图层上的数据库模式。它是数据库用户能够看见和使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。一个数据库可以有多个外模式,由于不同用户有不同的需求,以及拥有不同的访问权限,因此,对不同用户提供不同的外模式的描述,即每个用户只能看见和访问所对应的外模式中的数据。同一外模式可以为多个应用程序使用,但一个应用程序只能使用一个外模式。例如,大学的教学管理系统中,学生可能需要知道所选课程的名称、学分、授课教师、地点、时间以及课程成绩,但不必知道授课教师的工资、福利等信息。授课教师只需要知道所教学生的学号、姓名、性别、专业、所在学院以及所教课程的学生成绩,但不必知道学生其他课程的成绩以及学生的年龄、籍贯等其他信息。这样就需要为教师和学生分别建立一个数据库视图。DBMS提供外模式DDL来严格地定义外模式,例如为教师创建一个所教课程号为C1的学生成绩视图,使用SQL语句表示如下。有关SQL的内容将在本书第三部分详细介绍。CREATE VIEW 学生成绩
AS
SELECT 学号, 课程号, 成绩FROM 成绩WHERE 课程号="C1";(2)模式模式(Schema)也称逻辑模式,是在逻辑层描述数据库的设计。模式是数据库中全体数据的逻辑结构和特征的描述,通常称为数据模式,是所有用户的公共数据视图。模式实际上是数据库数据在逻辑层上的视图。DBMS一般提供模式DDL来严格定义数据的逻辑结构、数据之间的联系以及与数据有关的安全性要求、完整性约束等。数据的逻辑结构包括数据记录的名字以及数据项的名字、类型、取值范围等。下面给出了教学管理数据库系统中模式的例子,其中标有下划线的字段是主键:学生模式:学生(学号,姓名,性别,出生日期,所在系,班级)系模式:系(系号,系名,系主任)课程模式:课程(课程号,课程名,所在系,学分)选修模式:选修(学号,课程号,成绩)(3)内模式内模式也称存储模式。它是对数据库物理结构和存储方法的描述,是数据在存储介质上的保存方式。例如,数据的存储方式是顺序存储还是按照 B 树结构存储等。一般由DBMS提供的内模式DDL来定义内模式。内模式对一般用户是透明的,通常不需要关心内模式具体的实现细节,但它的设计会直接影响数据库的性能。2. 数据独立性与二级映像(1)数据独立性在三级模式中提供了二级映像,以保证数据库系统的数据独立性。数据的独立性包括物理独立性和逻辑独立性。物理独立性是指用户的应用程序与存储在磁盘上数据库中的数据相互独立,应用程序不会因为物理存储结构的改变而改变。物理独立性使得在系统运行中,为改善系统效率而调整物理数据库不会影响应用程序的正常运行。逻辑独立性是指用户的应用程序与数据库的逻辑结构相互独立。数据库的逻辑结构改变了,如增删字段或联系,也不需要重写应用程序。(2)二级映像二级映像在DBMS内部实现数据库三个抽象层次的联系和转换。二级映像包括外模式/模式映像和模式/内模式映像。二级映像保证了数据库系统中的数据具有较高的逻辑独立性和物理独立性。
外模式/模式映像。即外模式到逻辑模式的映像,它定义了数据的局部逻辑结构与全局逻辑结构之间的对应关系。该映像定义通常包含在各自外模式的描述中。对于每一个外模式,数据库系统都有一个外模式/模式映像。当逻辑模式改变时,由DBA对各个外模式/模式映像做相应改变,使外模式保持不变,从而不必修改应用程序,保证了数据的逻辑独立性。
模式/内模式映像。即逻辑模式到内模式的映像,定义了数据的全局逻辑结构与物理存储结构之间的对应关系。该映像定义通常包含在模式描述中。数据库中只有一个模式,也只有一个内模式,所以模式/内模式映像也是唯一的。当数据库的存储结构改变(如换了另一个磁盘来存储该数据库)时,由DBA对模式/内模式映像做相应改变,使模式和外模式保持不变,从而保证了数据的物理独立性。
重要提示
模式是内模式的逻辑表示,内模式是模式的物理实现,外模式则是模式的部分抽取,它定义在模式之上,独立于内模式和存储设备。
模式是数据库系统的中心和关键,因此,在数据库设计中首先应该确定数据库的模式。
外模式面向具体的应用程序,当应用需求发生较大变化导致相应的外模式不能满足其要求时,外模式就需要做相应的修改。因此,设计外模式时应充分考虑具体应用的可扩充性。
数据库三级模式之间的转换是在DBMS的统一控制下实现的。
1.5 小结
数据处理也称信息处理,数据是符号化的信息,信息是语义化的数据。数据管理是数据处理的中心问题,数据管理技术的优劣直接影响数据处理的效率。数据库技术是数据管理的最新技术。数据库是由数据库管理系统(DBMS)进行管理的数据集合,这种集合可以长期保存。数据库管理系统允许用户使用数据定义语言建立数据库并说明数据的逻辑结构,同时提供了查询、更新数据的操作以及控制多个用户或应用程序对数据的访问。数据库系统就是采用数据库技术的计算机系统。DBMS是数据库系统的核心,数据库中的数据都是由DBMS统一进行管理和控制的。从DBMS角度看,数据库系统通常采用三级模式结构和二级映像。三级模式结构是由外模式、模式和内模式三级组成。二级映像保证了数据的独立性。
习题1.名词解释:数据、信息、数据处理、数据库、数据库管理系统、数据库应用系统、数据库系统、数据库管理员、数据字典、外模式、逻辑模式、内模式、数据的独立性
2.简述文件管理方式的缺点。
3.简述数据库管理系统的主要功能。
4.简述数据库系统的特点。
5.简述数据库系统中的数据独立性是如何实现的。
Acunetix Web Vulnerability Scanner手册
目录:
0×00、什么是Acunetix Web Vulnarability Scanner ( What is AWVS?)
0×01、AWVS安装过程、主要文件介绍、界面简介、主要操作区域简介(Install AWVS and GUI Description)
0×02、AWVS的菜单栏、工具栏简介(AWVS menu bar & tools bar)
0×03、 开始一次新扫描之扫描类型、扫描参数详解(Scan Settings、Scanning Profiles)
0×04、AWVS的应用程序配置详解(Application Settings)
0×05、AWVS的蜘蛛爬行功能(Site Crawler)
0×06、AWVS的目标探测工具(Target Finder)
0×07、AWVS的子域名探测工具(Subdomain Scanner)
0×08、AWVS的SQL盲注测试工具(Blind SQL Injection)
0×09、AWVS的HTTP请求编辑器(HTTP Editor)
0×10、AWVS的HTTP嗅探工具(HTTP Sniffer)
0×11、AWVS的HTTP模糊测试工具(HTTP Fuzzer)
0×12、AWVS的认证测试工具(Authentication Tester)
0×13、AWVS的WEB WSDL扫描测试工具(Web Services Scanner、Web Services Editor)
0×00、什么是Acunetix Web Vulnarability Scanner
Acunetix Web Vulnerability Scanner(简称AWVS)是一款知名的Web网络漏洞扫描工具,它通过网络爬虫测试你的网站安全,检测流行安全漏洞。它包含有收费和免费两种版本,AWVS官方网站是:http://www.acunetix.com/,目前最新版是V10.5版本,官方下载地址:https://www.acunetix.com/vulnerability-scanner/download/,官方免费下载的是试用14天的版本。这里我们以V10.5破解版来讲解。
功能以及特点:
a)、自动的客户端脚本分析器,允许对 Ajax 和 Web 2.0 应用程序进行安全性测试。
b)、业内最先进且深入的 SQL 注入和跨站脚本测试
c)、高级渗透测试工具,例如 HTTP Editor 和 HTTP Fuzzer
d)、可视化宏记录器帮助您轻松测试 web 表格和受密码保护的区域
e)、支持含有 CAPTHCA 的页面,单个开始指令和 Two Factor(双因素)验证机制
f)、丰富的报告功能,包括 VISA PCI 依从性报告
h)、高速的多线程扫描器轻松检索成千上万个页面
i)、智能爬行程序检测 web 服务器类型和应用程序语言
j)、Acunetix 检索并分析网站,包括 flash 内容、SOAP 和 AJAX
k)、端口扫描 web 服务器并对在服务器上运行的网络服务执行安全检查
l)、可导出网站漏洞文件
0×01、AWVS安装过程、主要文件介绍、界面简介、主要操作区域简介
注:本文提供的破解 方式仅供软件试用,请于链接文字24小时内删除 ,如需使用请购买正版!
1、下载地址:http://pan.baidu.com/s/1i3Br6ol提取密码:u60f 。其中 2016_02_17_00_webvulnscan105.exe是AWVS v10.5的安装包,而Acunetix_Web_Vulnerability_Scanner_10.x_Consultant_Edition_KeyGen_Hmily 是破解补丁。AWVS安装的方法与安装windows程序安装方法一样,我们这里主要讲解安装的主要点:
2、安装到最后一步的时候将“Launch Acunetix Web Vulnerbility Scanner”前的勾去掉,安装完成之后将会在桌面生成两个图标:
3、之后我们将破解补丁移动到AWVS的安装目录,打开破解补丁。点击patch之后便可以完成破解,最后关闭破解补丁。
4、破解之后,程序将弹出下面程序,直接点击next下一步
5、最后提示激活成功之后,直接Flish完成安装,提示Successfuly表示成功安装。
6、启动桌面上的Acunetix Web Vulnerability Scanner 10.5,在菜单栏上选择——Help——About可以看到AWVS的版本,以及包括“Program Updates”可检查软件更新,我们这里就不更新。毕竟我们下的是最新版的。
7、主要程序介绍:在程序安装路径“C:\Program Files (x86)\Acunetix\Web Vulnerability Scanner 10” 中主要文件的作用如下:
8、安装界面介绍:启动AWVS可以看到整个程序的界面
①、标题栏
②、菜单栏
③、工具栏
④、主要操作区域
⑤、主界面
⑥、状态区域
9:主要操作区域简介:
0×02、AWVS的菜单栏、工具栏简介(AWVS menus bar & tools bar)
a)、菜单栏
File——New——Web Site Scan :新建一次网站扫描
File——New——Web Site Crawl:新建一次网站爬行
File——New——Web Services Scan:新建一个WSDL扫描
Load Scan Results:加载一个扫描结果
Sava Scan Results:保存一个扫描结果
Exit:退出程序
Tools:参考主要操作区域的tools
Configuration——Application Settings:程序设置
Configuration——Scan Settings:扫描设置
Configuration——Scanning Profiles:侧重扫描的设置
Help——Check for Updates:检查更新
Help——Application Directories——Data Directory:数据目录
Help——Application Directories——User Directory:用户目录
Help——Application Directories——Scheduler Sava Directory:计划任务保存目录
Help——Schedule Wen Interface:打开WEB形式计划任务扫描处
Help——Update License:更新AWVS的许可信息
Help——Acunetix Support——User Mannul(html):用户HTML版手册
Help——Acunetix Support——User Mannul(PDF):用户PDF版手册
Help——Acunetix Support——Acunetix home page:AWVS官网
Help——Acunetix Support——HTTP Status:HTTP状态码简介
b)、工具栏
从左到右分别是(这些都可以在主要操作区域找到,所以不常用):
新建扫描——网站扫描——网站爬行——目标查找——目标探测——子域名扫描——SQL盲注——HTTP编辑——HTTP嗅探——HTTP Fuzzer——认证测试——结果对比——WSDL扫描——WSDL编辑测试——程序设置——扫描设置——侧重扫描设置——计划任务——报告
0×03:一次新的扫描的功能全面概述(Scan Settings:扫描类型、扫描参数)
1、点击菜单栏的 New Scan 新建一次扫描, 网站扫描开始前,需要设定下面选项:
1). Scan type
2). Options
3). Target
4). Login
5). Finsh
1、Scan type:
①:Scan single website:在Website URL处填入需要扫描的网站网址,如果你想要扫描一个单独的应用程序,而不是整个网站,可以在填写网址的地方写入完整路径。wvs支持HTTP/HTTPS网站扫描。
②:Scan using saved crawling results:导入WVS内置 site crawler的爬行到的结果,然后对爬行的结果进行漏洞扫描。
③:Access the scheduler interface:如果被扫描的网站构成了一个列表形式(也就是要扫描多个网站的时候),那么可以使用Acunetix的Scheduler功能完成任务,访问http://localhost:8183,扫描后的文件存放在“C:\Users\Public\Documents\Acunetix WVS 10\Saves”.
Acunetix的计划任务,主要特性如下:
a). 可用于大量扫描,扫描结果保存在“C:\Users\Public\Documents\Acunetix WVS 10\Saves”。
b). 扫描结束,可以使用邮件通知。
c). 可设定计划时间,什么时候允许扫描,什么时候不允许扫描
2、Options:
Scanning options :侧重扫描的漏洞类型设置
①:Scanning profile:设置侧重扫描的类型,包含16种侧重检测类型,如下:
每种侧重扫描的类型又有包含多种扫描script,如果需要做调整或者修改,请查看 Configuration >> Scanning Profiles
Scanning Profiles中的每个侧重扫描的类型下都包含了非常多的扫描脚本,由于太多我就不一一介绍,随便点击一个,右边就有对该扫描脚本的介绍,随意抽选几个介绍,例如:
ftp_anonymous.script:扫描ftp匿名登录漏洞PHPInfo.script:扫描是否有phpinfo泄露
Backup_File.script:扫描网站的备份文件wordpress_8.script:针对 wordpress弱口令测试
你也可以选择扫描的脚本,然后新建自己的扫描策略,如下:
选择自己需要的策略,可以单击保存按钮保存一份策略,单击X按钮删除一个策略
Scan Setting:扫描配置
②:可定制扫描器扫描选项,AWVS在默认情况下只有“default”默认扫描参数配置策略,点击旁边的Customize则可以自定义:
与界面主操作区域对应:如下
(注意要点:如果在新建向导中设置Scan setting只会影响本次扫描的扫描参数设置,如果在主界面中的Scan Setting设置则是全局配置)
此处可以设置各种扫描参数配置,包括点击白色处“
”是新建配置,单击X则是删除配置。
a)、Scan options 扫描配置
①:禁用蜘蛛爬行出发现的问题,AWVS在漏洞测试之前会使用蜘蛛功能对网站先进行测试,此处是禁用蜘蛛爬行发现的问题,如:错误的链接。一般这样的错误都是风险很低的警告信息。
②:scanning mode 是指扫描的模式分为三种如下:
Heuristic:标准的扫描模式,扫描线程和深度一致
Quick:快速扫描模式
Extensive:扩展性扫描,完整扫描模式
它们三种模式的扫描线程、深度如下:
③:目录爬行的递归深度,默认为5级,使用0则关闭
不要发出超过500个相同类型的警告,使用0则关闭
④:开启目标端口扫描功能,但该扫描速度较慢,建议使用NMAP端口扫描
⑤:收集不常见的HTTP请求状态,例如HTTP 500状态码
⑥:在扫描过程中如果服务器停止响应尝试25次之后中止扫描
⑦:在扫描过程中,是否使用网站设定的cookie
⑧:网站中链接到其它主机的文件,而这些网站与主站的关系相近,例如:www.baidu.com链接中包含test.baidu.com,你可以在这里添加允许与主站关系很大的域名来进行扫描,可以使用通配符形式。这样扫描的时候将扫描这些主机的漏洞。
b)、Headers and Cookies 头部与Cookie
(a)、Test cookies for all files (by default it will only check files with parameters)
访问所有文件,都使用cookie测试(默认情况下,只有带参数的文件才使用cookie进行检测)。
(b)、Manipulate the HTTP headers listed below
操控HTTP头部信息,可按照自己的要求定制HTTP头。
(c)、Add Header
添加一个HTTP头部,在新增的“enter header name here”单击此处可以输入你的头部名称。
(d)、Remove Selected
移除你选中的HTTP头部
c)、Parameter Exclusion 扫描参数排除
有些参数不影响用户会话的操作,你可以排除这些参数被放在这个名单中,扫描器将不会去扫描测试这些参数,注意:名称应该为正则表达式
(a)、添加一个参数排除:
包含URL(*代表任何URL)、名字(要过滤的参数,一般以正则表达式表示)、type(请求方式,包含Any任何类型、GET、POST类型、COOKIE类型)
(b)、移除选中的排除
d)、GHDB 利用Google hacking数据库检测
Google hacking数据库设置,包含了1467条数据在数据库中
AWVS在扫描的过程中利用google hacking技术在google搜索引擎上对目标网站进行信息搜集。下面的语法是对网站的信息搜索的google语法。
(a)、Short description: 简要描述信息:(参考:http://baike.baidu.com/view/336231.htm)
(b)、Query String :Google上查询的字符
(c)、 Filter GHDB:GHDB过滤搜索 (Short description:简要描述 Query String 查询字符串 Full description:所有描述)
(d)、check visible:检测明显的 unchek visible:不检测明显的 check only visible:检测仅明显的
③: Crawling options 爬行设置:
针对特定的扫描场景,自定义爬虫的行为,这些选项将定义爬虫的行为:
start HTTP Sniffer for manual crawling at the end of process:蜘蛛爬行过程结束后启动HTTP嗅探,以发行更多链接。
Get first URL only:只扫描首页,不抓取任何链接。
Do not fetch anyting above start folder:不扫描上级目录,例如:新建扫描为http://www.baidu.com/cms/,将不会扫描cms上级目录的链接。
Fetch files below base folder:扫描子目录。
Fetch directory indexes even if not linked:获取目录索引,即使没有关联性的。
Retrieve and process robots.txt, sitemap.xml. :抓取并分析robots.txt、sitemap.xml中出现的目录、URL。
lgnore CASE differences in paths:忽略目录的大小写敏感
fetch default index files (index.php,default.asp):尝试获取每个目录下的默认索引文件,例如扫描http://qq.com,如果爬行到test目录则尝试获取test目录下是否有索引文件,例如:http://qq.c/test/index.php。
try to prevent infinite derectory recursion:防止抓取到死循环的无限目录。如:http://qq.com/admin/admin/admin/admin/admin
crawl should request only linked files: 爬行应请求只有关联性的文件。
ignore parameters on file extensions like .js .css…etc:忽略文件扩展名类似为js css的参数。
disable auto custom 404 detection(application will use only user defined reles):禁用自动定制404检测(应用程序将使用用户定义的规则)。
considerwww.domain.comand domain.com as the same host:如果启用该项那么AWVS会认为www域名和顶级域名是同一主机。
enable input limitaion heuristics:如果启用该选项,并在同一目录下的文件被检测20多个相同的输入方案,抓取工具只会抓取前20个相同的输入方案。
optimize inputs for known applications: 对已知应用程序输入的优化。
maximum num ber of variations:变化的最大数目,例如:http://www.baidu.com/index.php?id=1,这里设置ID的最大值为50。link depth limitation:链接深度限制,例如从A站点抓取发现了一个链接,又从该链接上发现另一个链接,以此类推最大深度默认为100。
structure depth limitation:子目录的最大深度的限制,默认最大15级目录。
maximun number of files in a derectory:在一个目录下AWVS爬取文件数量的最大值。
maximum number of path schemes:判断路径任务的最大任务数。
crawler file limit:爬虫爬行文件的数量限制。
④:file extension filters: 文件扩展名过滤
AWVS将读取该配置,尝试扫描哪些后缀的文件,例如排除掉的后缀文件,AWVS在工作的时候将不扫描被排除的后缀文件,因为扫描它们毫无意义。
a)、包含的扩展名,AWVS将会扫描的后缀扩展文件
b)、 排除的扩展名,AWVS将不扫描的后缀扩展文件
⑤: Directory and file filters:目录和文件过滤
定义一个目录列表被排除在爬行和扫描过程通配符允许您筛选一系列文件:如/dir1/* 或者/dir1/a *。表示将不扫描/dir1/下的文件,/dir1/a*表示的是不扫描dir1下以a开头的文件的漏洞。
a)、过滤的URL
b)、是否为正则表达式
⑥:URL Rewrite:URL重定向设置
一些网站使用URL重写,这里你可以定义一个列表的URL重定向不同网站帮助爬虫浏览这些网站。
⑦:HTTP Options
定义在爬行和扫描过程的HTTP头选项
(a)、用户当前的agent
(b)、定义不同浏览器的agent
(c)、检查最大的并发连接数
(d)、HTTP的请求超时时间
(e)、AWVS对两个请求之间延迟的毫秒,某些WAF对访问请求时间太快会进行拦截
(f)、HTTP请求的文件字节大小限制,默认5120kb
(h)、自定义HTTP 头部,例如自定义IP报头或者其它的HTTP头,如下:
⑧:Lan Settings
配置代理服务器来扫描网站漏洞
a)、http代理服务器
b)、Socks代理服务器
⑨:DeepScan
深度扫描,深度扫描技术,嵌入WebKit提供使用JavaScript基础技术如AJAX / HTML5和SPA 网站全面支持
a)、启用深度扫描
b)、扫描从外部引入的脚本中存在的漏洞,例如scr=http://www.qq.com/xx.jsp
c)、Session 超时的秒数
⑩:Custom Cookie
自定义Cookie,例如你在网站的登录之后获取Cookie,将Cookie添加到这来就可以实现预登陆状态下的扫描
a)、添加、移除自定义的cookie ,包含要添加的URL,使用*表示所有的URL,以及对应的Cookie值。
b)、扫描时锁定自定义的cookie
⑾:Input Fileds
此处主要设置提交表单时的字段对应的默认值,例如在HTML表单提交中出现age的字段,则会自动填写值为20。字段中:*web*中的是含有通配符的表示形式,例如1web2这样的就是满足*web*,而字段的值则有多种变量如下:
${alpharand}:a-z的随机字符串
${numrand}:0-9随机数字
${alphanumrand}:上两个的组合(随机字符串+随机数字)
(a)、从URL中 解析表单的字段,例如输入http://login.taobao.com将从这里读取表单的字段,值如果有默认则填写默认,没有则需要自己添加,例如对wooyun.org自动提取表单的字段,预设值则需要自己设置,这样方便在扫描的时候AWVS自动填写预设的值去提交表单进行漏洞测试
(b)、添加、移除、前后顺序设置自定义的表单字段,包含:名字、值、长度
⑿ : AcuSensor
传感器技术 ,从这个节点,您可以启用或禁用acusensor和它的功能和设置密码。
(a)、启动AcuSensor技术
(b)、为AcuSensor设置密码
(c)、请求文件列表
(d)、开启服务器警告
(e)、在一个特定的URL上测试AcuSensor
⒀:Port Scanner
配置端口扫描程序的、socket、超时和端口设置
(a)、用户扫描端口的线程数
(b)、连接超时的毫秒时间设置
(c)、添加、移除扫描的端口,这里已经列举了常用的端口,AWVS将会扫描这里的端口。
⒂:Custom 404
自定义404页面,为了扫描中防止误报,应当自定义404页面
自定404页面的方式:
①:自定义404的URL
②:404页面的关键字匹配
③:匹配的关键字出现的位置
Location header:出现在HTTP头部
Result body:出现在HTTP的正文处
Result headers:出现在HTTP的头部+正文处
④:测试404页面是否存在Pattern中输入的,如果成功表示404页面中存在该关键字
⑤:是否为正则表达式
当然你可以单击向下展开的按钮,可以测试网站的404页面包括头部、浏览形式的查看,然后你可以选择404的关键字,通过点击“Generate pattern from selection”来生成404的关键字或者表达式,并且会自动设置出现的位置。
Adjust advanced scan setting:
在扫描向导中显示高级扫描设置,如下面的Advanced就是高级选项
Advanced:
进入高级之后分别是:
①:在爬行结果之后选择我们需要扫描哪些文件
②:自定义从哪里开始扫描,导入txt文件,例如扫描http://www.baidu.com,不想从根路径开始扫,而从二级目录http://www.baidu.com/test/,将其保存到txt文件中之后将从test二级目录开始扫描
③:爬行的时候使用外部测试工具,蜘蛛爬行的过程中将运行您设置的命令,以及超时时间设置
④:设置包含一个火狐扩展插件Selenium IDE生成的HTML文件,蜘蛛爬行的过程中将会根据它来进行爬行。
Target:
(a)、扫描目标的根路径
(b)、服务的banner
(c)、目标URL
(d)、目标操作系统
(e)、目标的Web容器
(f)、目标的程序语言
Login:
①:使用预先设置的登录序列,可以直接加载lsr文件,也可以点击白色处开始按照步骤新建一个登录序列(具体步骤参考后面的演示)
②:填写用户名密码,尝试自动登录.在某些情况下,可以自动识别网站的验证。
Finish:
①:使用AcuSensor传感技术的设置
②:爬行与扫描中是否区分大小写
③:将这次的设置保存为一个策略,以便下次直接使用策略
开始扫描:
①:
依次为:
#1、Generater report from this scan :
使用Configuration Settings可定制报告的某些信息,例如logo等.
转换为不同的格式报告:
②:扫描结果显示,包含存在漏洞的名字、链接、参数等,Site Structrus是网站爬行出的结构状态、Cookie是爬行的Cookie信息。
③:详情信息显示,需要点击左边的扫描结果才会展示详情信息。如下图就是左侧显示的SQL注入和参数,右边是SQL注入的详情。
如果不点击则是扫描的高低危漏洞统计,如下图就是威胁等级:Level 3,漏洞总结果是17个,High(红色):高危漏洞2个,Medium(橙色):中危漏洞8个,Low(蓝色):低危漏洞5个,Informational(绿色):提示信息2个。
④ :显示三个信息。
Taget Information:包含目标站点 1、是否应答、2、WebServer的banner、3、操作系统、4、Web容器、5、程序语言
Statistics:对扫描的各种信息统计,包含1、扫描的总时间、2、HTTP请求数量、3、平均扫描时间、4、扫描重复次数
Progress:扫描进度信息的提示,包含1、是否扫描完成,100.00%表示已完成,2、端口扫描是否完成 3、蜘蛛爬行是否完成(文件数量、目录数量、变量数量)、4、脚本信息 5、内部模块
⑤ 显示应用程序运行、测试的日志、错误日志。
0×04、AWVS的应用程序配置详解
三个设置点:
1、Application Settings:
1、Application Updates: 程序升级的配置
Application Updates:程序升级
①:程序更新,分为两种:
At application startup:在程序启动时自动检查更新
When ‘check for updates’ is clicked:用户点击“General——Program Updates——Check for updates”时更新
②: 更新时使用代理服务器来更新程序,需填写主机名、代理端口、用户名和密码
2、Logging: 日志配置
①:Enable logging:开启日志功能
②:Log infomational messages:将程序的提示信息记入日志
③:Log warning messages:将程序的警告信息记入日志
④:Log Errir messages:将程序的错误信息记入日志
⑤:Log HTTP request and response to a file:将程序中发起的HTTP请求和响应信息记录到一个文件中log\httplog.txt
⑥:Log only HTTP error in HTTP log:只记录HTTP的错误信息在HTTP的日志中
⑦:Include timestamps:在记录日志的时候包含产生每条记录的时间戳
⑧:On error switch to Error Log tab:在发生错误信息的时候,自动切换到Error Log面板
⑨:number log files to keep before deleting:删除日志前需要保留的日志数量,默认2个
3、Saved Scan Results 扫描保存数据库的设置
①:保存报告的数据库类型:分为: MS Access 和 MS SQLSERVER两种,如果使用SQLserver将要填写SQLServer的数据库地址、用户名、密码包括数据库名等。
②:Access数据库的保存位置,默认是:C:\ProgramData\Acunetix WVS 10\Data\Database\vulnscanresults.mdb
③:如果你使用SQLServer数据库,不想填写数据库IP\用户名\密码\数据库名等信息,你可以直接导入.dbconfig格式的数据库配置
④:扫描完成之后自动保存结果。
4 、HTTP Authentication HTTP基本验证
此验证主要用于如下类似的HTTP基本认证:
①:AWVS在扫描过程中可识别基本验证,在此过程中不要询问我们是否需要验证,选中此项AWVS将不会提示我们哪些页面需要认证。
②:自动保存凭证信息,在AWVS扫描过程中询问我们HTTP认证的账号密码,勾选此项之后,当我们输入用户名密码之后,AWVS将自动保存我们的输入,以便以后扫描时不再需要输入。
③:配置需要验证的 Host主机、路径Path、Username用户名和Password密码。
按钮中:
Add Credentials:添加一个凭证
Remove Selected:删除选择的凭证
Edit:编辑选中的凭证
Show Password:显示已添加的凭证的密码
5、Client Certificates: 证书验证
①:Certificate file:选择证书文件 Password:证书密码 URL:验证证书的URL地址
②:Import Certificate:上方填写完整之后点击此按钮导入证书 Remove selected:移除选中的证书
6、Login Sequence Manager:表单验证 【重点】
表单验证用户某些页面,例如扫描后台、扫描用户登录后可访问的页面时候,需要登录用户密码验证再进行扫描
与新建扫描向导中的“Login”功能一致,需要新建一个表单验证。
①:New sequence :新建一个表单验证 Edit sequence:编辑一个表单验证 Remove sequence:移除选中的验证
Browser:浏览表单验证文件,后缀为.lsr。
如何新建一个表单验证,过程三个步骤如下,以DVWA渗透测试演练系统来演示:
#1、Record Login Actions 记录登录操作,这一步是选择需要登录的页面之后,输入账号密码进行登录,然后程序将会记录登录的所有操作、包括输入的账号密码以及登陆后跳转的页面
①:此处标记的是你扫描的URL
②:此处当然你登录的表单区域了
③:三个按钮 Record :开始记录登录的操作 Stop:停止记录登录操作 Play:回放你录制的登录操作来确定是否正确
⑤:这里记录的是你的几个动作,如上图只有三个动作:
1、导航到http://127.0.0.1/dvwa/login.php
2、对表单的username字段输入admin账号
3、对表单的password字段输入password密码
4、虽然上图没有第四步,但是第四步是:Clik on Login,就是我们点击登录的这个步骤
④: ↓ ↑:上下键来调整登录的步骤 ,+ 、- :增加或删除一个登录步骤
⑥:显示登录每个步骤的类型、目标、超时时间、填入的值
第一步记录登录操作已经成功完成,点击Next进入下一步
#2、Record Restrictions:记录限制请求,此处的记录的原因是如果AWVS在扫描登录状态的页面的时候,如果请求到类似Logout的退出请求,那么就会结束会话并退出登录,这样下来我们就无法继续扫描后台的漏洞了,所以此时我们需要记录一个限制的地址,也就是告诉AWVS,哪个请求是会退出会话,当然不仅仅是退出,如果一个后台有“注销”、“退出”、“重新登录”三个按钮,我们也要同时记录着三个请求。
针对DVWA的限制请求记录步骤
①:首先Restrict按钮是要呈现按下的状态,此时就会开始记录用户点击的限制请求
②:DVWA中的左侧导航“Logout”是退出的链接,我们点击它之后中间会弹出一个拦截
③:拦截中的数据就是我们点击“Logout”的请求,这里有三个按钮
Restrict request using exact match :记录下此请求标识为精确的限制约束,也就是说将它告诉AWVS不要请求该链接
Forward :放过这个请求,不标记它为限制请求
Forward all:停止抓取所有请求,释放所有的请求
所以这里我们选择:第一个按钮,标记http://127.0.0.1/dvwa/logout.php;为限制请求,不让AWVS去请求它。
如上图:停止抓取请求,点击“Restrict”使这个按钮呈未按下状态,然后可以看到右上角出现的限制约束的请求链接,OK,Next进入下一步了。看到successfully,我想你已经知道这步是成功确定了一种检测有效会话的模式。
#3、检测会话是否有效:完成第二部步骤之后进入第三步骤是检测我们的会话是否有效,如果有效就完成了一次表单登录验证的流程。
②:Detect while navigating:导航检测,选中进入进入下一步
①:随意点击一个需要登录链接,如果弹出Successfully则说明我们去点击这个链接的会话是正确的,
③:历史检测:获取历史检测的正确性
⑤:这里会自动获取登录状态之后的关键字或状态码,并以一种方式判断,这里分别有几种方法:
a)、检测到登录后的的状态码是多少,或者不是多少?
status code is
status code is not
b)、检测登录后的关键字是在头部、还是不在头部?
Pattern is found in headers
Pattern is not found in headers
c)、检测登录后的关键字是否在返回的响应中?
Pattern is found in response
Pattern is not found in response
④:Check Pattern:测试AWVS提取的关键字是否正确,如果是successfully则表示正确
⑥:完成登录表单验证的步骤之后保存会话文件,后缀为.lsr
最后AWVS可以正常扫描登录状态后的页面的漏洞了:
7、False Positives 处理误报
此处是存储误报的链接、请求的。在我们扫描的结果中,如果你认为这一项是AWVS的误报,右击选择它”Mark alert(s) as false positive“将它放置到误报区域内,AWVS下次扫该站点的时候将不会再认为它是一个漏洞。Removed Selected则是移除选中的误报。
8、HTTP Sniffer 代理型嗅探抓包设置
Acunetix HTTP 代理设置,默认监听8080端口(此功能默认不开启)
①:监听的接口分为两种:
local interface (recommended):接受本机的代理请求(推荐)
all interface (not recommended) 接受所有的代理请求(不推荐)
②:监听的端口,默认是8080
此配置设置之后点击“Apply”应用之后,在主操作区域的Tools中选择HTTP Sniffer,将本地浏览器设置代理为127.0.0.1:8080,再点击“Start”就可以获取嗅探到访问网页的数据包了
9、Scheduler:计划任务性扫描
用户可以不启动AWVS来扫描漏洞,可以直接访问Web版实现计划任务,可以扫描多个网站漏洞,使用该项服时要保证Acunetix WVS Scheduler v10服务已经启动。
Web Interface:Web版扫描的配置
Listen open port:Web界面计划任务的端口,访问:http://localthost:8183
Allow remote computers to connect:允许远程计算机访问我们的Web版的计划扫描页面,如果一旦开启则强制使用HTTPS协议另外还需要设置账户密码来进行验证,为了保证它的安全性。
Use HTTPS:使用HTTSP协议加密传输的数据
Require authentication:使用用户名、密码形式验证,一般配合“Allow remote computers to connect”来使用。
Change administrative password:修改认证的用户名密码
Scan:设置计划任务扫描的线程与保存结果
Scan results save folder:Web任务计划扫描结果的保存位置
Parallel scans (max 10):同时扫描的网站的数量,最多10,如果你的许可证书是正版,最大数量可达到500个
Email Notifications:配置邮件服务器将扫描工作通过邮件形式发送给您
Send email notifications when scans are fnished:选择是否扫描工作的时候发送邮件通知我们,如果勾选则启用该功能
Server ip/hostname:邮件系统的主机IP
Port:邮件系统的端口
The SMTP server requires authentication:勾选它SMTP服务器是否需要密码认证
Username:SMTP用户名
Password:认证密码
TT:邮件发送的目标,邮件将发送给谁。
CC:邮件将抄送给谁
From:发送的人的设置,就是说邮件是从哪个邮箱发送的
Check here to verify Settings:测试邮箱是否正确配置,是否能成功发送
Excluded hours Templates:禁止扫描时间设置模版
在长时间扫描的时候,假如你不想在流量高峰期扫描你的网站,你可以指定一个暂停扫描的时间范围。例如上图:红色区域表示不允许扫描的时间,蓝色区域表示扫描的时间,这里表示周六、周日早上4:00-4:59之间的时候不进行扫描。
10、Miscellaneous 杂七杂八项配置
Memory Optimization:内存优化
Use temporary files to reduce memory usage:使用临时文件,扫描中产生的临时文件存储在硬盘中,而不存储在内存中,以减少内存的使用情况。
Tamporary folder:临时文件的位置
Keep all AcuSensor data in memory fo inspection:保持所有的AcuSensor数据在内存中检测
Maximum memory during crawling:爬行过程中可占用的最大内存(单位:M),如果在爬行和扫描过程中内存不足,则自动停止扫描
Display Options:显示选项
Display custom HTTP status information:显示自定义HTTP状态信息
Display HTTPS status icon:显示HTTPS的状态图标,启用此选项的话,扫描的时候,如果发现https访问的区域,将会在爬行结果中显示出一个锁状的小图标
Password Protection:密码保护
Current password:当前密码
New password:新密码
Confirm new password:确认新密码
Set password:设置密码
设置密码的方式是,当前如果为空密码,直接在第二三个文本框输入密码,点击Set password就可以完成密码设置, 配置密码后,运行wvs主程序及主要程序时需要输入口令验证 。
如果需要清除设置的密码,只要输入当前密码,新密码处留空再点击设置密码即可。
0×05:AWVS的蜘蛛爬行功能:
作用:爬行网站所有URL,可了解网站基本目录结构,以便于进行下一步的扫描
①:Tools–Site Crawler 选择网站爬行功能
②:从左到右的功能分别为:
:打开格式为.cwl的蜘蛛爬行的结果
:保存格式为.cwl的蜘蛛爬行结果
:导出 export.xml蜘蛛爬行报告
: 从导入的文件建立结构
:扫描这个网站的漏洞
:选择一个文件进行扫描
:扫描的网站URL
③:被爬行网站的登录验证文件,加载这个文件可以爬行到需要登录的页面资源。Strart:开始爬行 Stop:停止爬行
④:被爬行网站的的爬行结果:
Name:爬行网站的的文件名称、Cookiie信息
HTTP Result:文件访问的状态,OK表示200,Forbidden表示403,Internal Server Error表示500
Inputs:可输入的参数值
Title:文件的标题
Content Type:文件的类型
⑤:详细信息显示区域,点击左边的任意文件,在这里可以显示它的详细信息。下方的选项卡分别为:
Info:文件详细信息
Referres:来源页信息
HTTP Header:HTTP头部信息
Inputs:可输入参数的信息
View Source:查看文件源代码
View Page:以浏览方式查看页面
Structure Analysis:结构分析
0×06:AWVS的目标探测工具(Target Finder)
相当于一款加强版(针对WEB渗透测试)的端口、banner探测工具
功能:
1、探测指定IP/IP段开放特定端口的IP
2、探测出IP后,探测该端口的banner信息,可探测出该端口上运行的WEB服务的中间件的版本信息
①:Tools——Target Finder打开该工具
②:被扫描的IP/IP段,IP段格式为:192.168.199.1-255,
③:被扫描的端口,这里是80,443端口
④:扫描出的结果包含: Server:目标主机 Hostname:主机名 Bnaner:Bnaner信息 Web Server:Web容器
⑤:将扫描的结果进行操作分别如下操作:
Scan this Server:用AWVS扫描这台主机的漏洞
Edit with HTTP Editor:用HTTP Editor测试目标
Save list of targets (for scanning):保存为.txr格式的目标列表作为后期的扫描目标
Export list of servers to CSV:导出为CSV格式的列表,包含所有的描述信息
⑥:查看目标主机的Response Headers(响应的HTTP头信息)、Response Data(响应的数据)、View Page(浏览形式查看)
0×07:AWVS的子域名探测工具(Subdomain Scanner)
作用:探测并猜解子域名的信息,
①: Tools——Subdomain Scanner 工具位置
②: 填写需要被扫描子域名的主机域名
③: 使用的DNS服务器,分为两种:
Use DNS Server from target:使用目标的DNS服务器探测解析
Use Specified DNS Server:使用自定义的DNS服务器,在旁边可以填写自定义的DNS服务器
④:Timout:超时时间,单位是秒
⑤:被探测出的子域名列表信息,分别包含Domain:被探测出的子域名; IP Address:子域名对应的IP; Web Server Banner(HTTP):HTTP的WEB服务器的Banner信息; Web Server Banner(HTTPS):HTTPS的WEB服务器的Banner信息
⑥:右击任意一个探测出的子域名,可对其如下操作:
Scan this Server:用AWVS扫描这台主机的漏洞
Edit with HTTP Editor:用HTTP Editor测试目标
Save list of targets (for scanning):保存为.txr格式的目标列表作为后期的扫描目标
Export list of servers to CSV:导出为CSV格式的列表,包含所有的描述信息
⑦:分为HTTP和HTTPS两种,各自均可查看目标主机的Response Headers(响应的HTTP头信息)、Response Data(响应的数据)、View Page(浏览形式查看)
0×08:AWVS的SQL盲注测试工具(Blind SQL Injection)
作用:在扫描网站的时候,发现网站存在SQL盲注漏洞,你可以倒入到SQL盲注工具中,你也可以直接将抓取的SQL盲注HTTP数据包粘贴到SQL盲注工具中进行注入测试。
HTTP Request:
①:Tools——Blind SQL Injection 工具位置
②:SQL盲注的工具栏,分别作用如下:
:开始执行测试SQL注入
:开始读取数据库
:获取表字段信息
:读取数据记录信息
:暂停操作
:中止操作
:新建一个SQL注入
:将当前进行注入的信息保存为.bln的文件
:打开.bln格式的文件进行注入分析
:导出xml格式的数据库结构信息
:保存.CVS的数据记录信息
:显示或隐藏HTTP Request界面
③:Default Value:SQL注入参数原来的值,这里/example1.php?name=root 原来的值是root
:添加一个注入的位置,被添加的地方会显示为:${injecthere}
④:SQL盲注的HTTP信息,可以在扫描网站得到SQL注入的时候,右键“Export to Blind SQL Injection ” ,也可以直接将存在盲注的HTTP请求信息粘贴进来
⑤:搜索区域。
:针对上方的HTTP请求信息进行搜索,包括翻阅上一个下一个按钮
:搜索的结果进行高亮显示
:搜索的关键字为正则表达式
:搜索的关键字匹配大小写
:HTTP信息显示的类型包括:文本、HTML、SQL、XML、CSS等等。。
⑥:此处显示当前的数据库的名字、用户名、版本,以及可列出数据库、表、字段、数据记录 ,如下图右击一个数据库可以获取表、右击表可以获取字段、右击表可以获取数据。Export the structure to file:将数据结构导出为.xml的文件
⑦:此处显示的是注出的所有数据记录,最下方一行显示的是信息状态。
Settings——General:
①:设置数据库的类型,包括三种类型:Autodetect(自动检测)、Mysql(Mysql数据库)、MSSQL(Mssql数据库)
②:数据库注入的方法,包括三种类型:Autodetect(自动检测)、condition based(根据条件情况而定)、Union select base(基于联合查询)
③:Show debug information:显示过程的调试信息
④:对SQL语句中的空格以/**/进行编码
⑤:强制对HTTP传输的SQL字符串进行编码,勾选此项下面两项就是设定编码方式
⑥:对所有的字符进行编码
⑦:对空格使用+进行编码
Settings——Condition Based Extractor:
①:SQL注入字符串的设置
Automatic detection:自动检测
Provided by user:用户自定义选择,条件是${},例如:1 and {condition}/*
②:真假条件识别器
Automatic detection:自动检测
Provided by Regex:指定正则表达式
Inverse Regex:当你想要真实的情况触发上述正则表达式的条件为假时,启用此选项。
③:特征提取
Bit Method:位测试方法,直接数值转换数字为测试
Half Method:则应用程序将尝试通过使用一半法找出字符的数值,以此递归
Try Parallel request:尝试平行请求
Settings——Union Select based extractor
①:指定联合查询中起始的字段数
②:指定联合查询中最大的字段数
③:指定可见的索引,0是自动检测
Tools:
①:通过load_file函数读取文件内容,需要root权限,点击“Extract”开始读取
File Name:被读取的文件
Offset:指定要从第几个字符开始读取
Length:指定读取多长的字符,0为读取全部
②:执行SQL查询语句,点击“Excute”进行查询。
SQL query:要查询的SQL语句
Offset:指定从第几个字符开始显示结果
Length:指定查询出显示结果的长度,0是全部
③:执行了上面两个操作,如果完成之后将会把结果保存在datebasde目录下,上图就是报错的读取文件和sql查询的结果。
0×09、AWVS的HTTP请求编辑器(HTTP Editor)
作用:包含两种模式,一种Request、一种Text Only模式,主要用于编辑HTTP信息,修改HTTP信息并发送给服务器获取返回的结果,是HTTP信息的重放过程。可修改HTTP的头部数据或者其它信息再提交给服务器处理等。
HTTP Request模式:
①:Tools——HTTP Editor 工具的位置
②:Start:将当前编辑的HTTP请求提交给服务器处理,并获取返回结果。 Encoder Tool是编码工具,界面如下:
支持:URL、HTML、Base64、C-style、MD5、MD4、SHA1、UTF-7等多种编码解码方式
③:从左到右的图标功能分别为:
:针对下方的Requesr Header添加一个新的HTTP头
:删去选择的HTTP头
:编辑Cookie信息,包括增加、删除Cookie某个变量
:使用HTTPS协议
Method:请求的方式,分为GET、HEAD、POST等
Protocol:HTTP的协议分别为1.0、1.1
URL:HTTP的URI部分
Edit Request Variables:修改HTTP信息中GET或者POST的参数、值
④:HTTP请求信息的头部Header
⑤:请求的数据,一般这里存放的是POST数据
⑥:服务器返回的信息,包含HTTP Header(响应的头部信息)、Response Data(响应的信息源码)、View Page:以浏览的方式显示、HTML Structrus Analysis(HTML的结构分析)
Text Only模式:
①:这里不再熬述,讲解SQL盲注功能的时候已经讲解了这一条按钮的作用
②:HTTP的信息,可以自己粘贴进来,也可以对扫描结果进行发送过来,如下:
③:返回响应信息,这里也不多多说,上面已经详细说明了。
0×10、AWVS的HTTP嗅探工具(HTTP Sniffer)
作用:设置代理拦截浏览器的数据包信息,并且可以将数据包发送到HTTP Edit编辑重放或者其它功能,要想抓取数据包应该将浏览器的代理设置为127.0.0.1:8080(默认),在Application Settings——HTTP Sniffer可以修改监听的端口和接收的请求范围。
①:Tools——HTTP Sniffer工具位置
②:Start/Stop:开始或者停止嗅探抓包
Edit Traps: 编辑抓包的规则,例如:拦截ASP、PHP的请求信息、拦截GET请求、拦截POST请求、拦截返回的信息、不拦截images、css、script、显示PHP报错信息、替换user-agent等等….
Enable Traps/Disabled Traps:开启或者关闭规则,如果规则开启,规则中假如设置了例如Trap ASP and PHP request,嗅探过程中会拦截ASP或者PHP的请求信息并且提示用户是否修改再发送还是丢弃这个包(有些类似HTTP Edit)。如下:
③:对嗅探到的链接进行操作,包括 Edit with HTTP Edit(发送到HTTP Edit进行编辑测试)、Scan to HTTP Fuzzer(发送到HTTP Fuzzer测试)、Start scan form here(从这里开始扫描漏洞)、 Remove disconnected entries(清空所有的嗅探信息)
:从左到右分别是清空所有嗅探信息、将嗅探的信息保存为slg格式的文件、导入slg格式的文件、搜索过滤嗅探的信息、当面板嗅探的信息逐渐增多时滚动条自动滚动
⑤:每个嗅探到的链接的具体的请求或响应信息
0×11、AWVS的HTTP模糊测试工具(HTTP Fuzzer)
作用:漏洞测试工具,用于批量数据自动提交,并测试出正确性的数据。与Burp中的intruder功能一致。
Request:
①:Tools——HTTP Fuzzer 工具位置
②:Start:开始启动Fuzzer程序测试 Fuzzer Filters:Fuzzer结果筛选,后面三个图标分别为保存为.fzs的文件、打开为.fzs的Fuzzer 文件、到处为XML的Fuzzer结果文件
③:Request:Fuzzer的HTTP数据,可以是自己抓包粘贴上去,也可以通过扫描发送到此处。如上图的${Gen_2}就代表是攻击位置使用字典
④:Add Generator:添加一个Fuzzer字典
Insert into Request:插入一个攻击位置,选中需要被攻击的位置后点击此按钮
Remove Generator:移除Fuuzer字典
Add Generator中包含了六种字典
每个字典的配置如下:
⑥:显示Fuzzer字典的名字、类型、描述信息
⑦:对Fuzzer字典的设置,参考上方详解
⑧:Fuzzer字典的简介
Results:
①:Fuzzer的次数统计
②:Fuzzer的结果显示,包含下面几个字段:
#:Fuzzer的次数ID
Status code:返回的响应的状态
URL:返回的页面
Generators:提交的参数
Response time:响应花费的时间
Response size:响应内容长度
Word count:单词数量
③:Request:提交的HTTP请求内容、Response:返回的响应内容、View Page:浏览形式查看、Raw Text:文本模式查看
Fuzzer Filters:是针对Fuzzer结果进行筛选的工具
①:选择一个筛选过滤器
②:分为5项,分别为:
Rule description:筛选器的名称描述
Rule type:筛选器的类型:Include(包含)、Exclude(不包含)、Log
Apply to:关键字出现的位置,其中有 Response(所有地方)、Response body(出现在body上)、 Response Header(出现在头部)、 Response status code(出现在状态码上)
Regular expression:输入正则表达式
③:更新、或者添加一个筛选器
0×12、AWVS的认证测试工具(Authentication Tester)
认证测试工具,用于基本身份认证、简单的表单认证的破解是从Fuzzer工具中拆分出来的一种。
#1、上图测试的是HTTP的基本验证,比如类似Tomcat的/html/manager 验证
①:Tools——Authentication Tester 工具位置
②:Target URL to test:测试目标 Start:开始Fuzzer
③:Authentication method:认证方式分为两种:
HTTP:基本认证
Web from based:简单的表单认证
④:Logon has failed if:认证失败的关键字分为三种:
HTTP Status code is :HTTP返回的状态码
Results Conditions:返回的结果关键字条件
Results match regular expresison:正则表达式匹配
⑤:Username dictionary path:用户名字典
⑥:Password dictionary path:密码字典
⑦:正确的结果显示
#2、表单的形式
表单的形式需要将认证方式改成:Web from based,右侧Select选择,AWVS将自动识别攻击目标中的表单,如下图识别出uname、pass两个字段,选中uname,单击左下角的“username”,选择“pass”,单击左下角的”Password”,这样表单就可以对应了,加载字典就可以成功Fuzzer了。
0×13、AWVS的WEB WSDL扫描测试工具(Web Services Scanner、Web Services Editor)
作用:扫描WSDL接口漏洞,并且可以对扫描的漏洞进行漏洞测试
WSDL:Web Services Description Language的缩写,是一个用来描述Web服务和说明如何与Web通信的XML语言。为用户提供详细的接口说明书。WSDL是Web Services的描述语言,是一种接口定义语言,用于描述Web Services的接口信息等。WSDL文档可以分为两部分,顶部由抽象定义组成,而底部由具体描述组成。
Web Services Scanner:
①:Web Services——Weeb Services Scanner
②:扫描的WSDL URL,Profile是侧重扫描的类型,默认是ws_default,Start:开始扫描
③: 扫描的结果
Web Services Editor:
①:Web Services——Web Services Editor 工具位置
②:WSDL URL(需要测试的目标URL)、打开图标(打开一个WSDL目标的文件)、Import(从web services scannner导入)
③:Service(选择的Service,默认)、Port(协议,分为ServiceSoap、ServiceSoap12)、Opration(扫描的方法名称)、Send(发送测试)、HTTP Editor(发送到HTTP Editor测试)
④:Editor:编辑模式 WSDL Structure:WSDL的结构信息 WSDL:目标XML格式的源信息
⑤:Request:方法名称、参数结构显示 SOAP:SOAP协议的源,如上我们针对参数username进行了注入测试
⑥:Response:返回XML源信息 Structured Data:返回结果的结构。可以看到已经爆出数据库版本了
070_《Delphi7程序设计技巧与实例》
《Delphi7程序设计技巧与实例》
Delphi 教程 系列书籍 (070) 《Delphi7程序设计技巧与实例》 网友(邦)整理 EMail: shuaihj@163.com
下载地址:
Part1 Part2 Part3
作者: 吴天准
书号: 7-113-05177-4
页码: 526
开本: 16开
版次:1-1
出版社: 中国铁道出版社
出版日期: 2003-5-1
内容简介
◆清华大学教师力作,包含作者多年编译器研究与程序设计教学经验
◆深入Object Pascal语言核心,澄清许多容易让人迷惑的概念
◆披露Delphi/Kylix实现的技术内幕,详细阐释深入编程的思考方法与实现策略
◆全书131个实例,近70,000行源代码,读者可直接使用的类与子程序近百个
前言
在中国,Delphi拥有一大批使用者、爱好者和追随者,他们组成了一个庞大而且日益引入注目的群体,著名的大富翁论坛(www. delphibbs.com)便是以Delphi技术讨论社区闻名于世的。很少有什么编程语言具有如此巨大的号召力,Delphi功能的强大和易学易用可见一斑。那么,究竟是什么使得Delphi如此地出类拔萃?本书将试图展示Delphi编程的全方位的魅力,引导读者一步步设计出各种复杂但有趣的程序。我们深信,当且仅当您亲手作出范例,陶醉于编程带来的喜悦和成功的快感之时,您将深深感受到Delphi的优越性,并将成为Delphi忠实的信徒。 本书的特点 分析透彻把Delphi中看似复杂、令人生畏的编程技术细细分解为容易掌握的知识要点,因为只有在透彻理解的基础上,读者才能构建起优秀、坚实的程序。深入详尽 在剖析Delphi 7 各种编程技术时,着重于各种难点和高级技术的分析讲解,结合相应的理论和背景知识,使得读者可以以更高的角度,在更广阔的背景上理解这些编程技术。深入浅出 本书务求语言简洁明快,通俗易懂,拉近与读者的距离,以浅显的语言揭示复杂的技术的精髓。 注重实践 本书实例非常丰富,对于大部分的知识点,都给出了有代表性或是提高性的例子,有助于读者理解和掌握。循序渐进 本书的编排原则是由易到难,由简到繁,先介绍有关知识和技术,再以实例说明其开发应用。每个例程分步阐述,条理清楚,对于程序中的重点和难点详加解释和说明。点滴积累 为方便读者,对于一些细节和重点以及综合性较强的内容,分别用“注意”、“技巧”、“提示”、“参考”等标出。 本书读者对象 本书适合于有一定编程基础和计算机基础的程序开发人员和DeIphi爱好者作为提高Delphi编程水平之用。对于比较基本的知识,本书只做简单介绍或是一笔带过。如果需要,建议读者可以参考以下方面的学习书籍:
● 计算机软件技术基础,用以了解高级语言的基本知识。
● 关系数据库理论和SQL语法,用以学习Delphi的数据库编程之用。
● HTML语法,用以制作网页之用。
● 网络的基础知识,用以学习Delphi网络编程之用。
本书章节安排
本书章节安排是这样的:
第1章 亲密接触Delphi 7
主要介绍了Delphi 7的特性、开发环境、各种工具的使用、Delphi中的基本概念和文件、工程等的说明和命名规范。
第2章 对象Pascal语言
主要介绍Delphi的编程语言——object Pascal的语法,以及面向对象编程的概念、特性,用实例来将各个知识点具体化,这是Delphi编程的基础。
第3章 Delphi的工程和框架类
主要介绍Delphi的工程组织结构、Delphi中重要的框架类的属性、方法介绍。
第4章 Delphi的编译与调试
介绍Delph的编译、调试的工具、方法和技巧,并介绍高级的调试工具,目的是让读者更好地利用Delphi进行程序开发。
第5章 Delphi界面设计
这一章向读者介绍Delphi中编程应用最广泛,也是最基本的界面设计技巧,内容涉及窗体、菜单、对话框、工具栏、按钮、标签及其他常用可视化组件的使用技巧,着重介绍各种非常规范的设计效果。
第6章 多媒体技术
这一章介绍Delphi中的图形、图像、音频、视频、多媒体、鼠标效果、光标效果等技术和技巧,用以使您的程序图文并茂,更加友好和引入注目。
第7章 COM、OLE和ActiveX技术
主要介绍在Delphi中如何实现Microsoft的COM系列技术,对COM、OLE、ActiveX、OLE Automation 等技术做了深入的讲解。
第8章 文件操作和管理
通过这一章的学习,您将对Delphi中文件操作的各种技术了然于心,并将了解各种文件相关的技巧。
第9章 Delphi的打印
这一章着重介绍Delphi中打印的组件使用、打印手段、与打印紧密相关的坐标和坐标映射,打印信息的获取和各种打印的效果的实现。
第10章 MDI应用程序
介绍了MDI程序的特性,MDI中的窗体融合等技术,各种非常规的MDI效果的实现。
第11章 多线程应用程序
介绍了进程、线程的概念,TThread类,线程的各种技术,最后介绍线程和进程的应用实例。
第12章 桌面数据库应用程序
这一章是Delphi数据库编程的基础,将涉及本地文件型数据库的各种技术,各种数据库,组件的特性和使用方法,以及Delphi中的数据库相关工具的使用。
第13章 ADO和ODBC数据库编程
分析了ADO和BDE、ODBC等数据库接口的概念、比较,介绍ADO组件的属性、方法和使用,并以实例展示ADO和ODBC编程中的几个技巧。
第14章 客户/服务器应用程序
本章首先介绍客户用匠务器模型的基本概念和模型结构,揭示其工作机制和优缺点,并以InterBase为例阐述服务器和客户端程序的实现。
第15章 MIDAS开发
这一章介绍了MIDAS的概念、体系、工作原理,阐述应用服务器、客户程序的建立和连接,并涉及MIDAS中的错误处理及发布问题。
第16章 网络编程
本章介绍了相当多的网络相关概念和技术背景,对Delphi中丰富的网络编程组件进行介绍,主要内容围绕Web数据库应用程序、CGI、套接字等技术展开。
第17章 Windows核心编程
这是本书的最后一章,全面介绍了Windows编程的核心技术,包括API、消息机制、动态链接库、动态数据交换、剪贴板、注册表、外壳技术、内存映射文件、钩子函数的应用等。通过本章的学习,读者将可以使自己的编程水平更上层楼,有助于更为透彻地理解前16章的各种编程技术。
附带光盘
本书附带光盘收录了全部例程的源代码和相关的文件。关于本书附带光盘的内容及其使用方法,请参考光盘内说明文档。建议读者按照本书的步骤亲自作出范例,如果遇到问题再参考光盘的例程。毕竟学习Delphi最好的办法是通过“实战”,只有在开发应用过程中才能发现问题,在解决问题的过程中才能真正掌握Delphi的编程技术。
致谢
本书由吴天准编著。参加本书编写工作的有张威、周德、朱放、陆剑、张轶、王成、路海明、祝萍、韩立、邢强、袁中、赵鸿、刘宏杰、许伟、冯彪、王清、孔文、聂梁、赵华、闰伟国、颜纯、吴峰、李杭、庞淳、张波、胡厚友、何斌、段洪、何洪、李星、何新、苗蕾、王巍、沈新、武学民、姚建等,陈贤淑、陈晓娟、廖康良等同志参与了本书的编排工作。在此,一致表示感谢。
由于编者水平有限,书中难免出现一些错误,诚恳希望读者对本书提出批评和建议,我们也会在适当时间进行修订和补充,并发布在天勤网站:http://www. qbooks.net“图书修订”栏目中。
作者
2003年2月
目录
第1章 亲密接触Delphi 7 1
1-1 关于Delphi的来龙去脉 2
1-2 Delphi 7的新特点 3
1-3 Delphi 7的集成开发环境(IDE) 4
1-4 编程环境的优化 5
1-5 编辑环境的设置 6
1-6 工程设置 7
1-7 搜索代码 8
1-8 使用“To-Do List” 8
1-9 使用项目管理 9
1-10 对齐组件 9
1-11 使用代码浏览器 9
1-12 使用代码编辑器 10
1-13 单元文件代码说明 10
1-14 工程文件代码说明 12
1-15 组件编辑技巧 12
1-16 复制组件模板 13
1-17 Delphi的对象库(Object Repository) 14
1-18 Delphi相关工具 14
1-19 Delphi几个易混概念的比较 15
1-20 Delphi程序设计技巧 15
1-21 IDE的快捷键 16
1-22 Delphi的命名规范 17
1-23 Delphi的文件格式 18
第2章 对象Pascal语言 21
2-1 Pascal的标识符(Identifiers) 22
2-2 Pascal的保留字 22
2-3 Pascal的数字和字符 23
2-4 Pascal的注释 23
2-5 Pascal的整数类型 24
2-6 Pascal的实数类型 24
2-7 Pascal的布尔类型 25
2-8 Pascal的字符类型 25
2-9 Pascal的字符串类型 26
2-10 Pascal的用户自定义类型 26
2-11 Pascal的枚举类型 27
2-12 Pascal的数组类型 27
2-13 Pascal的集合类型 28
2-14 Pascal的记录类型 29
2-15 Pascal的指针类型 30
2-16 Pascal的可变类型 31
2-17 Pascal的文件类型 31
2-18 Pascal的常量和变量 34
2-19 Pascal的运算符 35
2-20 Pascal的语句 36
2-21 Pascal的过程和函数 41
2-22 Pascal的作用域 44
2-23 基本数据类型相关函数 44
2-24 文件操作 48
2-25 面向对象编程(OOP) 50
2-26 Delphi中的类和封装 52
2-27 Delphi中的继承 54
2-28 Delphi中的多态 54
2-29 Delphi中的方法 56
2-30 Delphi中的接口 58
2-31 Delphi的异常处理 60
2-32 “异常”的异常 62
第3章 Delphi的工程和框架类 63
3-1 Delphi的工程结构 64
3-2 Delphi工程的建立 65
3-3 Delphi工程的管理 67
3-4 使用工程浏览器(Project Browser) 67
3-5 Delphi的TObject类 69
3-6 Delphi中的IInterface和IUnknown类 69
3-7 Delphi中的TPersistent类 70
3-8 Delphi中的TComponet类 70
3-9 Delphi中的TControl 类和TWinControl 类 71
3-10 Delphi中的TForm 类 72
3-11 Delphi中的TApplication 类 74
3-12 Delphi中的TCanvas类 77
3-13 Delphi中的TRecall类 78
3-14 Delphi中的TScreen类 79
3-15 Delphi中的TPrinter类 79
3-16 Delphi中的时间库异常类 81
3-17 Delphi中的对象异常类 84
3-18 Delphi中的组件异常类 85
第4章 Delphi的编译与调试 87
4-1 Delphi 7的编译 88
4-2 程序的运行 94
4-3 变量的查看 94
4-4 断点的使用 95
4-5 其他的调试查看窗口 97
4-6 向集成调试器传递命令行参数 97
4-7 数据的计算和修改 97
4-8 简化中断命令 98
4-9 编译设置 98
4-10 调试设置 99
4-11 使用Turbo Debugger调试 100
4-12 使用WinSight调试 100
第5章 Delphi界面设计 103
5-1 窗体概述 104
5-2 设置窗体的标题栏 104
5-3 设置窗体的外观和边框 104
5-4 设置窗体的字体整体风格 105
5-5 设置窗体的大小和显示状态 105
5-6 关闭窗体的常用处理方法 105
5-7 使用OnCloseQuery关闭窗体 106
5-8 创建窗体的初始化处理 106
5-9 处理窗体的键盘响应事件 107
5-10 绘制窗体 107
5-11 创建启动画面 108
5-12 创建透明窗体 109
5-13 限制窗体大小 111
5-14 随意拖动的窗体 111
5-15 禁止用户切换的窗口 112
5-16 不受用户控制的窗体 112
5-17 设置菜单属性的常用技巧 113
5-18 在菜单上添加历史文件 114
5-19 动态生成菜单 115
5-20 在菜单中添加图标 116
5-21 创建不规则窗体 117
5-22 在窗体上设置热键 118
5-23 工具条与按钮概述 119
5-24 状态栏的使用技巧 119
5-25 浮动工具栏设计 120
5-26 状态栏中插入进程条 121
5-27 设计与众不同的工具栏 123
5-28 Splitter的使用 124
5-29 TreeView的使用 125
5-30 制作彩色标签 126
5-31 分行提示 127
5-32 制作动态有声标签 127
5-33 ListView组件的使用 128
5-34 组件的拖放事件 129
5-35 使用查找和替换对话框 130
5-36 外部文件的拖放打开 133
第6章 多媒体技术 135
6-1 Delphi 7图形图像组件的使用 136
6-2 MediaPlayer组件的使用 137
6-3 TCanvas的使用 138
6-4 Tpen和TBrush的使用 141
6-5 TMediaPlayer的使用 142
6-6 TAnimate的使用 144
6-7 播放视频文件 146
6-8 视频的全屏显示 147
6-9 播放MP3 148
6-10 利用画布为控件添加边框 151
6-11 利用画布实现卡拉OK效果 152
6-12 显示鼠标选取框 154
6-13 鼠标绘图 156
6-14 通用动画演示 156
6-15 图像显示特效 158
6-16 放大镜效果 164
6-17 使用彩色光标 168
6-18 制作自己的屏保程序 169
6-19 用TChart组件显示内存使用情况 172
第7章 COM、OLE和ActiveX技术 175
7-1 什么是COM 176
7-2 面向对象Pascal中的COM的实现 177
7-3 COM对象的创建 178
7-4 什么是OLE 180
7-5 OLE与自动化 181
7-6 什么是ActiveX 184
7-7 Delphi中创建OLE对象 185
7-8 Delphi中使用自动化技术 189
7-9 Delphi中使用自动化事件 193
7-10 Delphi中使用OLE Server组件 198
7-11 添加ActiveX控件 202
7-12 Delphi中使用ActiveX控件 204
7-13 ActiveX程序发布和控件注册 206
第8章 文件操作和管理 207
8-1 Delphi中的文件类型 208
8-2 文本文件的操作 208
8-3 类型文件的操作 210
8-4 无类型文件的操作 212
8-5 文件管理的过程和函数 214
8-6 目录操作的过程和函数 217
8-7 Delphi的文件组件 220
8-8 Delphi中的文件流 221
8-9 文件相关的API函数 228
8-10 从文件中读取超过255个字符的行 230
8-11 INI文件的操作 230
8-12 将文件删除到回收站中 233
8-13 文件搜索 234
8-14 对多个文件进行操作 238
8-15 删除目录 241
8-16 拷贝整个目录 246
8-17 查询驱动器状态 248
8-18 如何把一个URL加入到浏览器中的收藏夹 249
8-19 获取同文件关联的图标 251
第9章 Delphi的打印 257
9-1 组件的简单打印 258
9-2 打印位图 259
9-3 使用TPrinter 260
9-4 打印相关的API函数 262
9-5 坐标系统和坐标映射 264
9-6 Delphi中的打印相关组件 267
9-7 打印的一些经验和技巧 270
9-8 检测打印的页边距 270
9-9 检测是否存在打印机 273
9-10 使用打印机内置字体打印 273
9-11 打印旋转字体 276
9-12 打印可视组件 279
9-13 制作预览窗口 283
9-14 改变系统默认打印机 291
第10章 MDI应用程序 293
10-1 MDI的窗体 294
10-2 创建MDI应用程序 294
10-3 MDI中的菜单融合 300
10-4 给MDI客户区加上背景图像 308
10-5 在MDI的客户区实现颜色渐变 310
10-6 去除MDI客户区的滚动条 311
10-7 使MDI主窗体响应键盘事件 313
第11章 多线程应用程序 315
11-1 任务、线程和进程 316
11-2 TThread类 317
11-3 线程与VCL的同步 321
11-4 线程的优先级 324
11-5 线程的同步 328
11-6 线程的数据存储 336
11-7 多线程查找 336
11-8 查看系统的进程 341
第12章 桌面数据库应用程序 345
12-1 数据库系统概述 346
12-2 使用SQL语句 349
12-3 使用数据库桌面 350
12-4 使用Borland数据库引擎 353
12-5 使用SQL Explorer 354
12-6 数据访问组件 355
12-7 使用Database组件 356
12-8 使用DataSource组件 358
12-9 TDataSet类 360
12-10 使用Table组件 364
12-11 使用Query组件 367
12-12 创建数据库应用程序 368
12-13 数据控制组件 370
12-14 记录的过滤、查找与排序 373
12-15 报表处理 380
12-16 数据处理综合应用 382
第13章 ADO和ODBC数据库编程 391
13-1 数据库接口的比较 392
13-2 Delphi的ADO组件 393
13-3 ADO组件的使用 397
13-4 动态设置ODBC数据源 401
13-5 访问ODBC数据库 403
第14章 客户/服务器应用程序 409
14-1 客户/服务器的基本概念 409
14-2 客户/服务器模型 411
14-3 客户/服务器模型的工作机制 412
14-4 为什么选用客户/服务器结构 412
14-5 使用InterBase服务器 414
14-6 服务器端的程序设计 416
14-7 存储过程 419
14-8 客户端程序设计 423
第15章 MIDAS开发 429
15-1 MIDAS和多层体系 430
15-2 MIDAS的组成 432
15-3 MIDAS的工作原理 434
15-4 Delphi中的MIDAS组件 434
15-5 创建应用服务器 436
15-6 创建客户程序 437
15-7 应用服务器和客户程序的连接 438
15-8 一个MIDAS应用程序实例 440
15-9 错误处理 443
15-10 MIDAS程序的发布 444
第16章 网络编程 447
16-1 CGI、ISAPI和NSAPI概述 448
16-2 Web应用系统的构成 448
16-3 Web程序的工作原理 451
16-4 Delphi中的Web组件 452
16-5 创建Web应用程序 459
16-6 使用Delphi创建计数器 462
16-7 开发自己的浏览器 470
16-8 套接字基础 473
16-9 网络通讯协议简介 476
16-10 使用WinSock实现FTP功能 478
第17章 Windows核心编程 485
17-1 Win32 API编程 486
17-2 消息机制 487
17-3 动态链接库 492
17-4 动态数据交换 496
17-5 剪贴板技术 499
17-6 注册表 502
17-7 制作托盘程序 508
17-8 设置快捷方式 515
17-9 内存映射文件 517
17-10 使用钩子 523
PostgreSQL SQL 语言:函数和操作符
本文档为PostgreSQL 9.6.0文档,本转载已得到原译者彭煜玮授权。
1. 逻辑操作符
常用的逻辑操作符有:
AND
OR
NOT
SQL使用三值的逻辑系统,包括真、假和null,null表示"未知"。观察下面的真值表:
操作符AND和OR是可交换的,也就是说,你可以交换左右操作数而不影响结果。
2. 比较函数和操作符
常见的比较操作符都可用,如Table 9-1所示。
Table 9-1. 比较操作符
Note: !=操作符在分析器阶段被转换成<>。不能把!=和<>操作符实现为做不同的事。
比较操作符可以用于所有可以比较的数据类型。所有比较操作符都是双目操作符,它们返回boolean类型;类似于1 < 2 < 3的表达式是非法的(因为没有<操作符可以比较一个布尔值和3)。
如Table 9-2所示,也有一些比较谓词。它们的行为和操作符很像,但是具有 SQL 标准所要求的特殊语法。
Table 9-2. 比较谓词
BETWEEN谓词可以简化范围测试:
a BETWEEN x AND y
等效于
a >= x AND a <= y
注意BETWEEN认为终点值是包含在范围内的。 NOT BETWEEN可以做相反比较:
a NOT BETWEEN x AND y
等效于
a < x OR a > y
BETWEEN SYMMETRIC和BETWEEN相似,不过BETWEEN SYMMETRIC不要求AND左边的参数小于或等于右边的参数。如果左参数不是小于等于右参数,这两个参数会自动被交换,这样总是会应用一个非空范围。
当有一个输入为空时,普通的比较操作符会得到空(表示"未知"),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS [ NOT ] DISTINCT FROM谓词:
a IS DISTINCT FROM b
a IS NOT DISTINCT FROM b
对于非空输入,IS DISTINCT FROM和<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值而不是"unknown"。
要检查一个值是否为空,使用下面的谓词:
expression IS NULL
expression IS NOT NULL
或者等效,但并不标准的谓词:
expression ISNULL
expression NOTNULL
不要写expression = NULL,因为NULL是不"等于"NULL的(控制代表一个未知的值,因此我们无法知道两个未知的数值是否相等)。
Tip: 有些应用可能要求表达式expression = NULL在expression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量transform_null_equals。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。
如果expression是行值,那么当行表达式本身为非空值或者行的所有域为非空时IS NULL为真。由于这种行为,IS NULL和IS NOT NULL并不总是为行值表达式返回反转的结果,特别是,一个同时包含 NULL 和非空值的域将会对两种测试都返回假。在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL会更好,它们只会检查整个行值是否为空而不需要在行的域上做额外的测试。
布尔值也可以使用下列谓词进行测试:
boolean_expression IS TRUE
boolean_expression IS NOT TRUE
boolean_expression IS FALSE
boolean_expression IS NOT FALSE
boolean_expression IS UNKNOWN
boolean_expression IS NOT UNKNOWN
这些谓词将总是返回真或假,从来不返回空值,即使操作数是空也如此。空值输入被当做逻辑值"未知"。 请注意实际上IS UNKNOWN和IS NOT UNKNOWN分别与IS NULL和IS NOT NULL相同, 只是输入表达式必须是布尔类型。
如Table 9-3中所示,也有一些比较相关的函数可用。
Table 9-3. 比较函数
3. 数学函数和操作符
PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学表达的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。
Table 9-4展示了所有可用的数学操作符。
Table 9-4. 数学操作符
按位操作操作符只能用于整数数据类型,而其它的操作符可以用于全部数字数据类型。按位操作的操作符还可以用于位串类型bit和bit varying, 如Table 9-13所示。
Table 9-5显示了可用的数学函数。在该表中,dp表示double precision。这些函数中有许多都有多种不同的形式,区别是参数不同。除非特别指明,任何特定形式的函数都返回和它的参数相同的数据类型。 处理double precision数据的函数大多数是在宿主系统的 C 库基础上实现的;因此,边界情况下的准确度和行为是根据宿主系统而变化的。
Table 9-5. 数学函数
Table 9-6展示了用于产生随机数的函数。
Table 9-6. 随机函数
random()返回的值的特征取决于系统实现。 它不适合用于加密应用,如果需要用于加密应用请参考pgcrypto模块。
最后,Table 9-7显示了可用的三角函数。所有三角函数都有类型为double precision的参数和返回类型。每一种三角函数都有两个变体,一个以弧度度量角,另一个以角度度量角。
Table 9-7. 三角函数
Note: 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()和degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入偏差。
4. 字符串函数和操作符
本节描述了用于检查和操作字符串值的函数和操作符。在这个环境中的串包括所有类型character、character varying和text的值。除非另外说明,所有下面列出的函数都可以处理这些类型,不过要小心的是,在使用character类型的时候, 它有自动填充空白的潜在影响。有些函数还可以处理位串类型。
SQL定义了一些字符串函数,它们使用关键字,而不是逗号来分隔参数。详情请见Table 9-8,PostgreSQL也提供了这些函数使用正常函数调用语法的版本(见Table 9-9)。
Note: 由于存在从那些数据类型到text的隐式强制措施,在PostgreSQL 8.3之前,这些函数也可以接受多种非字符串数据类型。这些强制措施在目前的版本中已经被删除,因为它们常常导致令人惊讶的行为。不过,字符串串接操作符(||)仍然接受非字符串输入,只要至少一个输入是一种字符串类型,如Table 9-8所示。对于其他情况,如果你需要复制之前的行为,可以为text插入一个显式强制措施。
Table 9-8. SQL字符串函数和操作符
还有额外的串操作函数可以用,它们在Table 9-9中列出。它们有些在内部用于实现Table 9-8列出的SQL标准字符串函数。
Table 9-9. 其他字符串函数
concat、concat_ws和format函数是可变的,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见Section 36.4.5)。数组的元素被当作函数的独立普通参数一样处理。如果可变数组参数为 NULL,concat和concat_ws返回 NULL,但format把 NULL 当作一个零元素数组。
还可以参阅Section 9.20中的string_agg。
Table 9-10. 内建转换
4.1 format
函数format根据一个格式字符串产生格式化的输出,其形式类似于 C 函数sprintf。
format(formatstr text [, formatarg "any" [, ...] ])
formatstr是一个格式字符串,它指定了结果应该如何被格式化。格式字符串中的文本被直接复制到结果中,除了使用格式说明符的地方。格式说明符在字符串中扮演着占位符的角色,它定义后续的函数参数如何被格式化及插入到结果中。每一个formatarg参数会被根据其数据类型的常规输出规则转换为文本,并接着根据格式说明符被格式化和插入到结果字符串中。
格式说明符由一个%字符开始并且有这样的形式
%[position][flags][width]type
其中的各组件域是:
position(可选)
一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被忽略,默认会使用序列中的下一个参数。
flags(可选)
控制格式说明符的输出如何被格式化的附加选项。当前唯一支持的标志是一个负号(-),它将导致格式说明符的输出会被左对齐(left-justified)。除非width域也被指定,否者这个域不会产生任何效果。
width(可选)
指定用于显示格式说明符输出的最小字符数。输出将被在左部或右部(取决于-标志)用空格填充以保证充满该宽度。太小的宽度设置不会导致输出被截断,但是会被简单地忽略。宽度可以使用下列形式之一指定:一个正整数;一个星号()表示使用下一个函数参数作为宽度;或者一个形式为n$的字符串表示使用第n个函数参数作为宽度。
如果宽度来自于一个函数参数,则参数在被格式说明符的值使用之前就被消耗掉了。如果宽度参数是负值,结果会在长度为abs(width)的域中被左对齐(如果-标志被指定)。
type(必需)
格式转换的类型,用于产生格式说明符的输出。支持下面的类型:
s将参数值格式化为一个简单字符串。一个控制被视为一个空字符串。
I将参数值视作 SQL 标识符,并在必要时用双写引号包围它。如果参数为空,将会是一个错误(等效于quote_ident)。
L将参数值引用为 SQL 文字。一个空值将被显示为不带引号的字符串NULL(等效于quote_nullable)。
除了以上所述的格式说明符之外,要输出一个文字形式的%字符,可以使用特殊序列%%。
下面有一些基本的格式转换的例子:
SELECT format('Hello %s', 'World');
结果:Hello World
SELECT format('Testing %s, %s, %s, %%', 'one', 'two', 'three');
结果:Testing one, two, three, %
SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly');
结果:INSERT INTO "Foo bar" VALUES('O''Reilly')
SELECT format('INSERT INTO %I VALUES(%L)', 'locations', E'C:\\Program Files');
结果:INSERT INTO locations VALUES(E'C:\\Program Files')
下面是使用width域和-标志的例子:
SELECT format('|%10s|', 'foo');
结果:| foo|
SELECT format('|%-10s|', 'foo');
结果:|foo |
SELECT format('|%*s|', 10, 'foo');
结果:| foo|
SELECT format('|%*s|', -10, 'foo');
结果:|foo |
SELECT format('|%-*s|', 10, 'foo');
结果:|foo |
SELECT format('|%-*s|', -10, 'foo');
结果:|foo |
这些例子展示了position域的例子:
SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three');
结果:Testing three, two, one
SELECT format('|%*2$s|', 'foo', 10, 'bar');
结果:| bar|
SELECT format('|%1$*2$s|', 'foo', 10, 'bar');
结果:| foo|
不同于标准的 C 函数sprintf,PostgreSQL的format函数允许将带有或者不带有position域的格式说明符被混在同一个格式字符串中。一个不带有position域的格式说明符总是使用最后一个被消耗的参数的下一个参数。另外,format函数不要求所有函数参数都被用在格式字符串中。例如:
SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
结果:Testing three, two, three
5. 二进制串函数和操作符
本节描述那些检查和操作类型为bytea的值的函数和操作符。
SQL定义了一些使用关键字而不是逗号来分割参数的串函数。详情请见Table 9-11。PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅Table 9-12)。
Note: 本页中显示的示例结果假设服务器参数bytea_output被设置为escape(传统PostgreSQL格式)。
Table 9-11. SQL二进制串函数和操作符
还有一些二进制串处理函数可以使用,在Table 9-12列出。 其中有一些是在内部使用,用于实现Table 9-11列出的 SQL 标准串函数。
Table 9-12. 其他二进制串函数
get_byte和set_byte把一个二进制串中的一个字节计数为字节 0。get_bit和set_bit在每一个字节中从右边起计数位;例如位 0 是第一个字节的最低有效位,而位 15 是第二个字节的最高有效位。
6. 位串函数和操作符
本节描述用于检查和操作位串的函数和操作符,也就是操作类型为bit和bit varying的值的函数和操作符。除了常用的比较操作符之外,还可以使用Table 9-13里显示的操作符。&、|和#的位串操作数必须等长。在移位的时候,保留原始的位串的的长度,如例子所示。
Table 9-13. 位串操作符
下面的SQL标准函数除了可以用于字符串之外,也可以用于位串: length、 bit_length、 octet_length、 position、 substring、 overlay。
下面的函数除了可以用于二进制串之外,也可以用于位串: get_bit、 set_bit。 当使用于一个位串时,这些函数将串的第一(最左)位计数为位 0。
另外,我们可以在整数和bit之间来回转换。一些例子:
44::bit(10) 0000101100
44::bit(3) 100
cast(-44 as bit(12)) 111111010100
'1110'::bit(4)::integer 14
请注意,如果只是转换为"bit",意思是转换成bit(1),因此只会转换整数的最低有效位。
Note: 把一个整数转换成bit(n)将拷贝整数的最右边的n位。 把一个整数转换成比整数本身长的位串,就会在最左边扩展符号。
7. 模式匹配
PostgreSQL提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、更近一些的SIMILAR TO操作符(SQL:1999 里添加进来的)和POSIX-风格的正则表达式。除了这些基本的"这个串匹配这个模式吗?"操作符外,还有一些函数可用于提取或替换匹配子串并在匹配位置分离一个串。
Tip: 如果你的模式匹配的要求超出了这些,请考虑用 Perl 或 Tcl 写一个用户定义的函数。
Caution
虽然大部分的正则表达式搜索都能被很快地执行,但是正则表达式仍可能被 人为地弄成需要任意长的时间和任意量的内存进行处理。要当心从不怀好意 的来源接受正则表达式搜索模式。如果必须这样做,建议加上语句超时限制。
使用SIMILAR TO模式的搜索具有同样的安全性危险, 因为SIMILAR TO提供了很多和 POSIX-风格正则表达式相同的能力。
LIKE搜索比其他两种选项简单得多,因此在使用 不怀好意的模式来源时要更安全些。
9.7.1. LIKE
string LIKE pattern [ESCAPE escape-character]
string NOT LIKE pattern [ESCAPE escape-character]
如果该string匹配了提供的pattern,那么LIKE表达式返回真(和预期的一样,如果LIKE返回真,那么NOT LIKE表达式返回假, 反之亦然。一个等效的表达式是NOT (string LIKE pattern))。
如果pattern不包含百分号或者下划线,那么该模式只代表它本身的串;这时候LIKE的行为就象等号操作符。在pattern里的下划线 (_)代表(匹配)任何单个字符; 而一个百分号(%)匹配任何零或更多个字符的序列。
一些例子:
'abc' LIKE 'abc' true
'abc' LIKE 'a%' true
'abc' LIKE '_b_' true
'abc' LIKE 'c' false
LIKE模式匹配总是覆盖整个串。因此,要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。
要匹配文本的下划线或者百分号,而不是匹配其它字符, 在pattern里相应的字符必须 前导逃逸字符。缺省的逃逸字符是反斜线,但是你可以用ESCAPE子句指定一个不同的逃逸字符。 要匹配逃逸字符本身,写两个逃逸字符。
Note: 如果你关掉了standard_conforming_strings,你在文串常量中写的任何反斜线都需要被双写。
请注意反斜线在串文本里已经有特殊含义了,所以如果你写一个 包含反斜线的模式常量,那你就要在 SQL 语句里写两个反斜线。 因此,写一个匹配单个反斜线的模式实际上要在语句里写四个反斜线。 你可以通过用 ESCAPE 选择一个不同的逃逸字符 来避免这样;这样反斜线就不再是 LIKE 的特殊字符了。 但仍然是字符文本分析器的特殊字符,所以你还是需要两个反斜线。) 我们也可以通过写ESCAPE ''的方式不选择逃逸字符,这样可以有效地禁用逃逸机制,但是没有办法关闭下划线和百分号在模式中的特殊含义。
关键字ILIKE可以用于替换LIKE, 它令该匹配根据活动区域成为大小写无关。这个不属于SQL标准而是一个PostgreSQL扩展。
操作符 等效于LIKE, 而 *对应ILIKE。 还有 ! 和! *操作符分别代表NOT LIKE和NOT ILIKE。所有这些操作符都是PostgreSQL特有的。
9.7.2. SIMILAR TO正则表达式
string SIMILAR TO pattern [ESCAPE escape-character]
string NOT SIMILAR TO pattern [ESCAPE escape-character]
SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 SQL 正则表达式是在LIKE标记和普通的正则表达式标记的奇怪的杂交。
类似LIKE,SIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_和%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的.和.*)。
除了这些从LIKE借用的功能之外,SIMILAR TO支持下面这些从 POSIX 正则表达式借用的 模式匹配元字符:
|表示选择(两个候选之一)。
*表示重复前面的项零次或更多次。
+表示重复前面的项一次或更多次。
?表示重复前面的项零次或一次。
{m}表示重复前面的项刚好m次。
{m,}表示重复前面的项m次或更多次。
{m,n}表示重复前面的项至少m次并且不超过n次。
可以使用圆括号()把多个项组合成一个逻辑项。
一个方括号表达式[...]声明一个字符类,就像 POSIX 正则表达式一样。
注意点号(.)不是SIMILAR TO的一个元字符。
和LIKE一样,反斜线禁用所有这些元字符的特殊含义;当然我们也可以用ESCAPE指定一个不同的逃逸字符。
一些例子:
'abc' SIMILAR TO 'abc' true
'abc' SIMILAR TO 'a' false
'abc' SIMILAR TO '%(b|d)%' true
'abc' SIMILAR TO '(b|c)%' false
带三个参数的substring,即substring(string from pattern for escape-character),提供了抽取一个匹配 SQL 正则表达式的子串的方法。和SIMILAR TO一样,声明的模式必须匹配整个数据串,否则函数失败并返回空值。为了标识在成功的时候应该返回的模式部分,模式 必须包含逃逸字符的两次出现,并且后面要跟上双引号(")。匹配这两个标记之间的模式的文本将被返回。
一些例子,使用#"定界返回串:
substring('foobar' from '%#"o_b#"%' for '#') oob
substring('foobar' from '#"o_b#"%' for '#') NULL
9.7.3. POSIX正则表达式
Table 9-14列出了所有可用于 POSIX 正则表达式模式匹配的操作符。
Table 9-14. 正则表达式匹配操作符
POSIX正则表达式提供了比LIKE和SIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrep、sed或awk使用一种与我们这里描述的类似的模式匹配语言。
正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。
一些例子:
'abc' ~ 'abc' true
'abc' ~ '^a' true
'abc' ~ '(b|d)' true
'abc' ~ '^(b|c)' false
POSIX模式语言的详细描述见下文。
带两个参数的substring函数,即substring(string from pattern),提供了抽取一个匹配 POSIX 正则表达式模式的子串的方法。如果没有匹配它返回空值,否则就是文本中匹配模式的那部分。 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅后文描述的非捕获性圆括号。
一些例子:
substring('foobar' from 'o.b') oob
substring('foobar' from 'o(.)b') o
regexp_replace函数提供了将匹配 POSIX 正则表达式模式的子串替换为新文本的功能。 它的语法是 regexp_replace(source, pattern, replacement [, flags ])。 如果没有匹配pattern,那么返回不加修改的source串。 如果有匹配,则返回的source串里面的匹配子串将被replacement串替换掉。replacement串可以包含n, 其中n是 1 到 9, 表明源串里匹配模式里第n个圆括号子表达式的子串应该被插入, 并且它可以包含&表示应该插入匹配整个模式的子串。如果你需要放一个文字形式的反斜线在替换文本里,那么写\。flags参数是一个可选的文本串,它包含另个或更多单字母标志,这些标志可以改变函数的行为。标志i指定大小写无关的匹配,而标志g指定替换每一个匹配的子串而不仅仅是第一个。支持的标志(但不是g)在Table 9-22中描述。
一些例子:
regexp_replace('foobarbaz', 'b..', 'X')
fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
fooXX
regexp_replace('foobarbaz', 'b(..)', E'X\\1Y', 'g')
fooXarYXazY
regexp_matches函数返回一个文本数组,该数组由匹配一个 POSIX 正则表达式模式得到的所有被捕获子串构成。其语法是regexp_matches(string, pattern [, flags ])。该函数可以不返回任何行、返回一行或者返回多行(见下文的g)。如果pattern不匹配,该函数不返回行。如果模式不包含圆括号子表达式,则每一个被返回的行都是一个单一元素的文本数组,其中包括匹配整个模式的子串。如果模式包含圆括号子表达式,该函数返回一个文本数组,它的第n个元素是匹配模式的第n个圆括号子表达式的子串("非捕获"圆括号不计算在内,详见下文)。flags参数是一个可选的文本字符串,它包含零个或更多个单字母标志,它们可以改变函数的行为。标志g让函数寻找串中的每一个匹配,而不仅仅是第一个,并且为每一个这样的匹配返回一行。支持的标志(但不是g)在Table 9-22中描述。
一些例子:
SELECT regexp_matches('foobarbequebaz', '(bar)(beque)');
regexp_matches
----------------
{bar,beque}
(1 row)
SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
regexp_matches
----------------
{bar,beque}
{bazil,barf}
(2 rows)
SELECT regexp_matches('foobarbequebaz', 'barbeque');
regexp_matches
----------------
{barbeque}
(1 row)
也可以强制regexp_matches()通过使用一个子选择来总是返回一行。当你希望所有行都被返回(甚至是不能匹配的行)时,把它用在一个SELECT目标列表中会特别有用:
SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;
regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern [, flags ])。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在Table 9-22中描述。
regexp_split_to_array函数的行为和regexp_split_to_table相同,不过regexp_split_to_array会把它的结果以一个text数组的形式返回。它的语法是regexp_split_to_array(string, pattern [, flags ])。这些参数和regexp_split_to_table的相同。
一些例子:
SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', E'\\s+') AS foo;
foo
-------
the
quick
brown
fox
jumps
over
the
lazy
dog
(9 rows)
SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', E'\\s+');
regexp_split_to_array
-----------------------------------------------
{the,quick,brown,fox,jumps,over,the,lazy,dog}
(1 row)
SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
foo
-----
t
h
e
q
u
i
c
k
b
r
o
w
n
f
o
x
(16 rows)
正如上一个例子所示,正则表达式分离函数会忽略零长度的匹配,这种匹配发生在串的开头或结尾或者正好发生在前一个匹配之后。这和正则表达式匹配的严格定义是相悖的,后者由regexp_matches实现,但是通常前者是实际中最常用的行为。其他软件系统如Perl也使用相似的定义。
7.3.1. 正则表达式细节
PostgreSQL的正则表达式是使用 Henry Spencer 写的一个包来实现的。下面的正则表达式的大部分描述都是从他的手册页中逐字拷贝过来的。
正则表达式(RE),在POSIX 1003.2 中定义, 它有两种形式:扩展的RE或者是ERE(大概地说就是那些在egrep里的), 基本的RE或者是BRE(大概地说就是那些在ed里的)。PostgreSQL支持两种形式,并且还实现了一些POSIX标准中没有但是在类似 Perl 或者 Tcl 这样的语言中得到广泛应用的一些扩展。使用了那些非POSIX扩展的RE叫高级RE, 或者本文档里说的ARE。ARE 几乎完全是 ERE 的超集,但是 BRE 有几个符号上的不兼容(以及更多的限制)。我们首先描述 ARE 和 ERE 形式, 描述那些只适用于 ARE 的特性,然后描述 BRE 的区别是什么。
Note: PostgreSQL初始时总是推测一个正则表达式遵循 ARE 规则。但是,可以通过为 RE 模式预置一个embedded option来选择限制更多的 ERE 或 BRE 规则,如Section 9.7.3.4中所述。这对为期望准确的POSIX 1003.2 规则的应用提供兼容性很有用。
一个正则表达式被定义为一个或更多分支,它们之间被|分隔。只要能匹配其中一个分支的东西都能匹配正则表达式。
一个分支是一个或多个量化原子或者约束连接而成。一个原子匹配第一个,然后后面的原子匹配第二个, 以此类推;一个空分支匹配空串。
一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在Table 9-15里面显示的任何可能。 可能的量词和它们的含义在Table 9-16里显示。
一个约束匹配一个空串,但只是在满足特定条件下才匹配。 约束可以在能够使用原子的地方使用,只是它不能跟着量词。简单的约束在Table 9-17里显示; 更多的约束稍后描述。
Table 9-15. 正则表达式原子
RE 不能以反斜线()结尾。
Note: 如果你关掉了standard_conforming_strings,任何你写在文字串常量中的反斜线都需要被双写。
Table 9-16. 正则表达式量词
使用{...}的形式被称作范围。 一个范围内的数字m和n都是无符号十进制整数, 允许的数值从 0 到 255(包含)。
非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见Section 9.7.3.5。
Note: 一个量词不能紧跟在另外一个量词后面,例如**是非法的。量词不能作为表达式或者子表达式的开头,也不能跟在^或者|后面。
Table 9-17. 正则表达式约束
ookahead 和 lookbehind 约束不能包含后引用 (参阅Section 7.3.3),并且其中的所有圆括号 都被认为是非捕获的。
7.3.2. 方括号表达式
方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个不在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII中[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。
想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[.和.]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及逃逸(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下不是特殊的, 但在 ARE 里,它是特殊的(引入一个逃逸)。
在一个方括号表达式里,一个排序元素(一个字符、一个被当做一个单一字符排序的多字符序列或者一个表示上面两种情况的排序序列名称) 包含在[.和.]里面的时候表示该排序元素的字符序列。该序列被当做该方括号列表 的一个单一元素。这允许一个包含多字符排序元素的方括号表达式去匹配多于一个字符,例如,如果排序序列包含一个ch排序元素, 那么 RE [[.ch.]]*c匹配chchcc的头五个字符。
Note: PostgreSQL当前不支持多字符排序元素。这些信息描述了将来可能有的行为。
在方括号表达式里,包围在[=和=]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[.和 .])。例如,如果o和^是一个等价类的成员,那么[[=o=]]、[[=^=]]和[o^]都是同义的。一个等价类不能是一个范围的端点。
在方括号表达式里,在[:和:]里面封装的字符类的名字代表属于该类的所有字符的列表。 标准的字符类名字是:alnum、 alpha、blank、 cntrl、digit、 graph、lower、 print、punct、 space、upper、 xdigit。 它们代表在ctype中定义的字符类。 一个区域可以会提供其他的类。字符类不能用做一个范围的端点。
方括号表达式里有两个特例:方括号表达式[[:<:]]和[[:>:]]是约束,分别匹配一个单词开头和结束的空串。 单词定义为一个单词字符序列,前面和后面都没有其它单词字符。单词字符是一个alnum字符(和ctype中定义的一样) 或者一个下划线。这是一个扩展,兼容POSIX 1003.2, 但那里面并没有说明, 而且在准备移植到其他系统里去的软件里一定要小心使用。通常下文描述的约束逃逸更好些(它们并非更标准,但是更容易键入)。
7.3.3. 正则表达式逃逸
逃逸是以开头,后面跟着一个字母数字字符得特殊序列。 逃逸有好几种变体:字符项、类缩写、约束逃逸以及后引用。在 ARE 里, 如果一个后面跟着一个字母数字,但是并未组成一个合法的逃逸, 那么它是非法的。在 ERE 中没有逃逸:在方括号表达式之外,一个后面跟着字母数字字符的只是表示该字符是一个普通的字符,而且在一个方括号表达式里,是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。
字符项逃逸用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在Table 9-18中。
类缩写逃逸用来提供一些常用的字符类缩写。它们显示在Table 9-19中。
约束逃逸是一个约束,如果满足特定的条件,它匹配该空串。它们显示在Table 9-20中。
后引用(n)匹配数字n指定的被前面的圆括号子表达式匹配的同一个串 (参阅Table 9-21)。例如, ([bc])1匹配bb或者cc, 但是不匹配bc或者cb。RE 中子表达式必须完全在后引用前面。子表达式以它们的先导圆括号的顺序编号。非捕获圆括号并不定义子表达式。
Table 9-18. 正则表达式字符项逃逸
十六进制位是0-9、a-f和A-F。八进制位是0-7。
指定 ASCII 范围(0-127)之外的值的数字字符项转义的含义取决于数据库编码。 当编码是 UTF-8 时,转义值等价于 Unicode 代码点,例如 u1234表示字符U+1234。对于其他多字节编码, 字符项转义通常只是指定该字符的字节值的串接。如果该转义值不对应数据库编码 中的任何合法字符,将不会发生错误,但是它不会匹配任何数据。
字符项逃逸总是被当作普通字符。例如,135是 ASCII 中的], 但135并不终止一个方括号表达式。
Table 9-19. 正则表达式类缩写逃逸
在方括号表达式里,d、s和w会失去它们的外层方括号,而D、S和 W是非法的(也就是说,例如[a-cd]等效于[a-c[:digit:]]。同样[a-cD]等效于 [a-c^[:digit:]]的,也是非法的)。
Table 9-20. 正则表达式约束逃逸
一个词被定义成在上面[[:<:]]和[[:>:]]中的声明。在方括号表达式里,约束逃逸是非法的。
Table 9-21. 正则表达式后引用
Note: 在八进制字符项逃逸和后引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制逃逸。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为后引用。 一个多位的非零开头的序列也被认为是后引用,只要它出现在合适的子表达式后面 (也就是说,在后引用的合法范围中的数),否则就被认为是一个八进制。
7.3.4. 正则表达式元语法
除了上面描述的主要语法之外,还有几种特殊形式和杂项语法。
如果一个 RE 以***:开头,那么剩下的 RE 都被当作 ARE(这在PostgreSQL中通常是无效的,因为 RE 被假定为 ARE,但是如果 ERE 或 BRE 模式通过flags参数被指定为一个正则表达式函数时,它确实能产生效果)。如果一个 RE 以***=开头, 那么剩下的 RE 被当作一个文本串,所有的字符都被认为是一个普通字符。
一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在Table 9-22中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
Table 9-22. ARE 嵌入选项字母
嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。
除了通常的(紧)RE 语法(这种情况下所有字符都有效), 还有一种扩展语法,可以通过声明嵌入的x选项获得。在扩展语法里,RE 中的空白字符被忽略,就像那些在#和其后的新行(或 RE 的末尾)之间的字符一样。这样就允许我们给一个复杂的 RE 分段和注释。不过这个基本规则有三种例外:
空白字符或前置了的#将被保留
方括号表达式里的空白或者#将被保留
在多字符符号里面不能出现空白和注释,例如(?:
为了这个目的,空白是空格、制表符、新行和任何属于空白字符类的字符。
最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。
7.3.5. 正则表达式匹配规则
在 RE 可以在给定串中匹配多于一个子串的情况下, RE 匹配串中最靠前的那个子串。如果 RE 可以匹配在那个位置开始 的多个子串,要么是取最长的子串,要么是最短的,具体哪种, 取决于 RE 是贪婪的还是非贪婪的。
一个 RE 是否贪婪取决于下面规则:
大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。
在一个 RE 周围加上圆括号并不会改变其贪婪性。
带一个固定重复次数量词 ({m}或者{m}?) 的量化原子和原子自身具有同样的贪婪性(可能是没有)。
一个带其他普通的量词(包括{m,n}中m等于n的情况)的量化原子是贪婪的(首选最长匹配)。
一个带非贪婪量词(包括{m,n}?中m等于 n的情况)的量化原子是非贪婪的(首选最短匹配)。
一个分支 — 也就是说,一个没有顶级|操作符的 RE — 和它里面的第一个有贪婪属性的量化原子有着同样的贪婪性。
一个由|操作符连接起来的两个或者更多分支组成的 RE 总是贪婪的。
上面的规则所描述的贪婪属性不仅仅适用于独立的量化原子, 而且也适用于包含量化原子的分支和整个 RE。这里的意思是, 匹配是按照分支或者整个 RE 作为一个整体匹配最长或者最短的可能子串。 一旦整个匹配的长度确定,那么匹配任意特定子表达式的部分就基于该子表达式的贪婪属性进行判断,在 RE 里面靠前的子表达式的优先级高于靠后的子表达式。
一个相应的例子:
SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
结果:123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
结果:1
在第一个例子里,RE 作为整体是贪婪的,因为Y*是贪婪的。它可以匹配从Y开始的东西,并且它匹配从这个位置开始的最长的串, 也就是,Y123。输出是这里的圆括号包围的部分,或者说是123。在第二个例子里, RE 总体上是一个非贪婪的 RE,因为Y*?是非贪婪的。它可以匹配从Y开始的最短的子串,也就是说Y1。子表达式[0-9]{1,3}是贪婪的,但是它不能修改总体匹配长度的决定; 因此它被迫只匹配1。
简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许"吃掉"的多少。
量词{1,1}和{1,1}?可以分别用于在一个子表达式 或者整个 RE 上强制贪婪或者非贪婪。当需要整个 RE 具有不同于从其元素中 推导出的贪婪属性时,这很有用。例如,假设我们尝试将一个包含一些数字的 字符串分隔成数字以及在它们之前和之后的部分,我们可能会尝试这样做:
SELECT regexp_matches('abc01234xyz', '(.*)(\d+)(.*)');
Result: {abc0123,4,xyz}
这不会有用:第一个.*是贪婪的,因此它会"吃掉" 尽可能多的字符而留下d+去匹配在最后一个可能位置上的最 后一个数字。我们可能会通过让它变成非贪婪来修复:
SELECT regexp_matches('abc01234xyz', '(.*?)(\d+)(.*)');
Result: {abc,0,""}
这也不会有用:因为现在 RE 作为整体来说是非贪婪的,因此它会尽快结束 全部的匹配。我们可以通过强制 RE 整体是贪婪的来得到我们想要的:
SELECT regexp_matches('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
Result: {abc,01234,xyz}
独立于 RE 的组件的贪婪性之外控制 RE 的整体贪婪性为处理变长模式提供了 很大的灵活性。
在决定更长或者更短的匹配时,匹配长度是以字符衡量的,而不是排序元素。一个空串会被认为比什么都不匹配长。例如:bb*匹配abbbc的中间三个字符;(week|wee)(night|knights)匹配weeknights的所有十个字符; 而(.*).*匹配 abc的时候,圆括号包围的子表达式匹配所有三个字符;当(a*)*被拿来匹配bc时,整个 RE 和圆括号 子表达式都匹配一个空串。
如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而1会变成2。
如果指定了新行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配新行字符(这样,匹配就绝对不会跨越新行,除非 RE 显式地安排了这样的情况)并且^和$除了分别匹配串开头和结尾之外,还将分别匹配新行后面和前面的空串。但是 ARE 逃逸A和Z仍然只匹配串的开头和结尾。
如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^和$。
如果指定了逆新行敏感匹配,那么它影响^和$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。
7.3.6. 限制和兼容性
在这个实现里,对 RE 的长度没有特别的限制。但是,那些希望高移植性的程序应该避免使用长度超过 256 字节的 RE,因为 POSIX 兼容 的实现可以拒绝接受这样的 RE。
ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。
许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括b、B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和后引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。
PostgreSQL 7.4 之前的版本中识别的 ARE 和 ERE 语法存在两个非常明显的不兼容:
在 ARE 中,后面跟着一个字母数字字符的要么是一个逃逸要么是一个错误, 但是在以前的版本里,它只是写该字母数字字符的另外一种方法。这个应该不是什么问题, 因为在以前的版本里没有什么理由会让我们写这样的序列。
在 ARE 里,在[]里还是一个特殊字符, 因此在方括号表达式里的一个文本必须被写成\。
7.3.7. 基本正则表达式
BRE 在几个方面和 ERE 不太一样。在 BRE 中,|、+和?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{和\}, 因为 {和}本身是普通字符。嵌套的子表达式的圆括号是\(和\),因为(和)自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的后引用,\<和\>分别是[[:<:]]和[[:>:]]的同义词;在 BRE 中没有其它可用的逃逸。
8. 数据类型格式化函数
PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。Table 9-23列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。
Table 9-23. 格式化函数
Note: 还有一个单一参数的to_timestamp函数,请见Table 9-30。
在一个to_char输出模板串中,一些特定的模式可以被识别并且被替换成基于给定值的被恰当地格式化的数据。任何不属于模板模式的文本都简单地照字面拷贝。同样,在一个输入 模板串里(对其他函数),模板模式标识由输入数据串提供的值。
Table 9-24展示了可以用于格式化日期和时间值的模版。
Table 9-24. 用于日期/时间格式化的模板模式
修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。Table 9-25展示了可用于日期/时间格式化的修饰语模式。
Table 9-25. 用于日期/时间格式化的模板模式修饰语
日期/时间格式化的使用须知:
FM抑制前导的零或尾随的空白, 否则会把它们增加到输入从而把一个模式的输出变成固定宽度。在PostgreSQL中,FM只修改下一个声明,而在 Oracle 中,FM影响所有随后的声明,并且重复的FM修饰语将触发填充模式开和关。
TM不包括结尾空白。to_timestamp和to_date会忽略TM修饰语。
如果没有使用FX选项,to_timestamp和to_date会跳过输入字符串中的多个空白。例如,to_timestamp('2000 JUN', 'YYYY MON')是正确的,但to_timestamp('2000 JUN', 'FXYYYY MON')会返回一个错误,因为to_timestamp只期望一个空白。FX必须被指定为模板中的第一个项。
to_timestamp和to_date的存在是为了 处理无法被简单转换的输入格式。这些函数会从字面上解释输入,并做一点点错误检查。当 它们产生有效输出时,该转换可能得到意料之外的结果。例如,这些函数的输入没有被限制 在正常的范围内,因此to_date('20096040','YYYYMMDD')会返回 2014-01-17而不是报错。而造型不会有这样的行为。
在to_char模板里可以有普通文本,并且它们会被照字面输出。你可以把一个子串放到双引号里强迫它被解释成一个文本,即使它里面包含模式关键字也如此。例如,在 '"Hello Year "YYYY'中,YYYY将被年份数据代替,但是Year中单独的Y不会。在to_date、to_number和to_timestamp中,双引号字符串会跳过包含在字符串中字符个数的字符,例如"XX"跳过两个输入字符。
如果你想在输出里有双引号,那么你必须在它们前面放反斜线,例如 '"YYYY Month"'。
如果年份格式声明少于四位(如YYY)并且提供的年份少于四位,年份将被调整为最接近于 2020 年,例如95会变成 1995。
在处理长于 4 位的年份时,从字串向timestamp或者date的YYYY转换有一个限制。你必须在YYYY后面使用一些非数字字符或者模板, 否则年份总是被解释为 4 位数字。例如(对于 20000 年):to_date('200001131', 'YYYYMMDD')将会被解释成一个 4 位数字的年份,而不是在年份后使用一个非数字分隔符,像to_date('20000-1131', 'YYYY-MMDD')或to_date('20000Nov31', 'YYYYMonDD')。
在从字符串向timestamp或date的转换中, 如果有YYY、YYYY或者Y,YYY域, 那么CC(世纪)域会被忽略。如果CC和YY或Y一起使用, 那么年份被计算时会认为年份位于指定的世纪中。如果该世纪被指定但是年份没有被指定,将假定用该世纪的第一年。
一个 ISO 8601 周编号的日期(与一个格里高利日期相区别)可以用两种方法之一被指定为to_timestamp和to_date:
年、周编号和工作日:例如to_date('2006-42-4', 'IYYY-IW-ID')返回日期2006-10-19。如果你忽略工作日,它被假定为 1(周一)。
年和一年中的日:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。
尝试使用一个混合了 ISO 8601 周编号和格里高利日期的域来输入一个日期是无意义的,并且将导致一个错误。在一个 ISO 周编号的年的环境下,一个"月"或"月中的日"的概念没有意义。在一个格里高利年的环境下,ISO 周没有意义。用户应当避免混合格里高利和 ISO 日期声明。
Caution
虽然to_date将会拒绝混合使用格里高利和 ISO 周编号日期的域, to_char却不会,因为YYYY-MM-DD (IYYY-IDDD) 这种输出格式也会有用。但是避免写类似IYYY-MM-DD的东西,那会得到在 起始年附近令人惊讶的结果。
在从字符串到timestamp的转换中,毫秒(MS)和微秒(US)值都被用作小数点后的秒位。例如to_timestamp('12:3', 'SS:MS')不是 3 毫秒, 而是 300,因为该转换把它看做 12 + 0.3 秒。这意味着对于格式SS:MS而言,输入值12:3、12:30和12:300指定了相同数目的毫秒。要得到三毫秒,你必须使用 12:003,转换会把它看做 12 + 0.003 = 12.003 秒。
下面是一个更复杂的例子∶to_timestamp('15:12:02.020.001230', 'HH:MI:SS.MS.US')是 15 小时、12 分钟和 2 秒 + 20 毫秒 + 1230微秒 = 2.021230 秒。
to_char(..., 'ID')的一周中日的编号匹配extract(isodow from ...)函数,但是to_char(..., 'D')不匹配extract(dow from ...)的日编号。
to_char(interval)格式化HH和HH12为显示在一个 12 小时的时钟上,即零小时和 36 小时输出为12,而HH24会输出完整的小时值,对于间隔它可以超过 23.
Table 9-26展示了可以用于格式化数字值的模版模式。
Table 9-26. 用于数字格式化的模板模式
数字格式化的用法须知:
使用SG、PL或MI格式化的符号并不挂在数字上面; 例如,to_char(-12, 'MI9999')生成'- 12',而to_char(-12, 'S9999')生成 ' -12'。Oracle 里的实现不允许在9前面使用MI,而是要求9在MI前面。
9导致一个值,这个值的位数好像有那么多个9在那里。如果一个数字不可用,它将输出一个空格。
TH不会转换小于零的数值,也不会转换小数。
PL、SG和TH是PostgreSQL扩展。
带有to_char的V会把输入值乘上10^n,其中n是跟在V后面的位数。带有to_number的V以类似的方式做除法。to_char和to_number不支持使用结合小数点的V(例如,不允许99.9V99)。
EEEE(科学记数法)不能和任何其他格式化模式或修饰语(数字和小数点模式除外)组合在一起使用,并且必须位于格式化字符串的最后(例如9.99EEEE是一个合法的模式)。
某些修饰语可以被应用到任何模板来改变其行为。例如,FM9999是带有FM修饰语的9999模式。Table 9-27中展示了用于数字格式化模式修饰语。
Table 9-27. 用于数字格式化的模板模式修饰语
Table 9-28展示了一些使用to_char函数的例子。
Table 9-28. to_char例子
9. 时间/日期函数和操作符
Table 9-30展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。Table 9-29演示了基本算术操作符 (+、*等)的行为。 而与格式化相关的函数。
所有下文描述的接受time或timestamp输入的函数和操作符实际上都有两种变体: 一种接收time with time zone或timestamp with time zone, 另外一种接受time without time zone或者 timestamp without time zone。为了简化,这些变种没有被独立地展示。此外,+和*操作符都是可交换的操作符对(例如,date + integer 和 integer + date);我们只显示其中一个。
Table 9-29. 日期/时间操作符
Table 9-30. 日期/时间函数
除了这些函数以外,还支持 SQL 操作符OVERLAPS:
(start1, end1) OVERLAPS (start2, end2)
(start1, length1) OVERLAPS (start2, length2)
这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非start和end相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。
SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
(DATE '2001-10-30', DATE '2002-10-30');
结果:true
SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
(DATE '2001-10-30', DATE '2002-10-30');
结果:false
SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
(DATE '2001-10-30', DATE '2001-10-31');
结果:false
SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
(DATE '2001-10-30', DATE '2001-10-31');
结果:true
当把一个interval值添加到timestamp with time zone上(或从中减去)时, days 部分会按照指定的天数增加或减少timestamp with time zone的日期。 对于横跨夏令时的变化(当会话的时区被设置为可识别DST的时区时),这意味着interval '1 day'并 不一定等于interval '24 hours'。例如,当会话的时区设置为CST7CDT时,timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' 的结果是timestamp with time zone '2005-04-03 12:00-06',而将interval '24 hours'增加到相同的初始timestamp with time zone的结果 则是timestamp with time zone '2005-04-03 13:00-06', 因为CST7CDT时区在2005-04-03 02:00有一个夏令时变更。
注意age返回的月数域可能有歧义,因为不同的月份有不同的天数。 PostgreSQL的方法是当计算部分月数时,采用两个日期中较早的月。例如:age('2004-06-01', '2004-04-30')使用4月份得到1 mon 1 day,而用5月分时会得到1 mon 2 days,因为5月有31天,而4月只有30天。
日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, 这样会得到两个值之间的秒数。这种方法将会适应每个月中天数、 时区改变和夏令时调整。使用"-"操作符的日期或时间 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 负值域进行调整。下面的查询展示了这些方法的不同。例子中的结果由 timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 时的变化:
SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00');
Result: 10537200
SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
/ 60 / 60 / 24;
Result: 121.958333333333
SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
Result: 121 days 23:00:00
SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
Result: 4 mons
9.9.1. EXTRACT, date_part
EXTRACT(field FROM source)
extract函数从日期/时间值中抽取子域,例如年或者小时等。source必须是一个类型 timestamp、time或interval的值表达式(类型为date的表达式将被造型为 timestamp,并且因此也可以被同样使用)。field是一个标识符或者字符串,它指定从源值中抽取的域。extract函数返回类型为double precision的值。 下列值是有效的域名字∶
century
世纪
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
结果:20
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
结果:21
第一个世纪从 0001-01-01 00:00:00 AD 开始, 尽管那时候人们还不知道这是第一个世纪。这个定义适用于所有使用格里高利历法的国家。其中没有 0 世纪,我们直接从公元前 1 世纪到公元 1 世纪。 如果你认为这个不合理,那么请把抱怨发给:罗马圣彼得教堂,梵蒂冈,教皇收。
day
对于timestamp值,是(月份)里的日域(1-31);对于interval值,是日数
SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
结果:16
SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
结果:40
decade
年份域除以10
SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
结果:200
dow
一周中的日,从周日(0)到周六(6)
SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
结果:5
请注意,extract的一周中的日和to_char(..., 'D')函数不同。
doy
一年的第几天(1 -365/366)
SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
结果:47
epoch
对于timestamp with time zone值, 是自 1970-01-01 00:00:00 UTC 以来的秒数(结果可能是负数); 对于date and timestamp值,是自本地时间 1970-01-01 00:00:00 以来的描述;对于interval值,它是时间间隔的总秒数。
SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08');
结果:982384720.12
SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
结果:442800
不能用to_timestamp把一个 epoch 值转换回成时间戳:
SELECT to_timestamp(982384720.12);
Result: 2001-02-17 04:38:40.12+00
hour
小时域(0 - 23)
SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
结果:20
isodow
一周中的日,从周一(1)到周日(7)
SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');
结果:7
除了周日,这和dow相同。这符合ISO 8601 中一周中的日的编号。
isoyear
日期所落在的ISO 8601 周编号的年(不适用于间隔)
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
结果:2005
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');
结果:2006
每一个ISO 8601 周编号的年都开始于包含1月4日的那一周的周一,在早的1月或迟的12月中ISO年可能和格里高利年不同。更多信息见week域。
这个域不能用于 PostgreSQL 8.3之前的版本。
microseconds
秒域,包括小数部分,乘以 1,000,000。请注意它包括全部的秒
SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');
结果:28500000
millennium
千年
SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
结果:3
19xx的年份在第二个千年里。第三个千年从 2001 年 1 月 1 日开始。
milliseconds
秒域,包括小数部分,乘以 1000。请注意它包括完整的秒。
SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');
结果:28500
minute
分钟域(0 - 59)
SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
结果:38
month
对于timestamp值,它是一年里的月份数(1 - 12); 对于interval值,它是月的数目,然后对 12 取模(0 - 11)
SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
结果:2
SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
结果:3
SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
结果:1
quarter
该天所在的该年的季度(1 - 4)
SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40');
结果:1
second
秒域,包括小数部分(0 - 59[1])
SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
结果:40
SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
结果:28.5
timezone
与 UTC 的时区偏移,以秒记。正数对应 UTC 东边的时区,负数对应 UTC 西边的时区(从技术上来看,PostgreSQL不使用 UTC,因为其中不处理闰秒)。
timezone_hour
时区偏移的小时部分。
timezone_minute
时区偏移的分钟部分。
week
该天在所在的ISO 8601 周编号的年份里是第几周。根据定义, 一年的第一周包含该年的 1月 4 日并且 ISO 周从星期一开始。换句话说,一年的第一个星期四在第一周。
在 ISO 周编号系统中,早的 1 月的日期可能位于前一年的第五十二或者第五十三周,而迟的 12 月的日期可能位于下一年的第一周。例如, 2005-01-01位于 2004 年的第五十三周,并且2006-01-01位于 2005 年的第五十二周,而2012-12-31位于 2013 年的第一周。我们推荐把isoyear域和week一起使用来得到一致的结果。
SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
结果:7
year
年份域。要记住这里没有0 AD,所以从AD年里抽取BC年应该小心处理。
SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
结果:2001
Note: 当输入值为 +/-Infinity 时,extract对于单调增的域(epoch、julian、year、isoyear、decade、century以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。
extract函数主要的用途是做计算性处理。对于用于显示的日期/时间值格式化。
在传统的Ingres上建模的date_part函数等价于SQL标准函数extract:
date_part('field', source)
请注意这里的field参数必须是一个串值,而不是一个名字。有效的date_part域名 和extract相同。
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
结果:16
SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
结果:4
9.2. date_trunc
date_trunc函数在概念上和用于数字的trunc函数类似。
date_trunc('field', source)
source是类型timestamp或interval的值表达式(类型date和 time的值都分别被自动转换成timestamp或者interval)。field选择对输入值选用什么样的精度进行截断。返回的值是timestamp类型或者所有小于选定的 精度的域都设置为零(或者一,对于日期和月份)的interval。
field的有效值是∶
microseconds
milliseconds
second
minute
hour
day
week
month
quarter
year
decade
century
millennium
例子:
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
结果:2001-02-16 20:00:00
SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
结果:2001-01-01 00:00:00
9.9.3. AT TIME ZONE
AT TIME ZONE结构允许把时间戳转换成不同的时区。Table 9-31展示了其变体。
Table 9-31. AT TIME ZONE Variants
在这些表达式里,我们需要的时区zone可以指定为文本串(例如,'PST')或者一个间隔 (例如,INTERVAL '-08:00')。 在文本情况下,可用的时区名字可以用Section 8.5.3中描述的任何方式指定。
例子(假设本地时区是PST8PDT):
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST';
结果:2001-02-16 19:38:40-08
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST';
结果:2001-02-16 18:38:40
第一个例子接受一个无时区的时间戳然后把它解释成 MST 时间(UTC-7),然后这个时间转换为 PST(UTC-8)来显示。 第二个例子接受一个指定为 EST(UTC-5)的时间戳,然后把它 转换成 MST(UTC-7)的当地时间。
函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。
9.4. 当前日期/时间
PostgreSQL提供了许多返回当前日期和时间的函数。这些 SQL 标准的函数全部都按照当前事务的开始时刻返回值:
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME(precision)
CURRENT_TIMESTAMP(precision)
LOCALTIME
LOCALTIMESTAMP
LOCALTIME(precision)
LOCALTIMESTAMP(precision)
CURRENT_TIME和CURRENT_TIMESTAMP传递带有时区的值;LOCALTIME和LOCALTIMESTAMP传递的值不带时区。
CURRENT_TIME、CURRENT_TIMESTAMP、LOCALTIME和 LOCALTIMESTAMP可以有选择地接受一个精度参数, 该精度导致结果的秒域被园整为指定小数位。如果没有精度参数,结果将被给予所能得到的全部精度。
一些例子:
SELECT CURRENT_TIME;
结果:14:39:53.662522-05
SELECT CURRENT_DATE;
结果:2001-12-23
SELECT CURRENT_TIMESTAMP;
结果:2001-12-23 14:39:53.662522-05
SELECT CURRENT_TIMESTAMP(2);
结果:2001-12-23 14:39:53.66-05
SELECT LOCALTIMESTAMP;
结果:2001-12-23 14:39:53.662522
因为这些函数全部都按照当前事务的开始时刻返回结果,所以它们的值在事务运行的整个期间内都不改变。 我们认为这是一个特性:目的是为了允许一个事务在"当前"时间上有一致的概念, 这样在同一个事务里的多个修改可以保持同样的时间戳。
Note: 许多其它数据库系统可能会更频繁地推进这些值。
PostgreSQL同样也提供了返回当前语句开始时间的函数, 它们会返回函数被调用时的真实当前时间。这些非 SQL 标准的函数列表如下:
transaction_timestamp()
statement_timestamp()
clock_timestamp()
timeofday()
now()
transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()和transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()是PostgreSQL的一个传统,等效于transaction_timestamp()。
所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果:
SELECT CURRENT_TIMESTAMP;
SELECT now();
SELECT TIMESTAMP 'now'; -- 对于和 DEFAULT 一起使用是不正确的
Tip: 在创建表期间指定一个DEFAULT子句时,你不会希望使用第三种形式。系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。
9.5. 延时执行
下面的这些函数可以用于让服务器进程延时执行:
pg_sleep(seconds)
pg_sleep_for(interval)
pg_sleep_until(timestamp with time zone)
pg_sleep让当前的会话进程休眠seconds 秒以后再执行。seconds是一个double precision 类型的值,所以可以指定带小数的秒数。pg_sleep_for是针对用 interval指定的较长休眠时间的函数。pg_sleep_until 则可以用来休眠到一个指定的时刻唤醒。例如:
SELECT pg_sleep(1.5);
SELECT pg_sleep_for('5 minutes');
SELECT pg_sleep_until('tomorrow 03:00');
Note: 有效的休眠时间间隔精度是平台相关的,通常 0.01 秒是通用值。休眠延迟将至少持续指 定的时长, 也有可能由于服务器负荷而比指定的时间长。特别地, pg_sleep_until并不保证能刚好在指定的时刻被唤醒,但它不会 在比指定时刻早的时候醒来。
Warning
请确保在调用pg_sleep或者其变体时,你的会话没有持有不必要 的锁。否则其它会话可能必须等待你的休眠会话,因而减慢整个系统速度。
Notes
[1] 如果操作系统实现了闰秒,则为60
10. 枚举支持函数
对于枚举类型(在Section 8.7中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在Table 9-32中。本例假定一个枚举类型被创建为:
CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
Table 9-32. 枚举支持函数
请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如例子中所建议。
11. 几何函数和操作符
几何类型point、box、 lseg、line、path、 polygon和circle有一大堆本地支持函数和操作符,如Table 9-33、Table 9-34和Table 9-35中所示。
Caution
请注意"same as"操作符(~=),表示point、box、polygon和circle类型的一般相等概念。这些类型中的某些还有一个=操作符,但是=只比较相同的面积。其它的标量比较操作符 (<=等等)也是为这些类型比较面积。
Table 9-33. 几何操作符
Note: 在PostgreSQL之前,包含操作符@>和<@被分别称为~和@。 这些名字仍然可以使用,但是已被废除并且最终将被移除。
Table 9-34. 几何函数
Table 9-35. 几何类型转换函数
我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 座标而 UPDATE t SET p[1] = ...改变 Y 座标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。
函数area可以用于类型box、circle和path。area函数操作path数据类型的时候, 只有在path的点没有交叉的情况下才可用。例如,path '((0,0),(0,1),(2,1),(2,2),(1,2),(1,0),(0,0))'::PATH是不行的, 而下面的视觉上相同的 path '((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))'::PATH就可以。 如果交叉和不交叉的path概念让你疑惑,那么把上面两个path都画在一张图纸上,你就明白了。
12. 网络地址函数和操作符
Table 9-36展示了可以用于cidr和 inet类型的操作符。 操作符<<、<<=、 >>、>>=和 &&测试用于子网包含。它们只考虑两个地址的网 络部分(忽略任何主机部分),然后判断其中一个网络部分是等于另外一个或者是 另外一个的子网。
Table 9-36. cidr和inet操作符
Table 9-37展示了所有可以用于cidr和inet类型的函数。函数abbrev、host和text主要是为了提供可选的显示格式用的。
Table 9-37. cidr和inet函数
任何cidr值都能够被隐式或显式地转换为inet值, 因此上述能够操作inet值的函数也同样能够操作cidr值(也有独立的用于inet和cidr的函数,因为它的行为应当和这两种情况不同)。inet值也可以转换为cidr值。完成时,该网络掩码右侧的任何位都将无声地转换为零以获得一个有效的cidr值。另外,你还可以使用常规的造型语法将一个文本字符串转换为inet或cidr值:例如,inet(expression)或colname::cidr。
Table 9-38展示了可以用于macaddr类型的函数。 函数trunc(macaddr)返回一个 MAC 地址,该地址的最后三个字节设置为零。这样可以把剩下的前缀与一个制造商相关联。
Table 9-38. macaddr函数
macaddr类型还支持标准关系操作符 (>、<=等) 用于编辑次序,并且按位算术操作符(~、&和|)用于 NOT、AND 和 OR。
13. 文本搜索函数和操作符
Table 9-39、 Table 9-40和 Table 9-41总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考Chapter 12。
Table 9-39. 文本搜索操作符
Note: tsquery的包含操作符只考虑两个查询中的词位,而忽略组合操作符。
除了显示在表中的操作符,还定义了tsvector和tsquery类型的普通B-tree比较操作符(=、<等)。它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。
Table 9-40. 文本搜索函数
Note: 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由default_text_search_config指定的配置。
Table 9-41中的函数被单独列出,因为它们通常不被用于日常的文本搜索操作。 它们有助于开发和调试新的文本搜索配置。
Table 9-41. 文本搜索调试函数
14. XML 函数
本节中描述的函数以及类函数的表达式都在类型xml的值上操作。类型xml的详细信息请参见Section 8.13。用于在值和类型xml之间转换的类函数的表达式xmlparse和xmlserialize就不在这里重复介绍。使用大部分这些函数要求安装时使用了configure --with-libxml进行编译。
14.1. 产生 XML 内容
有一组函数和类函数的表达式可以用来从 SQL 数据产生 XML 内容。它们特别适合于将查询结果格式化成 XML 文档以便于在客户端应用中处理。
14.1.1. xmlcomment
xmlcomment(text)
函数xmlcomment创建了一个 XML 值,它包含一个使用指定文本作为内容的 XML 注释。该文本不包含"--"或者也不会以一个"-"结尾,这样结果的结构是一个合法的 XML 注释。如果参数为空,结果也为空。
例子:
SELECT xmlcomment('hello');
xmlcomment
--------------
<!--hello-->
14.1.2. xmlconcat
xmlconcat(xml[, ...])
函数xmlconcat将由单个 XML 值组成的列表串接成一个单独的值,这个值包含一个 XML 内容片断。空值会被忽略,只有当没有参数为非空时结果才为空。
例子:
SELECT xmlconcat('<abc/>', '<bar>foo</bar>');
xmlconcat
----------------------
<abc/><bar>foo</bar>
如果 XML 声明存在,它们会按照下面的方式被组合。如果所有的参数值都有相同的 XML 版本声明,该版本将被用在结果中,否则将不使用版本。如果所有参数值有独立声明值"yes",那么该值将被用在结果中。如果所有参数值都有一个独立声明值并且至少有一个为"no",则"no"被用在结果中。否则结果中将没有独立声明。如果结果被决定要要求一个独立声明但是没有版本声明,将会使用一个版本 1.0 的版本声明,因为 XML 要求一个 XML 声明要包含一个版本声明。编码声明会被忽略并且在所有情况中都会被移除。
例子:
SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>');
xmlconcat
-----------------------------------
<?xml version="1.1"?><foo/><bar/>
14.1.3. xmlelement
xmlelement(name name [, xmlattributes(value [AS attname] [, ... ])] [, content, ...])表达式xmlelement使用给定名称、属性和内容产生一个 XML 元素。
例子:
SELECT xmlelement(name foo);
xmlelement
------------
<foo/>
SELECT xmlelement(name foo, xmlattributes('xyz' as bar));
xmlelement
------------------
<foo bar="xyz"/>
SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');
xmlelement
-------------------------------------
<foo bar="2007-01-26">content</foo>
不是合法 XML 名字的元素名和属性名将被逃逸,逃逸的方法是将违反的字符用序列_xHHHH_替换,其中HHHH是被替换字符的 Unicode 代码点的十六进制表示。例如:
SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));
xmlelement
----------------------------------
<foo_x0024_bar a_x0026_b="xyz"/>
如果属性值是一个列引用,则不需要指定一个显式的属性名,在这种情况下列的名字将被默认用于属性的名字。在其他情况下,属性必须被给定一个显式名称。因此这个例子是合法的:
CREATE TABLE test (a xml, b xml);
SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
但是下面这些不合法:
SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
如果指定了元素内容,它们将被根据其数据类型格式化。如果内容本身也是类型xml,就可以构建复杂的 XML 文档。例如:
SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
xmlelement(name abc),
xmlcomment('test'),
xmlelement(name xyz));
xmlelement
----------------------------------------------
<foo bar="xyz"><abc/><!--test--><xyz/></foo>
其他类型的内容将被格式化为合法的 XML 字符数据。这意味着字符 <, >, 和 & 将被转换为实体。二进制数据(数据类型bytea)将被表示成 base64 或十六进制编码,具体取决于配置参数xmlbinary的设置。为了将 SQL 和 PostgreSQL 数据类型和 XML 模式声明对齐,我们期待单独数据类型的特定行为能够改进,到那时将会出现一个更为精确的描述。
14.1.4. xmlforest
xmlforest(content [AS name] [, ...])
表达式xmlforest使用给定名称和内容产生一个元素的 XML 森林(序列)。
例子:
SELECT xmlforest('abc' AS foo, 123 AS bar);
xmlforest
------------------------------
<foo>abc</foo><bar>123</bar>
SELECT xmlforest(table_name, column_name)
FROM information_schema.columns
WHERE table_schema = 'pg_catalog';
xmlforest
-------------------------------------------------------------------------------------------
<table_name>pg_authid</table_name><column_name>rolname</column_name>
<table_name>pg_authid</table_name><column_name>rolsuper</column_name>
...
如我们在第二个例子中所见,如果内容值是一个列引用,元素名称可以被忽略,这种情况下默认使用列名。否则,必须指定一个名字。
如上文xmlelement所示,非法 XML 名字的元素名会被逃逸。相似地,内容数据也会被逃逸来产生合法的 XML 内容,除非它已经是一个xml类型。
注意如果 XML 森林由多于一个元素组成,那么它不是合法的 XML 文档,因此在xmlelement中包装xmlforest表达式会有用处。
14.1.5. xmlpi
xmlpi(name target [, content])
表达式xmlpi创建一个 XML 处理指令。如果存在内容,内容不能包含字符序列?>。
例子:
SELECT xmlpi(name php, 'echo "hello world";');
xmlpi
-----------------------------
<?php echo "hello world";?>
14.1.6. xmlroot
xmlroot(xml, version text | no value [, standalone yes|no|no value])
表达式xmlroot修改一个 XML 值的根结点的属性。如果指定了一个版本,它会替换根节点的版本声明中的值;如果指定了一个独立设置,它会替换根节点的独立声明中的值。
SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
version '1.0', standalone yes);
xmlroot
----------------------------------------
<?xml version="1.0" standalone="yes"?>
<content>abc</content>
14.1.7. xmlagg
xmlagg(xml)
和这里描述的其他函数不同,函数xmlagg是一个聚集函数。它将聚集函数调用的输入值串接起来,非常像xmlconcat所做的事情,除了串接是跨行发生的而不是在单一行的多个表达式上发生。聚集表达式的更多信息请见Section 9.20。
例子:
CREATE TABLE test (y int, x xml);
INSERT INTO test VALUES (1, '<foo>abc</foo>');
INSERT INTO test VALUES (2, '<bar/>');
SELECT xmlagg(x) FROM test;
xmlagg
----------------------
<foo>abc</foo><bar/>
为了决定串接的顺序,可以为聚集调用增加一个ORDER BY子句,如Section 4.2.7中所述。例如:
SELECT xmlagg(x ORDER BY y DESC) FROM test;
xmlagg
----------------------
<bar/><foo>abc</foo>
我们推荐在以前的版本中使用下列非标准方法,并且它们在特定情况下仍然有用:
SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
xmlagg
----------------------
<bar/><foo>abc</foo>
14.2. XML 谓词
这一节描述的表达式检查xml值的属性。
14.2.1. IS DOCUMENT
xml IS DOCUMENT
如果参数 XML 值是一个正确的 XML 文档,则IS DOCUMENT返回真,如果不是则返回假(即它是一个内容片断),或者是参数为空时返回空。文档和内容片断之间的区别请见Section 8.13。
14.2.2. XMLEXISTS
XMLEXISTS(text PASSING [BY REF] xml [BY REF])
如果第一个参数中的 XPath 表达式返回任何结点,则函数xmlexists返回真,否则返回假(如果哪一个参数为空,则结果就为空)。
例子:
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Toronto</town><town>Ottawa</town></towns>');
xmlexists
------------
t
(1 row)
BY REF子句在 PostgreSQL 中没有作用,但是为了和其他实现保持 SQL 一致性和兼容性还是允许它出现。每一种 SQL 标准,第一个BY REF是被要求的,而第二个则是可选的。也要注意 SQL 标准指定xmlexists结构来将一个 XQuery 表达式作为第一个参数,但 PostgreSQL 目前只支持 XPath,它是 XQuery的一个子集。
14.2.3. xml_is_well_formed
xml_is_well_formed(text)xml_is_well_formed_document(text)xml_is_well_formed_content(text)
这些函数检查一个text串是不是一个良构的 XML,返回一个布尔结果。xml_is_well_formed_document检查一个良构的文档,而xml_is_well_formed_content检查良构的内容。如果xmloption配置参数被设置为DOCUMENT,xml_is_well_formed会做第一个函数的工作;如果配置参数被设置为CONTENT,xml_is_well_formed会做第二个函数的工作。这意味着xml_is_well_formed对于检查一个到类型xml的简单造型是否会成功非常有用,而其他两个函数对于检查XMLPARSE的对应变体是否会成功有用。
例子:
SET xmloption TO DOCUMENT;
SELECT xml_is_well_formed('<>');
xml_is_well_formed
--------------------
f
(1 row)
SELECT xml_is_well_formed('<abc/>');
xml_is_well_formed
--------------------
t
(1 row)
SET xmloption TO CONTENT;
SELECT xml_is_well_formed('abc');
xml_is_well_formed
--------------------
t
(1 row)
SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</pg:foo>');
xml_is_well_formed_document
-----------------------------
t
(1 row)
SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</my:foo>');
xml_is_well_formed_document
-----------------------------
f
(1 row)
最后一个例子显示了这些检查也包括名字空间是否正确地匹配。
14.3. 处理 XML
要处理数据类型xml的值, PostgreSQL 提供了函数xpath和xpath_exists,它们计算 XPath 1.0 表达式。
xpath(xpath, xml [, nsarray])
函数xpath在 XML 值xml上计算 XPath 表达式xpath (a text value)。它返回一个 XML 值的数组,该数组对应于该 XPath 表达式产生的结点集合。如果该 XPath 表达式返回一个标量值而不是一个结点集合,将会返回一个单一元素的数组。
第二个参数必须是一个良构的 XML 文档。特殊地,它必须有一个单一根结点元素。
该函数可选的第三个参数是一个名字空间映射的数组。这个数组应该是一个二维text数组,其第二轴长度等于2(即它应该是一个数组的数组,其中每一个都由刚好 2 个元素组成)。每个数组项的第一个元素是名字空间的名称(别名),第二个元素是名字空间的 URI。并不要求在这个数组中提供的别名和在 XML 文档本身中使用的那些名字空间相同(换句话说,在 XML 文档中和在xpath函数环境中,别名都是本地的)。
例子:
SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
ARRAY[ARRAY['my', 'http://example.com']]);
xpath
--------
{test}
(1 row)
要处理默认(匿名)命名空间,做这样的事情:
SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
ARRAY[ARRAY['mydefns', 'http://example.com']]);
xpath
--------
{test}
(1 row)
xpath_exists(xpath, xml [, nsarray])
函数xpath_exists是xpath函数的一种特殊形式。这个函数不是返回满足 XPath 的单一 XML 值,它返回一个布尔值表示查询是否被满足。这个函数等价于标准的XMLEXISTS谓词,不过它还提供了对一个名字空间映射参数的支持。
例子:
SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
ARRAY[ARRAY['my', 'http://example.com']]);
xpath_exists
--------------
t
(1 row)
14.4. 将表映射到 XML
下面的函数将会把关系表的内容映射成 XML 值。它们可以被看成是 XML 导出功能:
table_to_xml(tbl regclass, nulls boolean, tableforest boolean, targetns text)
query_to_xml(query text, nulls boolean, tableforest boolean, targetns text)
cursor_to_xml(cursor refcursor, count int, nulls boolean,
tableforest boolean, targetns text)
每一个函数的返回值都是xml。
table_to_xml映射由参数tbl传递的命名表的内容。regclass类型接受使用常见标记标识表的字符串,包括可选的模式限定和双引号。query_to_xml执行由参数query传递的查询并且映射结果集。cursor_to_xml从cursor指定的游标中取出指定数量的行。如果需要映射一个大型的表,我们推荐这种变体,因为每一个函数都是在内存中构建结果值的。
如果tableforest为假,则结果的 XML 文档看起来像这样:
<tablename>
<row>
<columnname1>data</columnname1>
<columnname2>data</columnname2>
</row>
<row>
...
</row>
...
</tablename>
如果tableforest为真,结果是一个看起来像这样的 XML 内容片断:
<tablename>
<columnname1>data</columnname1>
<columnname2>data</columnname2>
</tablename>
<tablename>
...
</tablename>
...
如果没有表名可用,在映射一个查询或一个游标时,在第一种格式中使用串table,在第二种格式中使用row。
这几种格式的选择由用户决定。第一种格式是一个正确的 XML 文档,它在很多应用中都很重要。如果结果值要被重组为一个文档,第二种格式在cursor_to_xml函数中更有用。前文讨论的产生 XML 内容的函数(特别是xmlelement)可以被用来把结果修改成符合用户的要求。
数据值会被以前文的函数xmlelement中描述的相同方法映射。
参数nulls决定空值是否会被包含在输出中。如果为真,列中的空值被表示为:
<columnname xsi:nil="true"/>
其中xsi是 XML 模式实例的 XML 名字空间前缀。一个合适的名字空间声明将被加入到结果值中。如果为假,包含空值的列将被从输出中忽略掉。
参数targetns指定想要的结果的 XML 名字空间。如果没有想要的特定名字空间,将会传递一个空串。
下面的函数返回 XML 模式文档,这些文档描述上述对应函数所执行的映射:
table_to_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
query_to_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
cursor_to_xmlschema(cursor refcursor, nulls boolean, tableforest boolean, targetns text)
最重要的是相同的参数被传递来获得匹配的 XML 数据映射和 XML 模式文档。
下面的函数产生 XML 数据映射和对应的 XML 模式,并把产生的结果链接在一起放在一个文档(或森林)中。在要求自包含和自描述的结果是它们非常有用:
table_to_xml_and_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
query_to_xml_and_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
另外,下面的函数可用于产生相似的整个模式或整个当前数据库的映射:
schema_to_xml(schema name, nulls boolean, tableforest boolean, targetns text)
schema_to_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)
schema_to_xml_and_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)
database_to_xml(nulls boolean, tableforest boolean, targetns text)
database_to_xmlschema(nulls boolean, tableforest boolean, targetns text)
database_to_xml_and_xmlschema(nulls boolean, tableforest boolean, targetns text)
注意这些函数可能产生很多数据,它们都需要在内存中被构建。在请求大型模式或数据库的内容映射时,可以考虑分别映射每一个表,甚至通过一个游标来映射。
一个模式内容映射的结果看起来像这样:
<schemaname>
table1-mapping
table2-mapping
...
</schemaname>
其中一个表映射的格式取决于上文解释的tableforest参数。
一个数据库内容映射的结果看起来像这样:
<dbname>
<schema1name>
...
</schema1name>
<schema2name>
...
</schema2name>
...
</dbname>
其中的模式映射如上所述。
作为一个使用这些函数产生的输出的例子,Figure 9-1展示了一个 XSLT 样式表,它将table_to_xml_and_xmlschema的输出转换为一个包含表数据的扁平转印的 HTML 文档。以一种相似的方式,这些函数的结果可以被转换成其他基于 XML 的格式。
Figure 9-1. 转换 SQL/XML 输出到 HTML 的 XSLT 样式表
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/xhtml"
>
<xsl:output method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
indent="yes"/>
<xsl:template match="/*">
<xsl:variable name="schema" select="//xsd:schema"/>
<xsl:variable name="tabletypename"
select="$schema/xsd:element[@name=name(current())]/@type"/>
<xsl:variable name="rowtypename"
select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/>
<html>
<head>
<title><xsl:value-of select="name(current())"/></title>
</head>
<body>
<table>
<tr>
<xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name">
<th><xsl:value-of select="."/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="row">
<tr>
<xsl:for-each select="*">
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
15. JSON 函数和操作符
Table 9-42展示了可以用于两种 JSON 数据类型(见Section 8.14)的操作符。
Table 9-42. json和jsonb 操作符
Note: 对json和jsonb类型,这些操作符都有其并行变体。 域/元素/路径抽取操作符返回与其左手输入(json或jsonb) 相同的类型,不过那些被指定为返回text的除外,它们的返回值会被强制 为文本。如果该 JSON 输入没有匹配请求的正确结构(例如那样的元素不存在),这些 域/元素/路径抽取操作符会返回 NULL 而不是失败。 接受整数 JSON 数组下标的 域/元素/路径抽取操作符都支持表示从数组末尾开始的负值下标形式。
Table 9-1中展示的标准比较操作符只对 jsonb有效,而不适合json。
如Table 9-43中所示,还存在一些只适合 jsonb的操作符。这些操作符中的很多可以用jsonb 操作符类索引。
Table 9-43. 额外的jsonb操作符
Note: ||操作符将其每一个操作数的顶层的元素串接起来。它不会递归 操作。例如,如果两个操作数都是具有公共域名称的对象,结果中的域值将 只是来自右手操作数的值。
Table 9-44展示了可用于创建 json 和 jsonb值的函数(没有用于 jsonb的与row_to_json和 array_to_json等价的函数。不过,to_jsonb函数 提供了这些函数的很大一部分相同的功能)。
Table 9-44. JSON 创建函数
Note: array_to_json和row_to_json与to_json 具有相同的行为,不过它们提供了更好的打印选项。针对to_json所描述 的行为同样也适用于由其他 JSON 创建函数转换的每个值。
Note: hstore扩展有一个从hstore到json 的造型,因此通过 JSON 创建函数转换的hstore值将被表示为 JSON 对象,而不是原始字符串值。
Table 9-45展示了可用来处理json 和jsonb值的函数。
Table 9-45. JSON 处理
Note: 很多这些函数和操作符将把 JSON 字符串中的 Unicode 转义转换成合适的单一字符。如果 输入类型是jsonb,这就没有问题,因为该转换已经完成了。但是对于json 输入,这可能会导致抛出一个错误(如Section 8.14所述)。
Note: 在json_populate_record、json_populate_recordset、 json_to_record和json_to_recordset中,来自 JSON 的 类型强制是"尽力而为"并且对于某些类型可能得不到想要的值。JSON 键会被 匹配目标行类型中相同的列名。没有出现在目标行类型中的 JSON 域将会被从输出中忽略, 并且不匹配任何 JSON 域的目标列将被简单地作为 NULL。
Note: jsonb_set和jsonb_insert的path参数中除最后一项之外的所有项都必须存在于target中。如果create_missing为假,jsonb_set的path参数的所有项都必须存在。如果这些条件不满足,则返回的target不会被改变。
如果最后的路径项是一个对象键,在它不存在且给定了新值的情况下会创建它。如果最后的路径项是一个数组索引,为正值则表示从左边开始计数,为负值表示从右边开始计数 - -1表示最右边的元素,以此类推。如果该项超过范围 -array_length .. array_length -1 并且 create_missing 为真,则该项为负时把新值加载数组的开始处,而该项为正时把新值加在数组的末尾处。
Note: 不要把json_typeof函数的null返回值与 SQL 的 NULL 弄混。 虽然调用json_typeof('null'::json)将会返回null,但调用 json_typeof(NULL::json)将会返回一个 SQL 的 NULL。
Note: 如果json_strip_nulls的参数在任何对象中包含重复的域名称, 结果在语义上可能有所不同,具体取决于它们发生的顺序。这不是 jsonb_strip_nulls的一个问题,因为jsonb值 不能具有重复的对象域名称。
16. 序列操作函数
本节描述用于操作序列对象的函数,序列对象也被称为序列生成器或者就是序列。序列对象都是用CREATE SEQUENCE创建的特殊的单行表。序列对象通常用于为表的行生成唯一的标识符。Table 9-46中列出的这些序列函数,可以为我们从序列对象中获取连续的序列值提供了简单的、多用户安全的 方法。
Table 9-46. 序列函数
将要由序列函数调用操作的序列是用一个regclass参数声明的, 它只是序列在pg_class系统表里面的 OID。不过,你不需要手工查找 OID, 因为regclass数据类型的输入转换器会帮你做这件事情。 只要写出用单引号包围的序列名字即可,因此它看上去像文本常量。为了和普通SQL名字处理兼容,这个字串将转换成小写形式, 除非在序列名字周围包含双引号。因此:
nextval('foo') 操作序列foo
nextval('FOO') 操作序列foo
nextval('"Foo"') 操作序列Foo
必要时序列名可以用模式限定∶
nextval('myschema.foo') 操作myschema.foo
nextval('"myschema".foo') 同上
nextval('foo') 在搜索路径中查找foo
Note: 在PostgreSQL 8.1 之前,序列函数的参数类型是text, 而不是 regclass,并且前文所述的从文本串到 OID 值的转换将在每次调用的时候发生。 为了向后兼容,这个处理仍然存在,但是在内部实际上是通过在函数调用前隐式地将text转换成regclass实现的。
当你把一个序列函数的参数写成一个无修饰的文字串,那么它将变成类型为regclass的常量。因为这只是一个 OID,它将跟踪最初标识的序列,而不管后面是否改名、模式变化等等。 这种"早期绑定"的行为通常是列默认值和视图中引用的序列所需要的。 但是有时候你可能想要"延迟绑定",其中序列的引用是在运行时解析的。要得到延迟绑定的行为,我们可以强制常量被存储为text常量,而不是regclass:
nextval('foo'::text) foo在运行时查找
请注意,延迟绑定是PostgreSQL版本 8.1 之前唯一被支持的行为, 因此你可能需要做这些来保留旧应用的语义。
当然,序列函数的参数也可以是表达式。如果它是一个文本表达式,那么隐式的转换将导致运行时的查找。
可用的序列函数有∶
nextval
递增序列对象到它的下一个值并且返回该值。这个动作是自动完成的: 即使多个会话并发执行nextval,每个进程也会安全地收到一个唯一的序列值。
如果一个序列对象是用默认参数创建的,连续的nextval调用将会返回从 1 开始的连续的值。其他的行为可以通过在CREATE SEQUENCE命令中使用特殊参数来获得;详见该命令的参考页。
Important: 为了避免阻塞从同一个序列获取序号的并发事务,nextval操作从来不会被回滚。也就是说,一旦一个值被取出就视同被用掉并且不会被再次返回给调用者,即便调用该操作的外层事务后来中止或者调用查询后来没有使用取得的值也是这样。例如一个带有ON CONFLICT子句的INSERT会计算要被插入的元组,其中可能就包括调用nextval,然后才会检测到导致它转向ON CONFLICT规则的冲突。这种情况就会在已分配值的序列中留下未被使用的"空洞"。因此,PostgreSQL的序列对象不能被用来得到"无间隙"的序列。
currval
在当前会话中返回最近一次nextval取到的该序列的值(如果在本会话中从未在该序列上调用过nextval,那么会报告一个错误)。请注意因为此函数返回一个会话本地的值,不论其它会话是否在当前会话之后执行过nextval,它都能给出一个可预测的回答。
lastval
返回当前会话里最近一次nextval返回的值。 这个函数等效于currval,只是它不用序列名作为参数, 它会引用当前会话里面最近一次被应用的序列的nextval。如果当前会话还没有调用过nextval,那么调用lastval会报错。
setval
重置序列对象的计数器值。双参数的形式设置序列的last_value域为指定值并且将其is_called域设置为 true,表示下一次nextval将在返回值之前递增该序列。currval报告的值也被设置为指定的值。在三参数形式里,is_called可以设置为true或false。true具有和双参数形式相同的效果。如果你把它设置为false,那么下一次nextval将返回指定的值,而从随后的nextval才开始递增该序列。此外,在这种情况中currval报告的值不会被改变。 例如:
SELECT setval('foo', 42); 下一次nextval会返回 43
SELECT setval('foo', 42, true); 同上
SELECT setval('foo', 42, false); 下一次nextval将返回 42
setval返回的结果就是它的第二个参数的值。
Important: 因为序列是非事务的,setval造成的改变不会由于事务的回滚而撤销。
17. 条件表达式
本节描述在PostgreSQL中可用的SQL兼容的条件表达式。
Tip: 如果你的需求超过这些条件表达式的能力,你可能会希望用一种更富表现力的编程语言写一个存储过程。
17.1. CASE
SQL CASE表达式是一种通用的条件表达式,类似于其它编程语言中的 if/else 语句:
CASE WHEN condition THEN result
[WHEN ...]
[ELSE result]
END
CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。
例子:
SELECT * FROM test;
a
---
1
2
3
SELECT a,
CASE WHEN a=1 THEN 'one'
WHEN a=2 THEN 'two'
ELSE 'other'
END
FROM test;
a | case
---+-------
1 | one
2 | two
3 | other
所有result表达式的数据类型都必须可以转换成单一的输出类型。 参阅Section 10.5获取细节。
下面这个"简单"形式的CASE表达式是上述通用形式的一个变种:
CASE expression
WHEN value THEN result
[WHEN ...]
[ELSE result]
END
第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。
上面的例子可以用简单CASE语法来写:
SELECT a,
CASE a WHEN 1 THEN 'one'
WHEN 2 THEN 'two'
ELSE 'other'
END
FROM test;
a | case
---+-------
1 | one
2 | two
3 | other
CASE表达式并不计算任何无助于判断结果的子表达式。例如,下面是一个可以避免被零除错误的方法:
SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;
Note: 如Section 4.2.14中所述,在有几种情况中一个表达式的子表达式 会被计算多次,因此"CASE只计算必要的表达式"这 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 如此。
17.2. COALESCE
COALESCE(value [, ...])
COALESCE函数返回它的第一个非空参数的值。当且仅当所有参数都为空时才会返回空。它常用于在为显示目的检索数据时用缺省值替换空值。例如:
SELECT COALESCE(description, short_description, '(none)') ...
如果description不为空,这将会返回它的值,否则如果short_description非空则返回short_description的值,如果前两个都为空则返回(none)。
和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVL和IFNULL的能力,它们被用在某些其他数据库系统中。
17.3. NULLIF
NULLIF(value1, value2)
当value1和value2相等时,NULLIF返回一个空值。 否则它返回value1。 这些可以用于执行前文给出的COALESCE例子的逆操作:
SELECT NULLIF(value, '(none)') ...
在这个例子中,如果value是(none),将返回空值,否则返回value的值。
17.4. GREATEST和LEAST
GREATEST(value [, ...])
LEAST(value [, ...])
GREATEST和LEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅Section 10.5获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。
请注意GREATEST和LEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。
18. 数组函数和操作符
Table 9-47显示了可以用于数组类型的操作符。
Table 9-47. 数组操作符
数组比较使用默认的 B-Tree 在元素数据类型上的比较函数对数组内容按元素逐一进行。 多维数组的元素按照行序进行访问(最后的下标变化最快)。如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序(这是对PostgreSQL 8.2 之前版本的修改: 老版本认为内容相同的两个数组相等,即使它们的维数或下标范围并不相同)。
Table 9-48展示了可以用于数组类型的函数。
Table 9-48. 数组函数
在array_position和array_positions中, 每一个数组元素都使用IS NOT DISTINCT FROM 语义与要搜索的值比较。
在array_position中,如果值没有找到则返回 NULL。
在array_positions中,只有当数组为 NULL时才返回NULL,如果该值 没有在该数组中找到则返回一个空数组。
在string_to_array中,如果定界符参数为 NULL,输入字符串中的每一个字符将变成结果数组中的一个独立元素。如果定界符是一个空串,则整个输入字符串被作为一个单一元素的数组返回。否则输入字符串会被在每一个出现定界符字符串的位置分裂。
在string_to_array中,如果空值串参数被忽略或者为 NULL,输入中的子串不会被替换成 NULL。在array_to_string中,如果空值串参数被忽略或者为 NULL,该数组中的任何空值元素会被简单地跳过并且不会在输出串中被表示。
Note: string_to_array的行为中有两点与PostgreSQL 9.1之前的版本不同。首先,当输入串的长度为零时,它将返回一个空(无元素)数组而不是 NULL。其次,如果定界符串为 NULL,该函数会将输入划分成独立字符,而不是像以前那样返回 NULL。
19. 范围函数和操作符
范围类型的概述请见Section 8.17。
Table 9-49展示了范围类型可用的操作符。
Table 9-49. 范围操作符
简单比较操作符<、 >、<=和 >=首先比较下界,并且只有在下界相等时才比较上界。这些比较通常对范围不怎么有用,但是还是提供它们以便能够在范围上构建 B树索引。
当涉及一个空范围时,左部/右部/相邻操作符总是返回假;即一个空范围被认为不在任何其他范围前面或者后面。
如果结果范围可能需要包含两个分离的子范围,并和差操作符将会失败,因为这样的范围无法被表示。
Table 9-50显示可用于范围类型的函数。
Table 9-50. 范围函数
如果范围为空或者被请求的界是无限的,lower和upper函数返回空值。函数lower_inc、upper_inc、lower_inf和upper_inf对一个空范围全部返回假。
20. 聚集函数
聚集函数从一个输入值的集合计算一个单一结果。内建的普通聚集函数被列在Table 9-51和Table 9-52中。内建的顺序集聚集函数被列在Table 9-53和 Table 9-54中。分组聚集(与聚集函数更相关)被列在Table 9-55中。
Table 9-51. 通用聚集函数
请注意,除了count以外,这些函数在没有行被选中时返回控制。尤其是sum函数在没有输入行时返回空值,而不是零,并且array_agg在这种情况返回空值而不是一个空数组。必要时可以用coalesce把空值替换成零或一个空数组。
支持部分模式的聚集函数有资格参与到各种优化中,例如并行聚集。
Note: 布尔聚集bool_and和bool_or对应于标准的 SQL 聚集every和any或some。而对于any 和some,似乎在标准语法中有一个歧义:
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;如果子查询返回一行有一个布尔值的结果,这里的ANY可以被认为是引入一个子查询,或者是作为一个聚集函数。因而标准的名称不能指定给这些聚集。
Note: 在把count聚集应用到整个表上时,习惯于使用其他 SQL 数据管理系统的用户可能会对它的性能感到失望。一个如下的查询:
SELECT count(*) FROM sometable;
将会要求与整个表大小成比例的工作:PostgreSQL将需要扫描整个表或者整个包含表中所有行的索引。
与相似的用户定义的聚集函数一样,聚集函数array_agg、 json_agg、jsonb_agg、json_object_agg、jsonb_object_agg、string_agg和xmlagg会依赖输入值的顺序产生有意义的不同结果值。这个顺序默认是不用指定的,但是可以在聚集调用时使用ORDER BY子句进行控制,如Section 4.2.7中所示。作为一种选择,从一个排序号的子查询来提供输入值通常会有帮助。例如:
SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
注意如果外面的查询层次包含额外的处理(例如连接),这种方法可能会失败,因为这可能导致子查询的输出在计算聚集之前被重新排序。
Table 9-52展示了通常被用在统计分析中的聚集函数(这些被隔离出来是为了不和常用聚集混淆)。其中描述提到了N,它表示对应于所有非空输入表达式的输入行的数目。在所有情况中,如果计算是无意义的,将会返回空值,例如当N为零。
Table 9-52. 用于统计的聚集函数
Table 9-53展示了一些使用 有序集聚集语法的聚集函数。这些函数有时也被称为 "逆分布"函数。
Table 9-53. 有序集聚集函数
所有列在Table 9-53中的聚集会忽略它们的已 排序输入中的空值。对那些有一个fraction参数的聚 集来说,该分数值必须位于 0 和 1 之间,否则会抛出错误。不过,一个空分数值会 产生一个空结果。
每个列在Table 9-54中的聚集都与一个定义在 Section 9.21中的同名窗口函数相关联。在每种情况中,聚集 结果的计算方法是:假设根据args构建的"假想"行已 经被增加到从sorted_args计算得到的已排序行分组中, 然后用相关联的窗口函数针对该行返回的值就是聚集的结果。
Table 9-54. 假想集聚集函数
对于这些假想集聚集的每一个,args中给定的直接参数 列表必须匹配sorted_args中给定的聚集参数的 数量和类型。与大部分的内建聚集不同,这些聚集并不严格,即它们不会丢弃包含空值 的输入行。空值的排序根据ORDER BY子句中指定的规则进行。
Table 9-55. 分组操作
分组操作用来与分组集合(见Section 7.2.4)共同来 区分结果行。GROUPING操作的参数并不会被实际计算,但是它们必 须准确地匹配在相关查询层次的GROUP BY子句中给定的表达式。 最右边参数指派的位是最低有效位,如果对应的表达式被包括在产生结果行的分组 集合的分组条件中则每一位是 0,否则是 1。例如:
=> SELECT * FROM items_sold;
make | model | sales
-------+-------+-------
Foo | GT | 10
Foo | Tour | 20
Bar | City | 15
Bar | Sport | 5
(4 rows)
=> SELECT make, model, GROUPING(make,model), sum(sales) FROM items_sold GROUP BY ROLLUP(make,model);
make | model | grouping | sum
-------+-------+----------+-----
Foo | GT | 0 | 10
Foo | Tour | 0 | 20
Bar | City | 0 | 15
Bar | Sport | 0 | 5
Foo | | 1 | 30
Bar | | 1 | 20
| | 3 | 50
(7 rows)
窗口函数窗口函数提供在与当前查询行相关的行集合上执行计算的能力。
Table 9-56列出了内建的窗口函数。注意必须使用窗口函数的语法调用这些函数; 一个OVER子句是必需的。
除了这些函数外,任何内建的或用户定义的普通聚集函数(但有序集或假想集聚集除外)都可以作为窗口函数。仅当调用跟着OVER子句时,聚集函数才会作为窗口函数;否则它们作为常规的聚集。
Table 9-56. 通用窗口函数
在Table 9-56中列出的所有函数都依赖于相关窗口定义的ORDER BY子句指定的排序顺序。 在ORDER BY排序中不能区分的行被称为是同等行。定义的这四个排名函数,对于任何两个同等行的答案相同。
注意first_value、last_value和nth_value只考虑"窗口帧"内的行,它默认情况下包含从分区的开始行直到当前行的最后一个同等行。这对last_value可能不会给出有用的结果,有时对nth_value也一样。你可以通过向OVER子句增加一个合适的帧声明(RANGE或ROWS)来重定义帧。
当一个聚集函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚集。 一个使用ORDER BY和默认窗口帧定义的聚集产生一种"运行时求和"类型的行为,这可能是或者不是想要的结果。为了获取在整个分区上的聚集,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。
Note: SQL 标准为lead、lag、first_value、last_value和nth_value定义了 一个RESPECT NULLS或IGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 同样,标准中用于nth_value的FROM FIRST或FROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。
22. 子查询表达式
本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。
22.1. EXISTS
EXISTS (subquery)
EXISTS的参数是一个任意的SELECT语句, 或者说子查询。系统对子查询进行运算以判断它是否返回行。如果它至少返回一行,那么EXISTS的结果就为"真"; 如果子查询没有返回行,那么EXISTS的结果是"假"。
子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。
这个子查询通常只是运行到能判断它是否可以返回至少一行为止, 而不是等到全部结束。在这里写任何有副作用的子查询都是不明智的(例如调用序列函数);这些副作用是否发生是很难判断的。
因为结果只取决于是否会返回行,而不取决于这些行的内容, 所以这个子查询的输出列表通常是无关紧要的。一个常用的编码习惯是用EXISTS(SELECT 1 WHERE ...)的形式写所有的EXISTS测试。不过这条规则有例外,例如那些使用INTERSECT的子查询。
下面这个简单的例子类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶
SELECT col1
FROM tab1
WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
22.2. IN
expression IN (subquery)
右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是"真"。 如果没有找到相等行,那么结果是"假"(包括子查询没有返回任何行的情况)。
请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。
和EXISTS一样,假设子查询将被完成运行完全是不明智的。
row_constructor IN (subquery)
这种形式的IN的左手边是一个行构造器, 如Section 4.2.13中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为"true"。如果没有找到相等行, 那么结果为"假"(包括子查询不返回行的情况)。
通常,表达式或者子查询行里的空值是按照 SQL 布尔表达式的一般规则进行组合的。 如果两个行对应的成员都非空并且相等,那么认为这两行相等;如果任意对应成员为非空且不等,那么这两行不等; 否则这样的行比较的结果是未知(空值)。如果所有行的结果要么是不等, 要么是空值,并且至少有一个空值,那么IN的结果是空值。
22.3. NOT IN
expression NOT IN (subquery)
右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是"真"。 如果找到任何相等行,则结果为"假"。
请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。
和EXISTS一样,假设子查询会完全结束是不明智的。
row_constructor NOT IN (subquery)
这种形式的NOT IN的左手边是一个行构造器, 如Section 4.2.13中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为"true"。如果找到相等行, 那么结果为"假"(包括子查询不返回行的情况)。
通常,表达式或者子查询行里的空值是按照 SQL 布尔表达式的一般规则进行组合的。 如果两个行对应的成员都非空并且相等,那么认为这两行相等;如果任意对应成员为非空且不等,那么这两行不等; 否则这样的行比较的结果是未知(空值)。如果所有行的结果要么是不等, 要么是空值,并且至少有一个空值,那么NOT IN的结果是空值。
22.4. ANY/SOME
expression operator ANY (subquery)expression operator SOME (subquery)
这种形式的右手边是一个圆括弧括起来的子查询, 它必须返回正好一个列。左手边表达式将被计算并使用给出的 操作符对子查询结果逐行进行比较。如果获得任何真值结果,那么ANY的结果就是"真"。 如果没有找到真值结果,那么结果是"假"(包括子查询没有返回任何行的情况)。
SOME是ANY的同义词。IN等价于= ANY。
请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。
和EXISTS一样,假设子查询将被完全运行是不明智的。
row_constructor operator ANY (subquery)row_constructor operator SOME (subquery)
这种形式的左手边是一个行构造器,如Section 4.2.13所述。右手边是一个圆括弧括起来的子查询, 它必须返回和左手边列表给出的表达式一样多的列。左手边表达式将被计算并使用给出的操作符对子查询结果逐行进行比较。如果比较为任何子查询行返回真,则ANY的结果为"真"。如果比较对每一个子查询行都返回假,则结果为"假"(包括子查询不返回行的情况)。如果比较不对任何行返回真并且至少对一行返回 NULL,则结果为 NULL。
22.5. ALL
expression operator ALL (subquery)ALL 的这种形式的右手边是一个圆括弧括起来的子查询, 它必须只返回一列。左手边表达式将被计算并使用给出的 操作符对子查询结果逐行进行比较。该操作符必须生成布尔结果。 如果所有行得到真(包括子查询没有返回任何行的情况),ALL的结果就是"真"。如果没有存在任何假值结果,那么结果是"假"。如果比较为任何行都不返回假并且对至少一行返回 NULL,则结果为 NULL。
NOT IN等价于<> ALL。
和EXISTS一样,假设子查询将被完全运行是不明智的。
row_constructor operator ALL (subquery)
ALL的这种形式的左手边是一个行构造器, 右手边是一个圆括弧括起来的子查询,它必须返回和左手边行中表达式一样多的列。 左手边表达式将被计算并使用给出的 操作符对子查询结果逐行进行比较。如果对所有子查询行该比较都返回真,那么ALL的结果就是"真"(包括子查询没有返回任何行的情况)。如果对任何子查询行比较返回假,则结果为"假"。如果比较对任何子查询行都不返回假并且对至少一行返回 NULL,则结果为 NULL。
22.6. 单一行比较
row_constructor operator (subquery)
左手边是一个行构造器,右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。
23. 行和数组比较
本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。
23.1. IN
expression IN (value [, ...])右手边是一个圆括弧包围的标量列表。如果左手边表达式的结果等于任何右手边表达式中的一个,结果为"真"。它是下面形式的缩写
expression = value1
OR
expression = value2
OR
...
请注意如果左手边表达式得到空值,或者没有相等的右手边值并且至少有一个右手边的表达式得到空值,那么IN结构的结果将为空值,而不是假。这符合 SQL 处理空值的布尔组合的一般规则。
23.2. NOT IN
expression NOT IN (value [, ...])右手边是一个圆括弧包围的标量列表。如果左手边表达式的结果不等于所有右手边表达式,结果为"真"。它是下面形式的缩写
expression <> value1
AND
expression <> value2
AND
...
请注意如果左手边表达式得到空值,或者没有相等的右手边值并且至少有一个右手边的表达式得到空值,那么NOT IN结构的结果将为空值, 而不是我们可能天真地认为的真值。这符合 SQL 处理空值的布尔组合的一般规则。
Tip: x NOT IN y在所有情况下都等效于NOT (x IN y)。但是,在处理空值的时候,用NOT IN比用IN更可能迷惑新手。最好尽可能用正逻辑来表达你的条件。
23.3. ANY/SOME (array)
expression operator ANY (array expression)expression operator SOME (array expression)
右手边是一个圆括弧包围的表达式,它必须得到一个数组值。左手边表达式被计算并且使用给出的操作符对数组的每个元素进行比较,这个操作符必须得到布尔结果。如果得到了任何真值结果,那么ANY的结果是"真"。 如果没有找到真值结果(包括数组只有零个元素的情况),那么结果是"假"。
如果数组表达式得到一个空数组,ANY的结果将为空值。如果左手边的表达式得到空值,ANY通常是空值(尽管一个非严格比较操作符可能得到一个不同的结果)。另外,如果右手边的数组包含任何空值元素或者没有得到真值比较结果,ANY的结果将是空值而不是假(再次,假设是一个严格的比较操作符)。这符合 SQL 对空值的布尔组合的一般规则。
SOME是ANY的同义词。
23.4. ALL (array)
expression operator ALL (array expression)
右手边是一个圆括弧包围的表达式,它必须得到一个数组值。左手边表达式将被计算并使用给出的操作符与数组的每个元素进行比较,这个操作符必须得到一个布尔结果。如果所有比较都得到真值结果,那么ALL的结果是 "真"(包括数组只有零个元素的情况)。如果有任何假值结果,那么结果是"假"。
如果数组表达式得到一个空数组,ALL的结果将为空值。如果左手边的表达式得到空值,ALL通常是空值(尽管一个非严格比较操作符可能得到一个不同的结果)。另外,如果右手边的数组包含任何空值元素或者没有得到假值比较结果,ALL的结果将是空值而不是真(再次,假设是一个严格的比较操作符)。这符合 SQL 对空值的布尔组合的一般规则。
23.5. 行构造器比较
row_constructor operator row_constructor
每一边都是一个行构造器,如Section 4.2.13所述。两个行值必须具有相同数量的域。每一边被计算并且被逐行比较。当操作符是 =、 <>、 < <=、 >、 >=时,允许进行行构造器比较。每一个行元素必须是具有一个默认 B 树操作符类的类型,否则尝试比较会产生一个错误。
Note: Errors related to the number or types of elements might not occur if the comparison is resolved using earlier columns.
=和<>情况略有不同。如果两行的所有对应成员都是非空且相等则这两行被认为相等;如果任何对应成员是非空但是不相等则这两行不相等;否则行比较的结果为未知(空值)。
对于<、<=、>和>=情况,行元素被从左至右比较,在找到一处不等的或为空的元素对就立刻停下来。如果这一对元素都为空值,则行比较的结果为未知(空值);否则这一对元素的比较结果决定行比较的结果。例如,ROW(1,2,NULL) < ROW(1,3,0)得到真,而不是空值,因为第三对元素并没有被考虑。
Note: 在PostgreSQL 8.2之前,<、<=、>和>=情况不是按照每个 SQL 声明来处理的。一个像ROW(a,b) < ROW(c,d)的比较会被实现为a < c AND b < d,而结果行为等价于a < c OR (a = c AND b < d)。
row_constructor IS DISTINCT FROM row_constructor
这个结构与<>行比较相似,但是它对于空值输入不会得到空值。任何空值被认为和任何非空值不相等(有区别),并且任意两个空值被认为相等(无区别)。因此结果将总是为真或为假,永远不会是空值。
row_constructor IS NOT DISTINCT FROM row_constructor
这个结构与=行比较相似,但是它对于空值输入不会得到空值。任何空值被认为和任何非空值不相等(有区别),并且任意两个空值被认为相等(无区别)。因此结果将总是为真或为假,永远不会是空值。
23.6. 组合类型比较
record operator recordSQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。PostgreSQL只有在比较两个行构造器(如Section 9.23.5)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如Section 9.22中所述)。在其他比较两个组合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。为了得到组合类型的一致的排序和索引行为,这样做是必要的。
每一边都会被计算并且它们会被逐行比较。当操作符是 =、 <>、 <、 <=、 >或者 >=时或者具有与这些类似的语义时,允许组合类型的比较(更准确地说,如果一个操作符是一个 B 树操作符类的成员,或者是一个 B 树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 上述操作符的行为与用于行构造器(见Section 9.23.5)的IS [ NOT ] DISTINCT FROM相同。
为了支持包含无默认 B 树操作符类的元素的行匹配,为组合类型比较定义了下列操作符: =, <>, <, <=, >, and >=. 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能 具有不同的二进制表达。行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 这些操作符在内部被用于物化视图并且可能对其他如复制之类的特殊功能有用,但是它们 并不打算用在书写查询这类普通用途中。
24. 集合返回函数
本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如Table 9-57和Table 9-58所述。其他更特殊的集合返回函数在本手册的其他地方描述。
Table 9-57. 级数生成函数
当step为正时,如果start大于stop则返回零行。相反,当step为负时,如果start小于stop则返回零行。对于NULL输入也会返回零行。step为零是一个错误。下面是一些例子:
SELECT * FROM generate_series(2,4);
generate_series
-----------------
2
3
4
(3 rows)
SELECT * FROM generate_series(5,1,-2);
generate_series
-----------------
5
3
1
(3 rows)
SELECT * FROM generate_series(4,3);
generate_series
-----------------
(0 rows)
SELECT generate_series(1.1, 4, 1.3);
generate_series
-----------------
1.1
2.4
3.7
(3 rows)
-- 这个例子依赖于日期+整数操作符
SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a);
dates
------------
2004-02-05
2004-02-12
2004-02-19
(3 rows)
SELECT * FROM generate_series('2008-03-01 00:00'::timestamp,
'2008-03-04 12:00', '10 hours');
generate_series
---------------------
2008-03-01 00:00:00
2008-03-01 10:00:00
2008-03-01 20:00:00
2008-03-02 06:00:00
2008-03-02 16:00:00
2008-03-03 02:00:00
2008-03-03 12:00:00
2008-03-03 22:00:00
2008-03-04 08:00:00
(9 rows)
Table 9-58. 下标生成函数
generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。对于不具有请求维度的数组返回零行,对于 NULL 数组也返回零行(但是会对 NULL 数组元素返回合法的下标)。下面是一些例子:
-- 基本使用
SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s;
s
---
1
2
3
4
(4 rows)
-- 表示一个数组,下标和被下标的值需要一个子查询
SELECT * FROM arrays;
a
--------------------
{-1,-2}
{100,200,300}
(2 rows)
SELECT a AS array, s AS subscript, a[s] AS value
FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo;
array | subscript | value
---------------+-----------+-------
{-1,-2} | 1 | -1
{-1,-2} | 2 | -2
{100,200,300} | 1 | 100
{100,200,300} | 2 | 200
{100,200,300} | 3 | 300
(5 rows)
-- 平面化一个 2D 数组
CREATE OR REPLACE FUNCTION unnest2(anyarray)
RETURNS SETOF anyelement AS
$$
select $1[i][j]
from generate_subscripts($1,1) g1(i),
generate_subscripts($1,2) g2(j);
$$
LANGUAGE sql IMMUTABLE;
CREATE FUNCTION
SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]);
unnest2
---------
1
2
3
4
(4 rows)
When a function in the FROM clause is suffixed by WITH ORDINALITY, a bigint column is appended to the output which starts from 1 and increments by 1 for each row of the function's output. This is most useful in the case of set returning functions such as unnest().
-- set returning function WITH ORDINALITY
SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
ls | n
-----------------+----
pg_serial | 1
pg_twophase | 2
postmaster.opts | 3
pg_notify | 4
postgresql.conf | 5
pg_tblspc | 6
logfile | 7
base | 8
postmaster.pid | 9
pg_ident.conf | 10
global | 11
pg_clog | 12
pg_snapshots | 13
pg_multixact | 14
PG_VERSION | 15
pg_xlog | 16
pg_hba.conf | 17
pg_stat_tmp | 18
pg_subtrans | 19
(19 rows)
25. 系统信息函数
Table 9-59展示了多个可以抽取会话和系统信息的函数。
除了本节列出的函数,还有一些与统计系统相关的函数也提供系统信息。
Table 9-59. 会话信息函数
Note: current_catalog、current_schema、current_user、session_user和user在SQL里有特殊的语意状态: 它们被调用时结尾不要跟着园括号(在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用)。
session_user通常是发起当前数据库连接的用户,不过超级用户可以用SET SESSION AUTHORIZATION修改这个设置。current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被SET ROLE改变。它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。在 Unix 的说法里,那么会话用户是"真实用户",而当前用户是"有效用户"。
current_schema返回在搜索路径中的第一个模式名(如果搜索路径是空则返回空值)。 如果创建表或者其它命名对象时没有声明目标模式,那么它将是被用于这些对象的模式。current_schemas(boolean)返回一个在搜索路径中出现的所有模式名的数组。布尔选项决定pg_catalog这样的隐式包含的系统模式是否包含在返回的搜索路径中。
Note: 搜索路径可以在运行时修改。命令是:
SET search_path TO schema [, schema, ...]
inet_client_addr返回当前客户端的 IP 地址,inet_client_port返回它的端口号。
inet_server_addr返回接受当前连接的服务器的 IP 地址,而inet_server_port返回对应的端口号。如果连接是通过 Unix 域套接字进行的,那么所有这些函数都返回 NULL。
pg_blocking_pids返回一个进程 ID 的数组,数组中的进程中的会话阻塞了指定进程 ID 所代表的服务器进程,如果指定的服务器进程不存在或者没有被阻塞则返回空数组。如果一个进程持有与另一个进程加锁请求冲突的锁(硬锁),或者前者正在等待一个与后者加锁请求冲突的锁并且前者在该锁的等待队列中位于后者的前面(软锁),则前者会阻塞后者。在使用并行查询时,这个函数的结果总是会列出客户端可见的进程 ID(即pg_backend_pid的结果),即便实际的锁是由工作者进程所持有或者等待也是如此。这样造成的后果是,结果中可能会有很多重复的 PID。还要注意当一个预备事务持有一个冲突锁时,这个函数的结果中它将被表示为一个为零的进程 ID。对这个函数的频繁调用可能对数据库性能有一些影响,因为它需要短时间地独占访问锁管理器的共享状态。
pg_conf_load_time返回服务器配置文件最近被载入的timestamp with time zone(如果当前会话在那时就已经存在,这个值将是该会话自己重新读取配置文件的时间,因此在不同的会话中这个读数会有一点变化。如果不是这样,这个值就是 postmaster 进程重读配置文件的时间)。
pg_my_temp_schema返回当前会话临时模式的 OID,如果没有使用临时模式(因为它没有创建任何临时表)则返回零。如果给定的 OID 是另一个会话的临时模式的 OID,则pg_is_other_temp_schema返回真(这是有用的,例如,要将其他会话的临时表从一个目录显示中排除)。
pg_listening_channels返回当前会话正在监听的异步通知频道的名称的集合。pg_notification_queue_usage返回等待处理的通知占可用的通知空间的比例,它是一个 0-1 范围内的double值。详见LISTEN和NOTIFY。
pg_postmaster_start_time返回服务器启动的timestamp with time zone。
version返回一个描述PostgreSQL服务器版本的字符串。你也可以从server_version或者一个机器可读的版本server_version_num得到这个信息。软件开发者应该使用server_version_num(从 8.2 开始可用)或者 PQserverVersion ,而不必解析文本形式的版本。
Table 9-60列出那些允许用户编程查询对象访问权限的函数。参阅Section 5.6获取更多有关权限的信息。
Table 9-60. 访问权限查询函数
has_table_privilege判断一个用户是否可以用某种特定的方式访问一个表。 该用户可以通过名字或者 OID (pg_authid.oid) 来指定,也可以用public表示 PUBLIC 伪角色。如果省略该参数,则使用current_user。 该表可以通过名字或者 OID 指定(因此,实际上有六种 has_table_privilege的变体,我们可以通过它们的参数数目和类型来区分它们) 。如果用名字指定,那么在必要时该名字可以是模式限定的。 所希望的权限类型是用一个文本串来指定的,它必须是下面的几个值之一: SELECT、INSERT、UPDATE、DELETE、TRUNCATE、REFERENCES或TRIGGER。WITH GRANT OPTION可以被选择增加到一个权限类型来测试是否该权限是使用转授选项得到。另外,可以使用逗号分隔来列出多个权限类型,在这种情况下只要具有其中之一的权限则结果为真(权限字符串的大小写并不重要,可以在权限名称之间出现额外的空白,但是在权限名内部不能有空白)。一些例子:
SELECT has_table_privilege('myschema.mytable', 'select');
SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION');
has_sequence_privilege检查一个用户是否能以某种特定方式访问一个序列。它的参数可能性和has_table_privilege相似。所希望测试的访问权限类型必须是下列之一:USAGE、SELECT或UPDATE。
has_any_column_privilege检查一个用户是否能以特定方式访问一个表的任意列。其参数可能性和has_table_privilege类似,除了所希望的访问权限类型必须是下面值的某种组合:SELECT、INSERT、UPDATE或REFERENCES。注意在表层面上具有这些权限的任意一个都会隐式地把它授权给表中的每一列,因此如果has_table_privilege对同样的参数返回真则has_any_column_privilege将总是返回真。但是如果在至少一列上有一个该权限的列级授权,has_any_column_privilege也会成功。
has_column_privilege检查一个用户是否能以特定方式访问一个列。它的参数可能性与has_table_privilege类似,并且列还可以使用名字或者属性号来指定。希望的访问权限类型必须是下列值的某种组合:SELECT、INSERT、UPDATE或REFERENCES。注意在表级别上具有这些权限中的任意一种将会隐式地把它授予给表上的每一列。
has_database_privilege检查一个用户是否能以特定方式访问一个数据库。它的参数可能性类似 has_table_privilege。希望的访问权限类型必须是以下值的某种组合:CREATE、CONNECT、TEMPORARY或TEMP(等价于TEMPORARY)。
has_function_privilege检查一个用户是否能以特定方式访问一个函数。其参数可能性类似has_table_privilege。在用一个文本串而不是 OID 指定一个函数时,允许的输入和regprocedure数据类型一样(参阅 Section 8.18)。希望的访问权限类型必须是EXECUTE。一个例子:
SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
has_foreign_data_wrapper_privilege检查一个用户是否能以特定方式访问一个外部数据包装器。它的参数可能性类似于has_table_privilege。希望的访问权限类型必须是USAGE。
has_language_privilege检查一个用户是否可以以某种特定的方式访问一个过程语言。 其参数可能性类似 has_table_privilege。希望的访问权限类型必须是USAGE。
has_schema_privilege检查一个用户是否可以以某种特定的方式访问一个模式。 其参数可能性类似 has_table_privilege。希望的访问权限类型必须是CREATE或USAGE。
has_server_privilege检查一个用户是否可以以某种特定的方式访问一个外部服务器。 其参数可能性类似 has_table_privilege。希望的访问权限类型必须是USAGE。
has_tablespace_privilege检查一个用户是否可以以某种特定的方式访问一个表空间。其参数可能性类似 has_table_privilege。希望的访问权限类型必须是CREATE。
has_type_privilege检查一个用户是否能以特定的方式访问一种类型。其参数的可能性类同于has_table_privilege。在用字符串而不是 OID 指定类型时,允许的输入和regtype数据类型相同(见Section 8.18)。期望的访问特权类型必须等于USAGE。
pg_has_role检查一个用户是否可以以某种特定的方式访问一个角色。其参数可能性类似 has_table_privilege,除了public不能被允许作为一个用户名。希望的访问权限类型必须是下列值的某种组合:MEMBER或USAGE。MEMBER表示该角色中的直接或间接成员关系(即使用SET ROLE的权力),而USAGE表示不做SET ROLE的情况下该角色的权限是否立即可用。
row_security_active检查在 current_user的上下文和环境中是否为指定的 表激活了行级安全性。表可以用名称或者 OID 指定。
Table 9-61展示了决定是否一个特定对象在当前模式搜索路径中可见的函数。例如,如果一个表所在的模式在当前搜索路径中并且在它之前没有出现过相同的名字,这个表就被说是可见的。这等价于在语句中表可以被用名称引用但不加显式的模式限定。要列出所有可见表的名字:
SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
Table 9-61. 模式可见性查询函数
每一个函数对一种数据库对象执行可见性检查。注意pg_table_is_visible也可被用于视图、物化视图、索引、序列和外部表,pg_type_is_visible也可以被用于域。对于函数和操作符,如果在路径中更早的地方没有出现具有相同名称和参数数据类型的对象,该对象在搜索路径中是可见的。对于操作符类,名称和相关的索引访问方法都要考虑。
所有这些函数都要求用对象 OID 来标识将被检查的对象。如果你想用名称来测试一个对象,使用 OID 别名类型(regclass、regtype、regprocedure、regoperator、regconfig或regdictionary)将会很方便。例如:
SELECT pg_type_is_visible('myschema.widget'::regtype);
注意以这种方式测试一个非模式限定的类型名没什么意义 — 如果该名称完全能被识别,它必须是可见的。
Table 9-62列出了从系统目录抽取信息的函数。
Table 9-62. 系统目录信息函数
format_type返回一个数据类型的 SQL 名称,它由它的类型 OID 标识并且可能是一个类型修饰符。如果不知道相关的修饰符,则为类型修饰符传递 NULL。
pg_get_keywords返回一组记录描述服务器识别的 SQL 关键字。word列包含关键字。catcode列包含一个分类码:U为未被预定,C 为列名,T类型或函数名,R为预留。catdesc列包含一个可能本地化的描述分类的字符串。
pg_get_constraintdef、pg_get_indexdef、pg_get_ruledef和pg_get_triggerdef分别重建一个约束、索引、规则或触发器的创建命令(注意这是一个反编译的重构,而不是命令的原始文本)。pg_get_expr反编译一个表达式的内部形式,例如一个列的默认值。在检查系统目录内容时有用。如果表达式可能包含 Var,在第二个参数中指定它们引用的关系的 OID;如果不会出现 Var,第二个参数设置为 0 即可。pg_get_viewdef重构定义一个视图的SELECT查询。这些函数的大部分都有两种变体,一种可以可选地"优质打印"结果。优质打印的格式可读性更强,但是默认格式更可能被未来版本的PostgreSQL以相同的方式解释。在转出目的中避免使用优质打印输出。为优质打印参数传递假将得到和不带该参数的变体相同的结果。
pg_get_functiondef为一个函数返回一个完整的CREATE OR REPLACE FUNCTION语句。pg_get_function_arguments返回一个函数的参数列表,形式按照它们出现在CREATE FUNCTION中的那样。pg_get_function_result类似地返回函数的合适的RETURNS子句。pg_get_function_identity_arguments返回标识一个函数必要的参数列表,形式和它们出现在ALTER FUNCTION中的一样。这种形式忽略默认值。
pg_get_serial_sequence返回与一个列相关联的序列的名称,如果与列相关联的序列则返回 NULL。第一个输入参数是一个带可选模式的表名,第二个参数是一个列名。因为第一个参数可能是一个模式和表,它不能按照一个双引号包围的标识符来对待,意味着它默认情况下是小写的。而第二个参数只是一个列名,将被当作一个双引号包围的来处理并且会保留其大小写。函数返回的值会被适当地格式化以便传递给序列函数(参见Section 9.16)。这种关联可以使用ALTER SEQUENCE OWNED BY来改变或移除(该函数应该曾经被称作pg_get_owned_sequence,它目前的名字反映了它通常和serial或bigserial列一起使用)。
pg_get_userbyid抽取给定 OID 的角色的名称。
pg_index_column_has_property、pg_index_has_property和pg_indexam_has_property返回指定的索引列、索引或者索引访问方法是否具有指定性质。如果性质的名称找不到或者不适用于特定的对象,亦或者 OID 或者列号不表示合法的对象,则返回NULL。列的性质可参见Table 9-63,索引的性质可参见Table 9-64,访问方法的性质可参见Table 9-65(注意扩展访问方法可以为其索引定义额外的性质)。
Table 9-63. 索引列属性
Table 9-64. 索引性质
Table 9-65. 索引访问方法性质
当传入pg_class.reloptions或pg_attribute.attoptions时,pg_options_to_table返回存储选项名称/值对(option_name/option_value)的集合。
pg_tablespace_databases允许一个表空间被检查。它返回一组数据库的 OID,这些数据库都有对象存储在该表空间中。如果这个函数返回任何行,则该表空间为非空并且不能被删除。为了显示该表空间中的指定对象,你将需要连接到pg_tablespace_databases标识的数据库并且查询它们的pg_class目录。
pg_typeof返回传递给它的值的数据类型的 OID。这在检修或者动态构建 SQL 查询时有用。函数被声明为返回regtype,它是一个 OID 别名类型(见Section 8.18);这表明它和一个用于比较目的的 OID 相同,但是作为一个类型名称显示。例如:
SELECT pg_typeof(33);
pg_typeof
-----------
integer
(1 row)
SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
typlen
--------
4
(1 row)
表达式collation for返回传递给它的值的排序规则。例子:
SELECT collation for (description) FROM pg_description LIMIT 1;
pg_collation_for
------------------
"default"
(1 row)
SELECT collation for ('foo' COLLATE "de_DE");
pg_collation_for
------------------
"de_DE"
(1 row)
值可能被加上引号并且变成模式限定的。如果从参数表达式得不到排序规则,则返回一个空值。如果参数不是一个可排序的数据类型,则抛出一个错误。
to_regclass、to_regproc、to_regprocedure, to_regoper、to_regoperator、to_regtype、to_regnamespace和to_regrole函数把关系、函数、操作符、类型、模式和角色的名称(以text给出)分别转换成、regclass、regproc、regprocedure、regoper、regoperator、regtype、regnamespace和regrole对象。这些函数与 text 转换的不同在于它们不接受数字 OID,并且在名称无法找到时不会抛出错误而是返回空。对于to_regproc和to_regoper,如果给定名称匹配多个对象时返回空。
Table 9-66列出了与数据库对象 标识和定位有关的函数。
Table 9-66. 对象信息和定位函数
pg_describe_object会返回一个数据库对象的文本描述, 它由目录 OID、对象 OID 和一个(可能为零的)子对象 ID 所指定。这种描述是为 了人类可读的,并且可能是被翻译过的,具体取决于服务器配置。这有助于确定一 个存储在pg_depend目录中的对象的标识。
pg_identify_object返回一行,其中包含有足以唯一标识 由目录 OID、对象 OID 和一个(可能为零的)子对象 ID 指定的数据库对象的信息。 该信息是共机器读取的,并且不会被翻译。type标识数据库对象 的类型;schema是该对象所属的模式名,如果对象类型不属于 模式则为NULL;name是对象的名称,必要时会被 加上引号,只有在它可以被用作该对象的唯一标识符(可能还要带上模式名)时才 存在,否则为NULL;identity是完整的对象标识, 它会表现为与对象类型相关的精确格式,并且如有必要,该格式中的每个部分都会 被模式限定。
pg_identify_object_as_address返回一行,其中包含有 足以唯一标识由目录 OID、对象 OID 和一个(可能为零的)子对象 ID 指定的数据 库对象的信息。返回的信息独立于当前服务器,也就是说,它可以被用来在另一个 服务器中标识一个具有相同命名的对象。type标识数据库对象 的类型;name和args是文本数组,它们一起 构成了对对象的引用。这三个列可以被传递给 pg_get_object_address以获得该对象的内部地址。这个函数是 pg_get_object_address的逆函数。
pg_get_object_address返回一行,其中包含有足以唯一 标识由类型、对象名和参数数组指定的数据库对象的信息。返回值可以被用在诸如 pg_depend等系统目录中并且可以被传递给 pg_identify_object或pg_describe_object等其他 系统函数。catalog_id是包含该对象的系统目录 OID; object_id是对象本身的 OID,而 object_sub_id是子对象 ID,如果没有则为零。这个函数是 pg_identify_object_as_address的逆函数。
Table 9-67中展示的函数抽取注释,注释是由COMMENT命令在以前存储的。如果对指定参数找不到注释,则返回空值。
Table 9-67. 注释信息函数
col_description为一个表列返回注释,该表列由所在表的 OID 和它的列号指定(obj_description不能被用在表列,因为表列没有自己的 OID)。
obj_description的双参数形式返回一个由其 OID 和所在系统目录名称指定的数据库对象的注释。例如,obj_description(123456,'pg_class')将会检索出 OID 为123456的表的注释。obj_description的单参数形式只要求对象 OID。它已经被废弃,因为无法保证 OID 在不同系统目录之间是唯一的;这样可能会返回错误的注释。
shobj_description用起来就像obj_description,但是前者是用于检索共享对象上的注释。某些系统目录对于一个集簇中的所有数据库是全局的,并且其中的对象的描述也是全局存储的。
Table 9-68中展示的函数以一种可导出的形式提供了服务器事务信息。这些函数的主要用途是判断在两个快照之间哪些事务被提交。
Table 9-68. 事务 ID 和快照
内部事务 ID 类型(xid)是 32 位宽并且每 40 亿个事务就会回卷。但是,这些函数导出一种 64 位格式,它被使用一个"世代"计数器,这样在一个安装的生命期内不会回卷。这些函数使用的数据类型txid_snapshot存储了在一个特定时刻有关事务 ID 可见性的信息。它的成分在Table 9-69中描述。
Table 9-69. 快照成分
txid_snapshot的文本表示是xmin:xmax:xip_list。例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。
Table 9-70中展示的函数提供了有关于 已经提交事务的信息。这些函数主要提供有关事务何时被提交的信息。只有当 track_commit_timestamp配置选项被启用时它们才能 提供有用的数据,并且只对已提交事务提供数据。
Table 9-70. 已提交事务信息
Table 9-71中所展示的函数能打印initdb期间初始化的信息,例如系统目录版本。它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。对于同一种来源,它们返回和pg_controldata大致相同的信息,不过其形式更适合于SQL函数。
Table 9-71. 控制数据函数
pg_control_checkpoint返回一个Table 9-72中所示的记录
Table 9-72. pg_control_checkpoint列
pg_control_system返回一个Table 9-73中所示的记录
Table 9-73. pg_control_system列
pg_control_init返回一个Table 9-74中所示的记录
Table 9-74. pg_control_init列
pg_control_recovery返回一个Table 9-75中所示的记录
Table 9-75. pg_control_recovery列
26. 系统管理函数
这一节描述的函数被用来控制和监视一个PostgreSQL安装。
26.1. 配置设定函数
Table 9-76展示了那些可以用于查询以及修改运行时配置参数的函数。
Table 9-76. 配置设定函数
current_setting得到setting_name设置的当前值。它对应于SQL命令SHOW。一个例子:
SELECT current_setting('datestyle');
current_setting
-----------------
ISO, MDY
(1 row)
如果没有名为setting_name的设置,除非提供missing_ok并且其值为true,current_setting会抛出错误。
set_config将参数setting_name设置为new_value。如果 is_local设置为true,那么新值将只应用于当前事务。 如果你希望新值应用于当前会话,那么应该使用false。 它等效于 SQL 命令 SET。例如:
SELECT set_config('log_statement_stats', 'off', false);
set_config
------------
off
(1 row)
26.2. 服务器信号函数
在Table 9-77中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问特权授予给其他用户。
Table 9-77. 服务器信号函数
这些函数中的每一个都在成功时返回true,并且在失败时返回false。
pg_cancel_backend和pg_terminate_backend向由进程 ID 标识的后端进程发送信号(分别是SIGINT或SIGTERM)。一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用任务管理器)得到。一个活动后端的角色可以在pg_stat_activity视图的usename列中找到。
pg_reload_conf给服务器发送一个SIGHUP信号, 导致所有服务器进程重载配置文件。
pg_rotate_logfile给日志文件管理器发送信号,告诉它立即切换到一个新的输出文件。这个函数只有在内建日志收集器运行时才能工作,因为否则就不存在日志文件管理器子进程。 subprocess.
26.3. 备份控制函数
Table 9-78中展示的函数可以辅助制作在线备份。这些函数不能在恢复期间执行(pg_is_in_backup、pg_backup_start_time和pg_xlog_location_diff除外)。
Table 9-78. 备份控制函数
pg_start_backup接受一个参数,这个参数可以是备份的任意用户定义的标签(通常这是备份转储文件将被存储的名字)。当被用在排他模式中时,该函数向数据库集簇的数据目录写入一个备份标签文件(backup_label)和一个表空间映射文件(tablespace_map,如果在pg_tblspc/目录中有任何链接),执行一个检查点,然后以文本方式返回备份的起始事务日志位置。用户可以忽略这个结果值,但是为了可能需要的场合我们还是提供该值。 当在非排他模式中使用时,这些文件的内容会转而由pg_stop_backup函数返回,并且应该由调用者写入到备份中去。
postgres=# select pg_start_backup('label_goes_here');
pg_start_backup
-----------------
0/D4445B8
(1 row)
第二个参数是可选的,其类型为boolean。如果为true,它指定尽快执行pg_start_backup。这会强制一个立即执行的检查点,它会导致 I/O 操作的峰值,拖慢任何并发执行的查询。
在一次排他备份中,pg_stop_backup会移除标签文件以及pg_start_backup创建的tablespace_map文件(如果存在)。在一次非排他备份中,backup_label和tablespace_map的内容会包含在该函数返回的结果中,并且应该被写入到该备份的文件中(这些内容不在数据目录中)。
该函数还在事务日志归档区里创建一个备份历史文件。这个历史文件包含给予pg_start_backup的标签、备份的起始与终止事务日志位置以及备份的起始和终止时间。返回值是备份的终止事务日志位置(同样也可以被忽略)。在记录结束位置之后,当前事务日志插入点被自动地推进到下一个事务日志文件,这样结束的事务日志文件可以立即被归档来结束备份。
pg_switch_xlog移动到下一个事务日志文件,允许当前文件被归档(假定你正在使用连续归档)。返回值是在甘冈完成的事务日志文件中结束事务日志位置 + 1。如果从上一次事务日志切换依赖没有事务日志活动,pg_switch_xlog不会做任何事情并且返回当前正在使用的事务日志文件的开始位置。
pg_create_restore_point创建一个命名事务日志记录,它可以被用作恢复目标,并且返回相应的事务日志位置。这个给定的名字可以用于recovery_target_name来指定恢复要进行到的点。避免使用同一个名称创建多个恢复点,因为恢复会停止在第一个匹配名称的恢复目标。
pg_current_xlog_location以上述函数所使用的相同格式显示当前事务日志的写位置。类似地,pg_current_xlog_insert_location显示当前事务日志插入点,而pg_current_xlog_flush_location显示当前事务日志的刷写点。在任何情况下,插入点是事务日志的"逻辑"终止点,而写入位置是已经实际从服务器内部缓冲区写出的日志的终止点,刷写位置则是被确保写入到持久存储中的日志的终止点。写入位置是可以从服务器外部检查的终止点,对那些关注归档部分完成事务日志文件的人来说,这就是他们需要的位置。插入和刷写点主要是为了服务器调试目的而存在的。这些都是只读操作并且不需要超级用户权限。
你可以使用pg_xlogfile_name_offset从任何上述函数的结果中抽取相应的事务日志文件名称以及字节偏移。例如:
postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
file_name | file_offset
--------------------------+-------------
00000001000000000000000D | 4039624
(1 row)
相似地,pg_xlogfile_name只抽取事务日志文件名。当给定的事务日志位置正好在一个事务日志文件的边界,这些函数都返回之前的事务日志文件的名称。这对管理事务日志归档行为通常是所希望的行为,因为前一个文件是当前需要被归档的最后一个文件。
pg_xlog_location_diff以字节数计算两个事务日志位置之间的差别。它可以和pg_stat_replication或Table 9-78中其他的函数一起使用来获得复制延迟。
26.4. 恢复控制函数
Table 9-79中展示的函数提供有关后备机当前状态的信息。这些函数可以在恢复或普通运行过程中被执行。
Table 9-79. 恢复信息函数
Table 9-80中展示的函数空值恢复的进程。这些函数只能在恢复过程中被执行。
Table 9-80. 恢复控制函数
在恢复被暂停时,不会有进一步的数据库改变被应用。如果在热备模式,所有新的查询将看到数据库的同一个一致快照,并且在恢复被继续之前不会有更多查询冲突会产生。
如果流复制被禁用,暂停状态可以无限制地继续而不出问题。在流复制进行时,WAL 记录将继续被接收,最后将会填满可用的磁盘空间,取决于暂停的持续时间、WAL 的产生率和可用的磁盘空间。
26.5. 快照同步函数
PostgreSQL允许数据库会话同步它们的快照。一个快照决定对于正在使用该快照的事务哪些数据是可见的。当两个或者更多个会话需要看到数据库中的相同内容时,就需要同步快照。如果两个会话独立开始其事务,就总是有可能有某个第三事务在两个START TRANSACTION命令的执行之间提交,这样其中一个会话就可以看到该事务的效果而另一个则看不到。
为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。
如Table 9-81中所示,快照通过pg_export_snapshot函数导出,并且通过SET TRANSACTION命令导入。
Table 9-81. 快照同步函数
在恢复被暂停时,不会有进一步的数据库改变被应用。如果在热备模式,所有新的查询将看到数据库的同一个一致快照,并且在恢复被继续之前不会有更多查询冲突会产生。
如果流复制被禁用,暂停状态可以无限制地继续而不出问题。在流复制进行时,WAL 记录将继续被接收,最后将会填满可用的磁盘空间,取决于暂停的持续时间、WAL 的产生率和可用的磁盘空间。
26.5. 快照同步函数
PostgreSQL允许数据库会话同步它们的快照。一个快照决定对于正在使用该快照的事务哪些数据是可见的。当两个或者更多个会话需要看到数据库中的相同内容时,就需要同步快照。如果两个会话独立开始其事务,就总是有可能有某个第三事务在两个START TRANSACTION命令的执行之间提交,这样其中一个会话就可以看到该事务的效果而另一个则看不到。
为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。
如Table 9-81中所示,快照通过pg_export_snapshot函数导出,并且通过SET TRANSACTION命令导入。
Table 9-81. 快照同步函数
函数pg_export_snapshot保存当前的快照并且返回一个text串标识该快照。该字符串必须被传递(到数据库外)给希望导入快照的客户端。直到导出快照的事务的末尾,快照都可以被导入。如果需要,一个事务可以导出多于一个快照。注意这样做只在 READ COMMITTED事务中有用,因为在REPEATABLE READ和更高隔离级别中,事务在它们的生命期中都使用同一个快照。一旦一个事务已经导出了任何快照,它不能使用PREPARE TRANSACTION。
关于如何使用一个已导出快照的细节请见SET TRANSACTION.
26.6. 复制函数
Table 9-82中展示的函数 用于控制以及与复制特性交互。这些函数只限于超级 用户使用。
很多这些函数在复制协议中都有等价的命令。
Table 9-82. 复制 SQL 函数
26.7. 数据库对象管理函数
Table 9-83中展示的函数计算数据库对象使用的磁盘空间。
Table 9-83. 数据库对象尺寸函数
pg_column_size显示用于存储任意独立数据值的空间。
pg_total_relation_size接受一个表或 TOAST 表的 OID 或名称,并返回该表所使用的总磁盘空间,包括所有相关的索引。这个函数等价于pg_table_size + pg_indexes_size。
pg_table_size接受一个表的 OID 或名称,并返回该表所需的磁盘空间,但是排除索引(TOAST 空间、空闲空间映射和可见性映射包含在内)
pg_indexes_size接受一个表的 OID 或名称,并返回附加到该表的所有索引所使用的全部磁盘空间。
pg_database_size和 pg_tablespace_size接受一个数据库或表空间的 OID 或 名称, 并且返回它们所使用的全部磁盘空间。要使用 pg_database_size,你必须具有在指定数据库上的 CONNECT权限(默认会被授予)。要使用 pg_tablespace_size,你必须具有指定表空间上的 CREATE权限,除非它是当前数据库的默认表空间。
pg_relation_size接受一个表、索引或 TOAST 表的 OID 或者名称,并且返回那个关系的一个分叉所占的磁盘空间的字节尺寸(注意 对于大部分目的,使用更高层的函数pg_total_relation_size 或者pg_table_size会更方便,它们会合计所有分叉的尺寸)。 如果只得到一个参数,它会返回该关系的主数据分叉的尺寸。提供第二个参数 可以指定要检查哪个分叉:
'main'返回该关系主数据分叉的尺寸。
'fsm'返回与该关系相关的空闲空间映射(见 Section 65.3)的尺寸。
'vm'返回与该关系相关的可见性映射(见 Section 65.4)的尺寸。
'init'返回与该关系相关的初始化分叉(如 果有)的尺寸。
pg_size_pretty可以用于把其它函数之一的结果格式化成一种人类易读的格式,可以根据情况使用字节、kB、MB、GB 或者 TB。
pg_size_bytes可以被用来从人类可读格式的字符串得到其中所表示的字节数。其输入可能带有的单位包括字节、kB、MB、GB 或者 TB,并且对输入进行解析时是区分大小写的。如果没有指定单位,会假定单位为字节。
Note: 函数pg_size_pretty和pg_size_bytes所使用的单位 kB、MB、GB 和 TB 是用 2 的幂而不是 10 的幂来定义,因此 1kB 是 1024 字节,1MB 是 10242 = 1048576 字节,以此类推。
上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。只写包围在单引号内的表名,这样它看起来像一个文字常量。为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。
如果一个 OID 不表示一个已有的对象并且被作为参数传递给了上述函数,将会返回 NULL。
Table 9-84中展示的函数帮助标识数据库对象相关的磁盘文件。
Table 9-84. 数据库对象定位函数
pg_relation_filenode接受一个表、索引、序列或 TOAST 表的 OID 或名称,返回当前分配给它的"filenode"号。文件结点是关系的文件名的基本组件。对于大多数表结果和pg_class.relfilenode相同,但是对于某些系统目录relfilenode为零,并且必须使用此函数获取正确的值。 如果传递一个没有存储的关系(如视图),此函数将返回 NULL。
pg_relation_filepath与pg_relation_filenode类似,但是它返回关系的整个文件路径名(相对于数据库集簇的数据目录PGDATA)。
pg_filenode_relation是pg_relation_filenode的反向函数。给定一个"tablespace" OID 以及一个 "filenode",它会返回相关关系的 OID。对于一个在数据库的默认表空间中的表,该表空间可以指定为 0。
26.8. 索引维护函数
Table 9-85展示了可用于 索引维护任务的函数。这些函数不能在恢复期间执行。只有超级用户以及给定索引的拥有者才能是用这些函数。
Table 9-85. 索引维护函数
brin_summarize_new_values接收一个 BRIN 索引的 OID 或者名称作为参数并且检查该索引以找到基表中当前还没有被该索引汇总的页面范围。对任意一个这样的范围,它将通过扫描那些表页面创建一个新的摘要索引元组。它会返回被插入到该索引的新页面范围摘要的数量。
gin_clean_pending_list接受一个 GIN 索引的 OID 或者名字,并且通过把指定索引的待处理列表中的项批量移动到主 GIN 数据结构来清理该索引的待处理列表。它会返回从待处理列表中移除的页数。注意如果其参数是一个禁用fastupdate选项构建的 GIN 索引,那么不会做清理并且返回值为 0,因为该索引根本没有待处理列表。
26.9. 通用文件访问函数
Table 9-86中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 只有那些在数据库集簇目录和log_directory目录中的文件可以访问。使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。只有超级用户才能使用这些函数。
Table 9-86. 通用文件访问函数
所有这些函数都有一个可选的missing_ok参数, 它指定文件或者目录不存在时的行为。如果为true, 函数会返回 NULL (pg_ls_dir除外,它返回一个空 结果集)。如果为false,则发生一个错误。默认是 false。
pg_ls_dir返回指定目录中所有文件(以及目录和其他特殊文件) 的名称。include_dot_dirs指示结果集中是否包括 "."和".."。默认是排除它们(false),但是 当missing_ok为true时把它们包括在内是 有用的,因为可以把一个空目录与一个不存在的目录区分开。
pg_read_file返回一个文本文件的一部分,从给定的offset开始,返回最多length字节(如果先到达文件末尾则会稍短)。如果offset为负,它相对于文件的末尾。如果offset和length被忽略,整个文件都被返回。从文件中读的字节被使用服务器编码解释成一个字符串;如果它们在编码中不合法则抛出一个错误。
pg_read_binary_file与pg_read_file相似,除了前者的结果是一个bytea值;相应地,不会执行编码检查。通过与convert_from函数结合,这个函数可以用来读取一个指定编码的文件:
SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8');
pg_stat_file返回一个记录,其中包含文件尺寸、最后访问时间戳、最后修改时间戳、最后文件状态改变时间戳(只支持 Unix 平台)、文件创建时间戳(只支持 Windows)和一个boolean指示它是否为目录。通常的用法包括:
SELECT * FROM pg_stat_file('filename');
SELECT (pg_stat_file('filename')).modification;
26.10. 咨询锁函数
Table 9-87中展示的函数管理咨询锁。
Table 9-87. 咨询锁函数
pg_advisory_lock锁住一个应用定义的资源,可以使用一个单一64位键值或两个32位键值标识(注意这些两个键空间不重叠)。如果另一个会话已经在同一个资源标识符上持有了一个锁,这个函数将等待直到该资源变成可用。该锁是排他的。多个锁请求会入栈,因此如果同一个资源被锁住三次,则它必须被解锁三次来被释放给其他会话使用。
pg_advisory_lock_shared的工作和pg_advisory_lock相同,不过该锁可以与其他请求共享锁的会话共享。只有想要排他的锁请求会被排除。
pg_try_advisory_lock与pg_advisory_lock相似,不过该函数将不会等待锁变为可用。它要么立刻获得锁并返回true,要么不能立即获得锁并返回false。
pg_try_advisory_lock_shared的工作和pg_try_advisory_lock相同,不过它尝试获得一个共享锁而不是一个排他锁。
pg_advisory_unlock将会释放之前获得的排他会话级别咨询锁。如果锁被成功释放,它返回true。如果锁没有被持有,它将返回false并且额外由服务器报告一个 SQL 警告。
pg_advisory_unlock_shared的工作和pg_advisory_unlock相同,除了它释放一个共享的会话级别咨询锁。
pg_advisory_unlock_all将释放当前会话所持有的所有会话级别咨询锁(这个函数隐式地在会话末尾被调用,即使客户端已经不雅地断开)。
pg_advisory_xact_lock的工作和pg_advisory_lock相同,不过锁是在当前事务的末尾被自动释放的并且不能被显式释放。
pg_advisory_xact_lock_shared的工作和pg_advisory_lock_shared相同,除了锁是在当前事务的末尾自动被释放的并且不能被显式释放。
pg_try_advisory_xact_lock的工作和pg_try_advisory_lock相同,不过锁(若果获得)是在当前事务的末尾被自动释放的并且不能被显式释放。
pg_try_advisory_xact_lock_shared的工作和pg_try_advisory_lock_shared相同,不过锁(若果获得)是在当前事务的末尾被自动释放的并且不能被显式释放。
27. 触发器函数
当前PostgreSQL提供一个内建的触发器函数suppress_redundant_updates_trigger, 它将阻止任何不会实际更改行中数据的更新发生,这与正常的行为不管数据是否改变始终执行更新相反(这是正常的行为,使得更新运行速度更快,因为不需要检查,并在某些情况下也是有用的)。
理想的情况下,你通常应该避免运行实际上并没有改变记录中数据的更新。 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。触发器需要很短但不能忽略的时间来处理每条记录,所以如果大多数被一个更新影响的记录确实被更改,此触发器的使用将实际上使更新运行得更慢。
suppress_redundant_updates_trigger函数可以像这样被加到一个表:
CREATE TRIGGER z_min_update
BEFORE UPDATE ON tablename
FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
在大部分情况下,你可能希望在最后为每行触发这个触发器。考虑到触发器是按照名字顺序被触发,你需要选择一个位于该表所有其他触发器之后的触发器名字。
28. 事件触发器函数
PostgreSQL提供了这些助手函数来从 事件触发器检索信息。
更多有关事件触发器的信息请见Chapter 38。
28.1. 在命令结束处捕捉更改
当在一个ddl_command_end事件触发器的函数中调用时, pg_event_trigger_ddl_commands返回被每一个用户动作 执行的DDL命令的列表。如果在其他任何环境中 调用这个函数,会发生错误。 pg_event_trigger_ddl_commands为每一个被执行的基本 命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 这个函数返回下面的列:
28.2. 处理被 DDL 命令删除的对象
pg_event_trigger_dropped_objects返回其sql_drop事件中命令所删除的所有对象的列表。如果在任何其他环境中被调用,pg_event_trigger_dropped_objects将抛出一个错误。pg_event_trigger_dropped_objects返回下列列:
pg_event_trigger_dropped_objects可以被这样用在一个事件触发器中:
CREATE FUNCTION test_event_trigger_for_drops()
RETURNS event_trigger LANGUAGE plpgsql AS
$$
DECLARE
obj record;
BEGIN
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
LOOP
RAISE NOTICE '% dropped object: % %.% %',
tg_tag,
obj.object_type,
obj.schema_name,
obj.object_name,
obj.object_identity;
END LOOP;
END
$$
;
CREATE EVENT TRIGGER test_event_trigger_for_drops
ON sql_drop
EXECUTE PROCEDURE test_event_trigger_for_drops();
28.3. 处理表重写事件
The functions shown in Table 9-88 中所示的函数提供刚刚被调用过table_rewrite 事件的表的信息。如果在任何其他环境中调用,会发生错误。
Table 9-88. 表重写信息
可以在一个这样的事件触发器中使用 pg_event_trigger_table_rewrite_oid函数:
CREATE FUNCTION test_event_trigger_table_rewrite_oid()
RETURNS event_trigger
LANGUAGE plpgsql AS
$$
BEGIN
RAISE NOTICE 'rewriting table % for reason %',
pg_event_trigger_table_rewrite_oid()::regclass,
pg_event_trigger_table_rewrite_reason();
END;
$$
;
CREATE EVENT TRIGGER test_table_rewrite_oid
ON table_rewrite
EXECUTE PROCEDURE test_event_trigger_table_rewrite_oid();
x ↩
xX ↩
使用 Replication Manager 迁移到CDP 私有云基础
这是CDH/HDP/Apache Hadoop迁移到CDP系列的第一篇博客,如对迁移感兴趣,请关注该系列博客。Replication Manager 可用于将 Hive、Impala 和 HDFS 工作负载迁移到 CDP私有云基础。功能Replication Manager 是一种用于在企业数据云内的环境之间复制和迁移数据的服务。它是一种简单、易于使用且功能丰富的数据移动功能,可将现有数据和元数据移动到云中,以推动新的工作负载。支持的场景· CDH 到CDP 私有云基础1. Replication Manager概述Cloudera Manager 提供了一个集成的、易于使用的管理解决方案,用于在 Hadoop 平台上启用数据保护。Replication Manager 使您能够跨数据中心复制数据以用于灾难恢复场景。复制可以包括存储在 HDFS 中的数据、存储在 Hive 表中的数据、Hive 元存储数据以及与在 Hive 元存储中注册的 Impala 表关联的 Impala 元数据(目录服务器元数据)。当关键数据存储在 HDFS 上时,Cloudera Manager 有助于确保数据始终可用,即使在数据中心完全关闭的情况下也是如此。对于Hbase数据,还可以使用 HBase shell 来进行复制。(Cloudera Manager目前不管理 HBase的复制。)Replication Manager 需要 Cloudera Enterprise 许可证。您还可以使用 Cloudera Manager 来安排、保存和恢复 HDFS 目录和 HBase 表的快照。在Cloudera Manager 管理控制台中Cloudera Manager提供如下关键功能:· 选择- 选择对您的业务运营至关重要的数据集。· 调度- 为数据复制和快照创建适当的调度。根据您的业务需求触发复制和快照。· 监控- 通过中央控制台跟踪快照和复制作业的进度,并轻松识别无法传输的问题或文件。· 警报- 在快照或复制作业失败或中止时发出警报,以便快速诊断问题。Replication Manager 在HDFS和 Hive 中始终如一地运行:· 您可以在 HDFS 的文件或目录以及 Hive 的外部表上设置它——无需手动将 Hive 数据集转换为 HDFS 数据集,反之亦然。Hive Metastore 信息也被复制。· 依赖于存储在 Hive 中的外部表定义的应用程序在表定义更新时对副本和源进行操作。· 在HDFS用户应该有权访问所有数据集Hive,包括所有操作。否则,Hive 导入会在复制过程中失败。要提供访问权限,请执行以下步骤:1. 登录Ranger管理界面2. 在hdfs中的Hadoop_SQL部分下提供对hdfs用户的 “ all-database, table, column ”权限。在实际复制整个数据集之前,您还可以执行“试运行(Dry run)”以验证配置并了解整体操作的成本。2. CDP 私有云基础上的 Replication Manager 支持矩阵支持列表包含 Replication Manager 中跨功能的兼容性信息。Replication Manager 支持 HDFS 和 Hive 数据复制。该矩阵还列出了 CDH、CDP Private Cloud Base 和 Cloudera Manager 版本支持的版本。功能支持的最低 Cloudera Manager 版本最低支持的 CDH 版本支持的服务复制Cloudera Manager 5.14+CDH 5.13+HDFS、Hive、Impala与 Amazon S3 之间的复制*Cloudera Manager 5.14+CDH 5.13+HDFS、Hive、Impala快照Cloudera Manager 5.15+CDH 5.15+HDFS、Hive、Impala与 Microsoft ADLS Gen1 之间的复制Cloudera Manager 5.15、5.16、6.1+CDH 5.13+HDFS、Hive、Impala复制到 Microsoft ADLS Gen2 (ABFS)Cloudera Manager 6.1+CDH 5.13+HDFS、Hive、Impala*当 S3 配置为使用 SSE-KMS 时,Replication Manager 不支持 S3 作为源或目标。Note从CDP Private Cloud Base 7.0.3 到 7.1.6(源集群版本)都支持 Replication Manager 服务。Cloudera Manager 版本将从 7.0.3 开始。从 Cloudera Manager 6.1.0 开始,Replication Manager 在复制期间忽略 Kudu 支持的 Hive 表。此变更不会影响功能,因为 Replication Manager 不支持 Kudu 支持的表。进行此更改是为了防止由于 Hive Mestastore、Impala 和 Kudu 的交互方式导致数据丢失。2.1. 支持的复制场景2.1.1. 版本要将数据复制到 Cloudera Manager 7.x 管理的集群,或者从Cloudera Manager 7.x 管理的集群中复制数据,源或目标集群必须由 Cloudera Manager 5.14+ 或更高的版本来管理。请注意,某些功能在 Cloudera Manager 5.14.0 及更高版本或Cloudera Manager 6.0.0 及更高版本中可能不可用。2.1.2. Kerberos在集群上使用 Kerberos 身份验证时,Replication Manager 支持以下复制方案:· 安全来源到安全目的地。· 不安全的源到不安全的目的地。· 不安全来源到安全目的地。请记住以下要求:o 在目标集群具有多个源集群的复制场景中,所有源集群必须是安全的或不安全的。Replication Manager 不支持从安全和不安全源集群的混合复制。o 目标集群必须运行 Cloudera Manager 7.x 或更高版本。o 源集群必须运行兼容的 Cloudera Manager 版本。o 这种复制方案需要额外的配置。有关更多信息,请参阅从不安全集群复制到安全集群。2.1.3. 云存储Replication Manager 支持与 Amazon S3、Microsoft Azure ADLS Gen1 和 Microsoft Azure ADLS Gen2 (ABFS) 之间的复制。2.1.4. 传输层安全 (TLS)您可以将 TLS 与 Replication Manager 结合使用。此外,Replication Manager 支持为非 Hadoop 服务(Hive/Impala)启用 TLS 和禁用 TLS Hadoop 服务(例如 HDFS、YARN 和 MapReduce)的复制场景。2.1.5. Sentry到Ranger复制使用 HDFS 和 Hive 复制策略时要执行 Sentry 到 Ranger 复制,您必须在源集群上安装 Cloudera Manager 版本 6.3.1 及更高版本,并在目标集群上安装 Cloudera Manager 版本 7.1.1 及更高版本。当源集群启用了 Sentry 并且您要运行HDFS 复制策略时,请使用hdfs用户运行复制策略。复制策略将复制的文件和表的权限复制到目标集群。要使用任何其他用户帐户,请确保将用户帐户配置为在复制期间绕过 Sentry ACL。创建 Hive 复制策略时,请选择适当的选项以确保将 Sentry 权限迁移到 Ranger 权限。Replication Manager使用 authzmigrator 工具在 Hive 复制期间将数据从 Sentry 移动到 Ranger。2.2. 不支持的复制方案2.2.1. 版本不支持Cloudera Manager 6 受管集群和 Cloudera Manager 5.14.0 之前版本的集群之间进行复制。Note不支持在 HDP 和 Cloudera Manager 7.x 之间进行复制。2.2.2. Hive 复制Replication Manager 不支持托管表到托管表的复制。它将托管表从源集群转换为CDP 私有云基础集群的外部表。Replication Manager 将复制的表存储为外部表。2.2.3. Kerberos在集群上使用 Kerberos 身份验证时,不支持从安全源到不安全目标的复制。2.2.4. Ranger不支持 Ranger 到Ranger 复制。2.2.5. Apache Knox如果 Cloudera Manager 配置了Knox,Replication Manager 将不起作用。3. Replication Manager 的端口要求确保以下端口在源主机上是开放的并可访问的,以允许Cloudera Manager 服务器与 HDFS、Hive、MapReduce 和 YARN 主机之间的源和目标进行通信。3.1. Replication Manager 的端口详细信息ServiceDefault PortCloudera Manager Admin Console HTTP7180Cloudera Manager Admin Console HTTPS (with TLS enabled)7183Cloudera Manager Agent9000HDFS NameNode8020Key Management Server (KMS)16000HDFS DataNode9866NameNode WebHDFS9870YARN Resource Manager8032DataNode Secure1004NameNode Secure WebHDFS9871Hive Metastore9083Impala Catalog Server260004. 数据复制在使用 Replication Manager 之前,您必须了解有关数据复制的一些要求。4.1. Cloudera 复制许可证要求您必须拥有对应的许可证才能在 Replication Manager 中执行您的任务。4.2. 复制包含数千个文件和子目录的目录在具有数千个文件和子目录的目录中复制数据之前,请在hadoop-env.sh 文件中增加heap size。1. 在目标Cloudera Manager 实例上,转到HDFS 服务页面。2. 单击配置选项卡。3. 展开 Scope,然后选择HDFS 服务名称(Service-Wide)选项。4. 展开CategoryAdvanced并选择 Advanced。5. 找到HDFS Replication Environment Advanced Configuration Snippet (Safety Valve) for hadoop-env.sh属性6. 通过添加键值对来增加堆大小,例如: HADOOP_CLIENT_OPTS=-Xmx1g。在此示例中,1g将堆大小设置为 1 GB。此值应根据要复制的文件和目录的数量进行调整。7. 输入更改原因,然后单击保存更改以提交更改。4.3. Replication Manager日志保留默认情况下,Cloudera Manager 会将 Replication Manager 日志保留 90 天。您可以更改 Cloudera Manager 保留日志的天数或完全禁用日志保留。1. 转到Cloudera Manager > HDFS >配置部分。2. 在Cloudera Manager 管理控制台中,搜索以下属性:Backup and Disaster Log Retention.3. 输入要保留日志的天数。要禁用日志保留,请输入 -1。重要自动日志过期也会清除自定义设置的复制日志和元数据文件。这些路径由日志路径和目录设置,用于根据调度字段显示在 UI 上的元数据参数。用户有责任设置有效路径(例如,指定当前用户可写的合法 HDFS 路径)并为每个复制策略维护此信息。4.4. 从不安全集群复制到安全集群您可以使用 Replication Manager 将数据从不安全的集群(不使用 Kerberos 身份验证)复制到安全集群(使用 Kerberos 的集群)。请注意,反过来是不正确的。Replication Manager 不支持从安全集群复制到不安全集群。要执行复制,目标集群必须由 Cloudera Manager 6.1.0 或更高的版本进行管理。源集群必须运行 Cloudera Manager 5.14.0 或更高版本才能复制到 Cloudera Manager 6。Note在目标集群有多个源集群的复制场景中,所有源集群必须是安全的或不安全的。Replication Manager 不支持从安全和不安全源集群的混合复制。要启用从不安全集群到安全集群的复制,您需要在源集群和目标集群的所有主机上都存在一个用户。创建复制调度时,在Run As Username字段中指定此用户。1. 在源或目标集群中的主机上,使用以下命令添加用户:sudo -u hdfs hdfs dfs -mkdir -p /user/<username>例如,以下命令创建一个名为 milton 的用户:sudo -u hdfs hdfs dfs -mkdir -p /user/milton2. 使用以下命令设置用户目录的权限:sudo -u hdfs hdfs dfs -chown <username> /user/username例如,以下命令使 milton 成为 milton 目录的所有者:sudo -u hdfs hdfs dfs -chown milton /user/milton3. 使用以下命令为您在步骤1 中创建的用户创建supergroup组:groupadd supergroup4. 将您在步骤1 中创建的用户添加到您创建的组中:usermod -G supergroup <username>例如,将 milton 添加到名为 supergroup 的组中:usermod -G supergroup milton5. 对源和目标集群中的所有主机重复此过程,以便用户和组存在于所有主机上。完成此过程后,请在创建复制策略时在Run As Username字段中指定您创建的用户。5. 指定复制源您必须分配源集群来复制数据。最低要求角色: 集群管理员 (也由完全管理员提供)。您登录的 Cloudera Manager Server 是使用该 Cloudera Manager 实例设置的复制目标。在此目标 Cloudera Manager 实例的管理控制台中,您可以指定peer Cloudera Manager Server 作为 HDFS 和 Apache Hive 数据来源进行复制。5.1. 配置peer关系您必须将 Cloudera Manager 与peer连接,然后测试连接。如果您的集群使用 SAML 身份验证,请参阅在配置peer之前使用 SAML 身份验证配置peer。1. 在Cloudera Manager 中,选择左侧导航栏中的复制>peer。如果没有现有的peer,除了一条短消息之外,您只会看到一个添加peer点按钮。如果peer已存在,则它们会显示在“peer”列表中。2. 单击添加peer。3. 在“添加peer”对话框中,提供名称、要复制的数据的Cloudera Manager 服务器源的peer URL(包括端口)以及该服务器的登录凭据。重要分配给源服务器上的登录名的角色必须是用户管理员或完全管理员。Cloudera 建议使用 TLS/SSL。如果 URL 方案是 http 而不是 https,则会显示警告。将两个peer配置为使用 TLS/SSL 后,将远程源 Cloudera Manager TLS/SSL 证书添加到本地 Cloudera Manager 信任库,反之亦然。4. 单击对话框中的添加按钮以创建peer关系。peer被添加到peer列表中。Cloudera Manager 会自动测试 Cloudera Manager Server 和peer之间的连接。您也可以单击测试连接来测试连接。测试连接还测试集群的 Kerberos 配置。5.2. 修改peer您可以修改或删除peer。1. 要编辑peer,请选择peer点并单击操作>编辑。2. 进行更改。3. 单击更新peer以保存更改。4. 要删除peer,请选择peer并单击操作>删除。5.3. 使用 SAML 身份验证配置peer如果您的集群使用SAML 身份验证,请在创建peer点之前执行以下操作。1. 创建具有用户管理员或完全管理员角色的Cloudera Manager 用户帐户。您还可以使用具有这些角色之一的现有用户。由于您只会使用此用户来创建peer关系,因此您可以在添加peer后删除该用户帐户。2. 创建或修改peer。3. 删除刚刚创建的Cloudera Manager 用户帐户。6. HDFS 复制策略本节讨论与 HDFS 数据相关的复制。最低要求角色: 复制管理员(也由完全管理员提供)HDFS 复制使您能够将 HDFS 数据从一个 HDFS 服务复制到另一个服务,根据指定的复制策略将源服务上的数据集与目标服务上的数据集 同步。其中:目标服务必须由Cloudera Manager Server 管理,通过CM设置复制,而源服务可以由同一服务器或peer Cloudera Manager Server 管理。您还可以通过指定不同的源目录和目标目录来复制集群内的 HDFS 数据。远程的Replication Manager在复制文件时自动将 HDFS 元数据复制到目标集群。HDFS 元数据只需要在本地备份。6.1. 源数据当复制作业运行时,请确保源目录未被修改。复制期间添加的文件不会被复制。如果在复制期间删除文件,复制将失败。此外,确保目录中的所有文件都已关闭。如果源文件打开,复制将失败。如果您不能确保关闭所有源文件,您可以将复制配置为在出现错误的情况下继续进行。取消选中HDFS 复制的Abort on Error选项。复制完成后,您可以查看复制日志以识别打开的文件。确保在下一次复制之前关闭这些文件。6.2. 网络延迟和复制集群之间的高延迟会导致复制作业运行得更慢,但不会导致它们失败。为获得最佳性能,源集群 NameNode 和目标集群 NameNode 之间的延迟应小于 80 毫秒。(您可以使用Linux ping命令测试延迟 )。在延迟高达 360 毫秒时,Cloudera 已成功测试了的复制。随着延迟的增加,复制性能会下降。6.3. 性能和可扩展性限制HDFS 复制有一些限制。· 单个复制作业的最大文件数:1 亿。· 运行频率超过 8 小时一次的复制策略支持的最大文件数:1000 万。· 复制作业的吞吐量取决于源集群和目标集群的绝对读写吞吐量。· 需要定期重新平衡您的 HDFS 集群,以实现高效的复制操作。NoteCloudera Manager 提供可用于诊断 HDFS 复制性能的可下载数据。6.4. 从启用 Sentry 的集群进行 HDFS 复制在启用 Sentry 的源集群上运行 HDFS 复制策略时,复制策略可以复制文件和表及其权限。需要 Cloudera Manager 6.3.1 及更高版本才能在启用 Sentry 的源集群上运行 HDFS 复制策略。当您要在启用 Sentry 的源集群上运行 HDFS 复制策略时,您必须使用hdfs用户。如果要使用不同的用户帐户,则必须配置用户帐户以在复制过程中绕过 Sentry ACL。当 Sentry 不可用或 Sentry 不管理资源(如源集群中的文件或目录)的授权时,HDFS 使用其内部 ACL 来管理资源授权。当源集群启用了 Sentry 并且您使用hdfs用户名运行 HDFS 复制策略时,HDFS 会将 Sentry 中为复制的文件和表配置的 ACL 复制到目标集群。当启用 Sentry 并且您使用不同的用户名运行 HDFS 复制策略时,Sentry ACL 和 HDFS 内部 ACL 都会被复制,这会导致目标集群中的 HDFS 元数据不正确。如果 Sentry ACL 与 HDFS ACL 不兼容,则复制作业将失败。为避免非hdfs 用户的HDFS 和 Sentry ACL 之间的兼容性问题,您必须完成以下步骤:1. 创建一个仅用于Replication Manager作业的用户帐户,因为此用户将绕过 Sentry ACL。例如,创建一个名为bdr-only-user 的用户。2. 要在复制期间绕过Sentry ACL,请在源集群上执行以下步骤:a. 在Cloudera Manager 管理控制台中,选择Clusters > <HDFS service>。b. 选择配置并搜索以下属性:NameNode Advanced Configuration Snippet (Safety Valve) for hdfs-site.xml.c. 添加以下属性: Name - dfs.namenode.inode.attributes.provider.bypass.users Value - 输入[***USERNAME, USERNAME@REALMNAME***],其中[***USERNAME***] 是用户您在步骤 1 中创建的 [***REALMNAME***] 是 Kerberos 领域名称。例如,如果在Realm上的用户名是bdr-only-user,则输入bdr-only-user, bdr-only-user@ElephantRealm。d. 重新启动NameNode。3. 在目标集群上重复步骤2。创建HDFS 复制策略时,请在“Run As Username”和“Run on Peer as Username”(如果可用)字段中指定您在步骤 1 中创建的用户。Note在运行所用用户名字段被用来发动MapReduce工作拷贝数据。 Run on Peer as Username字段用于在源上运行副本列表,如果与Run as Username不同。重要确保将Run on Peer的值设置为Username与Run as Username相同,否则 Replication Manager 从源读取 ACL 作为hdfs,它将 Sentry 提供的 ACL 拉到目标集群并将它们应用到 HDFS 中的文件。它可能导致在目标集群中额外使用 NameNode 堆。6.5. 基于快照差异的复制指南默认情况下,Replication Manager 使用快照差异(“diff”)通过比较 HDFS 快照并仅复制源目录中更改的文件来提高性能。虽然 Hive 元数据需要完整复制,但存储在 Hive 表中的数据可以利用基于快照差异的复制。要使用此功能,请遵循以下准则:· 源和目标集群必须由 Cloudera Manager 5.15.0 或更高版本管理。· 源和目标集群运行 CDH 5.15.0 或更高版本、5.14.2 或更高版本或 5.13.3 或更高版本。· 验证 HDFS 快照是不可变的。在 Cloudera Manager 管理控制台中,转到Clusters > HDFS service > Configuration部分并搜索Enable Immutable Snapshots。· 不要对全局路径使用快照差异。它没有针对全局路径进行优化。· 将快照根目录在层次结构中设置得尽可能低。· 要使用快照差异功能,配置为运行作业的用户需要是超级用户或快照根目录的所有者,因为他们 run-as-user必须具有列出快照的权限。· 决定您是希望 Replication Manager 在快照差异失败时中止还是继续复制。如果您选择将 Replication Manager 配置为在遇到错误时继续复制,Replication Manager 将执行完整的复制。请注意,由于执行完整复制,因此继续复制可能会导致更长的持续时间。· 当以下一项或多项更改时,Replication Manager 执行完整复制:删除策略、保留策略、目标路径或排除路径。· 从路径两者中复制策略的源和目的地簇必须是snapshottable根目录下或应snapshottable为策略来使用快照的diff运行。· 如果源数据包含加密子目录,请在复制策略中创建排除正则表达式以在复制期间排除该子目录。创建另一个复制策略来复制加密的子目录。这是因为,如果源数据中存在加密的子目录,则基于快照差异的复制可能会失败。· 如果创建 Hive 复制策略来复制数据库,请确保该数据库中表的所有 HDFS 路径都是快照表或位于快照表根目录下。例如,如果正在复制的数据库具有外部表,则所有外部表 HDFS 数据位置也应该是可快照的。否则可能会导致Replication Manager无法生成差异报告。如果没有差异报告,Replication Manager 不使用快照差异。· 每次复制后,Replication Manager 都会在源集群上保留一个快照。使用源集群上的快照副本,Replication Manager 为下一个复制周期执行增量备份。只有在以下情况下,Replication Manager 才会在源集群上保留快照:o Cloudera Manager 中的源和目标集群为 5.15 及更高版本o 源和目标 CDH 分别为 5.13.3+、5.14.2+ 和 5.15+6.6. 配置 HDFS 数据的复制在调度 HDFS 数据复制之前,您必须设置集群。1. 验证您的集群是否符合支持的复制方案之一。2. 如果您对源集群和目标集群使用不同的Kerberos 主体,请将目标主体添加为源集群上的代理用户。例如,如果您使用hdfssrc源集群上的hdfsdest主体和目标集群上的主体,请将以下属性添加到源 集群上core-site.xml属性的 HDFS 服务集群范围高级配置片段(安全阀):<property>
<name>hadoop.proxyuser.hdfsdest.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hdfsdest.hosts</name>
<value>*</value>
</property>如果源集群由与目标集群不同的 Cloudera Manager 服务器管理,则部署客户端配置并重新启动源集群上的所有服务。3. 从Cloudera Manager >复制>复制策略页面,单击创建复制策略。4. 选择HDFS复制策略。出现 创建 HDFS 复制策略 对话框。5. 选择 常规 选项卡以配置以下内容:a. 单击 名称 字段并为复制策略添加唯一名称。b. 单击 源 字段并选择源 HDFS 服务。您可以选择由peer Cloudera Manager Server 管理的HDFS 服务、本地HDFS 服务(由您登录的管理控制台的Cloudera Manager Server 管理)。c. 输入 要复制的目录(或文件)的 源路径。d. 单击目标字段并从您登录的管理控制台的Cloudera Manager Server 管理的HDFS 服务中选择目标HDFS 服务。e. 输入应保存源文件的目标路径。f.选择一个时间表:§ 立即-立即运行调度。§ 一次- 在未来运行一次调度。设置日期和时间。§ 重复- 将来定期运行调度。设置日期、时间和运行间隔。g. 在用户名运行字段中输入运行复制作业的用户。默认情况下,这是hdfs. 如果要以其他用户身份运行作业,请在此处输入用户名。如果您使用的是Kerberos,您必须在此处提供一个用户名,并且必须是一个ID大于1000的用户名。(您也可以通过YARN或MapReduce服务中的min.user.id属性来配置最小用户ID号.) 验证运行该作业的用户是否有一个主目录/user/username,在HDFS 中由username:supergroup 拥有。此用户必须具有从源目录读取和写入目标目录的权限。请注意以下事项:§ 用户不得出现在 YARN 配置中使用禁止系统用户属性指定的禁止用户列表中(转到 YARN 服务,选择配置选项卡并搜索属性)。出于安全考虑,默认情况下禁止 hdfs 用户运行 YARN 容器。§ 通过将用户添加到由“允许的系统用户”属性指定的用户“白名单”,可以覆盖对大于 1000 的用户 ID 的要求。(转到 YARN 服务,选择配置选项卡并搜索属性。)6. 选择“资源”选项卡以配置以下内容:a. 调度程序池- (可选)在字段中输入资源池的名称。您输入的值由您在 Cloudera Manager 为复制执行 MapReduce 作业时指定的MapReduce 服务使用。作业使用以下属性之一指定值:§ § MapReduce – 公平调度程序: mapred.fairscheduler.pool§ MapReduce – 容量调度程序: 队列名称§ Yarn – mapreduce.job.queuenameb. 最大Map槽数- 每个映射器的Map槽数限制。默认值为 20。c. 最大带宽- 每个Map的带宽限制。默认值为 100 MB。d. 复制策略- 文件复制任务应该静态还是动态地分布在映射器之间。(默认为Dynamic。)静态复制预先 在映射器之间分配文件复制任务,以实现基于文件大小的统一分配。动态复制将文件复制任务以小集合分配给映射器,当每个映射器完成其任务时,它会动态获取并处理下一组未分配的任务。7. 选择高级选项选项卡,配置以下内容:a. 添加排除单击链接以从复制中排除一个或多个路径。将显示基于正则表达式的路径排除字段,您可以在其中输入基于正则表达式的路径。添加排除项时,请包括正则表达式的快照相对路径。例如,要排除 /user/bdr目录,请使用以下正则表达式,其中包括bdr目录的快照:.*/user/\.snapshot/.+/bdr.*要从全局源路径中的复制中排除顶级目录,您可以指定正则表达式的相对路径而不包括 .snapshot在路径中。例如,bdr要从复制中排除 目录,请使用以下正则表达式:.*/user+/bdr.*Note当您设置路径排除过滤器(并将删除策略设置为删除)时,目标集群上的路径应该保持不变。但是,当前的行为是,即使目录/文件与排除过滤器匹配,也会在目标集群上删除它们。您可以添加多个要排除的正则表达式。b. § MapReduce服务- 要使用的 MapReduce 或 YARN 服务。§ 日志路径-日志的备用路径。§ 描述- 复制策略的描述。§ 错误处理- 您可以选择以下内容:§ 跳过校验和检查- 是否跳过对复制文件的校验和检查。如果选中,则不会验证校验和。默认情况下检查校验和。重要的在以下情况下,您必须跳过校验和检查以防止由于校验和不匹配而导致复制失败:§ 从源集群上的加密区域复制到目标集群上的加密区域。§ 从源集群上的加密区域复制到目标集群上的未加密区域。§ 从源集群上的未加密区域复制到目标集群上的加密区域。校验和有两个用途:§ 跳过已复制文件的复制。如果选择Skip Checksum Checks,如果源集群和目标集群之间的文件长度和修改时间相同,则复制作业将跳过复制文件。否则,作业会将文件从源复制到目标。§ 冗余验证数据的完整性。但是,不需要校验和来保证集群之间的准确传输。HDFS 数据传输在传输过程中受校验和保护,存储硬件也使用校验和来确保数据被准确存储。这两种机制协同工作以验证复制数据的完整性。§ 跳过列表校验和检查- 在比较两个文件以确定它们是否相同时是否跳过校验和检查。如果跳过,则使用文件大小和上次修改时间来确定文件是否相同。跳过检查可提高映射器阶段的性能。请注意,如果您选择跳过校验和检查选项,也会跳过此检查。§ Abort on Error - 是否在出现错误时中止作业。如果选中,则复制到该点的文件将保留在目标上,但不会复制其他文件。默认情况下,错误中止是关闭的。§ 在快照差异失败时中止- 如果快照差异在复制期间失败,Replication Manager 使用完整副本来复制数据。如果选择此选项,Replication Manager 会在遇到错误时中止复制。c. 保留- 是保留源文件系统上存在的块大小、复制计数、权限(包括 ACL)和扩展属性 (XAttrs),还是使用目标文件系统上配置的设置。默认情况下会保留源系统设置。当Permission被选中并且源和目标集群都支持 ACL 时,复制会保留 ACL。否则,不会复制 ACL。当扩展属性检查,并且源和目标集群都支持扩展属性,复制保留它们。(此选项仅在源集群和目标集群都支持扩展属性时显示。)Note要保留对 HDFS 的权限,您必须以超级用户身份在目标集群上运行 。使用“以用户名运行”选项来确保是这种情况。d. 删除策略- 在源上删除的文件是否也应从目标目录中删除。此策略还确定目标位置中与源无关的文件的处理方式。选项包括:§ § 保留已删除的文件- 保留目标文件,即使它们在源中不再存在。(这是默认设置。)。§ 删除到垃圾箱- 如果启用了 HDFS 垃圾箱,文件将移动到垃圾箱文件夹。§ 永久删除- 使用最少的空间;谨慎使用。此选项不会删除顶级目录中的文件和目录。这符合 rsync/Hadoop DistCp 行为。e. 警报- 是否为复制工作流中的各种状态变化生成警报。您可以在失败、启动、成功或复制工作流中止时发出警报。8. 单击保存策略。复制任务现在在复制策略 表中显示为一行。(任务最多可能需要 15 秒才能出现。)如果您在Schedule字段中选择 Immediate,则在您单击Save Policy时复制作业开始运行。要指定其他复制任务,请选择Create > HDFS Replication。Note如果您的复制作业需要很长时间才能完成,并且在复制完成之前文件已更改,则复制可能会失败。考虑将目录设为可快照,以便复制作业在复制文件之前创建目录的快照,然后在执行复制时从这些可快照目录中复制文件。6.7. 限制复制主机如果您的集群在资源有限的主机上安装了客户端,HDFS 复制可能会使用这些主机来运行复制命令,这可能会导致性能下降。您可以通过指定 DataNode 主机的“白名单”来限制 HDFS 复制仅在选定的 DataNode 上运行。1. 单击集群> HDFS 服务>配置。2. 键入HDFS Replication搜索框。3. 找到HDFS 复制环境高级配置片段(安全阀)属性。4. 添加HOST_WHITELIST 属性。输入以逗号分隔的DataNode 主机名列表以用于HDFS 复制。例如:HOST_WHITELIST=host-1.mycompany.com,host-2.mycompany.com5. 单击保存更改以提交更改。6.8. 查看复制策略“复制策略”页面显示有关每个调度复制作业的一行信息。每行还显示有关上次运行复制作业的最新消息。图 1.复制策略表一次只能发生一个与复制策略对应的作业;如果与同一复制策略关联的另一个作业在前一个作业完成之前启动,则取消第二个作业。您可以通过选择左侧的过滤器来限制显示的复制作业。如果您没有看到预期的策略,请调整或清除过滤器。使用搜索框搜索路径、数据库或表名称的策略列表。的复制策略列在下表中进行了描述。表 1.复制策略表字段描述ID内部生成的 ID 号,用于标识策略。提供一种方便的方式来识别策略。单击ID列标签可按ID对复制策略表进行排序。姓名您在创建策略时指定的唯一名称。类型复制策略的类型,HDFS 或 Hive。来源复制的源集群。目的地复制的目标集群。吞吐量写入的所有文件的每个映射器/文件的平均吞吐量。请注意,吞吐量不包括以下信息:所有映射器的总吞吐量以及文件写入后对文件执行校验和所花费的时间。进度复制的进度。完成复制作业完成的时间。单击已完成 列标签以按时间对复制策略表进行排序。下一次运行根据为策略指定的调度参数,调度下一次复制的日期和时间。将鼠标悬停在日期上可查看有关调度复制的其他详细信息。单击上次运行列标签以按上次运行日期对复制策略表进行排序。行动“操作” 按钮提供以下项目:·显示历史记录- 打开复制历史记录页面以进行复制。·编辑配置- 打开编辑复制策略页面。·Dry Run - 模拟复制任务的运行,但实际上并不复制任何文件或表。试运行后,您可以选择 Show History,这将打开Replication History页面,您可以在其中查看任何错误消息以及将在实际复制中复制的文件或表的数量和大小。·立即运行 -立即运行复制任务。·单击收集诊断数据以打开发送诊断数据屏幕,该屏幕允许您收集策略的最后 10 次运行的特定于复制的诊断数据:1. 选择将诊断数据发送到 Cloudera以自动将包发送到 Cloudera 支持。您还可以在发送捆绑包时输入票号和评论。2. 单击收集并发送诊断数据以生成包并打开复制诊断命令屏幕。3. 命令完成后,单击下载结果数据以下载包含捆绑包的 zip 文件。·禁用 | 启用- 禁用或启用复制策略。没有为禁用的复制策略安排进一步的复制。·删除- 删除策略。删除复制策略不会删除复制的文件或表。· 当作业正在进行时,“上次运行”列会显示一个微调器和进度条,并且在作业所在行下方的消息中指示复制任务的每个阶段。单击命令详细信息链接以查看有关命令执行的详细信息。· 如果作业成功,则会指示复制的文件数。如果自上一个作业以来源文件没有更改,则不会复制该文件。因此,在初始作业之后,实际上可能只复制文件的一个子集,这会在成功消息中指示。· 如果作业失败,则显示图标。· 要查看有关已完成作业的更多信息,请选择操作>显示历史记录。6.9. 查看复制历史您可以在“复制历史”页面上查看有关复制作业的历史详细信息。6.9.1. 要查看复制作业的历史记录:1. 从Cloudera Manager 中,选择复制>复制策略。将显示可用复制策略的列表。2. 找到作业所在的行,选择相同的行,然后单击操作>显示历史记录。“复制历史记录”页面出现,其中包含作业信息。图 1.复制历史屏幕(HDFS)6.9.2. 复制历史表“复制历史记录”页面显示以前运行的复制作业的表格,其中包含以下列:字段描述开始时间显示有关作业的详细信息。您可以展开该部分以查看以下作业详细信息:\·开始时间 - 显示复制作业开始的时间。·持续时间 - 显示完成作业的持续时间。·命令详细信息 - 单击查看后在新选项卡中显示命令详细信息 。该命令详细信息 页显示有关命令运行过程中每一步的细节和信息。在此页面上,单击“上下文”可以查看与命令相关的服务状态页面,然后单击“下载”将摘要下载为 JSON 文件。要查看命令详细信息,请展开 Step部分,然后选择Show All Steps、Show Only Failed Steps或 Show Only Running Steps。在本节中,您可以执行以下任务:o 查看实际的命令字符串。o 查看命令的开始时间和持续时间。o 单击上下文链接可查看与命令相关的服务状态页面。o 选择选项卡之一以查看命令的角色日志、 标准输出和标准错误。查看正在运行和最近的命令·MapReduce 作业。点击链接查看职位详情。·HDS 复制报告。单击下载 CSV 以查看以下选项:o 列表- 单击以下载包含复制报告的 CSV 文件。该文件列出了在复制作业期间复制的文件和目录的列表。o 状态- 单击可下载包含完整状态报告的 CSV 文件。该文件包含文件的完整状态报告,其中复制状态为以下之一:§ ERROR – 发生错误,文件未复制。§ DELETED – 已删除的文件。§ SKIPPED – 跳过复制的文件,因为它是最新的。o 仅错误状态- 单击可下载包含所有复制文件的状态报告的 CSV 文件,其中包含错误。该文件列出了已复制文件的状态、路径和错误消息。o 仅已删除状态- 单击可下载包含所有已删除文件的状态报告的 CSV 文件。该文件列出了已删除数据库和表的状态、路径和消息。o 仅跳过状态- 单击可下载包含所有跳过文件的状态报告的 CSV 文件。该文件列出了被跳过的数据库和表的状态、路径和消息。o 性能- 单击可下载 CSV 文件,其中包含有关正在运行的复制作业的性能的摘要报告。性能摘要报告包括正在处理复制作业的每个映射器的最后一个性能示例。o 完整性能- 单击可下载包含作业性能报告的 CSV 文件。性能报告显示在复制作业完全执行期间为所有映射器采集的样本。·(仅限试运行)查看可复制文件的数量。显示实际复制期间将复制的文件数。·(仅限试运行)查看可复制字节数。显示在实际复制期间将复制的字节数。·查看复制的 Impala UDF 的数量。(仅对选择了复制 Impala 元数据的 Hive/Impala 复制显示。)·如果创建复制作业时在用户运行身份字段中指定了用户,则会显示所选用户。·查看从复制作业返回的消息。期间完成复制作业所需的时间。结果指示复制作业的状态为成功或失败。预期文件预期复制的文件数及其文件大小基于复制策略的参数。复制的文件复制作业的复制文件数及其文件大小。文件失败复制作业复制失败的文件数及其文件大小。文件已删除已删除的文件数及其复制作业的文件大小跳过的文件复制作业跳过的文件数及其文件大小。复制过程会跳过目标中已存在且未更改的文件。6.10. 监控 HDFS 复制的性能您可以使用从 Cloudera Manager 管理控制台下载为 CSV 文件的性能数据来监控 HDFS 复制策略的进度。此文件包含有关正在复制的文件、平均吞吐量和其他有助于诊断 HDFS 复制期间性能问题的详细信息的信息。您可以查看运行 HDFS 复制作业和已完成作业的性能数据。查看正在运行的HDFS 复制策略的性能数据。1. 从Cloudera Manager 中,选择复制>复制策略。2. 选择策略,然后单击操作>显示历史记录。3. 单击下载CSV,然后选择以下选项之一以查看性能报告:o 性能 - 单击可下载包含有关复制作业性能的摘要报告的 CSV 文件。性能摘要报告包括正在处理复制作业的每个映射器的最后一个性能示例。o 完整性能 - 单击可下载包含作业性能报告的 CSV 文件。完整的性能报告包括在复制作业完全执行期间为所有映射器采集的所有样本。4. 要查看数据,请在电子表格程序(如Microsoft Excel)中打开文件。查看已完成的HDFS 复制策略的性能数据:表 1. HDFS 性能报告列性能数据列描述时间戳收集性能数据的时间主持人运行 YARN 或 MapReduce 作业的主机的名称。复制的字节数为当前正在复制的文件复制的字节数。已用时间(毫秒)当前正在复制的文件的复制操作所用的总时间(以毫秒为单位)。复制的文件复制的文件数。平均吞吐量 (KB/s)自当前正在复制的文件开始以来的平均吞吐量(以千字节/秒为单位)。最后一个文件(字节)最后一个文件的文件大小(以字节为单位)。最后文件时间(毫秒)以毫秒为单位复制最后一个文件所花费的时间。上次文件吞吐量 (KB/s)自上一个文件开始复制以来的吞吐量(以千字节/秒为单位)。除了性能报告之外,您还可以查看错误文件、删除的文件和复制作业期间跳过的文件的报告。要查看报告,请执行以下步骤:· 在复制策略页面上,选择策略并单击操作>显示历史记录。出现复制策略的复制历史页面。展开以查看复制作业详细信息。· 单击下载 CSV以获取以下选项:· o 列表- 单击以下载包含复制报告的 CSV 文件。该文件列出了在复制作业期间复制的文件和目录的列表。o 状态- 单击可下载包含完整状态报告的 CSV 文件。该文件包含文件的完整状态报告,其中复制状态为以下之一:§ ERROR – 发生错误,文件未复制。§ DELETED – 已删除的文件。§ SKIPPED – 跳过复制的文件,因为它是最新的。o 仅错误状态- 单击可下载包含所有复制文件的状态报告的 CSV 文件,其中包含错误。该文件列出了已复制文件的状态、路径和错误消息。o 仅已删除状态- 单击可下载包含所有已删除文件的状态报告的 CSV 文件。该文件列出了已删除数据库和表的状态、路径和消息。o 仅跳过状态- 单击可下载包含所有跳过文件的状态报告的 CSV 文件。该文件列出了被跳过的数据库和表的状态、路径和消息。o 性能- 单击可下载 CSV 文件,其中包含有关正在运行的复制作业的性能的摘要报告。性能摘要报告包括正在处理复制作业的每个映射器的最后一个性能示例。o 完整性能- 单击可下载包含作业性能报告的 CSV 文件。性能报告显示在复制作业完全执行期间为所有映射器采集的样本。要查看数据,请在电子表格程序(如 Microsoft Excel)中打开文件。每两分钟收集一次性能数据。因此,在复制作业的初始执行期间没有可用的数据,因为没有足够的样本来估计吞吐量和其他报告的数据。在 Excel 中显示的示例 CSV 文件如下所示:请注意以下限制和已知问题:· 如果您在复制作业开始后过早单击 CSV 下载,Cloudera Manager 将返回一个空文件或一个仅包含列标题的 CSV 文件,并在实际收集性能数据后稍后尝试。· 如果您使用表单使用代理用户 用户@域,无法通过链接获得性能数据。· 如果复制作业只复制可以在不到几分钟内传输的小文件,则不会收集性能统计信息。· 对于指定动态复制策略的复制策略,有关 MapReduce 作业传输的最后一个文件的统计信息隐藏了该 MapReduce 作业执行的先前传输。· CSV 文件中仅报告每个 MapReduce 作业的最后一次跟踪。原文链接:https://docs.cloudera.com/cdp-private-cloud-upgrade/latest/data-migration/topics/rm-dc-hdfs-replication.html7. Hive/Impala复制策略Hive/Impala 复制使您能够根据指定的复制策略将 Hive 元存储和数据从一个集群复制(复制)到另一个集群,并将目标集群上的 Hive 元存储和数据集与源集群同步 。最低要求角色: 复制管理员(也由完全管理员提供)目标集群必须由设置复制的 Cloudera Manager Server 管理,源集群可以由同一服务器或Peer Cloudera Manager Server 管理。笔记由于 CDH 集群和 CDP-PvC Base 之间的仓库目录更改,Hive 复制不会从源集群中指定的数据库和表中复制表数据。但是复制作业成功运行而没有任何中断。在从 CDH 集群复制到 CDP-PVC BASE 时,建议 定义HDFS目标路径。如果未定义 HDFS 目标路径且 复制HDFS 文件 设置为 true,则使用原始源名称复制数据。例如,复制的表数据驻留在 /warehouse/tablespace/external/hive目录下,但数据被复制到 /user/hive/warehouse地点。此外, 在复制过程之前不定义 HDFS 目标路径可能会导致大量 HDFS 空间用于不需要的数据移动。重要的由于 Hive3 具有不同的默认表类型和仓库目录结构,因此在将 Hive 数据从 CDH5 或 CDH6 版本复制到 CDP-PVC BASE 时适用以下更改:· 在 Hive 复制期间,所有表都成为外部表。这是因为 Hive3 中的默认表类型是 ACID,这是唯一的托管表类型。在此版本中,BDR 不支持Hive2 -> Hive3复制到 ACID 表中,并且所有表都必须作为外部表进行复制。· 复制表将在Hive 配置参数hive.metastore.warehouse.external.dir 设置的外部 Hive 仓库目录下创建 。用户必须确保这与Hive 配置参数hive.metastore.warehouse.dir 具有不同的值 ,即托管表的位置。· 如果用户想要将相同的数据库从 Hive2 复制到 Hive3(设计上会有不同的路径),他们需要使用每个策略的强制覆盖选项以避免任何不匹配问题。笔记从 Sentry 复制到 Ranger 时,受支持的最低 Cloudera Manager 版本为 6.3.1 及更高版本。配置注意事项:· 如果hadoop.proxyuser.hive.groups配置已更改为将 Hive Metastore Server 的访问权限限制为某些用户或组,则该 hdfs组或包含该hdfs用户的组也必须包含在为Hive/Impala 复制指定的组列表中。此配置可以在 Hive 服务上指定为覆盖,也可以在核心站点 HDFS 配置中指定。这适用于源集群和目标集群上的配置设置。· 如果您在目标集群上配置了Hive/Impala 复制过程中复制 HDFS 数据的目录,复制过程中复制的权限会被 HDFS ACL 同步覆盖并且不会保留笔记如果您的部署包括由 Kudu 支持的表,Replication Manager 会过滤掉用于 Hive 复制的 Kudu 表,以防止数据丢失或损坏。7.1. Hive/Impala 复制的主机选择如果您的集群在资源有限的主机上安装了 Hive客户端,Hive/Impala复制可能会使用这些主机来运行复制命令,这可能会导致复制性能下降。为了提高性能,您可以指定要在复制期间使用的主机(“白名单”),以便不使用资源较少的主机。1. 单击集群> Hive 服务>配置。2. 键入Hive Replication搜索框。3. 找到Hive 复制环境高级配置片段(安全阀)属性。4. 添加HOST_WHITELIST属性。输入以逗号分隔的主机名列表,以用于 Hive/Impala 复制。HOST_WHITELIST=host-1.mycompany.com,host-2.mycompany.com5. 输入更改原因,然后单击保存更改以提交更改。7.2. Hive 表和 DDL 命令使用drop table和truncate table等DDL 命令时,以下内容适用。· 如果您配置 Hive表的复制,然后删除该表,该表将保留在目标集群上。发生后续复制时不会删除该表。· 如果删除目标集群上的表,并且该表仍包含在复制作业中,则复制期间将在目标上重新创建该表。· 如果删除源集群上的表分区或索引,复制作业也会将它们删除到目标集群上。· 如果您截断表,并且复制作业的删除策略设置为删除到垃圾箱或永久删除,则复制期间目标上的相应数据文件将被删除。7.3. 参数的复制数据库、表、分区和索引的参数在Hive/Impala 复制期间默认复制。您可以禁用参数复制:1. 登录到Cloudera Manager 管理控制台。2. 转到 Hive服务。3. 单击配置选项卡。4. 搜索Hive 复制环境高级配置片段。5. 添加以下参数:REPLICATE_PARAMETERS=false6. 单击保存更改。7.4. 动态环境中的 Hive 复制要在 Hive Metastore 更改的环境中使用 Replication Manager 进行 Hive 复制,例如在创建或删除数据库或表时,需要额外的配置。1. 打开 Cloudera Manager 管理控制台。2. 在源集群上搜索 hdfs-site.xml属性的HDFS 客户端高级配置片段(安全阀) 。3. 添加以下属性:a. 名称:replication.hive.ignoreDatabaseNotFound值:trueb. replication.hive.ignoreTableNotFound值:true4. 保存更改。5. 重启 HDFS 服务。7.5. 配置 Hive/Impala 数据的复制在配置Hive/Impala 复制作业之前,您必须设置集群。1. 验证您的集群是否符合支持的复制方案之一。2. 如果源集群由与目标集群不同的Cloudera Manager 服务器管理,请配置对等关系。3. 从Cloudera Manager > Replication,单击 Create Replication Policy。4. 选择Hive 复制策略。出现 创建 Hive 复制策略 对话框。5. 选择常规选项卡以配置以下内容:a. 使用名称字段为复制策略提供唯一名称。b. 使用源下拉列表选择您要复制的 Hive服务所在的集群。c. 使用目标下拉列表选择复制目标。如果 Cloudera Manager 管理的 Hive服务只有一个可用作目标,则将其指定为目标。如果此Cloudera Manager 管理多个 Hive服务,请从中选择。d. 根据您计划使用的目标集群类型,选择Use HDFS Destination。e. 选择以下权限之一:§ 不导入 Sentry 权限(默认)§ 如果 Sentry 权限是从 CDH 集群导出的,则同时导入 Hive 对象和 URL 权限§ 如果 Sentry 权限是从 CDH 集群导出的,则只导入 Hive 对象权限f. 选中“全部复制”以从源复制所有 Hive数据库。要仅复制选定的数据库,请取消选中此选项并输入要复制的数据库名称和表。§ 您可以使用加号指定多个数据库和表以向规范添加更多行。§ 您可以在一行中指定多个数据库,方法是用竖线 (|) 字符分隔它们的名称。例如: mydbname1|mydbname2|mydbname3。§ 正则表达式可用于数据库或表字段,如下表所述:正则表达式结果[\w].+任何数据库或表名。(?!myname\b).+除了名为 myname 的数据库或表之外的任何数据库或表。db1|db2[\w_]+db1 和 db2 数据库的所有表。数据库1[\w_]+单击“+”按钮,然后输入数据库[\w_]+db1 和 db2 数据库的所有表(替代方法)。g. 要指定应该运行 MapReduce 作业的用户,请使用Run As Username选项。默认情况下,MapReduce作业作为hdfs. 要以其他用户身份运行 MapReduce 作业,请输入用户名。如果您使用的是Kerberos,则必须在此处提供用户名,并且其 ID 必须大于 1000。笔记运行MapReduce工作的用户应该read与 execute对上Hive仓库目录的权限 源集群。如果您将复制作业配置为保留权限,则在目标集群上需要超级用户权限。h. 如果对等集群配置了不同的超级用户,请指定在对等上运行作为用户名选项。这仅适用于在kerberized 环境中工作时。6. 选择“资源”选项卡以配置以下内容:a. 调度程序池- (可选)在字段中输入资源池的名称。您输入的值由您在 Cloudera Manager 为复制执行MapReduce 作业时指定的MapReduce 服务使用。作业使用以下属性之一指定值:§ MapReduce – 公平调度程序: mapred.fairscheduler.pool§ MapReduce – 容量调度程序: queue.name§ Yarn – mapreduce.job.queuenameb. 最大Map槽和最大带宽 - 每个映射器的Map槽数量和带宽限制。默认值为 100 MB。c. 复制策略– 文件复制应该是静态的(默认)还是动态的。静态复制预先在映射器之间分配文件复制任务,以实现基于文件大小的统一分配。动态复制将文件复制任务以小集合分配给映射器,并且当每个映射器处理其任务时,它会动态获取并处理下一组未分配的任务。7. 选择Advanced选项卡指定导出位置,修改将执行复制的MapReduce 作业的参数,并设置其他选项。您可以选择一个MapReduce 服务(如果您的集群中有多个)并更改以下参数:a. 取消选中复制 HDFS文件复选框以跳过复制关联的数据文件。b. 如果源集群和目标集群都使用 CDH 5.7.0 或更高版本(包括5.11.x),请选择复制 Impala 元数据下拉列表并选择否以避免重复复制 Impala 元数据。(此选项仅在源集群和目标集群都支持时显示。)您可以为Replicate Impala Metadata选择以下选项:§ 是- 复制 Impala 元数据。§ 否– 不复制 Impala 元数据。§ Auto – Cloudera Manager 根据 CDH 版本确定是否复制 Impala 元数据。要在 Cloudera Manager 管理的 CDH 版本为 5.7 或更低版本时复制Impala UDF,请参阅有关何时选择此选项的信息。c. 该强制覆盖选项,如果选中,如果检测到不兼容的更改将强制覆盖到目的地metastore数据。例如,如果目标 Metastore 被修改,并且一个新分区被添加到表中,则此选项会强制删除该分区,并使用在源上找到的版本覆盖表。重要的如果 未设置Force Overwrite选项,并且 Hive/Impala 复制过程检测到源集群上的更改不兼容,则Hive/Impala 复制将失败。这有时会在重复复制中发生,其中与源集群上的现有数据库或表关联的元数据会随着时间的推移而发生变化。d. 默认情况下,Hive 元数据导出到默认 HDFS 位置( /user/${user.name}/.cm/hive),然后从此 HDFS 文件导入到目标 Hive元存储。在本例中,user.name是目标集群上 HDFS 服务的进程用户。要覆盖此导出文件的默认 HDFS位置,请在“导出路径”字段中指定路径。笔记在Kerberized 集群中,源集群上的 HDFS主体 必须具有read, write和 对目标集群上的导出路径目录的execute访问权限。e. 并发 HMS 连接数 - 并发 Hive Metastore 连接数。这些连接用于同时从 Hive导入和导出元数据。增加线程数可以提高 Replication Manager 的性能。默认情况下,新的复制策略使用 5 个连接。如果将该值设置为 1 或更多,Replication Manager 将使用具有指定连接数的多线程。如果将该值设置为 0 或更少,Replication Manager 将使用单线程和单连接。请注意,源和目标集群必须运行支持并发 HMS 连接的 Cloudera Manager 版本、Cloudera Manager 5.15.0 或更高版本和Cloudera Manager 6.1.0 或更高版本。f. 默认情况下,Hive HDFS 数据文件(例如 /user/hive/warehouse/db1/t1)被复制到相对于“ /”(在本例中为 /user/hive/warehouse/db1/t1)的位置。要覆盖默认值,请在HDFS Destination Path字段中输入路径。例如,如果您输入 /ReplicatedData,数据文件将被复制到 /ReplicatedData/user/hive/warehouse/db1/t1.g. 选择要用于此复制的MapReduce 服务(如果您的集群中有多个)。h. 日志路径-日志的替代路径。i. 描述- 复制策略的描述。j. Skip Checksum Checks - 是否跳过校验和检查,默认情况下执行。k.跳过列表校验和检查- 在比较两个文件以确定它们是否相同时是否跳过校验和检查。如果跳过,则使用文件大小和上次修改时间来确定文件是否相同。跳过检查可提高映射器阶段的性能。请注意,如果您选择 跳过校验和检查选项,也会跳过此检查。l. Abort on Error - 是否在出现错误时中止作业。通过选中该复选框,复制到该点的文件将保留在目标上,但不会复制其他文件。默认情况下,错误中止是关闭的。m. 在快照差异失败时中止- 如果快照差异在复制期间失败,Replication Manager 使用完整副本来复制数据。如果选择此选项,Replication Manager 会在遇到错误时中止复制。n. 删除策略- 源上的文件是否也应从目标目录中删除。选项包括:o.保留- 是保留源文件系统上存在的块大小、复制计数和权限 ,还是使用目标文件系统上配置的设置。默认情况下,设置保留在源上。笔记您必须以超级用户身份运行才能保留权限。使用“以用户名运行”选项来确保是这种情况。p. 警报- 是否为复制工作流中的各种状态变化生成警报。您可以提醒On Failure、 On Start、On Success或On Abort(复制工作流中止时)。8. 单击保存策略。复制任务在复制策略表中显示为一行 。要指定其他复制任务,请选择Create > Hive Replication。笔记如果您的复制作业需要很长时间才能完成,并且在复制完成之前表发生了变化,则复制可能会失败。考虑将 Hive 仓库目录和任何外部表的目录设为可快照,以便复制作业在复制文件之前创建目录的快照。7.6. 针对 Hive 复制策略的 Ranger 复制Sentry创建或编辑 Hive复制策略时,您可以选择迁移 Hive对象、Impala数据和正在复制的 URL 的Sentry 策略。Replication Manager 将Sentry 策略转换为目标集群中迁移数据的Ranger 策略。将Sentry 策略复制到Ranger 需要最低支持的Cloudera Manager 版本 6.3.1 及更高版本。在 Hive复制策略中,如果您选择如果 Sentry 权限从 CDH 集群导出,同时导入 Hive 对象和 URL 权限或如果 Sentry 权限从 CDH 集群导出,仅导入 Hive对象权限选项,复制管理器执行在复制作业运行期间自动执行以下任务:当您选择将Sentry 策略迁移到Ranger 时,Replication Manager 会自动执行以下任务:1. 使用authzmigrator 工具将每个Sentry 策略导出为单个 JSON文件。JSON 文件包含资源列表,例如 URI、数据库、表或列以及适用于它的策略。2. 使用DistCp 工具将导出的Sentry 策略复制到目标集群。3. 在使用authzmigrator 工具通过Ranger 其余端点过滤与复制作业相关的策略后,将Sentry 策略摄取到Ranger 中。为了过滤策略,Replication Manager 使用由Cloudera Manager 传递给authzmigrator 工具的过滤器表达式。如果您要复制数据库中表的子集,则数据库级策略将转换为每个被复制表的等效表级策略。(例如,对于每个复制的表,数据库上的 ALL -> 表上的 ALL)。Ranger 中将不会引用原始角色名称。权限直接授予组和用户关于资源而不是角色。这是在就地升级到CDP Private Cloud Base期间将Sentry 迁移到Ranger 的一种不同格式 ,后者确实导入和使用了 Sentry 角色。无论是否修改了策略,每次复制时都会重新创建每个策略。如果您希望继续安排数据复制,但您还想修改目标集群的Ranger 策略(并保留这些修改),您应该通过编辑复制策略在后续运行中禁用Sentry 到Ranger 迁移,并选择不导入 Sentry 权限(默认) 选项。7.7. Impala 和 Hive 用户定义函数 (UDF) 的复制默认情况下,对于 CDH 版本为 5.7 或更高版本的集群,Impala和 Hive UDF 保留在 Hive Metastore 中,并作为 Hive/Impala 复制的一部分自动复制。要在Cloudera Manager 管理的 CDH 版本为 5.6 或更低版本时复制Impala UDF,请参阅有关在创建Hive/Impala 复制策略时何时选择高级选项卡上的复制Impala 元数据选项的信息。复制作业运行后,您可以在复制策略页面上看到在计划的最后一次运行期间复制的 Impala 和 Hive UDF 的数量。您还可以在之前运行的复制的复制历史记录页面上查看复制的 UDF 数量 。7.8. 监控 Hive 或 Impala 复制的性能您可以使用从Cloudera Manager 管理控制台下载为 CSV 文件的性能数据来监控 Hive/Impala 复制策略的进度。此文件包含有关正在复制的表和分区的信息、平均吞吐量以及其他有助于诊断Hive/Impala 复制期间性能问题的详细信息。您可以查看运行Hive/Impala 复制作业和已完成作业的性能数据。查看正在运行的Hive/Impala复制的性能数据:1. 在Cloudera Manager 中,选择复制>复制策略。2. 找到策略所在行,选择策略,然后单击操作>显示历史记录。3. 单击Download CSV for HDFS Replication Report,然后选择以下选项之一以查看性能报告:o 性能- 单击可下载包含有关复制作业性能的摘要报告的 CSV 文件。性能摘要报告包括正在处理复制作业的每个映射器的最后一个性能示例。o 完整性能- 单击可下载包含作业性能报告的 CSV 文件。完整的性能报告包括在复制作业完全执行期间为所有映射器采集的所有样本。4. 要查看数据,请在电子表格程序(如Microsoft Excel)中打开文件。除了性能报告之外,您还可以查看错误文件、删除的文件和复制作业期间跳过的文件的报告。要查看报告,请执行以下步骤:1. 在“复制策略”页面上,找到该策略并单击“操作” >“显示历史记录”。出现复制策略的复制历史页面。展开以查看复制作业详细信息。2. 单击下载 CSV以获取以下选项:o 列表- 单击以下载包含复制报告的 CSV 文件。该文件列出了在复制作业期间复制的文件和目录的列表。o 状态- 单击可下载包含完整状态报告的 CSV 文件。该文件包含文件的完整状态报告,其中复制状态为以下之一:§ ERROR – 发生错误,文件未复制。§ DELETED – 已删除的文件。§ SKIPPED – 跳过复制的文件,因为它是最新的。o 仅错误状态- 单击可下载包含所有复制文件的状态报告的 CSV 文件,其中包含错误。该文件列出了已复制文件的状态、路径和错误消息。o 仅已删除状态- 单击可下载包含所有已删除文件的状态报告的 CSV 文件。该文件列出了已删除数据库和表的状态、路径和消息。o 仅跳过状态- 单击可下载包含所有跳过文件的状态报告的 CSV 文件。该文件列出了被跳过的数据库和表的状态、路径和消息。o 性能- 单击可下载 CSV 文件,其中包含有关正在运行的复制作业的性能的摘要报告。性能摘要报告包括正在处理复制作业的每个映射器的最后一个性能示例。o 完整性能- 单击可下载包含作业性能报告的 CSV 文件。性能报告显示在复制作业完全执行期间为所有映射器采集的样本。3. 要查看数据,请在电子表格程序(如Microsoft Excel)中打开文件。查看已完成的Hive/Impala 复制策略的性能数据:1. 在“复制策略”页面上,找到该策略并单击“操作” >“显示历史记录”。2. 要查看 Hive阶段的性能,请单击Hive 复制报告标签旁边的下载 CSV,然后选择以下选项之一:o 结果- 下载复制表的列表。o 性能- 下载 Hive 复制的性能报告。笔记如果复制的 HDFS阶段跳过所有 HDFS 文件,因为它们没有更改,或者如果复制 HDFS文件选项(在创建 Hive/Impala 复制策略时位于高级选项卡上) ,下载 HDFS复制报告的选项可能不会出现 未选中的。有关HDFS 性能报告中数据的说明,请参见表 1。3. 要查看数据,请在电子表格程序(如Microsoft Excel)中打开文件。每两分钟收集一次性能数据。因此,在复制作业的初始执行期间没有可用的数据,因为没有足够的样本来估计吞吐量和其他报告的数据。从 Cloudera Manager 管理控制台下载的 CSV 文件返回的数据具有以下结构:表 1. Hive 性能报告列Hive 性能数据列描述时间戳收集性能数据的时间主持人运行 YARN 或 MapReduce 作业的主机的名称。数据库名称数据库的名称。表名表的名称。TotalElapsedTimeSecs从复制操作开始经过的秒数。总表数要复制的表总数。该列的值将-1用于 Cloudera Manager 无法确定要更改的表数量的复制。总分区数要复制的分区总数。如果源集群运行 Cloudera Manager 5.9 或更低版本,则此列包含值 ,-1 因为旧版本不报告此信息。数据库计数当前复制的数据库数。数据库错误计数失败的数据库复制操作数。表数到目前为止复制的表总数(对于所有数据库)。当前表计数为当前数据库复制的表总数。表错误计数失败的表复制操作总数。分区计数到目前为止复制的分区总数(对于所有表)。当前分区计数为当前表复制的分区总数。分区跳过计数跳过的分区数,因为它们是在上次运行的复制作业中复制的。索引计数复制的索引文件总数(对于所有数据库)。当前索引计数为当前数据库复制的索引文件总数。索引跳过计数由于未更改而跳过的索引文件数。由于 Hive 中的错误,此值始终为零。Hive函数计数复制的 Hive 函数数。Impala 对象计数复制的 Impala 对象数。请注意以下限制和已知问题:· 如果您在复制作业开始后过早单击 CSV 下载,Cloudera Manager 将返回一个空文件或一个仅包含列标题的 CSV 文件,并在实际收集性能数据后稍后尝试。· 如果您使用表单代理用户,user@domain则无法通过链接获得绩效数据。· 如果复制作业只复制可以在不到几分钟内传输的小文件,则不会收集性能统计信息。· 对于指定动态复制策略的复制策略,有关MapReduce 作业传输的最后一个文件的统计信息隐藏了该MapReduce 作业执行的先前传输。· CSV 文件中仅报告每个MapReduce 作业的最后一次跟踪。7.9. 启用、禁用或删除复制策略创建新的复制策略时,它会自动启用。如果禁用复制策略,则可以稍后重新启用。管理复制策略。1. 从Cloudera Manager 中,选择复制>复制策略。2. 为所选下拉菜单选择操作,然后根据需要选择 启用|禁用|删除。要启用、禁用或删除多个复制策略,您可以从复制策略页面选择这些策略并重复步骤 2。8. 将数据复制到 Impala 集群Impala元数据作为常规Hive/Impala 复制操作的一部分进行复制。8.1. 复制 Impala 元数据Impala 元数据复制作为 Hive 复制的一部分执行。Impala复制仅支持在两个 CDH 集群之间进行。Impala 和 Hive服务必须在两个集群上运行。要启用 Impala 元数据复制,请执行以下任务:1. 安排 Hive复制。2. 确认在“创建 Hive复制”对话框的“高级”选项卡 上将“复制Impala 元数据”选项设置为“ 是” 。当您将复制 Impala 元数据选项设置为是时,Impala UDF(用户定义的函数)将在目标集群上可用,就像在源集群上一样。作为复制 UDF 的一部分,定义它们的二进制文件也会被复制。笔记要对已复制到目标集群的表运行查询或执行 DDL 语句,您必须在目标集群上运行 Impala INVALIDATE METADATA 语句以防止查询失败。8.2. 使 Impala 元数据无效对于不使用 LDAP身份验证的 Impala 集群,您可以将 Hive/Impala 复制作业配置为在复制完成后自动使Impala 元数据失效。如果集群使用Sentry,则Impala 用户应该有权运行INVALIDATE METADATA.配置导致Hive/Impala 复制作业运行ImpalaINVALIDATE METADATA完成复制后目标集群上每个表的语句。该语句在复制完成后清除目标集群Impala 中复制表和视图的元数据,允许目标上的其他Impala 客户端成功查询这些表并获得准确结果。但是,如果在复制运行时对任何复制的表或视图执行 DDL 操作,则此操作可能不安全。一般情况下,不建议直接修改目标上的复制数据/元数据。忽略这一点可能会导致使用这些表或视图的应用程序和查询出现意外或不正确的行为。笔记如果源包含 UDF,INVALIDATE METADATA即使您配置了自动失效,您也必须手动运行该语句并且不指定任何表。要配置该选项,请执行以下任务:1. 安排 Hive复制。2. 在Advanced选项卡上,选择Invalidate Impala Metadata on Destination选项。或者,您可以INVALIDATE METADATA为复制表手动运行该语句。9. 将快照与复制结合使用某些复制,尤其是那些需要很长时间才能完成的复制,可能会因为源文件在复制过程中被修改而失败。您可以通过将快照与复制结合使用来防止此类故障。CDH 5.0 及更高版本会自动使用快照。要利用这一点,您必须为快照启用相关目录(也称为使目录成为 快照表)。当复制作业运行时,它会检查指定的源目录是否是可快照的。在复制任何文件之前,复制作业会创建这些目录的时间点快照,并将它们用作文件副本的源。这可确保复制的数据与复制作业开始时的源数据一致。复制过程完成后,将保留用于后续运行的最新快照。目录是可快照的,因为它已启用快照,或者因为父目录已启用快照。快照目录的子目录包含在快照中。9.1. 带有快照的 Hive/Impala 复制如果您使用 Hive复制,Cloudera建议您将 Hive 仓库目录设为可快照。Hive 仓库目录位于 HDFS 文件系统中hive.metastore.warehouse.dir属性指定的位置。(默认位置是 /user/hive/warehouse。)要访问此属性:1. 打开Cloudera Manager 并浏览到 Hive服务。2. 单击配置选项卡。3. 在搜索框中,键入 hive.metastore.warehouse.dir。显示Hive 仓库目录属性。如果您在 Hive中使用外部表,还要使托管任何未存储在 Hive 仓库目录中的外部表的目录快照表。同样,如果您正在使用Impala 并使用Hive/Impala 复制来复制任何Impala 表,请确保表和关联数据库的存储位置也是可快照的。10. 使用 Kerberos 身份验证启用集群之间的复制要启用集群之间的复制,需要额外的设置步骤以确保源集群和目标集群可以通信。最低要求角色:集群管理员(也由完全管理员提供)重要的即使没有 Kerberos 领域信任关系,Cloudera Replication Manager 也可以与不同Kerberos 领域中的集群一起使用。Cloudera Manager 配置属性Trusted Kerberos Realms和Kerberos Trusted Realms用于 Cloudera Manager 和 CDH 配置,与 Kerberos 领域信任关系无关。如果您在不同Kerberos 领域中的集群之间使用独立的DistCp,则必须配置领域信任。10.1. 端口在启用Kerberos 身份验证的情况下使用Replication Manager 时,Replication Manager 需要以下页面中列出的所有端口Replication Manager 的端口要求。此外,用于Kerberos KDC 服务器和 KRB5服务的端口必须对目标集群上的所有主机开放。默认情况下,这是端口 88。10.2. 域名的注意事项如果源集群和目标集群都使用Kerberos 进行身份验证,请使用以下配置之一来防止运行复制作业时发生冲突。· 如果集群不使用相同的 KDC(Kerberos 密钥分发中心),Cloudera建议您为每个集群使用不同的领域名称。此外,如果您要跨两个不同领域中的集群进行复制,请参阅本主题后面的复制步骤以在这些集群之间建立信任。· 如果集群使用相同的 KDC 或属于统一领域一部分的不同 KDC,您可以使用相同的领域名称,例如其中一个 KDC 是主 KDC,另一个是工作 KDC。· 笔记如果您有多个集群用于隔离生产和非生产环境,则此配置可能会导致主体在两种环境中具有相同的权限。确保为每种类型的环境适当设置权限。重要的如果源集群和目标集群在同一领域但不使用相同的 KDC 或 KDC 不是统一领域的一部分,则复制作业将失败。10.3. HDFS、Hive 和 Impala 复制配置源集群和目标集群。1. 在目标集群中的主机上,确保每个主机上的 krb5.conf文件(通常位于 /etc/kbr5.conf)具有以下信息:o 源集群的Kerberos 领域的 KDC 信息。例如:[realms]
SRC.EXAMPLE.COM = {
kdc = kdc01.src.example.com:88
admin_server = kdc01.example.com:749
default_domain = src.example.com
}
DST.EXAMPLE.COM = {
kdc = kdc01.dst.example.com:88
admin_server = kdc01.dst.example.com:749
default_domain = dst.example.com
}o 源集群域的领域映射。您可以在[domain_realm]部分配置这些映射。例如:[domain_realm]
.dst.example.com = DST.EXAMPLE.COM
dst.example.com = DST.EXAMPLE.COM
.src.example.com = SRC.EXAMPLE.COM
src.example.com = SRC.EXAMPLE.COM笔记如果您遇到主机名不一致的情况,您必须导航到Cloudera Manager Host All Hosts并确保所有这些主机都以与domain_realm部分中所见类似的方式覆盖 。2. 在目标集群上,使用Cloudera Manager 将源集群的领域添加到Trusted Kerberos Realms配置属性:o 转到 HDFS 服务。o 单击配置选项卡。o 在搜索字段中键入Trusted Kerberos以查找Trusted Kerberos Realms 属性。o 单击加号图标,然后输入源 集群领域。o 输入更改原因,然后单击保存更改以提交更改。3. 转至 管理>设置。4. 在搜索字段中,键入domain name。5. 在域名字段中,输入要映射到目标集群 KDC 的任何域名或主机名。使用加号图标根据需要添加任意数量的条目。此属性中的条目用于生成 中的domain_realm 部分krb5.conf。6. 如果domain_realm在高级配置片段(安全阀)中配置了剩余的krb5.conf,请删除它的条目。7. 输入更改原因,然后单击保存更改以提交更改。10.4. Kerberos 连接测试作为测试连接的一部分,Cloudera Manager 测试在运行复制的源和目标集群上正确配置的 Kerberos 身份验证。添加对等方进行复制时,测试连接会自动运行,或者您可以从“操作”菜单手动启动测试连接 。当源和目标集群运行Cloudera Manager 5.12 或更高版本时,此功能可用。您可以通过设置禁用Kerberos的连通性测试 feature_flag_test_kerberos_connectivity,以false与Cloudera的管理器API: api/<version>/cm/config。如果测试检测到Kerberos 配置存在任何问题,Cloudera Manager 会根据Cloudera Manager 是否管理Kerberos 配置文件提供解决步骤。Cloudera Manager 测试以下场景:· 两个集群是否都启用了Kerberos。· 从Cloudera Manager 6.1 及更高版本开始,支持从不安全集群到安全集群的复制。· 如果源集群使用Kerberos 而目标集群不安全,则不支持复制。· 两个集群是否在同一个Kerberos 领域。同一个领域中的集群必须共享同一个 KDC,或者 KDC 必须在一个统一的领域中。· 集群是否位于不同的Kerberos 领域。如果集群在不同的领域,则必须根据以下标准配置目标集群:o 目标 HDFS 服务必须具有正确的 Trusted Kerberos Realms设置。o 该krb5.conf文件domain_realm在所有主机上都有正确的 映射。o 该krb5.conf文件包含realms有关所有主机的正确 信息。· 本地和对等 KDC 是否在可用端口上运行。该端口必须对集群中的所有主机开放。默认端口为 88。Cloudera Manager 运行测试后,Cloudera Manager 会提出解决任何Kerberos 配置问题的建议。10.4.1. Kerberos 建议如果Cloudera Manager 管理Kerberos 配置文件,Cloudera Manager 会为您正确配置Kerberos,然后提供您必须手动运行以完成集群配置的命令集。如果 Cloudera Manager 不管理Kerberos 配置文件,Cloudera Manager 会提供更正问题所需的手动步骤。11. 加密数据的复制HDFS 支持静态数据加密,包括通过 Hive访问的数据。本主题介绍了加密区域内和加密区域之间的复制如何工作,以及如何配置复制以避免因加密而失败。11.1. 加密集群之间传输的数据源目录和目标目录可能在也可能不在加密区域中。如果目标目录在加密区域中,则目标目录上的数据会被加密。如果目标目录不在加密区域中,即使源目录在加密区域中,该目录上的数据也不会加密。CDH 5.1 或更低版本不支持加密区域。配置加密区域时,您还可以配置密钥管理服务器(KMS) 来管理加密密钥。在复制过程中,当密钥从源集群传输到目标集群时,Cloudera Manager 使用TLS/SSL 对它们进行加密。配置加密区域时,您还可以配置密钥管理服务器(KMS) 来管理加密密钥。当指定加密源目录的 HDFS复制命令运行时,Cloudera Manager临时将加密密钥从源集群复制到目标集群,使用TLS/SSL(如果为 KMS 配置)来加密密钥。Cloudera Manager 然后使用这些密钥解密从源集群收到的加密文件,然后再将文件写入目标集群。重要的在配置 HDFS 复制时,必须选择 跳过校验和检查属性以防止在以下情况下复制失败:· 从源集群上的加密区域复制到目标集群上的加密区域。· 从源集群上的加密区域复制到目标集群上的未加密区域。· 从源集群上的未加密区域复制到目标集群上的加密区域。即使源目录和目标目录都在加密区域中,数据在从源集群读取时会被解密(使用源加密区域的密钥),并在写入目标集群时再次加密(使用密钥)用于目标加密区域)。如果您为 HDFS 数据传输配置了加密,则数据传输会被加密。笔记解密和加密步骤发生在运行复制数据的 MapReduce 作业的主机上的同一进程中。因此,纯文本数据仅存在于 Mapper 任务的内存中。如果源或目标集群上正在使用 KMS,并且您对源或目标目录使用加密区域,请为 KMS 配置 TLS/SSL 以防止将密钥作为纯文本传输到映射器任务。在复制期间,数据使用 distcp. 对于使用加密区域的集群,请使用 TLS/SSL 配置源和目标之间 KMS 密钥传输的加密。要配置源集群和目标集群之间的数据传输加密:· 在源集群和目标集群上为 HDFS客户端启用 TLS/SSL。您可能还需要在源和目标上的 SSL 证书之间配置信任。· 为两个对等Cloudera Manager 服务器启用TLS/SSL。· 使用 HDFS数据传输加密来加密数据传输。以下博客文章提供了有关使用 HDFS进行加密的其他信息:https : //blog.cloudera.com/blog/2013/03/how-to-set-up-a-hadoop-cluster-with-network-encryption/。11.2. 安全考虑您在计划复制作业时使用“运行方式”字段指定的用户需要对要复制的密钥和数据目录的完全访问权限。这不是 KMS 管理的推荐最佳实践。如果您更改 KMS 中的权限以启用此要求,您可能会意外地为该用户提供对使用相同密钥的其他加密区域中的数据的访问权限。如果未指定用户的运行方式领域,复制运行作为默认用户,hdfs。要访问加密数据,用户必须在 KMS 上获得他们需要与之交互的加密区域的授权。您在计划复制时使用运行方式字段指定的用户必须具有此授权。密钥管理员必须为该用户向 KMS 添加 ACL 以防止授权失败。使用 KMS 协议从源到客户端的密钥传输使用 REST 协议,这要求您为 KMS 配置 TLS/SSL。启用TLS/SSL 后,密钥不会以纯文本形式通过网络传输。12. 快照您可以使用Cloudera Manager 或使用命令行创建 HBase 和 HDFS 快照。HDFS 快照允许您创建目录或整个文件系统的时间点备份,而无需实际克隆数据。它们可以提高数据复制性能并防止因更改源目录而导致的错误。这些快照作为只读目录出现在文件系统上,可以像其他普通目录一样访问。12.1. Cloudera Manager 快照策略Cloudera Manager 支持创建快照策略,这些策略定义要创建快照的目录或表、应拍摄快照的时间间隔以及每个快照时间间隔应保留的快照数量。例如,您可以创建一个同时拍摄每日和每周快照的策略,并指定应维护七个每日快照和五个每周快照。最低要求角色: 复制管理员(也由完全管理员提供)笔记您还可以通过使用快照来提高可靠性。12.1.1. 管理快照策略您必须为快照启用 HDFS目录,以允许为该目录创建快照策略。要将 HDFS目录指定为快照表,请按照以下步骤操作12.1.1.1. 创建快照策略:1. 从Cloudera Manager,选择复制>快照策略。现有快照策略显示在表格中。2. 要创建新策略,请单击创建快照策略。3. 从下拉列表中,选择要为其创建策略的服务(HDFS 或 HBase)和集群。4. 为策略提供一个名称,并可以选择输入描述。5. 指定要包含在快照中的目录、命名空间或表。重要的不要拍摄根目录的快照。o 对于 HDFS 服务,选择要包含在快照中的目录路径。下拉列表允许您仅选择启用快照的目录。如果没有为快照启用目录,则会显示警告。单击以添加路径和删除路径。o 对于 HBase 服务,列出要包含在快照中的表。您可以使用 Java 正则表达式来指定一组表。例如,finance.*匹配名称以 开头的所有表finance。您还可以使用 语法为给定命名空间中的所有表创建快照。{namespace}:.*6. 指定快照计划。您可以每小时、每天、每周、每月或每年或这些的任意组合安排快照。根据您选择的频率,您可以指定拍摄快照的时间、星期几、月份中的某一天或一年中的月份,以及在每个时间间隔保留的快照数量。调度信息中的每个时间单位都与更大粒度的时间单位共享。也就是说,分钟值由所有选定的计划共享,小时由适用于小时的所有计划共享,依此类推。例如,如果您指定在半小时拍摄每小时快照,并在 20 小时拍摄每日快照,则每日快照将在 20:30 发生。要选择间隔,请选中相关框。这些字段显示您可以编辑要保留的快照的时间和数量的位置。7. 指定是否应为快照工作流中的各种状态更改生成警报。您可以在失败、启动、成功或快照工作流中止时发出警报。8. 单击保存策略。新策略出现在 快照策略页面上。12.1.1.2. 要编辑或删除快照策略:1. 从Cloudera Manager,选择复制>快照策略。现有快照策略显示在表格中。2. 找到该策略并单击操作菜单,然后选择 编辑或删除选项。12.1.2. 快照历史“快照历史记录”页面显示有关已运行或尝试的快照作业的信息。该页面显示了一个包含以下列的快照作业表:表 1.快照历史字段描述开始时间快照作业开始执行的时间。单击以显示有关快照的详细信息。例如:单击“查看”链接以打开“托管计划快照命令”页面,该页面显示有关执行命令的每个步骤的详细信息和消息。结果显示快照是成功还是失败。路径 | 处理的表HDFS 快照:为快照处理的路径数。HBase 快照:为快照处理的表数。路径 | 未处理的表HDFS Snapshots:快照未处理的路径数。HBase Snapshots:快照未处理的表 数。创建的快照创建的快照数量。快照已删除删除的快照数量。创建过程中的错误显示创建快照时发生的错误列表。每个错误都显示相关路径和错误消息。删除过程中的错误显示删除快照时发生的错误列表。每个错误都显示相关路径和错误消息。12.1.3. 孤立的快照当快照策略包含对要保留的快照数量的限制时,Cloudera Manager 会在每次添加新快照时检查存储的快照总数,并在必要时自动删除最旧的现有快照。编辑或删除快照策略时,从策略中删除的文件、目录或表可能会留下“孤立”快照,这些快照不会自动删除,因为它们不再与当前快照策略相关联。Cloudera Manager 从不选择这些快照进行自动删除,因为只有在策略创建包含这些文件、目录或表的新快照时才会选择删除。您可以通过Cloudera Manager 或通过创建使用 HDFS或 HBase 快照命令的命令行脚本手动删除快照。很难找到孤立的快照以进行手动删除。快照策略自动接收前缀, cm-auto后跟全局唯一标识符 (GUID)。您可以通过搜索该策略独有的前缀来查找特定策略的所有快照。cm-auto-guid为避免孤立快照,请在编辑或删除关联的快照策略之前删除快照,或记录要删除的快照的标识名称。该前缀显示在策略列表中的策略摘要中,并出现在删除对话框中。记录快照名称(包括关联的策略前缀)是必要的,因为在删除策略后无法确定与策略关联的前缀,并且快照名称不包含对快照策略的可识别引用。12.2. 管理 HDFS 快照本主题演示了如何使用Cloudera Manager 或命令行管理 HDFS 快照。对于 HDFS服务,使用文件浏览器选项卡查看与集群上的服务关联的 HDFS目录。您可以查看当前保存的文件快照,并删除或恢复它们。在 HDFS文件浏览器选项卡中,您可以:· 将 HDFS目录指定为“可快照”,以便可以为这些目录创建快照。· 启动 HDFS目录的即时(计划外)快照。· 查看当前维护的已保存快照列表。这些可以包括一次性的即时快照,以及基于策略的计划快照。· 删除保存的快照。· 从保存的快照恢复 HDFS目录或文件。· 将 HDFS目录或文件从保存的快照恢复到新目录或文件(恢复为)。在使用快照之前,请注意以下限制:· 包含加密目录的快照无法在创建它们的区域之外恢复。· Cloudera Manager Admin Console 无法对启用了静态加密的 HDFS路径执行快照操作(例如创建、恢复和删除)。此限制仅影响Cloudera Manager 管理控制台,不影响 CDH 命令行工具或未由管理控制台执行的操作,例如使用命令行工具的 Replication Manager。有关快照操作的更多信息,请参阅Apache HDFS 快照文档。12.2.1. 浏览 HDFS 目录您可以浏览 HDFS目录以选择正确的集群。要浏览 HDFS目录以查看快照活动:1. 从Clusters选项卡中,选择您的 CDH HDFS 服务。2. 转到文件浏览器选项卡。当您浏览 HDFS的目录结构时,您选择的目录的基本信息会显示在右侧(所有者、组等)。12.2.2. 启用和禁用 HDFS 快照要创建快照,必须为快照启用 HDFS目录。您不能将目录指定为快照策略的一部分,除非它已为快照启用。最低要求角色:集群管理员(也由完全管理员提供)12.2.2.1. 为快照启用 HDFS 目录1. 从Clusters选项卡中,选择 CDH HDFS 服务。2. 转到文件浏览器选项卡。3. 转到要启用快照的目录。4. 在文件浏览器中,单击完整文件路径旁边的下拉菜单并选择 启用快照。笔记为目录启用快照后,您将无法在其任何子目录上启用快照。只能在启用了快照的目录上拍摄快照。12.2.2.2. 禁用可快照目录要为启用了快照的目录禁用快照,请使用 右上角下拉菜单按钮中的禁用快照。如果目录的快照存在,则必须先将其删除,然后才能禁用快照。12.2.3.拍摄和删除 HDFS 快照要管理 HDFS快照,请为快照启用 HDFS目录。最低要求角色: 复制管理员(也由完全管理员提供)12.2.3.1. 拍摄快照笔记您还可以通过创建快照策略来安排定期发生快照。1. 从Clusters选项卡中,选择 CDH HDFS 服务。2. 转到文件浏览器选项卡。3. 转到包含要恢复的快照的目录。4. 单击完整路径名旁边的下拉菜单并选择 Take Snapshot。显示拍摄快照屏幕。5. 输入快照的名称。6. 单击“确定”。存在“拍摄快照”按钮,可立即对目录进行快照。7. 要拍摄快照,请单击“拍摄快照”,指定快照的名称,然后单击“拍摄快照”。快照被添加到快照列表中。已拍摄的任何快照均按拍摄时间、名称和菜单按钮列出。12.2.3.2. 删除快照1. 从Clusters选项卡中,选择 CDH HDFS 服务。2. 转到文件浏览器选项卡。3. 转到包含要删除的快照的目录。4. 在快照列表中,找到要删除的快照,单击。5. 选择删除。12.2.4. 恢复快照从快照还原之前,请确保有足够的磁盘空间。1. 从Clusters选项卡中,选择 CDH HDFS 服务。2. 转到文件浏览器选项卡。3. 转到要还原的目录。4. 在文件浏览器中,单击完整文件路径旁边的下拉菜单(在文件浏览器列表的右侧),然后选择以下选项之一:o 从快照恢复目录o 将目录从快照还原为...显示恢复快照屏幕。5. 如果要将快照恢复到其他目录,请选择从快照恢复目录为...。输入必须将快照还原到的目录路径。确保 HDFS上有足够的空间来从快照还原文件。笔记如果在将目录从快照还原为...字段中输入现有目录路径 ,则该目录将被覆盖。6. 选择以下选项之一:o 使用 HDFS 'copy' 命令- 此选项执行速度较慢,并且在安全集群中不需要凭据。它将快照的内容复制为子目录或目标目录中的文件。o 使用DistCp / MapReduce - 此选项执行速度更快,并且需要安全集群中的凭据(运行方式)。它将目标目录与源快照的内容合并。选择此选项后,以下附加字段(与配置复制时可用的字段类似)将显示在“更多选项”下:§ 恢复HDFS数据时,如果集群中存在MapReduce或YARN服务,则使用DistributedCopy(distcp)恢复目录,提高恢复速度。所述还原快照屏幕HDFS(下更多选项)允许使用的MapReduce或纱作为MapReduce的服务的选择。对于文件,或者如果MapReduce 或 YARN服务不存在,则执行正常复制。§ Skip Checksum Checks - 是否跳过校验和检查(默认是执行它们)。如果选中,则不会执行校验和验证。在以下情况下,您必须选择此属性以防止在恢复快照时失败:§ 在单个加密区域内恢复快照。§ 将快照从一个加密区域恢复到不同的加密区域。§ 将快照从未加密区域恢复到加密区域。原文链接:https://docs.cloudera.com/cdp-private-cloud-upgrade/latest/data-migration/topics/cdp-data-migration-replication-manager-to-cdp-data-center.html