Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4617968
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 22, 20262026-05-22T02:11:59+00:00 2026-05-22T02:11:59+00:00

I have realised that mnesia doesnot support auto-increment feature as does MySQL or other

  • 0

I have realised that mnesia doesnot support auto-increment feature as does MySQL or other RDBMS do.The counters talked about in mnesia documentation are not really well explained. forexample i have found sofar one function in the entire documentation which manipulates counters

mnesia:dirty_update_counter({Tab::atom(),Key::any()}, Val::positive_integer())

So, this has disturbed me for a time coz it works with records of type

{TabName, Key, Integer}

This is also unclear and possibly because no erlang book or mnesia documentation provides an example to explain it.This has forced me to implement my own counter manipulation APIs.Since i wanted to be able to access and manage my records using counters, i had to include a field called ‘counter’ in my records, then at the point of adding the record in the table which is intended to have counters, i do it like this:

#recordname{field1 = Val1,...,counter = auto_increment(?THIS_TABLE)}

The position of the counter fields doesnot matter. The API is implemented like this below:

%% @doc this function is called whenever u are writing a new record in the table
%% by giving its result to the counter field in your record.
%% @end
%%
%% @spec auto_increment(TableName::atom()) -> integer() | exit(Reason)
auto_increment(TableName)-> case lists:member(counter,table_info(TableName,attributes)) of false -> erlang:exit({counter,field,not_found,in_table,TableName}); true -> table_info(TableName,size) + 1 end.
table_info(Tab,Item)-> F = fun({X,Y}) -> mnesia:table_info(X,Y) end, mnesia:activity(transaction,F,[{Tab,Item}],mnesia_frag).

To explain this, if the counter field isnot an attribute of the table i forcibly let the process that is trying to execute this code to exit with a reason, so if the programmers call this within a try …catch, or a case (catch …) of body , they would easily see what is wrong. Alternatively, i could ask whether this code fragment is being executed within a transaction by using mnesia:is_transaction() and if this returns true, i call mnesia:abort/1, if false, i could just exit with reason.Also, i use mnesia_frag in the mnesia activity function because this implementation will work regardless of the fragmentation properties of a table.If i use the mnesia:transaction(Fun), fragmented tables will become inconsistent because this call will only access the initial fragment (the base table).

Now, when a record is deleted from the table with counters, we need to re-arrange the order in the table. This operation is expensive as it requires iteration over the whole table.Because if they delete a record whose counter = 5, the one with counter = 6 must become counter = 5 and so on following the pattern. All records whose counters were greater than the one deleted, must be decremented. So by passing the counter value deleted and the TableName, its possible to iterate over the table using
mnesia:foldl/3 or mnesia:foldr/3 , the difference between these two comes in only with ordered table types
Here is the function which takes care of this:


auto_decrement(Counter_deleted,TableName)->
    Attrs = table_info(TableName,attributes),
    case lists:member(counter,Attrs) of
        false -> erlang:exit({counter,field,not_found,in_table,TableName});
        true -> 
            Counter_position = position(counter,Attrs) + 1,         
            Iterator =  fun(Rec,_) when element(Counter_position,Rec) > Counter_deleted -> 
                            Count = element(Counter_position,Rec),
                            New_rec = erlang:setelement(Counter_position,Rec,Count - 1),
                            mnesia:write(TableName,New_rec,read),
                            [];
                        (_,_) -> []
                        end,
            Find = fun({Fun,Table}) -> mnesia:foldl(Fun, [],Table) end,
            mnesia:activity(transaction,Find,[{Iterator,TableName}],mnesia_frag)
    end.

You notice that i have code which helps me find the position of the counter field dynamically from the record. The code which helps me do this is shown below:


position(_,[]) -> -1;
position(Value,List)->
    find(lists:member(Value,List),Value,List,1).

