PG数据库管理 --对象(relation管理)总结
UNLOGGED表是从PostgreSQL9.1版本开始新增的一种表,主要是通过禁止产生WAL日志的方式提升写性能。因为没有WAL日志,所以表的内容无法在主备库直接同步,如果此时数据库异常宕机,表的内容将丢失,所以可以把UNLOGGED表称为“半临时表”。当然如果数据库是正常关机的,则UNLOGGED表的内容不会丢失。注意 在PostgreSQL中,不管是事务级的临时表还是会话级的临时表,当会话结
PT复制表:
create table t(like test including all/constraints/ indexes/ storage/ comments/);
create table t as select * from test with no data ;
TOAST技术
在介绍表的存储属性之前,这里先讲解一个TOAST技术,“TOAST”是“The Oversized-Attribute Storage Technique”的缩写,主要用于存储大字段的值。由于PostgreSQL页面的大小是固定的(通常是8KB),并且不允许行跨越多个页面,因此不可能直接存储非常大的字段值。为了突破这个限制,大的字段值通常被压缩或切片成多个物理行存到另一张系统表中,即TOAST表。
固定值2040字节<版本11<参数控制
postgres=# ALTER TABLE blog ALTER content SET STORAGE EXTERNAL;
11以后可以设置参数控制。
alter table test01 set (toast_tuple_target=128);
表的 fillfactor 参数
在 PostgreSQL 中,fillfactor 是一个存储参数,用于控制表中数据页的填充程度。默认值为 100,表示页可以完全填满。降低 fillfactor 可以预留空间以减少更新操作时的页分裂。
可以通过查询 pg_class 系统表查看表的当前 fillfactor 值:
SELECT relname, reloptions FROM pg_class WHERE relname = 'your_table_name';
ALTER TABLE your_table_name SET (fillfactor = 70);
修改 fillfactor 后,现有数据不会自动重新组织。需要通过 VACUUM FULL 或 CLUSTER 命令重建表:
- 较低的
fillfactor会减少更新操作导致的页分裂,但会增加存储空间需求。 - 对于频繁更新的表,建议设置为 70-90。
- 对于只读或很少更新的表,可以保持默认值 100。
临时表
PostgreSQL支持两种临时表,一种是会话级的临时表;另一种是事务级的临时表。在会话级别的临时表中,数据可以一直保存在整个会话的生命周期中,而在事务级别的临时表中,数据只存在于这个事务的生命周期中。
注意 在PostgreSQL中,不管是事务级的临时表还是会话级的临时表,当会话结束时都会消失,这与Oracle数据库不同,在Oracle数据库中,只是临时表中的数据消失,而临时表还存在。
默认创建的临时表是会话级别的,需要创建事务级别的可以使用ON COMMIT DELETE ROWS;
实际上,“ON COMMIT”子句有以下3种形式。
• ON COMMIT PRESERVE ROWS:若不带“ON COMMIT”子句,默认情况下,数据会一直存在于整个会话周期中。
• ON COMMIT DELETE ROWS:数据只存在于事务周期中,事务提交后数据就消失了。
• ON COMMIT DROP
UNLOGGED 表
UNLOGGED表是从PostgreSQL9.1版本开始新增的一种表,主要是通过禁止产生WAL日志的方式提升写性能。因为没有WAL日志,所以表的内容无法在主备库直接同步,如果此时数据库异常宕机,表的内容将丢失,所以可以把UNLOGGED表称为“半临时表”。当然如果数据库是正常关机的,则UNLOGGED表的内容不会丢失。
创建UNLOGGED表的命令是“CREATE UNLOGGED TABLE”,如下:
osdba=# CREATE UNLOGGED TABLE unlogged01(id int primary key, t text);
oralce:nologgingmysql:参数:
[mysqld]
replicate-ignore-db = database_name
replicate-ignore-table = database_name.table_name
pg数据库''和NULL也是不一致的类比MYSQL
postgres=# insert into t1 values('');
INSERT 0 1
postgres=# insert into t1 values('a');
INSERT 0 1
postgres=# insert into t1 values('B');
INSERT 0 1
postgres=# insert into t1 values('C');
INSERT 0 1
postgres=# insert into t1 values('D');
INSERT 0 1
postgres=# select * from t1 where name is NULL;
name
------
(0 行记录)
postgres=# select * from t1 where name='';
name
------(1 行记录)
postgres=# insert into t1 values(NULL);
INSERT 0 1
postgres=# select * from t1 where name='';
name
------(1 行记录)
postgres=# select * from t1 where name is NULL;
name
------(1 行记录)
postgres=#
触发器

普通触发器
CREATE OR REPLACE FUNCTION log_change()
RETURNS TRIGGER AS $$
BEGIN
-- 记录变更到日志表
INSERT INTO change_log (changed_at, changed_by, table_name, operation)
VALUES (now(), current_user, TG_TABLE_NAME, TG_OP);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_before_employee_change
BEFORE INSERT OR UPDATE ON employees
FOR EACH ROW EXECUTE FUNCTION log_change();FOR STATEMENT EXECUTE FUNCTION log_change();
event触发器
CREATE OR REPLACE FUNCTION student_delete_trigger()
RETURNS TRIGGER AS $$
BEGIN
DELETE FROM score WHERE student_no = OLD.student_no;
RETURN OLD;
END;
$$
LANGUAGE plpgsql;
再创建触发器:
CREATE TRIGGER delete_student_trigger
AFTER DELETE ON student
FOR EACH ROW EXECUTE PROCEDURE student_delete_trigger ();
statement触发器
CREATE FUNCTION log_student_trigger ()
RETURNS trigger AS
$$
BEGIN
INSERT INTO log_student values(now(), user, TG_OP);
RETURN NULL;
END;
$$
LANGUAGE "plpgsql";
上面函数中的“TG_OP”是触发器函数中的特殊变量,代表DML操作类型。
然后在表“student”上创建一个语句级触发器:
CREATE TRIGGER log_student_trigger
AFTER INSERT OR DELETE OR UPDATE ON student
FOR STATEMENT EXECUTE PROCEDURE log_student_trigger ();
更多推荐
所有评论(0)