zoukankan      html  css  js  c++  java
  • mnesia

    1、schema 表

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

      schema表的信息只能通过schema的方法来操作

      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都停止后才执行 

      1)、schema只能创建一次 
      2)、实际上,每个节点都保存一份schema拷贝 

    2、普通表的操作

         mnesia:create_table(funky, []).
         mnesia:delete_table(Tab).
         mnesia:clear_table(Tab).
         mnesia:move_table_copy(Tab, From, To).将表Tab从From拷贝到To节点。
         mnesia:add_table_copy(Tab, Node, Type).在node节点上创建Tab的备份.
         mnesia:del_table_copy(Tab, Node).在node节点删除Tab的备份,最后一个备份被删掉后,表本身也被删掉。
         mnesia:transform_table(Tab, Fun, NewAtrributeList, NewRecordName)改变表的记录格式。
         mnesia:change_table_copy_type(Tab, Node, ToType)修改表的存储类型.
         mnesia:info().
         mnesia:write().
         mnesia:transaction().
         
         mnesia:table_info(Tab, Key).
         mnesia:system_info(Key).
     
      脏操作:  

      mnesia:dirty_read({Tab, Key}),

      mnesia:dirty_write(Record)

      mnesia:dirty_delete({Tab,Key})

      mnesia:dirty_delete_object(Record)

      mnesia:dirty_firest(Tab)

      mnesia:dirty_next(Tab, key)

      mnesia:dirty_last(Tab)

      mnesia:dirty_prev(Tab, Key)

      mnesia:dirty_slot(Tab, Slot)

      mnesia:dirty_update_counter({Tab, Key}, Val)

      mnesia:dirty_match_object(Pat)

      mnesia:dirty_index_match_object(Pat, Pos)

      mnesia:dirty_all_key(Tab)

     
      在一个节点上,通过 mnesia:create_table(),则创建一个分布式的表。 
      mnesia会自动将该表同步到节点中其它节点上。 
      每个节点,实际上还是维护的本地的一个表。
      在任意一个节点上进行如上操作,都会同步反映到集群中的其它节点上。
      事务是同步的操作,性能低,但能确保一致性。 
      脏操作不能保证一致性,但是速度极快。 
    3、mnesia数据模型
      Mnesia的数据库数据由record组成,record由tuple表示 
      record的第一个元素是record名,第二个元素是表的key,前两个元素组成的tuple称为oid 
      Mnesia数据模型是对关系模型的扩展,因为该模型可以在域属性里存储任意的Erlang term 
      例如,可以在一个属性里存储指向其他表里的oid树,而这种类型的记录在传统的关系型DBMS里很难建模
     
      mnesia数据库被组织为一个表的集合,每个表有实例构成,表也包含一些属性,如位置和持久性。
      在mnesia里,表内所有记录必须有相同的名字,所有记录必须是同一记录类型的实例。
      存储类型为RAM_copies和disc_copies的Mnesia表内部是用ets表来实现的,因此,应用程序直接存取这些ets表是可能的。
      一个在记录中的单独字段能够包含任何类型的复合数据结构。
     
      对象ID 由表名和Key组成。如记录{employee, 10347, klacke, 7, male, 9810, {221, 015}}的Oid就是{employee, 10347}.
     
    4、启动mnesia
      在启动Mnesia之前我们必须在相应的节点上初始化一个空的schema 
      1)Erlang系统必须启动 
      2)必须使用create_schema(NodeList)来定义数据库schema 
      当运行一个分布式系统时,可能有多个节点参与,则mnesia:start()方法必须在相应的节点上运行 
     
      数据库只需初始化一次,下次只需mnesia:start()启动即可从硬盘启动系统 
      mnesia:stop()方法在当前节点上停止Mnesia,start/0和stop/0都在本地Mnesia系统上起作用,没有启动和停止一些节点的方法 
      mnesia:wait_for_table(TabList, Timeout)会等待表的加载 
     
    5、mnesia数据查询
      1) Mnesia方法 
        mnesia:select(employee, [{#employee{sex = female, name='$1', _='_'},[],['$1']}]).
        select 必须运行在类似事务的活动中
      2) QLC 
        QLC通常比直接使用mnesia函数 代价更高 。但是提供了更好的语法
        Q = qlc:q([E#employee.name || E <- mnesia:table(employee), E#employee.sex == female]),
        qlc:e(Q)
      
      通过key来遍历表   APIs:

      mnesia:dirty_first(Tab) 返回Tab中第一个Key, 如果表中没有记录,返回'$end_of_table'
      mnesia:dirty_next(Tab, Key) 返回Tab中的下一个Key, 如果表中没有下一个key,返回'$end_of_table'
      mnesia:dirty_last(Tab) 和mnesia:dirty_first(Tab)工作方式一样,只有当type是ordered_set的时候
      返回Erlang排序中的最后一项,其它类型的和mnesia:dirty_first(Tab)完全一样.
      mnesia:dirty_prev(Tab, Key) 和mnesia:dirty_next(Tab, Key)工作方式一样,只有当type是ordered_set的时候
      返回Erlang排序中的前一项,其它类型的和mnesia:dirty_next(Tab, Key)完全一样

    6、Mnesia锁 

      读锁, 在复制记录读前加读锁
      写锁, 在事务写记录前,会在指定记录的所有复件上添加写锁
      读表锁,如果一个事务遍历整个表搜索指定条件记录,最低效是设置记录锁,同时也是大量内存消耗。些时可以指定一个读表锁。
      写表锁,如果一个事务要大量写入一个表,最好你用写表锁
      粘锁,当一个事务操作完成后,锁依然存在。

      Mnesia锁的策略是在读取一条记录的时候,锁住该条记录;在写一条记录的时候锁住记录的所有副本
      写锁一般会要求在所有存放表的副本并且是活动的节点上设置,读锁只设置一个节点.  

      Mnesia采用动态策略应对如mnesia:read/1,自动添加和释放锁。程序员无须考虑。

      Mnesia不用担心死锁问题,当系统怀疑某个锁死锁时,它会释放该锁,然后再执行一遍, 多个相同事务不能保证顺序执行,但可以保证都执行。程序员不能设定某个事务的优先级。

      切不可执行代码带有事务副作用。如在receive语句在事务,可能产生系统假死等。

      当一个事务异常终止时,Mnesia会自动的释放其持有的所有锁。

      Mnesia函数:

      mnesia:transaction(Fun) -> {aborted, Reason} | {atomic, Value},该函数执行一个带函数Fun的事务。

      mnesia:read({Tab, Key}) -> transaction abort | RecordList, 返回所有带Key的记录

      mnesia:wread({Tab, Key}),该函数和上一函数相同,除由读锁改为写锁,如果执行一个读记录,修改, 写入记录,那么直接用写锁效率更高。

      mnesia:write(Record).写入一条记录到数据库
      mnesia:delete({Tab, Key}),删除指定表键的所有记录

      mnesia:delete_object(Record)用Record的OID删除对应记录

      

      粘锁:

      普通情况下mnesia每次写入操作的时候,都会锁住所有复件。如果针对一个大量写入到在一个复件的情况下, 那么粘锁就可以派上用场了。在没有其它复件存在的情况下,粘锁和普通锁差不多,没有什么特别影响。

      粘锁在第一次使用后, 并不立即释放。下次我们使用粘锁在同一节点的同一记录上,那么这个粘锁就已经设置好了。所有效率更高。多用于一主多从库, 对于有用到两复件间交互则消耗较大。

    7、索引  

      mnesia:add_table_index(Tab, AttributeName)

      mnesia:delete_table_index(Tab,AttributeName)

  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/lawen/p/5047771.html
Copyright © 2011-2022 走看看