在应用程序中通常采用不包含模式的表,当多个模式中存在同名的表时,就需要一种默认的方式指明具体的表。在PostgreSQL中就是通过搜索路劲来判断该表究竟是哪张表。搜索路劲就是一个需要查找的模式列表,搜索路劲中找到的第一个表就被当做选定的表。如果没有匹配的表就报错误,即使匹配表的名字在其他的模式(不在搜索路劲中)中也会报错。通过SHOW search_path查看。因此在添加了对应的模式下后,可能需要重新设置搜索路劲,否则可能无法直接查找到模式下的表。可以通过设置:
SET search_path TO "$user",public,newaddschema;
默认情况下,search_path是"$user",public。即在缺省的设置中搜索路劲(search_path)的第一个元素声明将要搜索一个和当前用户同名的模式。 因为还没有这样的模式存在,所以这条记录被忽略。第二个元素指向我们已经看过的公共模式。搜索路径中存在的第一个模式是创建新对象的缺省位置。 这就是为什么缺省的对象都会创建在 public 模式里的原因。如果在任何其它环境中引用对象,而且没有用模式修饰 (表修改,数据变更,或者查询命令),那么系统会遍历 搜索路径,直到找到一个匹配的对象。因此,在缺省的配置里, 任何未修饰的访问同样也只能引用 public 模式。
xxxx[xxxx@postgres]> create table city (name text, population float, altitude int);
CREATE TABLE
xxxx[xxxx@postgres]> \d city;
Table "public.city"
Column | Type | Modifiers
------------+------------------+-----------
name | text |
population | double precision |
altitude | integer |
xxxx[xxxx@postgres]>
xxxx[xxxx@postgres]>
xxxx[xxxx@postgres]> create table capitals(state char(2)) INHERITS(city);
CREATE TABLE
xxxx[xxxx@postgres]> \d capitals;
Table "public.capitals"
Column | Type | Modifiers
------------+------------------+-----------
name | text |
population | double precision |
altitude | integer |
state | character(2) |
Inherits: city
从上述的显示可知,在capital表中实际上包含了city的字段,其中capitals中只是添加了一个字段,但在表的描述中却直接继承了父类的成员。因此子表是比父表属性更多的表。
//插入数据到city表中
xxxx[xxxx@postgres]> insert into city(name, population, altitude) values ('zhangjiajie', 1.2, 1000), ('suzhou', 45, 20);
INSERT 0 2
//插入数据到capitals表中
xxxx[xxxx@postgres]> insert into capitals(name, population, altitude, state) values ('changsha', 102, 800, 'HN'), ('nanjing', 950, 30, 'JS');
INSERT 0 2
//查询city表, 其中数据包含了子表中的数据
xxxx[xxxx@postgres]> select * from city;
name | population | altitude
-------------+------------+----------
suzhou | 45 | 20
zhangjiajie | 1.2 | 1000
changsha | 102 | 800
nanjing | 950 | 30
(4 rows)
//查询子表,只包含子表中的数据
xxxx[xxxx@postgres]> select * from capitals;
name | population | altitude | state
----------+------------+----------+-------
changsha | 102 | 800 | HN
nanjing | 950 | 30 | JS
(2 rows)
//ONLY字段,只从父表中查询数据, 只包含了父表中的数据,并不包含子表中的数据。
xxxx[xxxx@postgres]> select * from only city;
name | population | altitude
-------------+------------+----------
suzhou | 45 | 20
zhangjiajie | 1.2 | 1000
(2 rows)
//更新父表中的数据属性
xxxx[xxxx@postgres]> update city SET population = 3 where name = 'zhangjiajie';
UPDATE 1
//通过父表更新子表中的数据成员
xxxx[xxxx@postgres]> update city SET population = 450 where name = 'changsha';
UPDATE 1
xxxx[xxxx@postgres]> select * from only city;
name | population | altitude
-------------+------------+----------
suzhou | 45 | 20
zhangjiajie | 3 | 1000
(2 rows)
xxxx[xxxx@postgres]> select * from city;
name | population | altitude
-------------+------------+----------
suzhou | 45 | 20
zhangjiajie | 3 | 1000
nanjing | 950 | 30
changsha | 450 | 800
(4 rows)
//删除父表中的数据
xxxx[xxxx@postgres]> delete from city where name = 'suzhou';
DELETE 1
//通过父表删除子表中的数据
xxxx[xxxx@postgres]> delete from city where name = 'nanjing';
DELETE 1
xxxx[xxxx@postgres]> select * from city;
name | population | altitude
-------------+------------+----------
zhangjiajie | 3 | 1000
changsha | 450 | 800
(2 rows)
继承定义了之后,没有办法从一个子表上删除一个继承关系, 除非是删除整个表。如果子表存在,则不能删除父表。 如果你想删除一个表和其所有后代,一个简单的方法是用 CASCADE 选项删除全部表。
xxxx[xxxx@postgres]> drop table city; //不能直接删除父表
ERROR: cannot drop table city because other objects depend on it
DETAIL: table capitals depends on table city
table subcity depends on table capitals
HINT: Use DROP ... CASCADE to drop the dependent objects too.
xxxx[xxxx@postgres]> drop table city CASCADE; //递归的形式删除父表、子表
NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table capitals
drop cascades to table subcity
DROP TABLE
对象标识符(OID) PostgreSQL 在内部使用对象标识符(OID)作为各种系统表的主键。 同时,系统不会给用户创建的表增加一个 OID 系统字段(除非在建表时声明了 WITH OIDS 或者是配置参数 default_with_oids 设置成了真)。 类型 oid 代表一个对象标识符。目前 oid 类型是用一个无符号的四字节整数实现的。 因此,它是不够用于提供大数据库范围内的唯一性保证的, 甚至在单个的大表中也不行。因此,我们不鼓励在用户创建的表中使用 OID 字段做主键。OID 最好只是用于引用系统表。