【问题标题】:Efficiently determine owner of a record in a hierarchy with MongoDB使用 MongoDB 有效地确定层次结构中记录的所有者
【发布时间】:2012-01-02 16:53:59
【问题描述】:

我正在努力实现以下目标:

选择我拥有的所有记录,其中所有权是我创建的对象或我管理的用户创建的对象,其中用户管理可以在管理用户的用户层次结构中

所有权显然是直截了当的,可以通过与所有者相对应的简单 id 来处理。用户管理的层次结构让我有点难以执行,而无需通过大量 ID 列表进行繁重的工作(您显然可以找到每个受管理的用户并列出由任何这些用户使用 IN 子句或类似语句创建的每个对象)。

理想情况下,这一切都发生在一个查询中,因此可以发生正常的分页和条件。

我在想可能有一些数学来完成它 - 拥有可以以某种方式散列以确定它们是否由命令链中的任何人拥有的 ID。

这类事情有什么参考资料吗?

我是否遗漏了一些明显的东西?

使用 MongoDB 会有所作为,但很高兴考虑其他数据库以获得灵感。

更新: 已经创建了一个包含 1,000,000 条记录的 MongoDB 集合,以获取一些可靠的数据,这些数据准确地说明了查询中 IN 子句的可管理数量的参数的构成。当我有一些具体信息时会报告。

分析:

使用 ruby​​-mongo-driver 和 ruby​​ 基准库。

包含 1039944 条记录的 MongoDB 集合

记录定义为:

{
    first_name: String,
    last_name: String,
    email: String,
    phone: String,
    company: String,
    owner: BSON::ObjectId
 }

为所有字段随机生成值。

所有者字段有一个索引。

在以下条件下运行查询:

conditions = {"owner" => { "$in" => id_list }}
opts = {skip: rand, limit: 100}

结果:

    # 10201 ids
    #              user     system      total        real
    # 0:       0.240000   0.000000   0.240000 (  0.265148)
    # 1:       0.240000   0.010000   0.250000 (  0.265757)
    # 2:       0.240000   0.000000   0.240000 (  0.267149)
    # 3:       0.240000   0.000000   0.240000 (  0.269981)
    # 4:       0.240000   0.000000   0.240000 (  0.270436)
    # Find:    0.240000   0.000000   0.240000 (  0.266709)


    # 5201 ids
    #              user     system      total        real
    # 0:       0.120000   0.000000   0.120000 (  0.133824)
    # 1:       0.120000   0.000000   0.120000 (  0.134787)
    # 2:       0.110000   0.000000   0.110000 (  0.133262)
    # 3:       0.110000   0.000000   0.110000 (  0.136046)
    # 4:       0.120000   0.000000   0.120000 (  0.141220)
    # Find:    0.130000   0.000000   0.130000 (  0.139110)

    # 201 ids
    #              user     system      total        real
    # 0:       0.010000   0.000000   0.010000 (  0.006044)
    # 1:       0.000000   0.000000   0.000000 (  0.004681)
    # 2:       0.010000   0.000000   0.010000 (  0.004578)
    # 3:       0.000000   0.000000   0.000000 (  0.007048)
    # 4:       0.010000   0.000000   0.010000 (  0.008487)
    # Find:    0.000000   0.000000   0.000000 (  0.005990)

    # 1 id (NOT using IN)
    #              user     system      total        real
    # 0:       0.000000   0.000000   0.000000 (  0.002868)
    # 1:       0.000000   0.000000   0.000000 (  0.004937)
    # 2:       0.010000   0.000000   0.010000 (  0.003151)
    # 3:       0.000000   0.000000   0.000000 (  0.002983)
    # 4:       0.000000   0.000000   0.000000 (  0.003313)
    # Find:    0.000000   0.000000   0.000000 (  0.002742)

即使查询中有 10k 个 ID 的列表,性能也相当出色。

【问题讨论】:

  • 经过反思,我想如果有一个“魔术”函数来计算父节点,那么围绕嵌套集、物化路径和邻接列表将树放入数据库的繁重工作将是没有意义的。

标签: mongodb database-design database-permissions database


【解决方案1】:

如果您尝试根据“列”从 MongoDB 中“选择”记录,该“列”的值来自一组可能的值,您需要与用户管理表进行连接才能确定,那么 NoSQL 对您不利...

如果用户 ID 列表仍然可以管理,您可以进行 where ownerId in (?,?,?,?,?...) 类型的查询(在首先确定列表之后):

db.documents.find({owner:{$in: [1234, 2345, 4444, 77777, 99999]}})

NoSQL 的方式可能是对事物进行非规范化,例如通过在文档中不仅包含 ownerId,还包含管理层次结构的完整路径:

{  _id: 'the document A',
   owner : 1234,
   managers: [ 2345, 4444, 77777, 99999 ]
}

当然,这需要在用户层次结构发生变化时进行更新。

【讨论】:

  • 然后索引managers 并使用Multikeys 进行搜索。
  • 是的,IN 选项是我看过的。问题是罐头管理员有管理员,每次权限更改时,您都必须遍历整个集合以重置所有内容。显然不是管理问题的理想方式。
  • 使用 IN 选项,权限更改就可以了,因为您不必更新集合本身(只需使用不同的 id 查询)。如果您进行反规范化,那么,是的,您将不得不“重建索引”。避免这种情况是规范化和连接的主要好处,但如果没有 RDBMS,您将无法获得。
  • 啊,我明白你的意思了……找到用户的所有 id,然后映射。去规范化的方法几乎会立即崩溃。
  • 但无论如何,我认为我不能依赖 id 列表是“可管理的”。
猜你喜欢
  • 2016-04-08
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
  • 2012-04-04
  • 2014-12-03
  • 2015-01-03
相关资源
最近更新 更多