PgSQL - 学習ノート 14: エイリアス、トリガー、インデックス

目次

PostgreSQL エイリアス: テーブル名またはフィールド名の変更

PostgreSQL トリガー: データベース コールバック関数

トリガーを作成します。

トリガーのリスト:

トリガーの削除:

PostgreSQL インデックス: 検索エンジンによるデータの取得を高速化する特別なテーブル クエリ

CREATE INDEX ステートメント: インデックスを作成します。

インデックスの種類

単一列インデックス: テーブルの 1 つの列のみに基づいて作成されるインデックス

複合インデックス: テーブルの複数の列に対して作成されるインデックス

一意のインデックス: 重複した値をテーブルに挿入することを許可しません

ローカル インデックス: テーブルのサブセットに基づいて構築されたインデックスです。

暗黙的なインデックス: オブジェクトの作成時にデータベース サーバーによって自動的に作成されるインデックス

テーブル内のすべてのインデックスを一覧表示します: /d table_name

データベース内のすべてのインデックスを一覧表示します: /di

インデックスの削除: DROP INDEX インデックス名;


PostgreSQL エイリアス: テーブル名またはフィールド名の変更

SQL を使用してテーブルまたはフィールドの名前を変更できます。この名前はテーブルまたはフィールドのエイリアスと呼ばれます。

エイリアスは、テーブル名または列名を読みやすくするために作成されます。

AS はSQL で  エイリアスを作成するために使用されます。

/*表的别名语法:*/
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属性はオプションです。選択すると、操作が変更されたときに行ごとに 1 回呼び出されます。

  • 対照的に、 FOR EACH STATEMENTが選択されている場合、変更される行の数に関係なく、各ステートメントによってマークされたトリガーは 1 回実行されます。

  • WHEN 句とトリガー アクションは、NEW.column-name および OLD.column-name を参照するフォームを挿入、削除、または更新するときに、各行要素にアクセスできます。ここで、column-name は、トリガーに関連付けられたテーブル内の列の名前です。

    • WHEN 句が存在する場合、PostgreSQL ステートメントは WHEN 句が true である行のみを実行します。

    • WHEN 句を使用しない場合、PostgreSQL ステートメントは各行で実行されます。

  • BEFORE または AFTER キーワードは、関連付けられた行の挿入、変更、または削除の前か後かに関係なく、トリガー アクションがいつ実行されるかを決定します。

  • 変更するテーブルは、トリガーがアタッチされているテーブルまたはビューと同じデータベース内に存在する必要があり、database.tablename ではなく、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;

インデックスの種類

単一列インデックス:テーブルの 1 つの列のみに基づいて作成されるインデックス

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

複合インデックス: テーブルの複数の列に対して作成されるインデックス

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

単一列インデックスであっても複合インデックスであっても、インデックスは WHERE 句のフィルター条件で頻繁に使用される列である必要があります。

使用する列が 1 つだけの場合は単一列インデックスを選択し、複数の列がある場合は結合インデックスを使用します。

一意のインデックス:重複した値をテーブルに挿入することを許可しません

一意のインデックスの使用は、パフォーマンスのためだけでなく、データの整合性のためにも役立ちます。

/*基本语法如下:*/
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 インデックス名;

例:

/*在 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