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:nologging

mysql:参数:

[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 ();
 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