13

我试图弄清楚如何在Riak中建模数据。假设您正在构建具有两个功能、新闻和产品的CMS 。您需要能够为多个客户端 X 和 Y 存储此信息。您通常如何构建此信息?

  1. 每个客户一个桶,然后是两个关键新闻产品。在每个键下存储多个对象,然后使用 map/reduce 对它们进行排序。

  2. 将新闻和产品存储在同一个存储桶中,但为每个新闻项和产品项使用一个新的自动生成的密钥。也就是说,X 一个桶,Y 一个桶。

  3. 每个客户端/功能组合一个存储桶,即存储桶将是X-newsX-productsY-newsY-products。然后在整个bucket上使用map/reduce按顺序返回结果。

哪个是处理这个问题的最佳方法?

4

2 回答 2

15

我会创建 2 个存储桶:新闻和产品。然后我会在每个存储桶中的键前面加上客户端名称。我可能还会在新闻键中包含日期以便于日期范围。

news/acme_2011-02-23_01
news/acme_2011-02-23_02
news/bigcorp_2011-02-21_01

并且可以选择在产品名称前加上类别名称

products/acme_blacksmithing_anvil
products/bigcorp_databases_oracle

然后在您的 map/reduce 中,您可以使用密钥过滤

// BigCorp News items
{
  "inputs":{
     "bucket":"news",
     "key_filters":[["starts_with", "bigcorp"]]
  }
  // ... rest of mapreduce job
}

// Acme Blacksmithing items
{
  "inputs":{
     "bucket":"products",
     "key_filters":[["starts_with", "acme_blacksmithing"]]
  }
  // ... rest of mapreduce job
}

// News for all clients from Feb 12th to 19th
{
  "inputs":{
     "bucket":"news",
     "key_filters":[["tokenize", "_", 2],
                    ["between", "2011-02-12", "2011-02-19"]]
  }
  // ... rest of mapreduce job
}
于 2011-02-24T00:34:33.527 回答
7

比使用密钥过滤(根据 Kev Burns 的建议)更有效的方法是使用二级索引Riak Search来模拟这种情况。

看看我对Which clustered NoSQL DB for a Message Storage purpose的回答?Riak 中的链接:与图形数据库相比,它们能做什么/不能做什么?用于讨论类似案例。

根据您的用例,您需要做出几个决定。在所有情况下,您都将从公司存储桶开始,以便每个公司都有一个唯一的密钥。

1) 是否将感兴趣的项目存储在 2 个单独的存储桶中(新闻产品)或存储在一个存储桶中(类似于items_of_interest)取决于您的偏好和查询的难易程度。如果您总是要在单个查询中同时查询一家公司的新闻和产品,那么您不妨将它们存储在一个存储桶中。但我建议使用 2 个单独的,以便更轻松地跟踪它们,特别是如果您将有类似“公司 X - 产品”和“公司 X - 新闻”的单独选项卡或页面。如果您需要将它们组合到一个提要中,您将进行 2 个查询(一个用于新闻,一个用于产品),并将它们组合到客户端代码中(按日期或其他)。

2) 如果一个新闻/产品项目可以有一个且只有一个公司所属的公司,为每个项目在company_key上创建一个二级索引。这样,您可以通过对该公司的二级索引 (2i) 查询轻松获取该公司的所有新闻或产品。

3)如果有一个多对多的关系(如果一个新闻/产品项目可以属于几个公司(也许新闻项目是关于两个独立公司的合资企业)),那么我建议将关系建模为一个单独的 Riak对象。例如,您可以创建一个提及桶,并且对于新闻报道中提到的每个公司,您将插入一个 Mention 对象,该对象具有自己的唯一键、company_key 的二级索引,并且该值将包含一个类型('news'或“产品”)和 item_key(新闻密钥或产品密钥)。像这样提取关系以分离 Riak 对象可以让您做很多有趣的事情——使用 Riak Search 任意标记它们,查询它们以获取订阅事件通知等。

于 2012-10-21T20:46:52.850 回答