Mnesia(4)

2019-01-12 11:40

select必须运行在transaction等activity里面,所有我们需要构造一个方法:

Java代码

??? all_females() -> ??? F = fun() ->

??? Female = #employee{sex = female, name = '$1', _ = '_'}, ??? mnesia:select(employee, [{Female, [], ['$1']}]) ??? end,

??? mnesia:transaction(F).

all_females() -> F = fun() ->

Female = #employee{sex = female, name = '$1', _ = '_'}, mnesia:select(employee, [{Female, [], ['$1']}]) end,

mnesia:transaction(F).

select表达式匹配employee表里所有的记录中sex为female的记录 该方法可以从shell里直接调用:

Java代码

??? 1> company:all_females().

??? {atomic, [\, \]}

1> company:all_females().

{atomic, [\

使用QLC

使用QLC可能比使用Mnesia方法开销更大,但是它提供了一个很好的语法

Java代码

??? Q = qlc:q([E#employee.name || E <- mnesia:table(employee), E#employee.sex == female]), ??? qlc:e(Q).

Q = qlc:q([E#employee.name || E <- mnesia:table(employee), E#employee.sex ==

female]), qlc:e(Q).

使用QLC list comprehension来访问Mnesia表时必须运行在一个transaction里:

Java代码

??? females() -> ??? F = fun() ->

??? Q = qlc:q([E#employee.name || E <- mnesia:table(employee), E#employee.sex == female]), ??? qlc:e(Q) ??? end,

??? mnesia:transaction(F).

females() -> F = fun() ->

Q = qlc:q([E#employee.name || E <- mnesia:table(employee), E#employee.sex == female]), qlc:e(Q) end,

mnesia:transaction(F).

调用QLC写的方法:

Java代码

??? company:females().

company:females().

list comprehension表达式: 1)[括号表示“构建list”

2)||表示“例如”,<-表示“从哪里取”

上面的list comprehension表示:构建list E#employee.name,E来自employee表,并且sex属性等于female

raise female salary的方法:

Java代码

??? raise_females(Amount) -> ??? F = fun() ->

??? Q = qlc:q([E || E <- mnesia:table(employee), ??? E#employee.sex == female]), ??? Fs = qlc:e(Q),

??? over_write(Fs, Amount) ??? end,

??? mnesia:transaction(F). ???

??? over_write([E|Tail], Amount) -> ??? Salary = E#employee.salary + Amount, ??? New = E#employee{salary = Salary}, ??? mnesia:write(New),

??? 1 + over_write(Tail, Amount); ???

??? over_write([], _) -> ??? 0.

raise_females(Amount) -> F = fun() ->

Q = qlc:q([E || E <- mnesia:table(employee), E#employee.sex == female]), Fs = qlc:e(Q),

over_write(Fs, Amount) end,

mnesia:transaction(F).

over_write([E|Tail], Amount) ->

Salary = E#employee.salary + Amount, New = E#employee{salary = Salary}, mnesia:write(New),

1 + over_write(Tail, Amount);

over_write([], _) -> 0.

Mnesia用户手册:三,构建Mnesia数据库

本章详细介绍了设计Mnesia数据库和编程结构的基本步骤: 1)定义schema 2)数据模型 3)启动Mnesia

4)创建新表

1,定义schema

Mnesia系统的配置在schema里描述

schema是一个特殊的表,它包含了表名、每个表的存储类型(表应该存储为RAM、硬盘或两者)以及表的位置等信息

不像数据表,schema表里包含的信息只能通过schema相关的方法来访问和修改 Mnesia提供多种方法来定义数据库schema,可以移动表、删除表或者重新配置表布局 这些方法的一个重要特性是当表在重配置的过程中可以被访问 例如,可以在移动一个表的同时执行写操作 该特性对需要连续服务的应用非常好

下面的方法是schema管理所要用到的,它们都返回一个tuple {atomic, ok}或{aborted, Reason} 1)mnesia:create_schema(NodeList)

该方法用来初始化一个新的空schema,在Mnesia启动之前这是一个强制必要的步骤

Mnesia是一个完全分布的DBMS,而schema是一个系统表,它备份到Mnesia系统的所有节点上

如果NodeList中某一个节点已经有schema,则该方法会失败 该方法需要NodeList中所有节点上的Mnesia都停止之后才执行

应用程序只需调用该方法一次,因为通常只需要初始化数据库schema一次 2)mnesia:delete_schema(DiscNodeList)

该方法在DiscNodeList节点上擦除旧的schema,它也删除所有的旧table和数据 该方法需要所有节点上的Mnesia都停止后才执行 3)mnesia:delete_table(Tab) 该方法永久删除Tab表的备份 4)mnesia:clear_table(Tab) 该方法永久删除Tab表的记录

5)mnesia:move_table_copy(Tab, From, To) 该方法将Tab表的copy从From节点移动到To节点

表的存储类型{type}保留,这样当移动一个RAM表到另一个节点时,在新节点上也维持一个RAM表

在表移动的过程中仍然可以有事务执行读和写操作 6)mnesia:add_table_copy(Tab, Node, Type) 该方法在

Node

节点上创建

Tab

表的备份,Type

参数为

ram_copies/disc_copies/disc_only_copies 7)mnesia:del_table_copy(Tab, Node)

该方法在Node节点上删除Tab表的备份,当最后一个备份被删除后,表也被删除 8)mnesia:transform_table(Tab, Fun, NewAttributeList, NewRecordName) 该方法对Tab表的所有数据更改format,它对表里所有记录调用Fun

Fun应该是一个方法,参数为记录的旧类型,返回记录的新类型,表的key不能更改

Java代码

? ?

-record(old, {key, val}). -record(new, {key, val, extra}).

? ? ? ? ? ? ?

Transformer =

fun(X) when record(X, old) -> #new{key = X#old.key, val = X#old.val, extra = 42} end,

?? {atomic, ok} = mnesia:transform_table(foo, Transformer, ?? record_info(fields, new), ?? new),

-record(old, {key, val}). -record(new, {key, val, extra}).

Transformer =

fun(X) when record(X, old) -> #new{key = X#old.key, val = X#old.val, extra = 42} end,

{atomic, ok} = mnesia:transform_table(foo, Transformer, record_info(fields, new), new),

Fun参数也可以为ignore,它表示只更新表的meta data,不推荐使用 9)mnesia:change_table_copy_type(Tab, Node, ToType) 该方法更改表的存储类型,如从RAM改为disc_table

2,数据模型

Mnesia的数据库数据由record组成,record由tuple表示

record的第一个元素是record名,第二个元素是表的key,前两个元素组成的tuple称为oid Mnesia数据模型是对关系模型的扩展,因为该模型可以在域属性里存储任意的Erlang term 例如,可以在一个属性里存储指向其他表里的oid树,而这种类型的记录在传统的关系型DBMS里很难建模

3,启动Mnesia

在启动Mnesia之前我们必须在相应的节点上初始化一个空的schema 1)Erlang系统必须启动

2)必须使用create_schema(NodeList)来定义数据库schema

当运行一个分布式系统时,可能有多个节点参与,则mnesia:start()方法必须在相应的节点上运行 典型的,在一个嵌入式环境里mnesia:start()应该为启动脚本的一部分

在一个测试环境或解释型环境里,mnesia:start()也可以从Erlang shell或其他程序里调用

初始化schema并启动Mnesia


Mnesia(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:基于单片机的数字电压表开题报告

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: