PgSQL——学习笔记14:别名 & 触发器 & 索引

目录

PostgreSQL 别名:重命名一张表或者一个字段的名称

PostgreSQL 触发器:数据库的回调函数

创建触发器:

列出触发器:

删除触发器:

PostgreSQL 索引:加速搜索引擎检索数据的一种特殊表查询

CREATE INDEX 语句:创建索引

索引类型

单列索引:是一个只基于表的一个列上创建的索引

组合索引:是基于表的多列上创建的索引

唯一索引:不允许任何重复的值插入到表中

局部索引:是在表的子集上构建的索引

隐式索引:是在创建对象时,由数据库服务器自动创建的索引

列出表中的所有索引:/d table_name

列出数据库中所有索引:/di

删除索引:DROP INDEX index_name;


PostgreSQL 别名:重命名一张表或者一个字段的名称

我们可以用 SQL 重命名一张表或者一个字段的名称,这个名称就叫着该表或该字段的别名。

创建别名是为了让表名或列名的可读性更强。

SQL 中 使用 AS 来创建别名。

/*表的别名语法:*/
SELECT column1, column2....
FROM table_name AS alias_name
WHERE [condition];

/*列的别名语法:*/
SELECT column_name AS alias_name
FROM table_name
WHERE [condition];

 实例:

mydb=# select * from company;
 id | name  | age |                      address                       | salary | join_date
----+-------+-----+----------------------------------------------------+--------+-----------
  1 | Paul  |  32 | California                                         |  20000 |
  2 | Allen |  25 | Texas                                              |  15000 |
  3 | Teddy |  23 | Norway                                             |  20000 |
  4 | Mark  |  25 | Rich-Mond                                          |  65000 |
  5 | David |  27 | South-Hall                                         |  85000 |
  8 | Paul  |  24 | Houston                                            |  20000 |
  9 | James |  44 | Norway                                             |   5000 |
 10 | James |  45 | Texas                                              |   5000 |
  6 | Kim   |  22 |                                                    |        |
  7 | James |  24 |                                                    |        |
(10 行记录)


mydb=# select * from department;
 id |                        dept                        | emp_id
----+----------------------------------------------------+--------
  1 | IT Billing                                         |      1
  2 | Engineering                                        |      2
  3 | Finance                                            |      7
  4 | Engineering                                        |      3
  5 | Finance                                            |      4
  6 | Engineering                                        |      5
  7 | Finance                                            |      6
(7 行记录)

/*下面我们分别用 C 和 D 表示 COMPANY 表和 DEPAERMENT 表的别名:*/
mydb=# SELECT C.ID, C.NAME, C.AGE, D.DEPT FROM COMPANY AS C, DEPARTMENT AS D WHERE  C.ID = D.EMP_ID;
 id | name  | age |                        dept
----+-------+-----+----------------------------------------------------
  1 | Paul  |  32 | IT Billing
  2 | Allen |  25 | Engineering
  7 | James |  24 | Finance
  3 | Teddy |  23 | Engineering
  4 | Mark  |  25 | Finance
  5 | David |  27 | Engineering
  6 | Kim   |  22 | Finance
(7 行记录)

/*下面,我们用 COMPANY_ID 表示 ID 列,COMPANY_NAME 表示 NAME 列,来展示列别名的用法:*/
mydb=# SELECT C.ID AS COMPANY_ID, C.NAME AS COMPANY_NAME, C.AGE, D.DEPT  FROM COMPANY AS C, DEPARTMENT AS D WHERE  C.ID = D.EMP_ID;
 company_id | company_name | age |                        dept
------------+--------------+-----+----------------------------------------------------
          1 | Paul         |  32 | IT Billing
          2 | Allen        |  25 | Engineering
          7 | James        |  24 | Finance
          3 | Teddy        |  23 | Engineering
          4 | Mark         |  25 | Finance
          5 | David        |  27 | Engineering
          6 | Kim          |  22 | Finance
(7 行记录)

PostgreSQL 触发器:数据库的回调函数

PostgreSQL 触发器是数据库的回调函数,它会在指定的数据库事件发生时自动执行/调用。

下面是关于 PostgreSQL 触发器几个比较重要的点:

  • PostgreSQL 触发器可以在下面几种情况下触发:

    • 在执行操作之前(在检查约束并尝试插入、更新或删除之前)。
    • 在执行操作之后(在检查约束并插入、更新或删除完成之后)。
    • 更新操作(在对一个视图进行插入、更新、删除时)。
  • 触发器的 FOR EACH ROW 属性是可选的,如果选中,当操作修改时每行调用一次;

  • 相反,选中 FOR EACH STATEMENT,不管修改了多少行,每个语句标记的触发器执行一次。

  • WHEN 子句和触发器操作在引用 NEW.column-name 和 OLD.column-name 表单插入、删除或更新时可以访问每一行元素。其中 column-name 是与触发器关联的表中的列的名称。

    • 如果存在 WHEN 子句,PostgreSQL 语句只会执行 WHEN 子句成立的那一行;

    • 如果没有 WHEN 子句,PostgreSQL 语句会在每一行执行。

  • BEFORE 或 AFTER 关键字决定何时执行触发器动作,决定是在关联行的插入、修改或删除之前或者之后执行触发器动作。

  • 要修改的表必须存在于同一数据库中,作为触发器被附加的表或视图,且必须只使用 tablename,而不是 database.tablename。

  • 当创建约束触发器时会指定约束选项。这与常规触发器相同,只是可以使用这种约束来调整触发器触发的时间。当约束触发器实现的约束被违反时,它将抛出异常。

