PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Baru Di PostgreSQL 12:Kolom yang Dihasilkan

PostgreSQL 12 hadir dengan fitur baru yang disebut kolom yang dihasilkan . RDBMSes populer lainnya sudah mendukung kolom yang dihasilkan sebagai "kolom yang dihitung" atau "kolom virtual." Dengan Postgres 12, Anda sekarang dapat menggunakannya di PostgreSQL juga. Baca terus untuk mempelajari lebih lanjut.

Apa itu kolom yang dihasilkan?

Kolom yang dihasilkan seperti tampilan, tetapi untuk kolom. Berikut ini contoh dasarnya:

db=# CREATE TABLE t (w real, h real, area real GENERATED ALWAYS AS (w*h) STORED);
CREATE TABLE
db=# INSERT INTO t (w, h) VALUES (10, 20);
INSERT 0 1
db=# SELECT * FROM t;
 w  | h  | area
----+----+------
 10 | 20 |  200
(1 row)

db=#

Kami membuat tabel t dengan dua kolom reguler yang disebut w dan h , dan kolom yang dihasilkan disebut area . Nilai luas dihitung pada waktu pembuatan, dan disimpan ke dalam disk.

Nilai kolom yang dihasilkan dihitung ulang saat baris diperbarui:

db=# UPDATE t SET w=40;
UPDATE 1
db=# SELECT * FROM t;
 w  | h  | area
----+----+------
 40 | 20 |  800
(1 row)

db=#

Fungsionalitas seperti itu sebelumnya biasanya dicapai dengan pemicu, tetapi dengan kolom yang dibuat, ini menjadi jauh lebih elegan dan bersih.

Beberapa poin yang harus Anda ketahui tentang kolom yang dihasilkan:

  • Kegigihan :Saat ini, nilai kolom yang dihasilkan harus dipertahankan, dan tidak dapat dihitung dengan cepat pada waktu kueri. Kata kunci “TERSIMPAN” harus ada dalam definisi kolom.
  • Ekspresi :Ekspresi yang digunakan untuk menghitung nilai harustidak dapat diubah , yaitu, harus deterministik. Itu dapat bergantung pada kolom lain, tetapi bukan kolom lain yang dihasilkan, dari tabel.
  • Indeks :Kolom yang dihasilkan dapat digunakan dalam indeks, tetapi tidak dapat digunakan sebagai kunci partisi untuk tabel yang dipartisi.
  • Salin dan pg_dump :Nilai kolom yang dihasilkan dihilangkan dalam output perintah “pg_dump” dan “COPY table”, karena tidak diperlukan. Anda dapat secara eksplisit memasukkannya ke dalam COPY menggunakan COPY (SELECT * FROM t) TO STDOUT daripada COPY t TO STDOUT .

Contoh Praktis

Mari tambahkan dukungan pencarian teks lengkap ke tabel menggunakan kolom yang dihasilkan. Berikut tabel yang menyimpan seluruh teks dari semua drama Shakespeare:

CREATE TABLE scenes (
    workid text,       -- denotes the name of the play (like "macbeth")
    act integer,       -- the act (like 1)
    scene integer,     -- the scene within the act (like 7)
    description text,  -- short desc of the scene (like "Macbeth's castle.")
    body text          -- full text of the scene
);

Berikut tampilan datanya:

shakespeare=# SELECT workid, act, scene, description, left(body, 200) AS body_start
shakespeare-# FROM scenes WHERE workid='macbeth' AND act=1 AND scene=1;
 workid  | act | scene |   description   |                  body_start
---------+-----+-------+-----------------+----------------------------------------------
 macbeth |   1 |     1 | A desert place. | [Thunder and lightning. Enter three Witches]+
         |     |       |                 |                                             +
         |     |       |                 | First Witch: When shall we three meet again +
         |     |       |                 | In thunder, lightning, or in rain?          +
         |     |       |                 |                                             +
         |     |       |                 | Second Witch: When the hurlyburly's done,   +
         |     |       |                 | When the battle's lost and won.             +
         |     |       |                 |
(1 row)

Kami akan menambahkan kolom yang akan berisi leksem dalam nilai "tubuh".Fungsi to_tsvectormengembalikan leksem yang kita butuhkan:

shakespeare=# SELECT to_tsvector('english', 'move moving moved movable mover movability');
             to_tsvector
-------------------------------------
 'movabl':4,6 'move':1,2,3 'mover':5
(1 row)

Jenis nilai yang dikembalikan oleh to_tsvector adalah tsvektor.

Mari kita ubah tabel untuk menambahkan kolom yang dihasilkan:

ALTER TABLE scenes
  ADD tsv tsvector
    GENERATED ALWAYS AS (to_tsvector('english', body)) STORED;

Anda dapat melihat perubahannya dengan \d :

shakespeare=# \d scenes
                                                Table "public.scenes"
   Column    |   Type   | Collation | Nullable |                               Default
-------------+----------+-----------+----------+----------------------------------------------------------------------
 workid      | text     |           | not null |
 act         | integer  |           | not null |
 scene       | integer  |           | not null |
 description | text     |           |          |
 body        | text     |           |          |
 tsv         | tsvector |           |          | generated always as (to_tsvector('english'::regconfig, body)) stored
Indexes:
    "scenes_pkey" PRIMARY KEY, btree (workid, act, scene)

Dan begitu saja, sekarang Anda dapat melakukan pencarian teks lengkap:

shakespeare=# SELECT
  workid, act, scene, ts_headline(body, q)
FROM (
  SELECT
    workid, act, scene, body, ts_rank(tsv, q) as rank, q
  FROM
    scenes, plainto_tsquery('uneasy head') q
  WHERE
    tsv @@ q
  ORDER BY
    rank DESC
  LIMIT
    5
) p
ORDER BY
  rank DESC;
  workid  | act | scene |                        ts_headline
----------+-----+-------+-----------------------------------------------------------
 henry4p2 |   3 |     1 | <b>Uneasy</b> lies the <b>head</b> that wears a crown.   +
          |     |       |                                                          +
          |     |       |    Enter WARWICK and Surrey                              +
          |     |       |                                                          +
          |     |       | Earl of Warwick
 henry5   |   2 |     2 | <b>head</b> assembled them?                              +
          |     |       |                                                          +
          |     |       | Lord Scroop: No doubt, my liege, if each man do his best.+
          |     |       |                                                          +
          |     |       | Henry V: I doubt not that; since we are well persuaded   +
          |     |       | We carry not a heart with us from hence
(2 rows)

shakespeare=#

Baca Selengkapnya

Jika Anda membutuhkan data pra-komputasi / "cache", terutama dengan beban kerja sedikit menulis dan banyak membaca, kolom yang dihasilkan akan sangat membantu menyederhanakan aplikasi / kode sisi server Anda.

Anda dapat membaca dokumentasi v12 dariCREATE TABLEdan ALTER TABLEuntuk melihat sintaks yang diperbarui.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menginstal hanya alat klien untuk PostgreSQL di Windows?

  2. Memasukkan nilai DEFAULT ke dalam kolom ketika parameternya NULL

  3. Bagaimana cara membaca semua baris dari tabel besar?

  4. Cara membersihkan SQL mentah di Rails 4

  5. sqlalchemy.exc.NoSuchModuleError:Tidak dapat memuat plugin:sqlalchemy.dialects:postgres