首页 > 数据库 >PostgreSQL-表继承

PostgreSQL-表继承

时间:2022-09-03 15:25:35浏览次数:82  
标签:elevation 继承 父表 TABLE PostgreSQL 子表 cities

让我们从一个例子开始:假设我们正在尝试为城市构建一个数据模型。每个州都有许多城市,但只有一个首府。我们希望能够快速检索任何特定州的首都。这可以通过创建两张表来完成,一张用于州首府,一张用于非首都城市。但是,当我们想要查询一个城市的数据时会发生什么,无论它是否是首都?继承特性可以帮助解决这个问题。我们定义 capitals 表,以便它继承自cities:

CREATE TABLE cities (
    name            text,
    population      float,
    elevation       int     -- in feet
);

CREATE TABLE capitals (
    state           char(2)
) INHERITS (cities);

在这种情况下,capitals 表继承了其父表 citys 的所有列。州首府也有一个额外的列,州,显示他们的州。

在 PostgreSQL 中,一个表可以从零个或多个其他表继承,一个查询可以引用一个表的所有行或一个表的所有行加上它的所有后代表。后一种行为是默认行为。例如,以下查询查找海拔超过 500 英尺的所有城市的名称,包括州首府:

SELECT name, elevation
FROM cities
WHERE elevation > 500;

另一方面,以下查询查找所有非州首府且海拔超过 500 英尺的城市:

SELECT name, elevation
FROM ONLY cities
WHERE elevation > 500;

这里的 ONLY 关键字表示查询应该只应用于城市,而不是继承层次结构中城市下面的任何表。我们已经讨论过的许多命令——SELECT、UPDATE 和 DELETE——都支持 ONLY 关键字。

您还可以在表名后面加上 * 以明确指定包含后代表:

SELECT name, elevation
FROM cities*
WHERE elevation > 500;

不需要写 *,因为此行为始终是默认行为。但是,仍然支持此语法以与可以更改默认值的旧版本兼容。

在某些情况下,您可能希望知道特定行来自哪个表。每个表中都有一个名为 tableoid 的系统列,可以告诉您原始表:

SELECT c.tableoid, c.name, c.elevation
FROM cities c
WHERE c.elevation > 500;

通过使用 pg_class 进行连接,您可以看到实际的表名:

SELECT p.relname, c.name, c.elevation
FROM cities c, pg_class p
WHERE c.elevation > 500 AND c.tableoid = p.oid;

获得相同效果的另一种方法是使用 regclass 别名类型,它将象征性地打印表 OID:

SELECT c.tableoid::regclass, c.name, c.elevation
FROM cities c
WHERE c.elevation > 500;

继承不会自动将数据从 INSERT 或 COPY 命令传播到继承层次结构中的其他表。在我们的示例中,以下 INSERT 语句将失败:

INSERT INTO cities (name, population, elevation, state)
VALUES ('Albany', NULL, NULL, 'NY');

父表上的所有检查约束和非空约束都由其子表自动继承,除非使用 NO INHERIT 子句明确指定。不继承其他类型的约束(唯一、主键和外键约束)。

一个表可以从多个父表继承,在这种情况下,它具有父表定义的列的并集。子表定义中声明的任何列都会添加到这些列中。如果相同的列名出现在多个父表中,或者同时出现在父表和子表的定义中,则这些列被“合并”,这样子表中就只有一个这样的列。要合并,列必须具有相同的数据类型,否则会引发错误。可继承的检查约束和非空约束以类似的方式合并。因此,例如,如果合并列来自的任何一个列定义被标记为非空,则合并列将被标记为非空。检查约束如果名称相同则合并,如果条件不同则合并失败。

表继承通常在创建子表时使用 CREATE TABLE 语句的 INHERITS 子句建立。或者,已经以兼容方式定义的表可以使用 ALTER TABLE 的 INHERIT 变体添加新的父关系。为此,新的子表必须已经包含与父列具有相同名称和类型的列。它还必须包含与父项同名的检查约束和检查表达式。类似地,可以使用 ALTER TABLE 的 NO INHERIT 变体从子项中删除继承链接。当继承关系用于表分区时,像这样动态添加和删除继承链接可能很有用。

父表不能在其任何子表保留时被删除。如果从任何父表继承,子表的列或检查约束也不能被删除或更改。如果您希望删除一个表及其所有后代,一种简单的方法是使用 CASCADE 选项删除父表。

