不知道如何尋找這個,所以我很抱歉,如果這是之前問。隨着時間的推移翻轉記錄的狀態無迴歸
據說我提供了一組記錄。這些記錄具有某種狀態,即true
或false
。隨着時間的推移,我們的客戶希望將文檔的特定子集從一個或另一個狀態切換。
所以當前記錄存儲在SQL數據庫(準確地說是PostgreSQL)。所以爲了保持狀態翻轉的歷史(並且爲了確保我們可以從頭開始重新運行所有的東西,萬一有些事情搞砸了),我們將所有更新語句存儲在版本控制的存儲庫中。但是,因爲這是SQL,並且一段時間後SQL變得非常複雜(爲了確保不迴歸,即以前請求爲false
時未將狀態設置爲true
)。
例如,我們在過去的翻轉記錄true
和false
收到票#1和#2分別
-- DO THIS FOR TICKET #1
UPDATE record
SET status = TRUE
WHERE id IN (SELECT id
FROM records
WHERE this_criteria = 'that');
-- DO THIS FOR TICKET #2
UPDATE record
SET status = FALSE
WHERE id IN (SELECT id
FROM records
WHERE another_criteria = 'whatever')
這是當我們有一票#3是在涉及的一個子集,我們做什麼在#1和#2的記錄
-- DO THIS FOR TICKET #3
UPDATE records
SET statue = TRUE
WHERE id IN (SELECT id
FROM records
WHERE true_criteria = 'something')
AND id NOT IN (-- regression ticket #1
SELECT id
FROM records
WHERE this_criteria = 'that'
UNION
-- regression ticket #2
SELECT id
FROM records
WHERE another_criteria = 'whatever');
所以我們現在正在做的是運行的#1的更新語句,再其次是#2,#最後3。正如所料,#3將永遠運行。我可以優化查詢,但從長遠來看它仍然不會起作用,因爲將來的票據將導致越來越複雜的條件被寫入,以避免覆蓋以前票證中設置的狀態。
既然我們正在尋找另一個項目的替代方案,並且我們期待未來地位的翻轉發生得更加頻繁。有什麼可能是一種更好的方式來管理這一點,並且如果可能的話,爲我們提供一種實際記錄更改的方式(不一定是SQL)?
我們不是逐批更新它們(想象一下,我們會定期將記錄逐個發送到管道中,並且客戶端的每個請求都是一個盒子,以便在適用的情況下翻轉記錄的狀態,最後這些記錄將被插入某些數據存儲)。所以我們將SQL替換成一些基於規則的迷你DSL,以確保在翻轉狀態之前滿足條件。但是,這看起來不像是對SQL方法的改進,因爲條件遲早會由於迴歸檢查而增長,並且規則實際上只是另一種格式的SQL。
的新門票#3的一個例子是這樣的
SET status TO TRUE
CONDITION (is_equal, true_criteria, 'something') # new ticket #3 request
# REGRESSION in ticket #1
AND (not_equal, this_criteria, 'that')
# REGRESSION in ticket #2
AND (not_equal, another_criteria, 'whatever')
一些事情正如你可以看到,而我沒有一次像SQL,語句把它做的所有記錄以上實際上只是原始SQL對應的變體。
編輯:
- 這不是關於SQL優化,我還可以實現這一點沒有使用關係型數據庫,然後我可以刪除標識符列。狀態變量不是由標識符的值決定的。
- 假設我要將收藏集放入Search Appliance,即ElasticSearch,所以如果我可以預先計算狀態會很好,所以我不必在用戶發出的查詢之上附加一個巨大的查詢DSL,以確保只返回
status=true
記錄。 - 我正在尋找替代解決方案,不必在關係數據庫中實施(因此我刪除了
postgresql
標籤)。 - 客戶端並不總是在乎他們的新請求是否會導致某些先前設置的狀態翻轉,他們只是希望確保以前翻轉的狀態在應用新條件時不會被隱式重寫。
- 在SQL實現中,我們犯了一個錯誤,就是沒有記錄狀態字段的更新日誌,而我們正在起草的那個將會有這種情況,所以是的,我們必須有一種方法來記錄狀態翻轉。
是id字段獨特之處? –
是的,但這並不重要,我並不是在尋找SQL優化,但更多的是關於其他人如何在Jeffrey04上做這個 – Jeffrey04
的策略是的,它*確實很重要,因爲你的子查詢指的是完全相同的記錄爲更新語句的目標記錄。見@BennjoeMordeno的答案。另外:您的狀態實際上是多餘的,因爲它可以從其他列重新計算。 – joop