位置: 编程技术 - 正文

PostgreSQL教程(三):表的继承和分区表详解

编辑:rootadmin

推荐整理分享PostgreSQL教程(三):表的继承和分区表详解,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

一、表的继承:

这个概念对于很多已经熟悉其他数据库编程的开发人员而言会多少有些陌生,然而它的实现方式和设计原理却是简单易懂,现在就让我们从一个简单的例子开始吧。 1. 第一个继承表: capitals表继承自cities表的所有属性。在PostgreSQL里,一个表可以从零个或多个其它表中继承属性,而且一个查询既可以引用父表中的所有行,也可以引用父表的所有行加上其所有子表的行,其中后者是缺省行为。 如果希望只从父表中提取数据,则需要在SQL中加入ONLY关键字,如: 上例中cities前面的"ONLY"关键字表示该查询应该只对cities进行查找而不包括继承级别低于cities的表。许多我们已经讨论过的命令--SELECT,UPDATE和DELETE--支持这个"ONLY"符号。 在执行整表数据删除时,如果直接truncate父表,此时父表和其所有子表的数据均被删除,如果只是truncate子表,那么其父表的数据将不会变化,只是子表中的数据被清空。 2. 确定数据来源: 有时候你可能想知道某条记录来自哪个表。在每个表里我们都有一个系统隐含字段tableoid,它可以告诉你表的来源: 以上的结果只是给出了tableoid,仅仅通过该值,我们还是无法看出实际的表名。要完成此操作,我们就需要和系统表pg_class进行关联,以通过tableoid字段从该表中提取实际的表名,见以下查询: 3. 数据插入的注意事项: 继承并不自动从INSERT或者COPY中向继承级别中的其它表填充数据。在我们的例子里,下面的INSERT语句不会成功: 我们可能希望数据被传递到capitals表里面去,但是这是不会发生的:INSERT总是插入明确声明的那个表。 4. 多表继承: 一个表可以从多个父表继承,这种情况下它拥有父表们的字段的总和。子表中任意定义的字段也会加入其中。如果同一个字段名出现在多个父表中,或者同时出现在父表和子表的定义里,那么这些字段就会被"融合",这样在子表里面就只有一个这样的字段。要想融合,字段必须是相同的数据类型,否则就会抛出一个错误。融合的字段将会拥有它所继承的字段的所有约束。 5. 继承和权限:

表访问权限并不会自动继承。因此,一个试图访问父表的用户还必须具有访问它的所有子表的权限,或者使用ONLY关键字只从父表中提取数据。在向现有的继承层次添加新的子表的时候,请注意给它赋予所有权限。 继承特性的一个严重的局限性是索引(包括唯一约束)和外键约束只施用于单个表,而不包括它们的继承的子表。这一点不管对引用表还是被引用表都是事实,因此在上面的例子里,如果我们声明cities.name为UNIQUE或者是一个PRIMARY KEY,那么也不会阻止capitals表拥有重复了名字的cities数据行。 并且这些重复的行缺省时在查询cities表的时候会显示出来。实际上,缺省时capitals将完全没有唯一约束,因此可能包含带有同名的多个行。你应该给capitals增加唯一约束,但是这样做也不会避免与cities的重复。类似,如果我们声明cities.name REFERENCES某些其它的表,这个约束不会自动广播到capitals。在这种条件下,你可以通过手工给capitals 增加同样的REFERENCES约束来做到这点。 二、分区表:

PostgreSQL教程(三):表的继承和分区表详解

1. 概述分区表: 分区的意思是把逻辑上的一个大表分割成物理上的几块儿,分区可以提供若干好处: 1). 某些类型的查询性能可以得到极大提升。 2). 更新的性能也可以得到提升,因为表的每块的索引要比在整个数据集上的索引要小。如果索引不能全部放在内存里,那么在索引上的读和写都会产生更多的磁盘访问。 3). 批量删除可以用简单地删除某个分区来实现。 4). 将很少用的数据可以移动到便宜的、慢一些地存储介质上。 假设当前的数据库并不支持分区表,而我们的应用所需处理的数据量也非常大,对于这种应用场景,我们不得不人为的将该大表按照一定的规则,手工拆分成多个小表,让每个小表包含不同区间的数据。这样一来,我们就必须在数据插入、更新、删除和查询之前,先计算本次的指令需要操作的小表。对于有些查询而言,由于查询区间可能会跨越多个小表,这样我们又不得不将多个小表的查询结果进行union操作,以合并来自多个表的数据,并最终形成一个结果集返回给客户端。可见,如果我们正在使用的数据库不支持分区表,那么在适合其应用的场景下,我们就需要做很多额外的编程工作以弥补这一缺失。然而需要说明的是,尽管功能可以勉强应付,但是性能却和分区表无法相提并论。 目前PostgreSQL支持的分区形式主要为以下两种: 1). 范围分区: 表被一个或者多个键字字段分区成"范围",在这些范围之间没有重叠的数值分布到不同的分区里。比如,我们可以为特定的商业对象根据数据范围分区,或者根据标识符范围分区。 2). 列表分区: 表是通过明确地列出每个分区里应该出现那些键字值实现的。

