`
hideto
  • 浏览: 2692884 次
  • 性别: 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

相关推荐

    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用户手册 4.4.10版.rar

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

    oracle rac

    书中还讨论了RAC集群可能遇到的特殊问题,如并发控制、健忘症(Amnesia)、脑裂(SplitBrain)和IO隔离(IOFencing),并回顾了RAC的历史演变及其相对于OPS(Oracle Parallel Server)的优势。 ### Oracle ...

    手撕源码C++哈希表实现:从底层原理到性能优化,看完面试官都怕你!(文末附源码)

    哈希表源码

    sun_3ck_03_0119.pdf

    sun_3ck_03_0119

    MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost时间序列预测(含模型描述及示例代码)

    内容概要:本文档详细介绍了基于 MATLAB 实现的 LSTM-AdaBoost 时间序列预测模型,涵盖项目背景、目标、挑战、特点、应用领域以及模型架构和代码示例。随着大数据和AI的发展,时间序列预测变得至关重要。传统方法如 ARIMA 在复杂非线性序列中表现欠佳,因此引入了 LSTM 来捕捉长期依赖性。但 LSTM 存在易陷局部最优、对噪声鲁棒性差的问题,故加入 AdaBoost 提高模型准确性和鲁棒性。两者结合能更好应对非线性和长期依赖的数据,提供更稳定的预测。项目还展示了如何在 MATLAB 中具体实现模型的各个环节。 适用人群:对时间序列预测感兴趣的开发者、研究人员及学生,特别是有一定 MATLAB 编程经验和熟悉深度学习或机器学习基础知识的人群。 使用场景及目标:①适用于金融市场价格预测、气象预报、工业生产故障检测等多种需要时间序列分析的场合;②帮助使用者理解并掌握将LSTM与AdaBoost结合的实现细节及其在提高预测精度和抗噪方面的优势。 其他说明:尽管该模型有诸多优点,但仍存在训练时间长、计算成本高等挑战。文中提及通过优化数据预处理、调整超参数等方式改进性能。同时给出了完整的MATLAB代码实现,便于学习与复现。

    免费1996-2019年各地级市平均工资数据

    1996-2019年各地级市平均工资数据 1、时间:1996-2019年 2、来源:城市nj、各地级市统计j 3、指标:平均工资(在岗职工) 4、范围:295个地级市

    [AB PLC例程源码][MMS_040384]Winder Application.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    C2Former: 解决RGB-红外物体检测中模态校准与融合不精确问题的标定互补变压器

    内容概要:本文介绍了一种新颖的变压器模型C2Former(Calibrated and Complementary Transformer),专门用于解决RGB图像和红外图像之间的物体检测难题。传统方法在进行多模态融合时面临两个主要问题——模态错位(Modality miscalibration)和融合不准确(fusion imprecision)。作者针对这两个问题提出采用互模交叉注意力模块(Inter-modality Cross-Attention, ICA)以及自适应特征采样模块(Adaptive Feature Sampling, AFS)来改善。具体来说,ICA可以获取对齐并且互补的特性,在特征层面进行更好的整合;而AFS则减少了计算成本。通过实验验证了基于C2Former的一阶段和二阶段检测器均能在现有公开数据集上达到最先进的表现。 适合人群:计算机视觉领域的研究人员和技术人员,特别是从事跨模态目标检测的研究人员,对Transformer架构有一定了解的开发者。 使用场景及目标:适用于需要将可见光和热成像传感器相结合的应用场合,例如全天候的视频监控系统、无人驾驶汽车、无人

    上海人工智能实验室:金融大模型应用评测报告-摘要版2024.pdf

    上海人工智能实验室:金融大模型应用评测报告-摘要版2024.pdf

    malpass_02_0907.pdf

    malpass_02_0907

    C++-自制学习辅助工具

    C++-自制学习辅助工具

    微信生态系统开发指南:涵盖机器人、小程序及公众号的技术资源整合

    内容概要:本文提供了有关微信生态系统的综合开发指导,具体涵盖了微信机器人的Java与Python开发、全套及特定应用的小程序源码(PHP后台、DeepSeek集成),以及微信公众号的基础开发与智能集成方法。文中不仅给出了各种应用的具体案例和技术要点如图灵API对接、DeepSeek大模型接入等的简述,还指出了相关资源链接以便深度探究或直接获取源码进行开发。 适合人群:有意开发微信应用程序或提升相应技能的技术爱好者和专业人士。不论是初涉者寻求基本理解和操作流程,还是进阶者期望利用提供的资源进行项目构建或是研究。 使用场景及目标:开发者能够根据自身兴趣选择不同方向深入学习微信平台的应用创建,如社交自动化(机器人)、移动互联网服务交付(小程序),或者公众信息服务(公众号)。特别是想要尝试引入AI能力到应用中的人士,文中介绍的内容非常有价值。 其他说明:文中提及的多个项目都涉及到了最新技术栈(如DeepSeek大模型),并且为不同层次的学习者提供从零开始的详细资料。对于那些想要迅速获得成果同时深入了解背后原理的人来说是个很好的起点。

    pimpinella_3cd_01_0916.pdf

    pimpinella_3cd_01_0916

    mellitz_3cd_01_0516.pdf

    mellitz_3cd_01_0516

    schube_3cd_01_0118.pdf

    schube_3cd_01_0118

    [AB PLC例程源码][MMS_046683]ME Faceplates for 1738 Digital and Analog I-O with Descriptions.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_040371]Communication between CompactLogix Controllers on DeviceNet.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_046507]SE Faceplates for 1797 Digital and Analog I-O.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

Global site tag (gtag.js) - Google Analytics