11 Mnesia 数据库问题
Mnesia 是 Erlang 附带的实时分布式数据库的略带怪异的名字。
11.1 Mnesia 在哪些方面表现良好?
锁定和事务
如果您需要维护一个将被多个进程和/或节点使用的数据库,使用 Mnesia 就意味着您无需编写自己的访问控制。
分布式
表可以在多个节点上复制,既是为了效率(数据库查找是本地操作),也是为了健壮性(冗余意味着如果一个节点出现故障,其他节点仍然保留数据的副本)。
非完全规范化数据
与大多数数据库系统不同,记录可以包含任意大小和结构的数据。
监控
监控 - 进程可以订阅在数据发生各种操作(更新、删除等)时发送的事件。RDBMS 包允许更细粒度的控制。
11.2 Mnesia 在哪些方面表现不佳?
Mnesia 主要用作内存驻留数据库。其设计中的某些权衡反映了这一点。
非常大的表必须以碎片化的方式存储。
11.3 Mnesia 适合存储 blob 吗?
视情况而定。Erlang 可以毫无问题地存储任意大小的 Erlang 二进制数据类型,但是由于 mnesia 强调内存驻留数据库设计,存储大量二进制数据最终会遇到许多限制中的一个。这些限制由以下因素驱动
-
存储类型 - ram_copies 和 disc_copies 表都依赖于在主内存中存储整个表和数据的完整副本。这将限制总的 blob 存储大小为可用内存的大小。
另一方面,disc_only_copies 表不受此限制的影响,但它们速度很慢(来自磁盘),数据存储在 dets 表中,如果未正确关闭(例如,在系统崩溃后),修复可能需要很长时间(这在最近的版本中得到了改进,但仍然不快)。
复制 - 如果表有副本,那么更新条目并在重新启动后重建会将数据复制到两台机器之间的网络上。根据可用带宽和正常运行时间要求,这可能是可接受的,也可能不是。
与往常一样,建议对您的特定应用程序的不同机制进行测量。
关于这些主题的更详细的讨论可以在这个 邮件列表帖子中找到。
11.4 Mnesia 有 SQL 接口吗?
一个部分的 SQL 接口作为硕士项目被构建,它使用有限,并且没有得到广泛使用。
QLC 是 Mnesia 和 ETS 的查询引擎。它比 SQL 更适合 Erlang。
11.5 Mnesia 可以存储多少数据?
这取决于表的存储类型。
-
对于 ram_copies 和 disc_copies,整个表都保存在内存中,因此数据大小受可用 RAM 的限制。
请注意,对于 disc_copies 表,整个表需要在节点启动时从磁盘读入内存,这对于大型表来说可能需要很长时间。
-
disc_only_copies 表每个表的大小限制为 2 GB。如果您的表已碎片化,每个碎片都算作一个单独的表,因此组合大小可能会超过 2 GB。
此限制的原因是 disc_only_copies 表由 Dets 表支持,而 Dets 文件格式使用带符号的 32 位整数作为文件偏移量。
此常见问题解答条目之前的版本声称所有表都受 Dets 限制。直到 R7B-4(于 2001 年 9 月 30 日发布),这种情况才发生变化,当时 disc_copies 表从 Dets 移到了 disk_log。