ALTER TABLE 将传播列数据定义中的任何更改并检查继承层次结构中的约束。同样,只有在使用 CASCADE 选项时才能删除其他表所依赖的列。ALTER TABLE 遵循与 CREATE TABLE 期间应用的重复列合并和拒绝相同的规则。

继承查询仅对父表执行访问权限检查。因此,例如,授予对城市表的 UPDATE 权限意味着当通过城市访问它们时,也允许更新 capitals 表中的行。这保留了数据(也)在父表中的外观。但是,如果没有额外的授权,就无法直接更新 capitals 表。以类似的方式,父表的行安全策略在继承查询期间应用于来自子表的行。子表的策略(如果有)仅在它是查询中显式命名的表时应用;在这种情况下,任何附加到其父级的策略都会被忽略。

外部表也可以是继承层次结构的一部分,可以作为父表或子表,就像常规表一样。如果外部表是继承层次结构的一部分,则外部表不支持的任何操作也不支持整个层次结构。

请注意,并非所有 SQL 命令都能够处理继承层次结构。用于数据查询、数据修改或模式修改的命令(例如,SELECT、UPDATE、DELETE、ALTER TABLE 的大多数变体,但不包括 INSERT 或 ALTER TABLE ... RENAME)通常默认包含子表并支持 ONLY符号以排除它们。执行数据库维护和调整的命令(例如 REINDEX、VACUUM)通常只适用于单个物理表,并且不支持对继承层次结构进行递归。

继承特性的一个严重限制是索引(包括唯一约束)和外键约束仅适用于单个表,而不适用于它们的继承子表。

标签:elevation,继承,父表,TABLE,PostgreSQL,子表,cities
From: https://www.cnblogs.com/shigongp/p/16652643.html

相关文章

  • PostgreSQL-schema
    数据库包含一个或多个命名模式,这些模式又包含表。模式还包含其他类型的命名对象,包括数据类型、函数和运算符。相同的对象名称可以在不同的模式中使用而不会发生冲突;例如,sch......
  • PostgreSQL-更改表
    当您创建一个表并意识到您犯了一个错误,或者应用程序的需求发生变化时,您可以删除该表并重新创建它。但是,如果表已经被数据填充,或者表被其他数据库对象引用(例如外键约束),这不......
  • PostgreSQL-系统列
    每个表都有几个由系统隐式定义的系统列。因此,这些名称不能用作用户定义列的名称。(请注意,这些限制与名称是否是关键字是分开的;引用名称不会让您逃避这些限制。)您实际上不需......
  • PostgreSQL-基础2
    一、类型转换的方式CAST(expressionAStype)expression::typetypename(expression)二、生成列生成的列是始终从其他列计算的特殊列。因此,对于列,视图对于表是......
  • Java中具有继承的对象序列化
    在序列化中,当引入继承时,则根据超类和子类定义了某些情况,这使对每种情况下的序列化的理解变得更加简单。应遵循的基本规则如下。1.当超类实现时,可序列化接口而子类则不。......
  • 面向对象(方法、继承、重写)
    前言本文主要介绍方法(实例方法、类方法、静态方法)、继承(单继承和多继承)以及重写等内容。一、方法1、实例方法用户自定义的方法。classStudent:#类属性stu......
  • 19 | JAVA反射之获取继承关系
    反射获取继承关系获取父类的Class有了Class实例,我们还可以获取它的父类的Class://reflectionpublicclassMain{publicstaticvoidmain(String[]args)thro......
  • PostgreSql 数据库导出
    运行位置在安装目录的的bean文件夹下(有一个pg_dump文件)。命令pg_dump-h127.0.0.1-p5432-Upostgres-dxxx>C:\Users\admin\Desktop\临时文件\xxx.sql-h:ip地......
  • Windows 系统 PostgreSQL 手工安装配置方法
    自从2020年底开始接触PostgreSQL以来就喜欢上了这个数据库,个人感觉比MySQL好用,多表联合查询性能好很多,同时也不存在SQLServer的版权授权费用问题。搭配.NET开发很......
  • PostgreSQL-标识符
    一、标识符标识符由字母或下划线()开头,标识符中的后续字符可以是字母、下划线、数字或美元符号。请注意,根据SQL标准的字母,标识符中不允许使用美元符号,因此使用它们可能会使......