1
votes

I have a ram_copies mnesia set up and I can insert the records, and I can print the them using the following code located here: How to read all the records of mnesia database in erlang?

Start Record:

-record(someRecord, {a=null, b=null}).

Table:

mnesia:create_table(someRecord,
    [{attributes, record_info(fields, someRecord)},
      {index, [#someRecord.b]},
      {ram_copies, Nodes},
      {type, set}]),

Inserting:

i(rA, rB) ->
  F = fun() -> mnesia:write(#someRecord{a=rA, b=rB}) end,
  mnesia:transaction(F).

Reading:

r(rB) ->
  F = fun() -> mnesia:read({someRecord, rB}) end,
  mnesia:transaction(F).

This returns {atomic, Result} and Result is empty.

Wondering what I am doing wrong.

Thanks!

Update: It turns out that if I use the record "a" as they key it works. But why? I have it set to record "b" for key.

1
Does this work: mnesia:index_read(someRecord, B, #someRecord.b)?Dogbert
@Dogbert This works. However, why does create_table have a key value that is not used then " {index, [#someRecord.b]}," (unless I am using it wrong). The read/2 will work for me if I replace rB with "a". Seems like the key is the first element, is this hardcoded? Also, what is the impact of using index_read vs read?Mike5050
I've posted an answer for all your questions except the last one. I am not sure about the impact. I believe it should be as fast as searching the first field but there will be an overhead in other operations because of the extra index mnesia needs to maintain.Dogbert

1 Answers

1
votes

The {index, List} option specifies which of the elements of the tuple mnesia should index. It does not change the behavior of mnesia:read to search those fields. The first field of the record is treated as the primary key and indexed automatically and is the one mnesia:read searches. To make a query against any other element, you need to use mnesia:index_read and specify the index of the element:

mnesia:index_read(someRecord, B, #someRecord.b)

Also note that since the type your table is set, and the first field of the record is the primary key, you will not be able to store more than one record with the same value of a. If you want b to be the primary key and the key on which the set detects duplicates, you'll have to reorder the fields of the record and move b to before a. If you do that, you don't need to specify any index option and you'll also be able to use mnesia:read instead of mnesia:index_read. This should be more efficient as well since mnesia won't have to maintain an extra index.