PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Mới trong PostgreSQL 12:Các cột được tạo

PostgreSQL 12 đi kèm với một tính năng mới được gọi là cột được tạo . Các RDBMS phổ biến khác đã hỗ trợ các cột được tạo dưới dạng “cột được tính toán” hoặc “cột ảo”. Với Postgres 12, bây giờ bạn cũng có thể sử dụng nó trong PostgreSQL. Đọc để tìm hiểu thêm.

Cột được tạo là gì?

Một cột được tạo giống như một dạng xem, nhưng đối với các cột. Đây là một ví dụ cơ bản:

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=#

Chúng tôi đã tạo bảng t với hai cột thông thường được gọi là w h và một cột được tạo có tên là khu vực . Giá trị của khu vực là thời gian tạo không đổi được tính toán và được lưu giữ trên đĩa.

Giá trị của các cột đã tạo được tính toán lại khi hàng được cập nhật:

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

db=#

Chức năng như vậy trước đó thường đạt được với trình kích hoạt, nhưng với các cột được tạo, điều này sẽ trở nên thanh lịch và sạch sẽ hơn nhiều.

Một số điểm bạn nên biết về các cột đã tạo:

  • Tính bền bỉ :Hiện tại, giá trị của các cột đã tạo phải được bổ sung và không thể được tính toán nhanh tại thời điểm truy vấn. Từ khóa "ĐƯỢC LƯU TRỮ" phải có trong định nghĩa cột.
  • Biểu thức :Biểu thức được sử dụng để tính giá trị phải là không thay đổi , nghĩa là, nó phải có tính xác định. Nó có thể phụ thuộc vào các cột khác chứ không phụ thuộc vào các cột được tạo khác của bảng.
  • Chỉ mục :Các cột đã tạo có thể được sử dụng trong chỉ mục, nhưng không thể được sử dụng làm khóa phân vùng cho các bảng được phân vùng.
  • Sao chép và pg_dump :Giá trị của các cột đã tạo bị bỏ qua trong đầu ra của lệnh “pg_dump” và “COPY table”, vì nó là không cần thiết. Bạn không bao gồm chúng trong SAO CHÉP một cách rõ ràng bằng cách sử dụng COPY (SELECT * FROM t) TO STDOUT chứ không phải là COPY t TO STDOUT .

Ví dụ thực tế

Hãy thêm hỗ trợ tìm kiếm văn bản đầy đủ vào bảng bằng cách sử dụng các cột đã tạo. Đây là bảng lưu trữ toàn bộ nội dung của tất cả các vở kịch của 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
);

Đây là giao diện của dữ liệu:

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)

Chúng tôi sẽ thêm một cột sẽ chứa các lexemes trong giá trị "body". Hàm to_tsvector trả về các lexem mà chúng tôi cần:

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

Loại giá trị được trả về bởi to_tsvector là tsvector.

Hãy thay đổi bảng để thêm một cột đã tạo:

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

Bạn có thể thấy sự thay đổi với \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)

Và giống như vậy, bây giờ bạn có thể thực hiện tìm kiếm toàn văn:

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=#

Đọc thêm

Nếu bạn có nhu cầu về dữ liệu được tính toán trước / “đã lưu trong bộ nhớ cache”, đặc biệt là với khối lượng công việc ít lần ghi và nhiều lần đọc, các cột được tạo sẽ giúp đơn giản hóa mã ứng dụng / phía máy chủ của bạn rất nhiều.

Bạn có thể đọc tài liệu v12 về CREATE TABLE và ALTER TABLE để xem cú pháp được cập nhật.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bánh xe xây dựng không thành công cho psycopg2 - MacOSX sử dụng virtualenv và pip

  2. Python / postgres / psycopg2:nhận ID của hàng vừa được chèn

  3. PostgreSQL JOIN với kiểu mảng có thứ tự các phần tử mảng, cách thực hiện?

  4. PostgreSQL 12:Khóa ngoại và bảng phân vùng

  5. Làm cách nào để sử dụng tên cột động trong câu lệnh UPDATE hoặc SELECT trong một hàm?