Skip to Content

unique 規則

unique 為一至三個欄位建立不可重複的複合鍵。典型用途是訂單編號,或「公司 + 外部系統 ID」的組合。它由資料庫層約束,可處理兩個請求同時通過前端檢查的競態。

Payload

{ "type": "unique", "name": "同一客戶的訂單編號不可重複", "columns": ["客戶", "訂單編號"], "case_insensitive": true }

columns 可包含 stored scalar(含 decimal),或 cardinality 為 one 的 link。json 欄位會被拒絕(json columns cannot be unique components …),computed 欄位(rollup、lookup 與 live formula;computation_mode: "stored" 的 formula v2 欄位則以其結果型別算作 stored scalar)、multi_select、interval、attachment、coordinate、principal_list 欄位與 cardinality many 的 link 也一樣。每條規則最多三個 component;同一個欄位出現兩次——顯示名稱與內部 key 視為同一欄——會回 400 duplicate component '<顯示名稱>'。一張表的 unique 約束總共最多五條,unique_tuple 規則也計入同一個上限(400 a table takes at most 5 unique rules)。

case_insensitive 預設為 false,省略即區分大小寫。設為 true 時會把每個文字形式的 component(string、text、select、date/datetime 文字、principal id)轉成小寫;link component 一律以原始目標 id 比較。它適合不區分大小寫的文字識別碼。若需要超過三個 component、明確的 null 政策、支援 Unicode 的 case folding 或 NFC 正規化,請改用 unique_tuple。

空值與更新

唯一鍵以正規化後的持久化值判斷:數字會正規化(1 ≡ 1.0),boolean 變成 true/false,decimal 使用去掉尾端零的標準形式(1.50 ≡ 1.5)。任一 component 為 null、空字串或缺值(或 link 沒有目標)的列會被豁免:它不記錄鍵,也永遠不會碰撞。Create、update 與 restore 都可能碰到既有鍵(409;當呼叫者讀得到鍵的每一個 component 時,detail 帶 constraint 與 columns,而且只有衝突列也位於呼叫者的可讀範圍時,才會再帶 conflicting_record_id 與 key_tuple);delete 會釋放該列占用的鍵。自後端 5.21.0 起,衝突回應絕不會點出呼叫者讀不到的欄位:只要有 component 被隱藏,columns 就只列出讀得到的那幾個,constraint 改成規則不透明的 rule_<hex> ID,而不是作者寫的名稱(名稱可能直接拼出隱藏欄位),並以 message: "Unique constraint conflict" 標示這是被遮蔽的回應,連可讀列的 conflicting_record_id 與 key_tuple 也一併不給。當沒有任何 component 讀得到,或無法為寫入者解析出讀取範圍時,detail 只剩 {"message": "Unique constraint conflict"}。要判斷回應是否被遮蔽,請檢查 message 是否等於 "Unique constraint conflict",不要檢查 constraint。在既有資料已經重複的表上啟用規則會回 409,列出最多五組碰撞樣本,且不會儲存任何東西。只有讀得到每一個 component 與每一筆碰撞列的呼叫者才拿得到樣本,其他人只會得到上面說明的衝突中繼資料。不要先做「查詢後再寫入」並假設結果仍有效,應直接處理伺服器回傳的 unique conflict。

Note unique 是無條件 SQL 約束,因此不接受有效的 when。如果只有某些狀態需要唯一性,應重新檢視資料模型,而不是在前端模擬條件式唯一鍵。

發布時保留既有 rule_<hex> ID,讓規則與底層 constraint 的對應保持穩定。端點流程見 rules.get 與 rules.set。

Last updated on