find(false,_,_,_) -> -1;
find(true,V,[V|_],N)-> N;
find(true,V,[_|X],N)->
    find(V,X,N + 1).

find(V,[V|_],N)-> N;
find(V,[_|X],N) -> find(V,X,N + 1).

This is so because this module must not know any of the programmers’ records to help him with counters.Hence in order to access the value of the counter from the record using tuple manipulation functions such as element(N::integer(),Tuple::tuple()), i have to calculate its position in the tuple representation of the record, dynamically.

These two functions have worked for me and are still working till auto_increment
is implemented in mnesia.

For example, using qlc (query list comprehension) to query tables with dynamic constraints, consider these pieces of code below:


select(Q)->
    F = fun(QH) -> qlc:e(QH) end,
    mnesia:activity(transaction,F,[Q],mnesia_frag).

read_by_custom_validation(Validation_fun,From_table)->
    select(qlc:q([X || X <- mnesia:table(From_table),Validation_fun(X) == true])).

%% Applying the two functions....
find_records_with_counter(From_this,To_that) when 
is_integer(From_this),is_integer(To_that),To_that > From_this -> F = fun(#recordName{counter = N}) when N >= From_this,N =< To_That -> true; (_) -> false end, read_by_custom_validation(F,TableName).

In a stock management system, this is working…



(stock_project@127.0.0.1)6> stock:get_items_in_range(1,4).
[#item{item_id = "D694",name = "cement",
       time_stamp = {"30/12/2010","11:29:10 am"},
       min_stock = 500,units = "bags",unit_cost = 20000,
       state = available,last_modified = undefined,
       category = "building material",counter = 1},
 #item{item_id = "131B",name = "nails",
       time_stamp = {"30/12/2010","11:29:10 am"},
       min_stock = 20000,units = "kgs",unit_cost = 1000,
       state = available,last_modified = undefined,
       category = "building material",counter = 2},
 #item{item_id = "FDD9",name = "iron sheets",
       time_stamp = {"30/12/2010","11:29:10 am"},
       min_stock = 20,units = "bars",unit_cost = 50000,
       state = available,last_modified = undefined,
       category = "building material",counter = 3},
 #item{item_id = "09D4",name = "paint",
       time_stamp = {"30/12/2010","11:29:10 am"},
       min_stock = 30000,units = "tins",unit_cost = 5000,
       state = available,last_modified = undefined,
       category = "building material",counter = 4}]
(stock_project@127.0.0.1)7>

This is working for me. Please advise me on how else i should take care of counters.Or you could tell me how u r handling them over that side.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-22T02:11:59+00:00Added an answer on May 22, 2026 at 2:11 am

    Is a counter the best solution for your problem? I expect that a highly distributed system is probably better off not having them and hence they have been left out.

    1. If you want a count of how many elements are in the table. Have a separate table of record {counts, TableName, Count} and use the dirty_update_counter operation in the add and remove transactions of your storage tables.
    2. If you want to retrieve data in a specific order (the order they were added for instance) look at using an OrderedBy solution shown here.
    3. If you want fast foreign key lookups, I would look at playing around with the type of your keys (binary values for item_id maybe faster) and test if you get any significant improvement.

    Also, I don’t understand why you have to update the counter on every record when a table entry is deleted. I didn’t think MySQL or any other RDBMS did this.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have an abstract class called DatabaseRow that, after being derived and constructed, is
I've been using Capybara for integration/request testing, but have only just realised I can't
I have the following string: s=80 . I need to put this in an
I realise that this question has probably been asked to death, but none of
Edit: This problem only occurs on windows 7 and vista from what I've heard.
I'm finding myself doing more C/C++ code against Win32 lately, and coming from a
I'm writing a vbscript to pull some data from a webpage, strip out a
I had a similar question to this here: Delphi XE - should I use
My ASP.NET web app runs fine under IIS 7.5. But I want to make
My app is crashing occasionally and when I see the crash logs this is

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.