继承
PostgreSQL 实现了表继承,这个特性对数据库设计人员来说是一个很有效的工具。SQL99 及以后的标准定义了类型继承特性,和我们在这里描述的很多特性有区别。
让我们从一个例子开始:假设我们试图制作一个城市数据模型。每个州都有许多城市,但是只有一个首府。我们希望能够迅速检索任何州的首府。这个任务可以通过创建两个表来实现,一个是州府表,一个是非州府表。不过,如果我们不管什么城市都想查该怎么办?继承的特性可以帮助我们解决这个问题。我们定义 capitals 表,它继承自 cities 表:
CREATE TABLE cities (
name text,
population float,
altitude int -- 英尺
);
CREATE TABLE capitals (
state char(2)
) INHERITS (cities);在这种情况下,capitals 表继承它的父表 cities 中的所有属性。州首府有一个额外的 state 属性显示其所在的州。
在 PostgreSQL 里,一个表可以从零个或多个其它表中继承属性,而且一个查询既可以引用一个表中的所有行,也可以引用一个表及其所有后代表的行(后面这个是缺省行为)。比如,下面的查询查找所有海拔 500 英尺以上的城市名,包括州首府:
SELECT name, altitude
FROM cities
WHERE altitude > 500;使用 PostgreSQL 教程里面的数据,它返回:
name | altitude
-----------+----------
Las Vegas | 2174
Mariposa | 1953
Madison | 845另一方面,如果要找出不包括州首府的所有海拔超过 500 英尺的城市,查询应该是这样的:
SELECT name, altitude
FROM ONLY cities
WHERE altitude > 500;
name | altitude
-----------+----------
Las Vegas | 2174
Mariposa | 1953cities 前面的 ONLY 表明该查询应该只针对 cities 而不包括其后代。许多我们已经讨论过的命令(SELECT, UPDATE, DELETE)都支持 ONLY 关键字。
有时候你可能想知道某个行版本来自哪个表。在每个表里我们都有一个 tableoid 系统属性可以告诉你源表是谁:
SELECT c.tableoid, c.name, c.altitude
FROM cities c
WHERE c.altitude > 500;结果如下(你可能会得到不同的 OID):
tableoid | name | altitude
----------+-----------+----------
139793 | Las Vegas | 2174
139793 | Mariposa | 1953
139798 | Madison | 845通过和 pg_class 做一个连接,就可以看到实际的表名字
SELECT p.relname, c.name, c.altitude
FROM cities c, pg_class p
WHERE c.altitude > 500 and c.tableoid = p.oid;它返回:
relname | name | altitude
----------+-----------+----------
cities | Las Vegas | 2174
cities | Mariposa | 1953
capitals | Madison | 845对于 INSERT 或 COPY ,继承并不自动影响其后代表。在我们的例子里,下面的 INSERT 语句将会失败:
INSERT INTO cities (name, population, altitude, state)
VALUES ('New York', NULL, NULL, 'NY');我们可能希望数据被传递到 capitals 表里面去,但这是不会发生的:INSERT 总是插入明确声明的那个表。在某些情况下,我们可以使用规则进行重定向插入(参阅章35)。不过它不能对上面的例子有什么帮助,因为 cities 表并不包含 state 字段,因此命令在规则施加之前就会被拒绝掉。
所有父表的检查约束和非空约束都会自动被所有子表继承。不过其它类型的约束(唯一、主键、外键)不会被继承。
一个子表可以从多个父表继承,这种情况下它将拥有所有父表字段的总和,并且子表中定义的字段也会加入其中。如果同一个字段名出现在多个父表中,或者同时出现在父表和子表的定义里,那么这些字段就会被"融合",这样在子表里就只有一个这样的字段。要想融合,字段的数据类型必须相同,否则就会抛出一个错误。融合的字段将会拥有其父字段的所有检查约束,并且如果某个父字段存在非空约束,那么融合后的字段也必须是非空的。
表继承通常使用带 INHERITS 子句的 CREATE TABLE 语句定义。另外,一个已经用此方法定义的子表可以使用带 INHERIT 的 ALTER TABLE 命令添加一个新父表。注意:该子表必须已经包含新父表的所有字段且类型一致,此外新父表的每个约束的名字及其表达式都必须包含在此子表中。同样,一个继承链可以使用带 NO INHERIT 的 ALTER TABLE 命令从子表上删除。允许动态添加和删除继承链对基于继承关系的表分区很有用。
创建一个将要作为子表的新表的便利途径是使用带 LIKE 子句的 CREATE TABLE 命令。它将创建一个与源表字段相同的新表。如果源表中存在约束,那么应该指定 LIKE 的 INCLUDING CONSTRAINTS 选项,因为子表必须包含源表中的 CHECK 约束。
任何存在子表的父表都不能被删除,同样,子表中任何从父表继承的字段也不能被删除或修改。如果你想删除一个表及其所有后代,最简单的办法是使用 CASCADE 选项。
ALTER TABLE 会把所有数据定义和检查约束传播到后代里面去。另外,只有在使用 CASCADE 选项的情况下,才能删除父表的字段或者约束。ALTER TABLE 在重复字段融合和拒绝方面和 CREATE TABLE 的规则相同。
5.8.1. 警告
表访问权限并不会自动继承。因此,要么同时具有访问父表与所有子表的权限,要么必须使用 ONLY 表示法。所以在添加新子表的时候,请注意给它赋予适当的权限。
继承的一个严重局限性是索引(包括唯一约束)和外键约束只能用于单个表,而不能包括它们的子表(不管对引用表还是被引用表都是如此),因此,在上面的例子里:
即使我们声明 cities.name 为 UNIQUE 或 PRIMARY KEY 也不会阻止 capitals 表拥有重复名字的 cities 数据行。并且这些重复的行在查询 cities 表的时候会显示出来。实际上,缺省时 capitals 将完全没有唯一约束,因此可能包含带有同名的多个行。你应该给 capitals 增加唯一约束,但即使这样做也不能避免与 cities 的重复。
类似的,即使我们声明 cities.name 参照(REFERENCES)某些其它的表,这个约束也不会自动传播到 capitals 表。在这种条件下,你可以通过手工给 capitals 表增加同样的 REFERENCES 约束来做到这点。
声明一个其它表的字段为 REFERENCES cities(name) 将允许其它表包含城市名,但是不包含首府名。这种情况下没有很好的绕开办法。
这些缺点很可能在将来的版本中修补,但同时你也需要考虑一下,继承是否对你的问题真正有用。
【已废弃】在7.1以前的 PostgreSQL 版本里,缺省的行为是不在查询里包含子表。后来发现这么做很容易出错并且也违反了 SQL 标柱。你可以通过关闭 sql_inheritance 配置选项来兼容以前的行为。
分享到:
相关推荐
PostgreSQL PostgreSQL PostgreSQL学习手册 学习手册 学习手册 (表的继承和分区 表的继承和分区 表的继承和分区 表的继承和分区 ) 10 一、表的继承: 一、表的继承: 一、表的继承: .10 PostgreSQL PostgreSQL ...
- **3.6 继承**:探讨 PostgreSQL 中继承机制的工作原理及使用场景。 - **3.7 结论**:总结 PostgreSQL 的核心特性和使用技巧。 以上内容覆盖了 PostgreSQL 9.6 官方文档的主要知识点,从基本概念到具体操作均有...
在PostgreSQL中,表的继承是一个非常有用且强大的特性,它可以使得一个表(子表)继承另一个表(父表)的所有列和约束。这为数据库设计提供了一种灵活的方式来组织相似类型的数据,特别是当需要对一组共享相同属性的...
-postgresql-是一个功能强大且开源的关系数据库管理系统,本手册旨在为读者提供一个系统的学习指南,涵盖PostgreSQL的基本概念、数据类型、模式设计、表的定义、继承和分区、函数和操作符等方面的知识点。...
PostgreSQL学习手册(表的继承和分区) PostgreSQL学习手册(常用数据类型) PostgreSQL学习手册(函数和操作符<一>) PostgreSQL学习手册(函数和操作符<二>) PostgreSQL学习手册(函数和操作符<三>) PostgreSQL学习手册...
PostgreSQL 是最初伯克利代码的一个开放源码的继承人。它支持大部分 SQL 标准并且提供了许多其它现代特性: 复杂查询 外键 触发器 视图 事务完整性 多版本并发控制 另外,PostgreSQL 可以用许多方法进行扩展...
首先,手册中介绍了PostgreSQL的基本概念和简史,说明了什么是PostgreSQL以及它的发展历程。接着,手册通过教程的形式逐步引导用户了解如何安装数据库、创建数据库以及如何访问和操作数据库。 在SQL语言方面,手册...
Postgres95是POSTGRES项目的最后一个版本,而PostgreSQL则是1996年后的开源继承者。 PostgreSQL在随后的版本迭代中不断增加新功能和改进性能。手册中提到的PostgreSQL 10.1版本,在其上一个版本PostgreSQL 9.6.0的...
在PostgreSQL中,一个重要的特性是表的继承功能,它允许创建一个表(子表)继承另一个表(父表)的特性。此外,PostgreSQL提供了多种扩展机制,通过安装扩展模块可以为系统增加额外的功能。 PostgreSQL的工具包括...
在PostgreSQL中,SQL语言被用来创建、修改、删除和查询数据库中的数据。从基本的表创建和数据填充,到复杂的表连接、聚合函数、数据更新和删除操作,这些都是数据库操作中不可或缺的部分。 教程还介绍了PostgreSQL...
1. **并行查询**:虽然在 PostgreSQL 8 中并行查询功能相对较弱,但了解其基本原理有助于理解后续版本的并行处理。 2. **分区表**:对于大型表,可以使用分区来提高查询效率和管理复杂性。 3. **PL/pgSQL 存储过程...
SERIAL类型字段在PostgreSQL中用于创建自增字段,类似于Oracle中的Sequence。表中也可以设置检查约束(CHECK constraints),以确保数据的完整性。例如,定义一个检查约束确保price字段必须大于0,或者指定字段名和...
PostgreSQL提供了如表继承、类型系统、函数重载和触发器等对象关系特性,使得数据库设计更加灵活且易于维护。 3. **性能提升** PostgreSQL 8.0在查询优化方面进行了显著改进,例如使用了更先进的查询规划器和执行...
6. **事务处理与并发控制**:理解ACID(原子性、一致性、隔离性、持久性)原则,以及PostgreSQL中的行级锁定机制。 7. **函数与过程**:掌握自定义函数的编写,包括内联函数、存储过程,以及使用PL/pgSQL和其他语言...
PostgreSQL是一款流行的开源对象关系数据库系统(ORDBMS),它使用SQL作为查询语言,并且支持复杂查询、外键、触发器、视图和事务完整性等功能。PostgreSQL的文档手册是学习和参考该数据库系统的重要资源。以下内容...
PostgreSQL是最初的伯克利代码的开源继承者。它支持大部分 SQL 标准并且提供了许多现代特性: 复杂查询 外键 触发器 可更新视图 事务完整性 多版本并发控制 同样,PostgreSQL可以用许多方法扩展,比如, ...
PostgreSQL的SQL语法遵循SQL标准,并扩展了诸如窗口函数、递归查询、物化视图、表继承等高级特性。这些功能使得PostgreSQL在数据分析和复杂的业务逻辑处理中具有强大优势。 安全性是另一个重要方面,PostgreSQL提供...
文档介绍了PostgreSQL的一些高级特性,比如视图(Views)、外键(Foreign Keys)、事务处理(Transactions)、窗口函数(Window Functions)和继承(Inheritance)等。 7. SQL语法 在文档的第二部分详细介绍了SQL...
3. Advanced Features(高级特性):介绍postgresql中更高级的特性,如视图、外键、事务、窗口函数、继承等。每个高级特性都有详细的解释和用例,帮助用户更有效地管理和操作数据库。 尽管给出的文档内容有所缺失,...