我正在使用PostgreSQL 9.1。假設我有一張表,其中一些列有約束條件UNIQUE
。最簡單的例子:SQL - 依賴於INSERT期間的服務器錯誤
CREATE TABLE test (
value INTEGER NOT NULL UNIQUE
);
現在,插入一些值的時候,我不得不單獨處理的情況下,在要插入的值已經在表中。我有兩個選擇:
- 做一個
SELECT
事先保證的值不在表中,或: - 執行
INSERT
,看服務器可能會返回任何錯誤。
使用PostgreSQL數據庫的應用程序是用Ruby編寫的。下面是我將如何編寫第二個選項:
require 'pg'
db = PG.connect(...)
begin
db.exec('INSERT INTO test VALUES (66)')
rescue PG::UniqueViolation
# ... the values are already in the table
else
# ... the values were brand new
end
db.close
這裏是我的想法:讓我們假設我們做一個SELECT
第一,插入前。 SQL引擎必須掃描行並返回任何匹配的元組。如果沒有,我們做一個INSERT
,這可能是另一次掃描,看是否約束不會被任何機會侵犯。所以,從理論上講,第二種選擇會使執行速度提高50%。這是PostgreSQL實際上的行爲方式嗎?
當涉及到異常本身時(例如,我們只有一個UNIQUE
約束),我們假設沒有歧義。
這是常見的做法嗎?或者有任何警告嗎?還有更多的選擇嗎?
+1'ON CONFLICT'和檢查數量的插入行。 「ON CONFLICT」的官方文檔是[here](http://www.postgresql.org/docs/devel/static/sql-insert.html#SQL-ON-CONFLICT)。 –
UI反映了數據庫本身的結構 - 並且由於我在數據庫中聲明瞭'UNIQUE'約束,因此UI不允許重複。建議的'ON CONFLICT'語法和檢查插入行的數量看起來像是一個完美的SQL-only-ish選擇。太糟糕了,我不會有任何機會把它放在它上面。 – Tomalla