我为什么要在MongoDB中保留默认的_id?

时间:2015-12-22 10:24:59

标签: mongodb primary-key composite-primary-key objectid

我是MongoDB的初学者。

我想知道在性能/内存等方面使用默认的_id(对象ID)和_id(作为主键的几列组合)之间是否存在任何权衡。

1 个答案:

答案 0 :(得分:1)

  1. _id是二进制的,因此占用的空间更少。

  2. ObjectIds也有排序因子 它们最终将处于插入顺序(或非常接近),同时保持唯一。排序对于某些事情可能是好的,但对于其他事物则是不需要的(例如分片键)。

  3. 您还可以从ObjectId中提取时间戳(第二个分辨率),这很方便。

  4. 另一个链接:https://groups.google.com/forum/#!msg/meteor-talk/f-ljBdZOwPk/oQYZQxCAKN8J

    默认_id,对象id是一个12字节的BSON类型,使用以下构造:

    • 一个4字节的值,表示自Unix纪元以来的秒数,
    • 一个3字节的机器标识符,
    • 一个2字节的进程ID,
    • 一个3字节的计数器,以随机值开始。

    因此它在集合上是独一无二的,它默认具有索引。

    MongoDB使用B-Tree索引。在B树中搜索特定值在平均和最差情况下具有O(log n)复杂度,这可以被认为是相当快的(即二进制搜索)。它不是常数复杂度= O(1),所以如果索引大小比可用RAM大,你仍然可能会有一些减速效果。

    MongoDB尝试将索引保留在RAM中,并且在磁盘上查找索引所需的每个IO都会大大减慢查询速度。

    因此,如果维护了索引主列并且该索引位于磁盘上,那么为什么我们需要一个额外的主索引键。虽然您可以根据需要创建唯一约束。

    <强>更新 您可能无法创建具有散列索引字段的复合索引。如果尝试创建包含散列索引的复合索引,则会收到错误。散列索引用于分片(当在同一个集合中有大量数据时,分片很有用。)

    如果您有数百万条记录,那么您应该使用分片收集。如果要添加唯一约束,可以创建组合键,并指定更快搜索的顺序。

    db.products.createIndex( { "price": 1, "stock": -1 } ).
    

    因此,可以更快地搜索库存较高且价格较低的产品。

    因此,它高度依赖于您要搜索的数据。通过使用具有对象Id的附加复合键,如果在正确的属性上进行,则将非常有用。