You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Erlang记录的首个元素无法作为Mnesia表的索引?

为什么Erlang记录的首个元素无法作为Mnesia表的索引?

当你尝试将Erlang记录的第一个字段设为Mnesia表的索引时,会遇到表创建失败的问题,但把该字段调整到非首位置后就能成功,具体现象如下:

执行失败的代码示例

(hlu@192.168.0.40)16> rd(pilot, {id, name, weight, phone}).
pilot
(hlu@192.168.0.40)17> mnesia:create_table(pilot,
(hlu@192.168.0.40)17> [{attributes, record_info(fields, pilot)},
(hlu@192.168.0.40)17> {index, [#pilot.id]},
(hlu@192.168.0.40)17> {disc_copies, Nodes},
(hlu@192.168.0.40)17> {type, set}]).
{aborted,{bad_type,pilot,{index,[{2,ordered}]}}}

执行成功的代码示例

(hlu@192.168.0.40)18> rf(pilot).                                
ok
(hlu@192.168.0.40)19> rd(pilot, {name, weight, phone, id}).     
pilot
(hlu@192.168.0.40)20> mnesia:create_table(pilot,
(hlu@192.168.0.40)20> [{attributes, record_info(fields, pilot)},
(hlu@192.168.0.40)20> {index, [#pilot.id]},
(hlu@192.168.0.40)20> {disc_copies, Nodes},
(hlu@192.168.0.40)20> {type, set}]).
{atomic,ok}

原因解释

Mnesia的set类型表有个默认规则:记录的第一个属性会自动成为表的主键,而主键本身已经自带了索引功能,Mnesia不允许给主键字段额外创建显式索引——这属于重复操作,会触发类型错误。

在失败的示例中,id是记录的第一个属性,创建set表时它自动成为主键,此时你试图把id加入index列表,就会抛出bad_type错误。错误信息里的{2,ordered}对应主键在元组中的位置(因为Erlang记录的第一个元素是记录名,所以属性id是元组的第2个元素)。

而成功的示例中,id被移到了记录的最后一位,此时表的主键变成了第一个属性name,id不再是主键,因此可以给它创建索引,表创建操作顺利完成。

补充说明

如果你本来就打算用id作为表的主键,那根本不需要额外给它加索引——主键本身就支持高效的查询,直接省略{index, [#pilot.id]}这个配置项即可正常创建表。

内容的提问来源于stack exchange,提问作者Gabor Szelei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 05:12:23