【问题标题】:BDB, How to get primary keys in specified order?BDB,如何按指定顺序获取主键?
【发布时间】:2011-01-26 03:05:36
【问题描述】:

我在 oracle 论坛上问了几天同样的问题,但没有得到答案:( 链接为:http://forums.oracle.com/forums/thread.jspa?threadID=2162345&tstart=0

您好,我使用BDB作为后端数据库,论坛数据库,主题数据库和帖子数据库共享一个环境来构建BBS。这个 BBS Web 应用程序是多线程程序。如果用户选择了一个论坛,其主题将按最后回复时间的顺序排列;选择一个主题,帖子也将按回复时间的顺序排列。

struct forum {
UInt16 forumID;
string forumName;
string _lastPoster; // who is the last one replied in this forum
};

struct topic {
UInt32 topicID;
UInt16 forumID; // topic comes from this forum
string title; // topic title
UInt64 dateOfLastReply; // when last reply to this topic happen
};

struct post {
UInt64 postID;
UInt32 topicID; // post comes from this topic
string title; // post title as of topic
UInt64 dateOfPost; // when this post is created
};

我为主题创建一个主库和两个从库,主键是topicID,辅助键分别是forumID和dateOfLastReply,我想在第一个浏览器页面上以最新回复时间顺序显示第1个25个主题,第2个25个主题在第二个浏览器页面上,等等。

如果使用 SQL,它将是:SELECT topicID FROM topic WHERE forumID=xx ORDER BY dateOfLastReply DESC

从性能的角度来看,我想获取同一个论坛的所有主题ID,并且需要它们按回复时间顺序来,然后根据返回的主题ID一个一个检索主题,我该怎么做?猜我必须使用连接。 另外,鉴于每次浏览器想要请求下一页(即本论坛的第 2 25 个主题)时都会发生主题检索这一事实,您对检索性能有什么建议吗? DB_DBT_MULTIPLE 对我有帮助吗?

谢谢。

【问题讨论】:

    标签: database algorithm sorting selection berkeley-db


    【解决方案1】:

    您需要使用复合键创建一个辅助数据库,由 (forum_id, dateoflastreply) 组成。然后,您想要的所有结果都将位于连续的行范围内,您可以通过范围扫描来查询它们(例如,从 (1, 2010-01-01) 开始的 20 行)。

    【讨论】:

    • 嗨尼克,我也认为复合键可能对我有帮助,但是,我不知道如何创建复合键?是 DB_DBT_MULTIPLE 吗?我应该自定义比较功能吗? etc.sample 代码可能会更好。
    • 我有一段时间没有使用 BDB 了,所以我不能提供示例代码。通常,所有 BDB 值都是字节,因此您需要通过将字段编码在一起来自己创建复合值。这应该很简单,例如,如果两个字段都是固定长度的 - 只需将它们连接在一起。只要编码值按预期方式按字节排序,您就不需要自定义比较函数。
    【解决方案2】:

    您在使用 BDB 的新 SQL access layers 吗?如果是这样,只需使用 SQL。

    如果不是,BDB(大部分)只是一个键值数据存储。它有几种访问方法(散列、B+树等),但其核心仅此而已。如果您想按非主键排序/搜索,则必须在这些值上创建索引,并在您自己的代码中进行搜索/连接。

    【讨论】:

    • 您好,我使用的是非 sql 版本的 BDB。是的,我知道 BDB 是一个键值数据库,并且我也创建了二级索引,但是,我找不到任何方法来满足我的问题中描述的要求
    • 如果您的二级索引在 dateoflastreply 上,那么您只需在该范围内进行迭代。不过,您仍然必须手动将每一个与您的 WHERE forumID 条件进行比较。无论如何,这就是数据库引擎在内部为您做的事情。
    • 您好Corey,您的意思是BDB 在插入或更新时不会对记录进行排序?本来我认为BDB会在插入或更新时使用set_bt_compare设置的比较函数对记录进行排序。
    【解决方案3】:

    假设 topic_secondary 数据库(包含辅助键)是通过 DB_ASSOCIATE 定义的,那么您将在 topic_secondary 数据库上打开一个游标,并使用带有 DB_SET_RANGE 的 DBC->get() 将游标定位在所需的 forumID 和从那里向前移动光标。

    通过在辅助数据库上使用光标,您可以按所需顺序从主数据库返回数据。通过在初始 DBC->get() 中使用 DB_SET_RANGE 指定 forumID,您可以将光标定位在适当的位置开始扫描。

    请参阅CursorsSecondary indexes 上的文档。

    如果这回答了您的问题,请告诉我。

    问候,

    戴夫

    【讨论】:

    • 您好,感谢您的回答,我会试一试。据我所知,插入时会发生排序,也就是说,如果我想获得所需的顺序,我必须在插入(放置)而不是获取之后保持这些记录的排序;当然,应用程序可以在返回所有所需记录后进行排序,但这可能会降低性能
    • 根据您的索引,键按排序顺序插入。我假设您的表是 BTree,在这种情况下,数据将根据键进行排序。
    • 你好,我用forumID和dateOfLastReply的组合键做二级数据库,同时设置比较功能,符合我的要求,谢谢你的帮助
    • Tiplip,您想在这里、Github、Google Code 或其他地方发布您的代码作为示例吗?它可能会帮助下一个也有兴趣用 Berkeley DB 解决类似问题的人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多