<p>将多个值关联到一个键的正确方法是使用例如json.dumps文件". 在</p>
<p>以下是一个例子:</p>
<pre><code>#!/usr/bin/python
from json import dumps
from json import loads
import bsddb
# write
users = bsddb.hashopen("users.db","w")
primarykey = 'amz'
users[primarykey] = dumps(dict(username="amz", age=30, bio="craftsman"))
users.close()
# read
users = bsddb.hashopen("users.db","r")
for key in users.keys():
print loads(users[key])
users.close()
</code></pre>
<p>这是与bsddb一起使用的基本模式,适用于其他键/值dbs,如leveldb。在</p>
<p><strong>额外:</strong></p>
<p>考虑到bsddb hashmap键是按字典顺序排序的(例如python2字符串),您可以使用键的可预测顺序来构建hashmap,从而省去遍历所有表的麻烦。在</p>
<p>为了更好地利用这个特性,你必须建立有用的键。同样,您需要一个打包函数,将python排序顺序转换为lexigraphic顺序(即<code>11 > 2</code>但是<code>"11" < "2"</code>)。下面是这样一个包装函数的例子:</p>
^{pr2}$
<p>这有点天真,你可以多做一点,支持<code>float</code>和更好的打包{<cd4>}来节省空间。在</p>
<p>例如,给定简化模式<code>User(username, age)</code>,您可以构建另一个我们称为<code>age_index</code>的哈希映射,使用它可以轻松地检索到
30岁。hashmap可以如下所示:</p>
<pre><code> key | value
-----------------
29 tom | X
30 amz | X
30 joe | X
30 moh | X
</code></pre>
<p>这是一个人类可读的hasmap视图:密钥实际上与上面的<code>pack</code>函数打包在一起。如您所见,键是<code>age</code>的组合</strong>,以及之前存储的项的<code>primarykey</code>。在这种情况下,不使用该值,因为我们不需要它。请记住,每个键都是且必须是唯一的。在</p>
<p>一旦该模式就位,您就可以使用<a href="https://www.jcea.es/programacion/pybsddb_doc/dbcursor.html#set_range" rel="nofollow noreferrer">^{<cd10>}</a>执行“选择查询”,在bsddb中称为范围查询。这将把光标设置在最近的键上,并返回关联的键/值对(根据数据库,语义可能会有所不同)。在</p>
<p>例如,要检索第一个拥有<code>age=30</code>的人,可以使用以下代码:</p>
<pre><code>def get_first_person_with_age_thirty()
key, _ = age_index.set_range(pack(30)) # we don't need value
age, pk = unpack(key)
# set_range, will set the key to "30" and a pk
# or with a key prefix superior to 30.
# So we need to check that age is really 30.
if age == 30:
return loads(users[pk])
</code></pre>
<p>这将返回与用户<code>amz</code>关联的文档。在</p>
<p>要进一步,需要使用另一个bsddb接口,它的入口点是<code>bsddb.db.DB</code>和{<cd14>}(<a href="https://www.jcea.es/programacion/pybsddb_doc/" rel="nofollow noreferrer">documentation</a>)。通过这个接口,您可以将多个hashmap绑定到同一个事务上下文,即使它不需要使用事务。在</p>