我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么理解PostgreSQL表继承

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么理解PostgreSQL表继承

这篇文章主要介绍“怎么理解PostgreSQL表继承”,在日常操作中,相信很多人在怎么理解PostgreSQL表继承问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解PostgreSQL表继承”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

PostgreSQL实现了表继承,这对数据库设计者来说是一种有用的工具(SQL:1999及其后的版本定义了一种类型继承特性,但和这里介绍的继承有很大的不同)。让我们从一个例子开始:假设我们要为城市建立一个数据模型。每一个州有很多城市,但是只有一个首府。我们希望能够快速地检索任何特定州的首府城市。这可以通过创建两个表来实现:一个用于州首府,另一个用于不是首府的城市。然而,当我们想要查看一个城市的数据(不管它是不是一个首府)时会发生什么?继承特性将有助于解决这个问题。我们可以将capitals表定义为继承自cities表:

jydb=# CREATE TABLE cities (
jydb(# name text,
jydb(# population float,
jydb(# altitude int -- in feet
jydb(# );
CREATE TABLE
jydb=# CREATE TABLE capitals (
jydb(# state char(2)
jydb(# ) INHERITS (cities);
CREATE TABLE
jydb=# insert into cities values('Las Vegas',600,2174);
INSERT 0 1
jydb=# insert into cities values('Mariposa',500,1953);
INSERT 0 1
jydb=# insert into cities values('Madison',450,845);
INSERT 0 1
jydb=# insert into capitals values('Houston',400,745,'LA');
INSERT 0 1
jydb=# select * from cities;
   name    | population | altitude
-----------+------------+----------
 Las Vegas |        600 |     2174
 Mariposa  |        500 |     1953
 Madison   |        450 |      845
 Houston   |        400 |      745
(4 rows)
jydb=# select * from capitals;
  name   | population | altitude | state
---------+------------+----------+-------
 Houston |        400 |      745 | LA
(1 row)

在这种情况下,capitals表继承了它父表cities的所有列。州首府还有一个额外的列state用来表示它所属的州。

在PostgreSQL中,一个表可以从0个或者多个其他表继承,而对一个表的查询则可以引用一个表的所有行或者该表的所有行加上它所有的后代表。默认情况是后一种行为。例如,下面的查询将查找所有海拔高于500尺的城市的名称,包括州首府:

jydb=# SELECT name, altitude FROM cities WHERE altitude > 500;
   name    | altitude
-----------+----------
 Las Vegas |     2174
 Mariposa  |     1953
 Madison   |      845
 Houston   |      745
(4 rows)

在另一方面,下面的查询将找到海拔超过500尺且不是州首府的所有城市:

jydb=# SELECT name, altitude FROM ONLY cities WHERE altitude > 500;
   name    | altitude
-----------+----------
 Las Vegas |     2174
 Mariposa  |     1953
 Madison   |      845
(3 rows)

这里的ONLY关键词指示查询只被应用于cities上,而其他在继承层次中位于cities之下的其他表都不会被该查询涉及。很多我们已经讨论过的命令(如SELECT、UPDATE和DELETE)都支持ONLY关键词。

我们也可以在表名后写上一个*来显式地将后代表包括在查询范围内:

jydb=# SELECT name, altitude FROM cities* WHERE altitude > 500;
   name    | altitude
-----------+----------
 Las Vegas |     2174
 Mariposa  |     1953
 Madison   |      845
 Houston   |      745
(4 rows)

*并不是必须的,因为它对应的行为是默认的(除非改变sql_inheritance配置选项的设置)。但是书写*有助于强调会有附加表被搜索。

在某些情况下,我们可能希望知道一个特定行来自于哪个表。每个表中的系统列tableoid可以告诉我们行来自于哪个表:

jydb=# SELECT c.tableoid, c.name, c.altitude FROM cities c WHERE c.altitude > 500;
 tableoid |   name    | altitude
----------+-----------+----------
    24653 | Las Vegas |     2174
    24653 | Mariposa  |     1953
    24653 | Madison   |      845
    24659 | Houston   |      745
(4 rows)

(如果重新生成这个结果,可能会得到不同的OID数字。)通过与pg_class进行连接可以看到实际的表名:

jydb=# SELECT p.relname, c.name, c.altitude
jydb-# FROM cities c, pg_class p
jydb-# WHERE c.altitude > 500 AND c.tableoid = p.oid;
 relname  |   name    | altitude
----------+-----------+----------
 cities   | Las Vegas |     2174
 cities   | Mariposa  |     1953
 cities   | Madison   |      845
 capitals | Houston   |      745
(4 rows)

另一种得到同样效果的方法是使用regclass伪类型, 它将象征性地打印出表的 OID:

jydb=# SELECT c.tableoid::regclass, c.name, c.altitude
jydb-# FROM cities c
jydb-# WHERE c.altitude > 500;
 tableoid |   name    | altitude
----------+-----------+----------
 cities   | Las Vegas |     2174
 cities   | Mariposa  |     1953
 cities   | Madison   |      845
 capitals | Houston   |      745
(4 rows)

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

jydb=# INSERT INTO cities (name, population, altitude, state) VALUES (’Albany’, NULL, NULL, ’NY’);
ERROR:  column "state" of relation "cities" does not exist
LINE 1: INSERT INTO cities (name, population, altitude, state) VALUE...

^

我们也许希望数据能被以某种方式被引入到capitals表中,但是这不会发生:INSERT总是向指定的表中插入。在某些情况下,可以通过使用一个规则(见第 39 章)来将插入动作重定向。但是这对上面的情况并没有帮助,因为cities表根本就不包含state列,因而这个命令将在触发规则之前就被拒绝。

父表上的所有检查约束和非空约束都将自动被它的后代所继承。其他类型的约束(唯一、主键和外键约束)则不会被继承。

一个表可以从多个父表继承,在这种情况下它拥有父表们所定义的列的并集。任何定义在子表上的列也会被加入到其中。如果在这个集合中出现重名列,那么这些列将被"合并",这样在子表中只会有一个这样的列。重名列能被合并的前提是这些列必须具有相同的数据类型,否则会导致错误。可继承的检查约束和非空约束以类似的方式合并。因此,例如,如果任何列定义被标记为not-null,则合并列将被标记为not-null。如果检查约束具有相同的名称,则合并它们;如果条件不同,则合并将失败。

表继承通常是在子表被创建时建立,使用CREATE TABLE语句的INHERITS子句。一个已经被创建的表也可以另外一种方式增加一个新的父亲关系,使用ALTER TABLE的INHERIT变体。要这样做,新的子表必须已经包括和父表相同名称和数据类型的列。子表还必须包括和父表相同的检查约束和检查表达式。相似地,一个继承链接也可以使用ALTER TABLE的 NO INHERIT变体从一个子表中移除。动态增加和移除继承链接可以用于实现表划分

一种创建一个未来将被用做子女的新表的方法是在CREATE TABLE中使用LIKE子句。这将创建一个和源表具有相同列的新表。如果源表上定义有任何CHECK约束,LIKE的INCLUDING CONSTRAINTS选项可以用来让新的子表也包含和父表相同的约束。

当有任何一个子表存在时,父表不能被删除。当子表的列或者检查约束继承于父表时,它们也不能被删除或修改。如果希望移除一个表和它的所有后代,一种简单的方法是使用CASCADE选项删除父表

ALTER TABLE将会把列的数据定义或检查约束上的任何变化沿着继承层次向下传播。同样,删除被其他表依赖的列只能使用CASCADE选项。ALTER TABLE对于重名列的合并和拒绝遵循与CREATE TABLE同样的规则。

继承查询只对父表执行访问权限检查。因此,例如,对cities表授予update权限会意味着通过cities访问capitals表时也能更新capitals表。这体现了子表中的数据也在父表中。但是capitals表在没有额外地授权情况下不能被直接更新。以类似的方式,父表的行安全策略在执行继承查询时会应用到子表的行记录。子表的策略(如果有的话)仅当它是查询中显式命名的表时才应用;在这种情况下,任何附加到其父级的策略都将被忽略。

外部表也可以是继承层次 中的一部分,即可以作为父表也可以作为子表,就像常规表一样。如果一个外部表是继承层次的一部分,那么任何不被该外部表支持的操作也不被整个层次所支持。

到此,关于“怎么理解PostgreSQL表继承”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么理解PostgreSQL表继承

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么理解Python类的继承

这篇文章主要讲解了“怎么理解Python类的继承”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解Python类的继承”吧!1、对继承的理解继承(Inheritance) :代码复用的高
2023-06-25

C++类的继承怎么理解

这篇文章主要讲解了“C++类的继承怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++类的继承怎么理解”吧!而基类中的公有成员在public派生时,不仅可以由派生类对象成员访问,也可
2023-06-17

C++继承与虚继承怎么实现

这篇文章主要介绍“C++继承与虚继承怎么实现”,在日常操作中,相信很多人在C++继承与虚继承怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++继承与虚继承怎么实现”的疑惑有所帮助!接下来,请跟着小编
2023-06-30

怎么解析PHP extends类继承

怎么解析PHP extends类继承,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。PHP extends类继承编写代码比较容易实现。对于初学者来说也是很容易就会
2023-06-17

java怎么继承类

一、基本知识(推荐:java视频教程)1、在Java语言中,实现类的继承使用extends关键字格式如下:[public] class SubClass extends SuperClass{  //类体的定义}2、被继承的类称为父类或超类或基类,而继承得到的
java怎么继承类
2018-09-11

C++中菱形继承怎么处理

本篇内容介绍了“C++中菱形继承怎么处理”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!封装,继承,多态。这是C++语言的三大特性,而每次在谈
2023-06-29

怎么在python中定义单继承和多继承

本篇文章为大家展示了怎么在python中定义单继承和多继承,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。python的数据类型有哪些?python的数据类型:1. 数字类型,包括int(整型)、lo
2023-06-14

如何理解VB.NET继承规则

如何理解VB.NET继承规则,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。VB.NET中也有继承相关应技术,而且相对于初学者来说并不是很好理解这一应用。下面就首先让我们从VB.
2023-06-17

如何理解PHP类的继承

如何理解PHP类的继承,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。PHP类的继承在PHP语言的学习中是一个比较重要的知识点。那么我们该如何正确的学习PHP类的继承呢?在P
2023-06-17

C++ 虚拟函数与继承:理解多态继承中的奥秘

虚拟函数和继承在面向对象编程中实现多态性:声明虚拟函数允许派生类重写基类方法,并根据对象的运行时类型调用。继承建立类层次,派生类可访问和扩展基类数据和方法。多态继承允许派生类从多个基类继承,最派生的对象可用所有基类的虚拟函数。虚拟函数的调用
C++ 虚拟函数与继承:理解多态继承中的奥秘
2024-04-28

编程热搜

目录