`
hideto
  • 浏览: 2678247 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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不能更改
-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
要想在a@gin和b@skeppet这两个节点上运行Company数据库,每个节点必须已经具备Mnesia目录并初始化schema
有两种方式指定Mnesia目录
1)通过程序参数来指定
%erl -mnesia dir '"/ldisc/scratch/Mnesia.Company"'

2)如果没有输入命令行参数,则Mnesia使用当前节点的当前工作目录来作为Mnesia目录
以下命令在两个指定节点上运行Company数据库:
1)gin节点上
gin %erl -sname a -mnesia dir '"/ldisc/scratch/Mnesia.company"'

2)在skeppet节点上
skeppet %erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'

3)在两个节点之一执行create_schema:
(a@gin1) > mnesia:create_schema([a@gin, b@skeppet]).
4)在两个节点上运行mnesia:start()
5)在两个节点之一执行以下代码来初始化数据库:
dist_init() ->
  mnesia:create_table(employee,
                      [{ram_copies, [a@gin, b@skeppet]},
                       {attributes, record_info(fields, employee)}]),
  mnesia:create_table(dept,
                      [{ram_copies, [a@gin, b@skeppet]},
                       {attributes, record_info(fields, dept)}]),
  mnesia:create_table(project,
                      [{ram_copies, [a@gin, b@skeppet]},
                       {attributes, record_info(fields, project)}]),
  mnesia:create_table(manager,
                      [{ram_copies, [a@gin, b@skeppet]},
                       {attributes, record_info(fields, manager)}]),
  mnesia:create_table(at_dept,
                      [{ram_copies, [a@gin, b@skeppet]},
                       {attributes, record_info(fields, at_dept)}]),
  mnesia:create_table(in_proj,
                      [{ram_copies, [a@gin, b@skeppet]},
                       {attributes, record_info(fields, in_proj)}]).

数据库只需初始化一次,下次只需mnesia:start()启动即可从硬盘启动系统
mnesia:stop()方法在当前节点上停止Mnesia,start/0和stop/0都在本地Mnesia系统上起作用,没有启动和停止一些节点的方法

启动过程
Mnesia通过调用mnesia:start()来启动
该方法在本地初始化DBMS
配置选择会更改表的位置和加载顺序:
1)表只存储在本地,从本地Mnesia目录初始化
2)根据哪个备份是最新的来决定备份表从本地硬盘还是其它节点的完整表copy来初始化,Mnesia会决定哪份备份是最新的
3)一旦表被加载,则可以被其他节点访问
表的初始化时同步的,如果数据库比较大,则mnesia:start()可能消耗一部分时间
mnesia:wait_for_table(TabList, Timeout)会等待表的加载
mnesia:force_load_table(Tab)会强制从硬盘加载表而不管其他情况,这时可能远程的备份上的操作会丢失

4,创建新表
Mnesia提供方法mnesia:create_table(Name, ArgList)来创建新表,返回{atomic, ok}或{aborted, Reason}
1)Name是表名
2)ArgList是{Key, Value}的tuple
-{type, Type}
  Type值为set、ordered_set或bag,默认为set
  bag可以一个key对应多条record,而set和ordered_set只能一个key对应一条record
  Mnesia表中不会出现重复的record(同样的key和content)
-{disc_copies, NodeList}
  表存储在硬盘上
  disc_copies类型的表备份的写操作会将数据写到disc和RAM中的表副本中
  如果我们有如下需求:
  1)读操作必须很快,直接在RAM操作
  2)写操作必须写到硬盘中
  那么我们可以一个表放到RAM中,一个disc_copies放到硬盘上
  对disc_copies的表的写操作会分两步执行,首先将写操作添加到日志文件中,然后再RAM里执行真正的写操作
-{ram_copies, NodeList}
  表存储在RAM里
  ram_copies类型的表备份可以用mnesia:dump_tables(TabList)方法来导入到硬盘上
-{disc_only_copies, NodeList}
  这种类型的表备份只存储在硬盘上,因此访问比较慢,但是这种类型的表消耗更少的内存
-{index, AttributeNameList}
  AttributeNameList指定Mnesia构建和维护的索引名,有一个index表来索引list里的每个元素
  Mnesia record的第一个field是key,所以不需要额外的索引
-{snmp, SnmpStruct}
  表示该表通过简单网络管理协议(SNMP)来访问
-{local_content, true}
  表名对所有Mnesia节点可见,但是内容对每个节点唯一
-{attributes, AtomList}
  指定表的字段名
  AtomList一般使用record_info(fields, record_name),而是硬编码属性列表,这样更易维护和更健壮,如果以后表结构更改则只用改record
-{record_name, Atom}
  指定表记录的common name,表里所有的record都以Atom作为第一个元素
例如我们定义如下record:
-record(funky, {x, y}).

那么在两个备份节点和y属性上的一个额外索引的bag类型的表的创建代码:
mnesia:create_table(funky, [{disc_copies, [N1, N2]}, {index, [y]}, {type, bag}, {attributes, record_info(fields, funky)}]).

而mnesia:create_table(stuff, [])将在本地节点创建一个RAM表stuff,没有额外的索引,并且表的字段为[key,val]
分享到:
评论
1 楼 hideto 2008-08-27  
要想创建disc_copies和disc_only_copies类型的表有两个前提条件:
1)mnesia:start()之前要调用mnesia:create_schema,否则创建disc_copies和disc_only_copies类型的表时会报错
2)在创建disc_copies和disc_only_copies类型的表要指定节点(如本地节点node()),否则不会创建的是还是ram_copies

相关推荐

    Mnesia 用户手册中文版 pdf

    Mnesia是一个分布式数据库管理系统,特别适用于需要持续运行和具备软实时特性的Erlang应用,如电信系统。它作为开放式电信平台(OTP)的一部分,是用Erlang编程语言实现的。Mnesia的设计初衷是为了解决电信应用中的...

    erlang——Mnesia用户手册.pdf

    3、构建.Mnesia.数据库 3.1.定义模式 3.2.数据模型 3.3.启动.Mnesia 3.4.创建新表 4、事务和其他上下文存取 4.1.事务属性 4.2.锁 4.3.脏操作 4.4.记录名与表 4.5.作业(Activity)概念和多种存取上...

    Mnesia用户手册.zip

    《Mnesia用户手册》是专为理解和操作Erlang编程语言中的Mnesia数据库管理系统而编写的详尽指南。Mnesia是Erlang OTP (Open Telephony Platform) 库中的一个核心组件,它是一个强大的分布式数据库系统,特别适用于...

    Mnesia用户手册 4.4.10版.rar

    3 、构建 Mnesia 数据库 . . .. . .. . 22 3.1 定义模式 . . .. . .. . .. . 22 3.2 数据模型 . . .. . .. . .. . 23 3.3 启动 Mnesia . . . 23 3.4 创建新表 . . .. . .. . .. . 26 4 、事务和其他上下文存取 ...

    Mnesia用户手册(docx版)

    3. **构建 Mnesia 数据库** - **定义模式**:模式定义了数据的结构,类似于数据库中的表结构。在Mnesia中,模式是Erlang的数据类型,如记录或原子值。 - **数据模型**:Mnesia 支持两种主要的数据模型:*正交表...

    mnesia数据库文档

    5. **模式定义**:Mnesia允许用户定义数据库模式,包括表、索引和属性等,提供了一种结构化的方式来组织和访问数据。 6. **查询语言**:Mnesia提供了自己的查询语言,允许用户执行复杂的查询和数据操作,同时也有对...

    mnesia_pg:Postgres后端通过mnesia_ext到Mnesia

    “mnesia_pg:Postgres后端通过mnesia_ext到Mnesia” 这个标题揭示了一个项目,它的目标是将PostgreSQL数据库作为Erlang的Mnesia分布式数据库系统的一个后端。Mnesia_ext是Mnesia的一个扩展,它允许添加自定义的数据...

    amnesia_cck:“ amensia”项目的源代码,已针对CCK展示进行了修改-Show source code

    总结来说,"Amnesia_CCK"是一个开源项目,它将"Amnesia"游戏的源代码进行了CCK兼容性的修改,旨在提供一个平台,让用户能够更自由地创造和分享"Amnesia"的游戏内容。通过这个项目,开发者和玩家可以深入探索游戏的...

    oauth2_mnesia_backend:Kivraoauth2项目的Mnesia后端

    OAuth2是一种授权框架,广泛用于安全地允许第三方应用访问用户资源,而无需共享用户的原始凭证。在OAuth2流程中,后端通常扮演着关键角色,管理令牌、客户端信息、用户授权等。 **OAuth2框架简述** OAuth2的主要...

    mnesiam:Mnesiam使Mnesia数据库的群集变得容易

    Mnesiam使Mnesia数据库的群集变得容易。 可以在上找到模块文档。 安装 该软件包可以通过添加安装mnesiam你在依赖列表mix.exs : def deps do [{ :mnesiam , " ~> 0.1.1 " }] end 在您的应用程序之前,请确保已...

    angular-amnesia-cache:角度的短期缓存

    失忆缓存 ... 只要在给定时间内没有查询同一实体,它就会返回相同的实体。 如果您需要更多自定义处理/行为,为这些编写服务可能是一个更好的主意。 AmnesiaCache只是方便。 假设我们给AmnesiaCache的生命周期是2000 ( ...

    备忘录:Mnesia分布式数据库的简单+强大接口

    **Mnesia:分布式数据库的简单而强大的接口** Mnesia是一个高度可扩展的分布式数据库管理系统,主要为实时系统设计,尤其适用于Erlang和Elixir编程语言。它作为OTP(Open Telephony Platform)的一部分,提供了对高...

    Mnesia User's Guide

    session, specify a Mnesia database directory, initialize a database schema, start Mnesia, and create tables. Initial prototyping of record definitions is also discussed. • Build a Mnesia Database ...

    amnesia:失忆备忘录

    虽然市面上类似的功能很多,我之前也一直使用日事清这款软件,但是使用这样的软件太重了,就相当于我要去三千米之外的地方你让我坐飞机去,虽然也能达到,但是... 最开始它的目的就是记录当天的要完成的事项,但是...

    erlang mnesia 数据库基本查询

    Mnesia是一个分布式数据库管理系统,适合于电信和其它需要持续运行和具备软实时特性的Erlang应用,越来越受关注和使用,但是目前Mnesia资料却不多,很多都只有官方的用户指南。下面的内容将着重说明 如何做 Mnesia ...

Global site tag (gtag.js) - Google Analytics