2. 实现分区: 1). 创建"主表",所有分区都从它继承。 2). 创建几个"子"表,每个都从主表上继承。通常,这些"子"表将不会再增加任何字段。我们将把子表称作分区,尽管它们就是普通的PostgreSQL表。 上面创建的子表,均已年、月的形式进行范围划分,不同年月的数据将归属到不同的子表内。这样的实现方式对于清空分区数据而言将极为方便和高效,即直接执行DROP TABLE语句删除相应的子表,之后在根据实际的应用考虑是否重建该子表(分区)。相比于直接DROP子表,PostgreSQL还提供了另外一种更为方便的方式来管理子表: 和直接DROP相比,该方式仅仅是使子表脱离了原有的主表,而存储在子表中的数据仍然可以得到访问,因为此时该表已经被还原成一个普通的数据表了。这样对于数据库的DBA来说,就可以在此时对该表进行必要的维护操作,如数据清理、归档等,在完成诸多例行性的操作之后,就可以考虑是直接删除该表(DROP TABLE),还是先清空该表的数据(TRUNCATE TABLE),之后再让该表重新继承主表,如: 3). 给分区表增加约束,定义每个分区允许的健值。同时需要注意的是,定义的约束要确保在不同的分区里不会有相同的键值。因此,我们需要将上面"子"表的定义修改为以下形式: 4). 尽可能基于键值创建索引。如果需要,我们也同样可以为子表中的其它字段创建索引。 5). 定义一个规则或者触发器,把对主表的修改重定向到适当的分区表。 如果数据只进入最新的分区,我们可以设置一个非常简单的规则来插入数据。我们必须每个月都重新定义这个规则,即修改重定向插入的子表名,这样它总是指向当前分区。 其中NEW是关键字,表示新数据字段的集合。这里可以通过点(.)操作符来获取集合中的每一个字段。 我们可能想插入数据并且想让服务器自动定位应该向哪个分区插入数据。我们可以用像下面这样的更复杂的规则集来实现这个目标。 请注意每个规则里面的WHERE子句正好匹配其分区的CHECK约束。 可以看出,一个复杂的分区方案可能要求相当多的DDL。在上面的例子里我们需要每个月创建一次新分区,因此写一个脚本自动生成需要的DDL是明智的。除此之外,我们还不难推断出,分区表对于新数据的批量插入操作有一定的抑制,这一点在Oracle中也同样如此。 除了上面介绍的通过Rule的方式重定向主表的数据到各个子表,我们还可以通过触发器的方式来完成此操作,相比于基于Rule的重定向方法,基于触发器的方式可能会带来更好的插入效率,特别是针对非批量插入的情况。然而对于批量插入而言,由于Rule的额外开销是基于表的,而不是基于行的,因此效果会好于触发器方式。另一个需要注意的是,copy操作将会忽略Rules,如果我们想要通过COPY方法来插入数据,你只能将数据直接copy到正确的子表,而不是主表。这种限制对于触发器来说是不会造成任何问题的。基于Rule的重定向方式还存在另外一个问题,就是当插入的数据不在任何子表的约束中时,PostgreSQL也不会报错,而是将数据直接保留在主表中。

6). 添加新分区:

这里将介绍两种添加新分区的方式,第一种方法简单且直观,我们只是创建新的子表,同时为其定义新的检查约束,如: 第二种方法的创建步骤相对繁琐,但更为灵活和实用。见以下四步: 7). 确保postgresql.conf里的配置参数constraint_exclusion是打开的。没有这个参数,查询不会按照需要进行优化。这里我们需要做的是确保该选项在配置文件中没有被注释掉。 3. 分区和约束排除: 约束排除(Constraint exclusion)是一种查询优化技巧,它改进了用上面方法定义的表分区的性能。比如: 如果没有约束排除,上面的查询会扫描measurement表中的每一个分区。打开了约束排除之后,规划器将检查每个分区的约束然后再视图证明该分区不需要被扫描,因为它不能包含任何符合WHERE子句条件的数据行。如果规划器可以证明这个,它就把该分区从查询规划里排除出去。 你可以使用EXPLAIN命令显示一个规划在constraint_exclusion打开和关闭情况下的不同。用上面方法设置的表的典型的缺省规划是: 从上面的查询计划中可以看出,PostgreSQL扫描了所有分区。下面我们再看一下打开约束排除之后的查询计划: 请注意,约束排除只由CHECK约束驱动,而不会由索引驱动。 目前版本的PostgreSQL中该配置的缺省值是partition,该值是介于on和off之间的一种行为方式,即规划器只会将约束排除应用于基于分区表的查询,而on设置则会为所有查询都进行约束排除,那么对于普通数据表而言,也将不得不承担由该机制而产生的额外开销。 约束排除在使用时有以下几点注意事项: 1). 约束排除只是在查询的WHERE子句包含约束的时候才生效。一个参数化的查询不会被优化,因为在运行时规划器不知道该参数会选择哪个分区。因此像CURRENT_DATE这样的函数必须避免。把分区键值和另外一个表的字段连接起来也不会得到优化。 2). 在CHECK约束里面要避免跨数据类型的比较,因为目前规划器会无法证明这样的条件为假。比如,下面的约束会在x是整数字段的时候可用,但是在x是一个bigint的时候不能用: CHECK (x = 1) 对于bigint字段,我们必须使用类似下面这样的约束: CHECK (x = 1::bigint) 这个问题并不仅仅局限于bigint数据类型,它可能会发生在任何约束的缺省数据类型与其比较的字段的数据类型不匹配的场合。在提交的查询里的跨数据类型的比较通常是OK的,只是不能在CHECK条件里。 3). 在主表上的UPDATE和DELETE命令并不执行约束排除。 4). 在规划器进行约束排除时,主表上的所有分区的所有约束都将会被检查,因此,大量的分区会显著增加查询规划的时间。 5). 在执行ANALYZE语句时,要为每一个分区都执行该命令,而不是仅仅对主表执行该命令。

