• mongodb指南(翻译)(十三) developer zone 数据类型和约定(二)之Object ID


    Object IDs

    在mongodb中的文档需要使用唯一的关键字_id来标识他们。

    _id字段

    几乎每一个mongodb文档都使用_id字段作为第一个属性(在系统集合和定容量集合(capped collection)中有一些例外)。_id值可以是任何类型,最常见的做法是使用ObjectId类型。每一个文档的_id字段在该集合中必须是唯一的;这是由于集合会自动为_id建立索引而强制要求的(除了前面提到的那些例外)。

    如果用户尝试插入一个不带_id字段的文档,数据库会自动生成一个对象id并保存在_id字段。

    _id值可以是任何类型,只要它是唯一的,但除了数组。如果你的文档有一个天然独有的不可更改的主键,我们推荐你使用它代替自动生成的_id。数组不允许作为_id,是因为他们是多键的。

    BSON ObjectId 数据类型

     虽然_id值可以是任何类型,但是mongodb依然为对象id提供了一个特殊的BSON数据类型。该类型设计为12个字节的二进制值,这样就具有相当高的概率保证分配时的唯一性。所有官方支持的mongodb驱动都默认使用该类型作为_id的值。同时,mongo数据库自身在插入无_id字段的文档时,也使用这个类型给_id赋值。

    在mongodb shell,ObjectId()可以在用来传教ObjectIds.ObjectId(String)使用指定的16进制字符串创建对象ID。

    > x={ name: "joe" }
    { name : "joe" }
    > db.people.save(x)
    { name : "joe" , _id : ObjectId( "47cc67093475061e3d95369d" ) }
    > x
    { name : "joe" , _id : ObjectId( "47cc67093475061e3d95369d" ) }
    > db.people.findOne( { _id: ObjectId( "47cc67093475061e3d95369d" ) } )
    { _id : ObjectId( "47cc67093475061e3d95369d" ) , name : "joe" }
    > db.people.findOne( { _id: new ObjectId( "47cc67093475061e3d95369d" ) } )
    { _id : ObjectId( "47cc67093475061e3d95369d" ) , name : "joe" }

    BSON ObjectID 详细说明

    一个BSON ObjectID是12字节的值,包含了4字节的时间戳(纪元以来的秒数),3字节机器id,2字节进程id,和3字节计数值。注意不同于BSON中的其他字段,时间戳和计数值字段必须存储为big endian。这是由于会对它们按字节比较,我们希望大多数情况下保证是升序。它的格式:

    0 1 2 3 4 5 6 7 8 9 10 11
    time machine pid inc

     

     

    • TimeStamp.这是一个unix风格的时间戳。它是有符号整数,代表自1970年1月1日之后或者之前的秒数。
    • Machine。它是机器主机名hash(md5)后值,或者mac/network 地址,或者虚拟机id的前三个字节。
    • pid。它是进程生成的2字节的进程id(或线程id)。
    • increment。这是一个自增值,或者在当前语言/运行时不能使用计数器时的随机值。

     BSON ObjectIds可以是任意唯一的12字节二进制字符串;但是,服务器本身和绝大多数驱动都使用了上面的格式。

    顺序号

    传统的数据库经常使用递增的顺序号作为主键。在MongoDB中,较好的方法是使用Object IDs。这个概念是说在一个非常大的集群中,创建一个Object ID比维护全局的,单调增长的顺序号要容易的多。

    尽管如此,有些时候你还是需要一个顺序号。你可以通过创建"counter"文档和使用findAndModify命令来达到这一目的。

    function counter(name) {
    var ret = db.counters.findAndModify({query:{_id:name}, update:{$inc : {next:1}}, "new":true,
    upsert:true});
    // ret == { "_id" : "users", "next" : 1 }
    return ret.next;
    }
    db.users.insert({_id:counter("users"), name:"Sarah C."}) // _id : 1
    db.users.insert({_id:counter("users"), name:"Bob D."}) // _id : 2
    //repeat

    UUIDs

    _id字段可以是任意类型;但是必须是唯一的。这样的话你就可以在_id字段使用UUIDs来代替BSON ObjectIds(BSON ObjectIds要轻巧一些;它们不需要全球唯一,仅仅在当前数据库集群唯一就可以了).当使用UUIDs,你的应用程序要自己生成UUID.考虑到效率,将UUID存储为[DOCS:BSON]类型是理想的 - 无论如何你还是可以将它作为16进制字符串插入,如果你知道空间和速度在此时不是一个问题。

  • 相关阅读:
    无法嵌入互操作类型“ADOX.CatalogClass”。请改用适用的接口。
    编码:隐匿在计算机软硬件背后的语言(3)--二进制加法器
    编码:隐匿在计算机软硬件背后的语言(2)--二进制
    C#中Mutex的用法
    C#中创建二维数组,使用[][]和[,]的区别
    git同时存在两个账号(在同一台电脑上)——三步完成(已修正)
    C++之标准库vector
    C++之标准库map
    sublime和vscode 格式化Json ——两步走
    二十八、linux下权限管理chmod
  • 原文地址:https://www.cnblogs.com/xinghebuluo/p/2285777.html
Copyright © 2020-2023  润新知