我有几个语义三元组.一些例子:
Porky,species,pig // Porky's species is "pig"
Bob,sister,May // Bob's sister is May
May,brother,Sam // May's borther is Sam
Sam,wife,Jane // Sam's wife is Jane
... and so on ...
Run Code Online (Sandbox Code Playgroud)
我将每个三联储存在6个不同的哈希中.例:
$ijk{Porky}{species}{pig} = 1;
$ikj{Porky}{pig}{species} = 1;
$jik{species}{Porky}{pig} = 1;
$jki{species}{pig}{Porky} = 1;
$kij{pig}{Porky}{species} = 1;
$kji{pig}{species}{Porky} = 1;
Run Code Online (Sandbox Code Playgroud)
这让我有效地提出如下问题:
什么物种是Porky(keys %{$ijk{Porky}{species}})
列出所有猪(keys %{$jki{species}{pig}})
我在Porky上有什么信息?(keys %{$ijk{Porky}})
列出所有物种(keys %{$jik{species}})
等等.请注意,上面的示例都没有一次列出一个元素.他们都"立即"接受我的回答.换句话说,每个答案都是一个哈希值.当然,答案本身可能是一个列表,但我不会遍历任何列表来得到答案.
但是,定义6个单独的哈希似乎效率很低.没有使用外部数据库引擎有没有更简单的方法 (对于这个问题,SQLite3算作外部数据库引擎)?
或者我刚刚将一小部分SQL复制到Perl中?
编辑:我想我想说的是:我喜欢关联数组,但它们似乎是这项工作的错误数据结构.这里的数据结构是什么,Perl模块实现了什么?
“高效”在这里并不是真正正确的词,因为您担心提高速度以换取内存,这通常是它的工作原理。
唯一真正的替代方案是将三元组存储为不同的值,然后只在其中添加三个“索引”:
$row = [ "Porky", "species", "pig" ];
push @{$subject_index{Porky}}, $row;
push @{$relation_index{species}}, $row;
push @{$target_index{pig}}, $row;
Run Code Online (Sandbox Code Playgroud)
要执行“列出所有猪”之类的操作,您必须找到$relation_index{species}和的交集$target_index{pig}。您可以手动执行此操作,也可以使用您最喜欢的设置实现。
然后将其全部包装在一个漂亮的对象接口中,您就基本上实现了INNER JOIN. :)