PostgreSQL教程(二):模式Schema详解 一个数据库包含一个或多个命名的模式,模式又包含表。模式还包含其它命名的对象,包括数据类型、函数,以及操作符。同一个对象名可以在不同的

PostgreSQL教程(四):数据类型详解 一、数值类型:下面是PostgreSQL所支持的数值类型的列表和简单说明:1.整数类型:类型smallint、integer和bigint存储各种范围的全部是数字的数,也就是没

PostgreSQL教程(五):函数和操作符详解(1) 一、逻辑操作符:常用的逻辑操作符有:AND、OR和NOT。其语义与其它编程语言中的逻辑操作符完全相同。二、比较操作符:下面是PostgreSQL中提供的比较

标签: PostgreSQL教程(三):表的继承和分区表详解

本文链接地址:https://www.jiuchutong.com/biancheng/312238.html 转载请保留说明!

上一篇:PostgreSQL教程(一):数据表详解

下一篇:PostgreSQL教程(二):模式Schema详解

  • 印花税的实质
  • 回购股票为什么股价下跌
  • 减免增值税计入其他收益
  • 小规模纳税人免税怎么做账
  • 自然人税收管理系统怎么申报个税
  • 外资企业享受什么优惠政策
  • 公司零申报怎么注销
  • 个人怎么捐赠物资
  • 资产负债表的编制方法和步骤
  • 财务离开公司需要交接哪些资料?
  • 售后维修费怎么开票
  • 采购折扣怎么结转成本?
  • 开出转账支票怎么入账
  • 小规模纳税人零申报是每季度报吗
  • 跨年度销售退回所得税
  • 小规模纳税人专票开1%还是3%
  • 劳务费开发票还要代扣代缴吗?
  • 建筑企业在增值税方面新出台的政策
  • 携税宝服务费可以入办公费吗
  • 什么叫未完税
  • 汇算清缴补交需要调报表吗
  • 微众银行账户验证账户0019向您尾号677账户
  • 免税销售额对应的进项税额
  • uv价值是怎么计算公式
  • 滴滴发票开公司名称可以抵扣进项吗
  • 奖金发放如何做账
  • 主营业务收入的计算公式
  • 计提水电费用什么科目
  • 技术合同指什么
  • PHP调用API
  • php 钩子
  • macos使用技巧
  • 网络和共享中心在哪里打开
  • 贷款损失准备的会计核算
  • PHP:iconv_get_encoding()的用法_iconv函数
  • json格式字符串提取值
  • php与ajax交互
  • php curl_exec
  • vue项目安装路由
  • wallengine
  • php设置目录权限
  • java桥接模式的应用场景
  • 业务招待费包括哪些内容和费用
  • 免税农产品包括30万元吗
  • 银行存款出现负数
  • 预收货款尚未发货
  • php 队列
  • 帝国cms批量添加文章
  • 劳务派遣工资的发放单位
  • SQL Server 2016 CTP2.2安装配置方法图文教程
  • 企业残障金缴纳标准
  • 小微企业免税销售额是多少2023年
  • 定期定额自行申报表
  • 一个公户从农业银行开户
  • 公司聚餐做什么科目
  • 房地产企业什么时候停止预缴增值税
  • sql自定义数据类型
  • sql判断字段是否有某个值
  • 修改注册表解决画面撕裂
  • ubuntu for lot
  • ubuntu基本配置
  • win8玩英雄联盟fps低怎么办
  • windowsxp有密码忘了怎么办
  • linux系统百科
  • win8怎么装驱动
  • mac内存管理在哪里
  • web项目可以打包成jar包吗
  • Windows下的写字板功能是
  • js如何使用
  • dosbox终止程序
  • 可重复进行编程的可编程器件有 ( )
  • linux小技巧
  • AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录
  • bud3d跑酷
  • JavaScript焦点事件、鼠标事件和滚轮事件使用详解
  • js prev()
  • 怎么设置python前面序号
  • 浅析是什么意思
  • 国家税务总局税务稽查科
  • 河南电子税务局电话
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设