• 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)

  • 相关阅读:
    [论文笔记] Human Computation (DAC, 2009)
    [论文收集] HCOMP 2011概况及收录论文
    [论文笔记] reCAPTCHA: HumanBased Character Recognition via Web Security Measures (Science, 2008)
    [论文笔记] Crowdsourced Databases: Query Processing with People (CIDR, 2011)
    [论文笔记] Crowdsourcing Translation: Professional Quality from NonProfessionals (ACL, 2011)
    [阅读笔记] A Report on the Human Computation Workshop (HCOMP, 2009)
    [论文速读] Towards crowdsourcing translation tasks in library cataloguing, a pilot study (DEST, 2010)
    [文章摘录] Strategies for EarlyStage Collaborative Design (IEEE Software, 2012)
    [论文笔记] Task Matching in Crowdsourcing (iThings & CPSCom, 2011)
    [论文笔记] Exploring microwork opportunities through cybercafés (ACM DEV, 2012)
  • 原文地址:https://www.cnblogs.com/lawen/p/5047771.html
Copyright © 2020-2023  润新知