iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
自我挑戰組

Hello SQL 初次見面你好系列 第 16

Day 16 在 PostgreSQL 中使用 序列(sequence)

  • 分享至 

  • xImage
  •  

在 PostgreSQL 中,序列(sequence)是一種特殊的數據庫對象

它可以生成一個獨一無二的整數序列,經常用於為資料表中的主鍵列生成唯一的值

這與其他數據庫系統中的自動增長列(auto-increment column)或 identity 列功能相似

如何使用序列

建立序列

要創建一個新的序列,你可以使用 CREATE SEQUENCE 語句:

CREATE SEQUENCE my_serial START 1;

CREATE SEQUENCE

這會創建一個名為 my_serial 的序列,從 1 開始

讓我們來查看一下,跟查看 table 的方式一樣可以使用 SELECT * FROM sequence_name:

SELECT * FROM my_serial;

 last_value | log_cnt | is_called
------------+---------+-----------
          1 |       0 | f
(1 row)
  1. last_value: 這個欄位顯示的是最近一次從序列中獲取的值。不過,這個值可能會變,因為序列會根據增量進行更新

  2. log_cnt: 這個欄位通常與序列的緩存大小有關。在 PostgreSQL 中,序列的緩存大小是指一次性從序列中獲取的值的數量。log_cnt 欄位通常顯示這個緩存中尚未使用的值的數量。在一些 PostgreSQL 的版本中,這個欄位可能不會顯示。

  3. is_called
    這個欄位是一個布爾值,用於表示序列中的最後一個值是否已經被調用過。如果 is_calledt,則表示 last_value 已經被賦予了一個資料行。如果 is_calledf,則表示 last_value 尚未被使用。這個欄位通常在調用 setval 函數時會被設定。

使用序列生成值

要從序列中獲取下一個值,你可以使用 nextval 函數:

SELECT nextval('my_serial');
  • 注意:每次使用 nextval 函數,序列都會生成下一個整數

設定資料表中的欄位自動使用序列值

當建立資料表時,你可以使用 SERIAL 類型來為某個欄位自動建立並使用序列:

  • 通常會用在 id 這個流水編號,大部分情況都是作為 PRIMARY KEY 使用
CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100)
);

使用 \z 來查看現在資料庫的結構

demo_db=# \z
                                    Access privileges
 Schema |       Name       |   Type   | Access privileges | Column privileges | Policies
--------+------------------+----------+-------------------+-------------------+----------
 public | employees        | table    |                   |                   |
 public | employees_id_seq | sequence |                   |                   |
(2 rows)

我們可以看到我們建立 employees 資料表時,因為我們的 id 使用 SERIAL 作爲欄位類型 ,所以 PostgreSQL 自動幫我們做了一個 employees_id_seq 的序列

再深入查看 employees table,使用 \d 指令

demo_db=# \d employees
                                    Table "public.employees"
 Column |          Type          | Collation | Nullable |                Default
--------+------------------------+-----------+----------+---------------------------------------
 id     | integer                |           | not null | nextval('employees_id_seq'::regclass)
 name   | character varying(100) |           |          |
Indexes:
    "employees_pkey" PRIMARY KEY, btree (id)
  • regclass: 一種特殊的數據類型,它用於存儲對資料庫中表(或其他與表相關的對象,如序列)的引用,所以我們的例子中 'employees_id_seq'::regclass 他會將前面的字串 "employees_id_seq" 轉換成 regclass 類型,使得 PostgreSQL 去找到符合的對象

我們可以看到 id 的預設值就是,nextval('employees_id_seq'::regclass),所以 id 就會不斷的長下去,並不會重複

自動增長列

在 PostgreSQL 中,使用 SERIAL 類型來創建自動增長列是常見的做法,這會自動創建並設定一個序列。

插入數據

當你為具有自動增長列的資料表插入數據時,你不需要手動為該列指定值:

INSERT INTO employees (name) VALUES ('John');

這樣,id 欄位的值會自動由對應的序列生成

其他 RDBMS 是如何做到呢?

MYSQL

在設定欄位時加上 AUTO_INCREMENT 就可以了

CREATE TABLE employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100)
);

SQL Server

SQL Server 則是在設定欄位時使用 IDENTITY

CREATE TABLE customers (
  C_Id INT IDENTITY PRIMARY KEY,
  Name varchar(50),
  Address varchar(255),
  Phone varchar(20)
);

自定義你的序列

在 PostgreSQL 中,您可以在創建序列時進行各種自定義設定
例如設定最小值、最大值、起始值和增量值等。下面是一個創建序列的範例,其中展示了如何設定這些屬性:

CREATE SEQUENCE custom_sequence
    START WITH 1  -- 設定序列的起始值
    INCREMENT BY 2  -- 設定每次增量值
    MINVALUE 1  -- 設定序列的最小值
    MAXVALUE 1000  -- 設定序列的最大值
    NO CYCLE;  -- 表示當序列達到最大值時不會循環到最小值重新開始

在此例中:

  • START WITH 1:序列從 1 開始。
  • INCREMENT BY 2:每次從序列中獲取值時,序列的當前值會增加 2。
  • MINVALUE 1MAXVALUE 1000:序列的值將始終位於 1 和 1000 之間。
  • NO CYCLE:當序列達到 MAXVALUE 時,將不會循環回 MINVALUE

當您從這個序列中獲取值時,第一個值將是 1,接下來將是 3,5,7,依此類推,直到 999
因為設定了 NO CYCLE,所以當序列達到 999(最大值)時,將無法再從這個序列中獲取更多的值
如果您希望序列在達到最大值後循環回最小值並重新開始,您可以使用 CYCLE 關鍵

  • 但是應該通常不會有人這樣做 ?

預設的序列

-- 我們建立一個預設的序列

CREATE SEQUENCE all_default;

-- 在用 \d 指令查看

\d all_default
                        Sequence "public.all_default"

  Type  | Start | Minimum |       Maximum       | Increment | Cycles? | Cache
--------+-------+---------+---------------------+-----------+---------+-------
 bigint |     1 |       1 | 9223372036854775807 |         1 | no      |     1

序列好處和注意事項

好處

  1. 簡單性和便利性:序列和自動增長列使得生成唯一識別符變得非常簡單。
  2. 一致性和完整性:自動生成的唯一值有助於維護數據的一致性和完整性。

注意事項

  1. 性能:雖然序列生成是高效的,但在高並發環境中,序列可能會成為性能瓶頸。
  2. 管理和維護:序列的管理和維護需要注意,例如,如果序列的值用完,可能需要重新設定序列

上一篇
Day 15 SQL 檢視表(VIEW)
下一篇
Day 17 處理日期、時間與字串相關函數
系列文
Hello SQL 初次見面你好30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言