2009-11-30 80 views
7

我有三個字段,I,a和b的函數mnesia表更新單個字段值,創建使用記錄二郎:Mnesia的:在一排

-record(rec, {i, a,b}). 

現在我將行插入表作爲:

mnesia:transaction(fun() -> mnesia:write("T", #rec{i=1, a=2, b=3}, write) end). 

現在,我該怎麼辦,如果我想更新此行,改變的僅值10,同時留下我和b具有相同的價值觀?有沒有像「UPDATE T SET a=10 WHERE i=1」這樣的SQL等價物?

如果我做這樣的事情:

mnesia:transaction(fun() -> mnesia:write("T", #rec{i=1, a=10}, write) end) 

行存儲爲:

{rec,1,10,undefined} 

回答

9

這個功能如果一個Mnesia將使用更新的價值:交易

update_a(Tab, Key, Value) -> 
    fun() -> 
    [P] = mnesia:wread({Tab, Key}), 
    mnesia:write(P#pixel{a=Value}) 
    end. 

建議:必須在QLC偷看,如果你想要一些語法糖是更喜歡的SQL語法。

表現當然是最好的基準,但QLC有開銷,我不確定它們是否與其他細節相關。我只是想,你給的SQL例子會更新所有記錄i=1。使用QLC提取該組記錄比mnesia調用更漂亮。

另外需要注意的是,wread直接聲明瞭對記錄的寫入鎖定,因爲我們提前知道我們將更新該記錄。這是一種微型優化,可以避免先讀取鎖定,然後改變主意並獲得寫入鎖定。儘管如此,我還沒有很長時間做過基準測試。

如果性能仍然是一個問題,你應該看看你使用髒操作的各種方法。但是你真的應該試着弄清楚你需要的每秒多少次交易,「足夠快」。

+0

我需要關注效率,所以你會推薦我使用QLC還是上面指定的方法? – ErJab

+0

我試過了,出於某種原因,它不起作用。該值未被更新。 – ErJab

+0

@ErJab,檢查出dirty_update_counter,它可能會滿足您的需求。 – Zed

2

我認爲你需要閱讀的「行」,更新哪個領域你需要,然後所有這些操作在「事務」中寫回結果

+0

是的,我也想過,但這不是一個昂貴的操作? – ErJab

+0

數據庫通常會在事務中執行「UPDATE」操作,否則它們將如何保證正確性?在'mnesia'中,我想一個人應該更加明確,因爲某種原因,現在我逃脫了。 – jldupont