2009-11-30 16 views
7

行における単一フィールドの値を更新私は三つのフィールド、I、AとBとのmnesiaテーブルを持っているが、今のように、テーブルに行を挿入レコードをアーラン:Mnesia:

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

を使用して作成しました:同じ値でiとBを残したまま

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

は今、私はこの行を更新したい場合、私は何をしますか、と10の値のみを変更しますか? "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. 

提案:あなたはより多くのSQL構文のようなものですいくつかのシンタックスシュガーをしたい場合はQLCでのぞき見を持っています。

パフォーマンスはもちろん、ベンチマークが最適ですが、QLCにはオーバーヘッドがあります。他の詳細と比べてパフォーマンスが適切かどうかはわかりません。私はあなたが与えたSQLの例がi=1のすべてのレコードを更新すると考えていました。 QLCを使用してそのレコードのセットを抽出することは、記憶媒介の呼び出しよりも綺麗です。

通知すると、wreadは、事前にレコードを更新することがわかっているので、レコードに直接書き込みロックを要求します。これは、最初に読み取りロックを回避し、その後、私たちの心を変えて書き込みロックを得るためのマイクロ最適化です。私は長いことベンチマークしていません。

パフォーマンスが引き続き問題になる場合は、ダーティ操作を使用するさまざまな方法を検討する必要があります。しかし、実際には、必要な秒あたりのトランザクション数を把握して、「十分に速い」ことを確認する必要があります。

+0

私は効率性を考えなければならないので、上記のQLCまたは方法を使用することをお勧めしますか? – ErJab

+0

私はこれを試しましたが、何らかの理由で動作しません。値は更新されていません。 – ErJab

+0

@ErJab、dirty_update_counterをチェックすると、あなたのニーズに合うかもしれません。 – Zed

2

、更新があなたが必要とする、その後、どのような分野その結果をのすべての結果を「トランザクション」内に書き戻します。

+0

私はそれについても考えましたが、これは高価な操作ではありませんか? – ErJab

+0

データベースは通常、トランザクションで「更新」操作を行いますが、そうでない場合は、どのようにして正当性が保証されますか? 'mnesia'では、私は現時点で私を逃れる何らかの理由で、より明示的にする必要があると思います。 – jldupont