创建触发器:

/*创建触发器时的基础语法如下:*/
CREATE  TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name
ON table_name
[
 -- 触发器逻辑....
];

/*event_name 可以是在所提到的表 table_name 上的 INSERT、DELETE 和 UPDATE 数据库操作。*/
/*您可以在表名后选择指定 FOR EACH ROW。*/

/*以下是在 UPDATE 操作上在表的一个或多个指定列上创建触发器的语法:*/
CREATE  TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name
ON table_name
[
 -- 触发器逻辑....
];

列出触发器:

/*你可以把从 pg_trigger 表中把当前数据库所有触发器列举出来:*/
runoobdb=# SELECT * FROM pg_trigger;

/*列举出特定表的触发器,语法如下:*/
runoobdb=# SELECT tgname FROM pg_trigger, pg_class WHERE tgrelid=pg_class.oid AND relname='company';

删除触发器:

/*基础语法如下:*
drop trigger ${trigger_name} on ${table_of_trigger_dependent};

/*删除本文上表 company 上的触发器 example_trigger 的指令为:*/
drop trigger example_trigger on company;

实例: 

postgres=# \c learn

/*让我们假设一个情况,我们要为被插入到新创建的 COMPANY 表中的每一个记录保持审计试验:*/
learn=# CREATE TABLE COMPANY(
learn(#    ID INT PRIMARY KEY     NOT NULL,
learn(#    NAME           TEXT    NOT NULL,
learn(#    AGE            INT     NOT NULL,
learn(#    ADDRESS        CHAR(50),
learn(#    SALARY         REAL
learn(# );
CREATE TABLE

/*为了保持审计试验,我们将创建一个名为 AUDIT 的新表。每当 COMPANY 表中有一个新的记录项时,日志消息将被插入其中:*/
//EMP_ID 是来自 COMPANY 表的 ID,DATE 将保持 COMPANY 中记录被创建时的时间戳。
learn=# CREATE TABLE AUDIT(
learn(#    EMP_ID INT NOT NULL,
learn(#    ENTRY_DATE TEXT NOT NULL
learn(# );
CREATE TABLE

/*在 COMPANY 表上创建一个触发器,如下所示:*/
learn=# CREATE TRIGGER example_trigger AFTER INSERT ON COMPANY FOR EACH ROW EXECUTE PROCEDURE auditlogfunc();
错误:  函数 auditlogfunc() 不存在

/*auditlogfunc() 是 PostgreSQL 一个程序,其定义如下:*/
learn=# CREATE OR REPLACE FUNCTION auditlogfunc() RETURNS TRIGGER AS $example_table$
learn$#    BEGIN
learn$#       INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, current_timestamp);
learn$#       RETURN NEW;
learn$#    END;
learn$# $example_table$ LANGUAGE plpgsql;
CREATE FUNCTION

/*在 COMPANY 表上创建一个触发器,如下所示:*/
learn=# CREATE TRIGGER example_trigger AFTER INSERT ON COMPANY FOR EACH ROW EXECUTE PROCEDURE auditlogfunc();
CREATE TRIGGER

/*往 COMPANY 表中插入数据:*/
learn=# INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Paul', 32, 'California', 20000.00 );
INSERT 0 1

learn=# select * from company;
 id | name | age |                      address                       | salary
----+------+-----+----------------------------------------------------+--------
  1 | Paul |  32 | California                                         |  20000
(1 行记录)
/*这时,COMPANY 表中插入了一条记录:*/
/*同时, AUDIT 表中也插入了一条记录,因为我们在插入 COMPANY 表时创建了一个触发器。*/
learn=# select * from audit;
 emp_id |          entry_date
--------+-------------------------------
      1 | 2022-05-19 14:58:52.062211+08
(1 行记录)

/*从 pg_trigger 表中把当前数据库所有触发器列举出来:*/
learn=# select * from pg_trigger;
 tgrelid |     tgname      | tgfoid | tgtype | tgenabled | tgisinternal | tgconstrrelid | tgconstrindid | tgconstraint | tgdeferrable | tginitdeferred | tgnargs | tgattr | tgargs | tgqual | tgoldtable | tgnewtable
---------+-----------------+--------+--------+-----------+--------------+---------------+---------------+--------------+--------------+----------------+---------+--------+--------+--------+------------+------------
   17156 | example_trigger |  17170 |      5 | O         | f            |             0 |             0 |            0 | f            | f              |       0 |        | \x     |        |            |
(1 行记录)

/*列举出特定表的触发器,语法如下:*/
learn=# SELECT tgname FROM pg_trigger, pg_class WHERE tgrelid=pg_class.oid AND relname='company';
     tgname
-----------------
 example_trigger
(1 行记录)

/*删除上表 company 上的触发器 example_trigger 的指令为:*/
learn=# drop trigger example_trigger on company;
DROP TRIGGER
learn=# SELECT tgname FROM pg_trigger, pg_class WHERE tgrelid=pg_class.oid AND relname='company';
 tgname
--------
(0 行记录)

PostgreSQL 索引:加速搜索引擎检索数据的一种特殊表查询

索引是加速搜索引擎检索数据的一种特殊表查询。

简单地说,索引是一个指向表中数据的指针。

一个数据库中的索引与一本书的索引目录是非常相似的。

拿汉语字典的目录页(索引)打比方,我们可以按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到需要的字。

  • 索引有助于加快 SELECT 查询和 WHERE 子句,但它会减慢使用 UPDATE 和 INSERT 语句时的数据输入。索引可以创建或删除,但不会影响数据。
  • 使用 CREATE INDEX 语句创建索引,它允许命名索引,指定表及要索引的一列或多列,并指示索引是升序排列还是降序排列。

索引也可以是唯一的,与 UNIQUE 约束类似,在列上或列组合上防止重复条目。

CREATE INDEX 语句:创建索引

/*CREATE INDEX (创建索引)的语法如下:*/
CREATE INDEX index_name ON table_name;

索引类型

单列索引:是一个只基于表的一个列上创建的索引

/*基本语法如下:*/
CREATE INDEX index_name
ON table_name (column_name);

组合索引:是基于表的多列上创建的索引

/*基本语法如下:*/
CREATE INDEX index_name
ON table_name (column1_name, column2_name...);

不管是单列索引还是组合索引,该索引必须是在 WHERE 子句的过滤条件中使用非常频繁的列。

如果只有一列被使用到,就选择单列索引,如果有多列就使用组合索引。

唯一索引:不允许任何重复的值插入到表中

使用唯一索引不仅是为了性能,同时也为了数据的完整性。

/*基本语法如下:*/
CREATE UNIQUE INDEX index_name
on table_name (column_name);

局部索引:是在表的子集上构建的索引

子集由一个条件表达式定义。索引只包含满足条件的行。

/*基本语法如下:*/
CREATE INDEX index_name
on table_name (conditional_expression);

隐式索引:是在创建对象时,由数据库服务器自动创建的索引

索引自动创建为主键约束和唯一约束。

列出表中的所有索引:/d table_name

列出数据库中所有索引:/di

删除索引:DROP INDEX index_name;

实例:

/*在 COMPANY 表的 SALARY 列上创建索引:*/
learn=# CREATE INDEX salary_index ON COMPANY (salary);
CREATE INDEX

/*用 \d company 命令列出 COMPANY 表的所有索引:*/
learn=# \d company
                 数据表 "public.company"
  栏位   |     类型      | Collation | Nullable | Default
---------+---------------+-----------+----------+---------
 id      | integer       |           | not null |
 name    | text          |           | not null |
 age     | integer       |           | not null |
 address | character(50) |           |          |
 salary  | real          |           |          |
索引:
    "company_pkey" PRIMARY KEY, btree (id) /*company_pkey 是隐式索引 ,是表创建表时创建的:*/
    "salary_index" btree (salary)

/*用 \di 命令列出数据库中所有索引:*/
learn=# \di
                      关联列表
 架构模式 |     名称     | 类型 |  拥有者  | 数据表
----------+--------------+------+----------+---------
 public   | company_pkey | 索引 | postgres | company
 public   | salary_index | 索引 | postgres | company
(2 行记录)

/*DROP INDEX (删除索引)————删除之前创建的索引:*/
learn=# DROP INDEX salary_index;
DROP INDEX

learn=# \di
                      关联列表
 架构模式 |     名称     | 类型 |  拥有者  | 数据表
----------+--------------+------+----------+---------
 public   | company_pkey | 索引 | postgres | company
(1 行记录)

什么情况下要避免使用索引?

虽然索引的目的在于提高数据库的性能,但这里有几个情况需要避免使用索引。

使用索引时,需要考虑下列准则:

  • 索引不应该使用在较小的表上。
  • 索引不应该使用在有频繁的大批量的更新或插入操作的表上。
  • 索引不应该使用在含有大量的 NULL 值的列上。
  • 索引不应该使用在频繁操作的列上。

猜你喜欢

转载自blog.csdn.net/qq_41361442/article/details/124862735
今日推荐