PostgreSQL-基础2
一、类型转换的方式
CAST ( expression AS type )
expression::type
typename ( expression )
二、生成列
生成的列是始终从其他列计算的特殊列。因此,对于列,视图对于表是一样的。生成的列有两种:存储列和虚拟列。存储生成的列在写入(插入或更新)时计算,并像普通列一样占用存储空间。虚拟生成的列不占用存储空间,在读取时计算。因此,虚拟生成列类似于视图,存储生成列类似于实体化视图(除了它总是自动更新)。PostgreSQL 目前只实现存储生成的列。
要创建生成的列,请使用 CREATE TABLE 中的 GENERATED ALWAYS AS 子句,例如:
CREATE TABLE people (
...,
height_cm numeric,
height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED
);
无法直接写入生成的列。在 INSERT 或 UPDATE 命令中,不能为生成的列指定值,但可以指定关键字 DEFAULT。
考虑具有默认值的列和生成的列之间的差异。如果没有提供其他值,则在第一次插入行时使用列默认值;每当行更改并且无法覆盖时,都会更新生成的列。列默认值可能不引用表的其他列;生成表达式通常会这样做。列默认值可以使用 volatile 函数,例如 random() 或引用当前时间的函数;这对于生成的列是不允许的。
限制:
- 生成表达式只能使用不可变函数,不能使用子查询或以任何方式引用当前行以外的任何内容。
- 生成表达式不能引用另一个生成的列。
- 生成表达式不能引用系统列,tableoid 除外。
- 生成列不能有列默认值或标识定义。生成列不能是分区键的一部分。
- 外部表可以具有生成列。
- 对于继承:
如果父列是生成列,则子列也必须是使用相同表达式的生成列。
在子列的定义中,省略 GENERATED 子句,因为它将从父列复制。
在多重继承的情况下,如果一个父列是生成列,则所有父列必须是生成列并且具有相同的表达式。如果父列不是生成列,则可以将子列定义为生成列或不生成列。
注意:
- 生成列独立于其基础基列维护访问权限。因此,可以对其进行安排,以便特定角色可以从生成列中读取,但不能从基础基列中读取。
- 从概念上讲,生成列在 BEFORE 触发器运行后更新。因此,在 BEFORE 触发器中对基本列所做的更改将反映在生成列中。但相反,不允许访问 BEFORE 触发器中生成列。
三、外键
外键由表中的一个字段或者多个字段构成,一个表的外键用来指向另一个表的主键(Primary Key);包含外键的表称为从表,被指向的表称为主表。从表的数据受到主表的约束,向从表中插入或者更新数据时,外键的值必须存在于主表的主键中。
create table products(
product_no serial primary key,
name varchar(100),
price numeric
);
create table prodcuct_item(
id serial primary key,
product_no integer references products(product_no),
txt_desc text
);
insert into products(name,price) values('产品1',100);
insert into products(name,price) values('产品2',300);
insert into products(name,price) values('产品3',500);
插入product_no在producs表中存在的记录:
insert into prodcuct_item(product_no,txt_desc) values(1,'测试1');
插入product_no在producs表中不存在的记录:
insert into prodcuct_item(product_no,txt_desc) values(4,'测试4');
当删除products中的记录时,prodcduct_item中的外键product_no怎么处理呢?
1.NO ACTION
2.RESTRICT
3.CASCADE
4.SET NULL
5.SET DEFAULT
限制和级联删除是两个最常见的选项。RESTRICT 防止删除引用的行。NO ACTION 表示如果在检查约束时仍然存在任何引用行,则会引发错误;如果您不指定任何内容,这是默认行为。(这两种选择之间的本质区别是 NO ACTION 允许将检查推迟到事务的后期,而 RESTRICT 不允许。) CASCADE 指定当一个引用的行被删除时,引用它的行应该被自动删除也是。还有两个其他选项:SET NULL 和 SET DEFAULT。当被引用的行被删除时,这些会导致引用行中的引用列被分别设置为空值或它们的默认值。
外键设置为NO ACTION:
删除主表:
delete from products where product_no=1;
外键设置为RESTRICT:
create table prodcuct_item(
id serial primary key,
product_no integer references products(product_no) ON DELETE RESTRICT,
txt_desc text
);
insert into prodcuct_item (product_no,txt_desc) values(1,'测试1');
当外键设置为ON DELETE CASCADE:
create table prodcuct_item(
id serial primary key,
product_no integer references products(product_no) ON DELETE CASCADE,
txt_desc text
);
insert into prodcuct_item (product_no,txt_desc) values(1,'测试1');
当外键设置为SET NULL:
create table prodcuct_item(
id serial primary key,
product_no integer references products(product_no) ON DELETE set null,
txt_desc text
);
insert into prodcuct_item (product_no,txt_desc) values(2,'测试2');
delete from products where product_no =2;
当外键设置为SET DEFAULT:
create table prodcuct_item(
id serial primary key,
product_no integer references products(product_no) ON DELETE set default,
txt_desc text
);
insert into prodcuct_item (product_no,txt_desc) values(2,'测试2');
四、排除约束
排除约束确保如果使用指定的运算符在指定的列或表达式上比较任意两行,则这些运算符比较中的至少一个将返回 false 或 null。语法是:
CREATE TABLE circles (
c circle,
EXCLUDE USING gist (c WITH &&)
);
例子参考https://blog.csdn.net/rudygao/article/details/50547465