Mnesia

Mnesia is a program written in Erlang database system. It will only be used directly in conjunction with Erlang, a connection to other languages ​​does not exist. Mnesia has soft real -time capabilities, can be configured easily distributed and is also optimized for speed.

Name

Joe Armstrong, one of the main developers of Erlang, answered the question about the name Mnesia in his book "Programming Erlang " as follows:

"The original name what Amnesia. One of our bosses did not like the name. He said, ' You can not Possibly call it Amnesia -you can not have a database did forgets things! '. So we dropped the A and the name stuck. "

" The original name was Amnesia. But one of our bosses did not like that name. He said, but you can not call the thing Amnesia - you can develop any database, forgets things! '. So we have the A omitted and the name stuck. "

Use

As Erlang Mnesia has been developed for use in telecom environments where it comes to low latency and high availability and concurrency. Mnesia is not designed to replace conventional SQL-based databases, but rather as embedded in the language database, similar to the Berkeley DB.

Integration in Erlang

Mnesia was highly specialized in Erlang, it supports storing any Erlang terms. Erlang terms here are the Datenstrukturen-/Typen used in the language itself:

  • Lists: [ 1,2,3 ]
  • Scalar: 42
  • Atoms: hello world, xyz
  • Tuple: { hello, 1,3.4, [1,2,3 ], { 5, abc }} Records: R = # recordName { a = 1, b = 2}
  • Funs: fun () -> doSomething () end.

There is therefore no conversion of the data types.

Use of other languages ​​as Erlang is not possible. Within the Mnesia Erlang module is used to communicate with the database server, which works with various Erlang processes.

Memory model

Mnesia Erlang stores tuples in tables. The tuples are structured as follows:

{ Table name, key, field1, field2, ...} Table name is Mnesia to insert the record in the right table, while a unique key in the corresponding table key (typical for relational database management systems ), such as a serial number. The rest of the tuple are different data fields.

Because of this structure Records for working with Mnesia be used in most cases. The record -record ( table1, { field1, field2 = defaultValue }). is converted into a tuple { table1, value1, value2 }, and is therefore well suited to be stored in Mnesia.

Transactions

Read, write, and queries should only take place in so-called transactions ( transactions ). Transactions are Erlang Funs ( Fun is synonymous with Anonymous function in Erlang ) in which Mnesia commands for reading, writing and queries are executed. Such Fun is then handed over to the Mnesia transaction manager.

The purpose of transactions is to achieve Atomicity ( indivisibility ) and thus consistency. Either the entire transaction is successful, or the entire transaction fails. The database remains consistent. For example, two adjacent records to be written to the database. The letter of the first record is successful, the beats of the second fails ( for example because of a forgotten field in the inserted record). Now the first write operation is undone, to regain consistency. Thereafter, the program is notified that something has gone wrong.

In addition to transactions, there are dirty operations, so dirty operations that are many times faster than transactions, but give it no guarantee of consistency or atomicity.

Working with Mnesia - some small examples

Scheme

Before the database can be used a so-called scheme must be created. A schema is actually just a folder in the current directory, which is named after the pattern Mnesia.node (), at an unnamed Erlang instance so nohost Mnesia.nonode @. The schema is used to secure depending on the mode data on the hard disk and manage the link with other Mnesia instances.

Mnesia: CREATE_SCHEMA ([' [email protected] ', ' [email protected] ' node () ] ). This command creates for those two nodes ( Erlang VMs that are able to be accessed over the network ), as well as the current node ( node () ) the necessary files. table1 is currently the only table in the database. The entire structure takes in 20 entries, an approximately 28 KB, an empty database requires approximately 20 KB.

Mnesia.node1 @ host.domain.com / ├ ─ ─ DECISION_TAB.LOG ├ ─ ─ LATEST.LOG ├ ─ ─ schema.DAT ├ ─ ─ table1.DCD └ ─ ─ table1.DCL So this scheme stores the meta-information for working with a database. Linking to a running Mnesia server is done automatically, ie when a Mnesia server is started in a node and finds a schema with the node names matching name, this will be used.

Once a scheme has been applied, Mnesia must be started on all participating nodes:

Mnesia: start ( ). tables

An important basic element of relational databases are tables. A table consists of a series of in Mnesia Erlang tuples that all begin with the same name, namely the table. The most appropriate for a Erlang Record:

-record ( table1, { field1, field2 = defaultValue }). mnesia:create_table(table1,[{attributes,[record_info(fields,table1)]},{disc_copies,['[email protected]','[email protected]']}]). table1 is the table name, which must match the record name. The second argument is a list of Optionstupeln. Used here:

  • { attributes, [ field1, field2 ]} - list of fields. record_info () returns the list of fields of a given record back.
  • { disc_copies, [' [email protected] ', ' [email protected] ']} - storage method. Besides disc_copies ( Location: RAM; backup to disk ) only RAM exist ( ram_copies or no argument ) and only hard drive ( disc_only_copies ). The nodelist always can contain only nodes that were specified when creating the schema, since a special cookie must match between the schemas. This configures the nodelist table so that copies of the table are stored on two nodes, but not on the main node on which the application is running that performs this function straight. A typical scenario would be a front -end application, wherein the application server having processing power and in particular to provide the other two nodes of the memory.

Letter

First, a function object is created with the desired behavior, and then pass the transaction manager. The Mnesia functions used in transactions only run in a transaction context, ie it is not possible with these features, outside of a transaction changing the database.

Transaction_Fun = fun () ->      Data = # table1 { field1 = 1337, field2 = 42},      mnesia: write (data )      end.   mnesia: transaction ( Transaction_Fun ). retrieval

The polling is done via the list comprehensions often used in Erlang. To all the values ​​of field1 in records where field2 is greater than 100 extract, the following question is formulated:

Transaction_Fun = fun () ->      Query = qlc: q ( [ X # table1.field1 | X <- mnesia: table ( table1 ), X # table1.field2 > 100 ] ),      qlc: e ( Query)      end.   mnesia: transaction ( Transaction_Fun ). QLC here is a module for querying different tables, for example ETS or just Mnesia. qlc: q () compiles a list comprehensions, qlc: e () executes it and returns the values. With this list comprehensions also joins are possible.

The SQL equivalent for this query would be:

SELECT field1 FROM table1 WHERE field2 > 100 References

577435
de