Erlang:Mnesia:连续更新单个字段值

Posted

技术标签:

【中文标题】Erlang:Mnesia:连续更新单个字段值【英文标题】:Erlang : Mnesia : Updating a single field value in a row 【发布时间】:2010-12-21 17:11:27 【问题描述】:

我有一个 mnesia 表,其中包含三个字段 i、a 和 b,使用记录创建

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

现在我在表中插入一行:

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

现在,如果我想更新这一行,并且只将 a 的值更改为 10,同时让 i 和 b 保持相同的值,我该怎么办?有没有类似“UPDATE T SET a=10 WHERE i=1”的 SQL 等价物?

如果我这样做:

mnesia:transaction( fun() -> mnesia:write("T", #reci=1, a=10, write) end )

该行存储为:

rec,1,10,undefined

【问题讨论】:

【参考方案1】:

如果在 mnesia:transaction 中使用,此函数的值将更新 a

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

建议:如果你想要一些更像 SQL 语法的语法糖,可以看看 QLC。

性能当然是最好的基准,但 QLC 有开销,我不确定它们与其他细节相比是否相关。我只是认为您提供的 SQL 示例将更新所有具有i=1 的记录。使用 QLC 提取那组记录比 mnesia 调用更漂亮。

还要注意,wread 直接在记录上声明写锁,因为我们提前知道我们将更新该记录。这是一个微优化,首先避免读锁,然后改变主意并获得写锁。不过,我已经很久没有对此进行基准测试了。

如果性能仍然是一个问题,您应该查看使用脏操作的各种方法。但是你真的应该试着弄清楚你每秒需要多少事务,才能“足够快”。

【讨论】:

我需要关注效率,所以你建议我使用QLC还是你上面指定的方法? 我试过这个,但由于某种原因它不起作用。该值未更新。 @ErJab,查看dirty_update_counter,它可能满足您的需求。 它现在可以工作了,我正在监督我的代码中表名的一个小错误! @Zed 我要更新的字段不是整数。我在问题中使用的代码只是一个例子。无论如何,谢谢,现在我知道我可以使用dirty_update_counter 来更新整数字段了。【参考方案2】:

我相信您需要读取“行”,更新您需要的任何字段,然后在“事务”中写回结果所有这些操作。

【讨论】:

是的,我也想过,但这不是很昂贵的手术吗? 数据库通常会在事务中执行“更新”操作,否则它们如何保证正确性?在mnesia 中,我想需要更明确一些,出于某种我现在无法理解的原因。

以上是关于Erlang:Mnesia:连续更新单个字段值的主要内容,如果未能解决你的问题,请参考以下文章

Erlang判断记录是不是有字段

与 Mnesia 保持关系完整性

Erlang:为 mnesia 指定工作目录?

Erlang-如何在没有记录的情况下使用 Mnesia

erlang r19里面的mnesia_ext

在 Elixir/Erlang 中的(本地)Mnesia 实例上实现最佳写入性能