Mysql 如何在MongoDB中实现自动递增的主ID?

Mysql 如何在MongoDB中实现自动递增的主ID?,mysql,mongodb,database,Mysql,Mongodb,Database,就像在MYSQL中一样,我需要一个递增的ID。MongoDB旨在横向扩展。在这种情况下,自动递增将导致id冲突。这就是为什么id看起来更像guid/uuid。您需要使用MongoDB的命令。有了它,你可以 这将增加用户集合的计数器,您可以在插入之前将其添加到文档中。因为它是原子的,所以您不必担心导致ID冲突的竞争条件 它不像MySQL的auto_increment标志那样无缝,但您通常也可以选择在Mongo驱动程序中指定自己的ID工厂,因此您可以实现一个工厂,使用findAndModify透明地

就像在MYSQL中一样,我需要一个递增的ID。

MongoDB旨在横向扩展。在这种情况下,自动递增将导致id冲突。这就是为什么id看起来更像guid/uuid。

您需要使用MongoDB的命令。有了它,你可以

这将增加
用户
集合的计数器,您可以在插入之前将其添加到文档中。因为它是原子的,所以您不必担心导致ID冲突的竞争条件

它不像MySQL的
auto_increment
标志那样无缝,但您通常也可以选择在Mongo驱动程序中指定自己的ID工厂,因此您可以实现一个工厂,使用findAndModify透明地增加和返回ID,从而获得更像MySQL的体验


这种方法的缺点是,由于每次插入都依赖于序列集合上的写锁,因此如果要进行大量写操作,很快就会在这方面遇到瓶颈。如果您只是想保证集合中的文档按插入顺序排序,那么请查看。

虽然不支持自动增量,但您可以轻松实现自己的小类来发布增量值


我自己也需要这个特性,所以我用php编写了一个小类。我在我的博客上写到,

如果您怀疑您的数据可能跨越多个服务器(也称为碎片),那么请与Dennis一起使用本机ObjectId

如果您更喜欢int/long id(在URL上看起来更好),那么您可以按照Chris的建议,使用findAndModify简单地实现生成器。
当/如果性能/锁定开始成为问题,您可以升级生成器以实现Hi/Lo算法。这将大大减少对“seq”集合的压力。切实解决这个问题。(客户端生成器正在使用一个“池”,只有在数据库没有可用ID时才与数据库联系)

@TIMEX:如果您正在查找序列号而不是ID,请检查下面的链接是否可以帮助您(因为mongo保留了ID)

@丹尼斯·伯顿 自动递增如果用户不这样做会不会导致冲突?我觉得,因此mongo db使用它自己的_Id,这样可以避免冲突,但是如果用户希望有一个列作为运行序列,他们可以随意使用它

我正在使用这个-
MongoDB提供了两种自动递增id(或自定义键)的方法

反托收
在这里,我们需要创建一个集合,该集合存储最大数量的键,并在每次调用此函数时递增1

1。存储功能

function getNextSequence(collectionName) {
   var ret = db.counters.findAndModify({
               query: { _id: collectionName },
               update: { $inc: { seq: 1 } },
               new: true,
               upsert: true
             });

   return ret.seq;
}
function insertDocument(doc, targetCollection) {

    while (1) {

        var cursor = targetCollection.find( {}, { _id: 1 } ).sort( { _id: -1 } ).limit(1);

        var seq = cursor.hasNext() ? cursor.next()._id + 1 : 1;

        doc._id = seq;

        var results = targetCollection.insert(doc);

        if( results.hasWriteError() ) {
            if( results.writeError.code == 11000 /* dup key */ )
                continue;
            else
                print( "unexpected error inserting data: " + tojson( results ) );
        }

        break;
    }
}
2。插入文档

db.users.insert({
  _id: getNextSequence("USER"),
  name: "Nishchit."
})
var myCollection = db.USERS;

insertDocument(
   {
     name: "Nishchit Dhanani"
   },
   myCollection
);
乐观循环
在此模式中,乐观循环计算递增的_id值,并尝试插入具有计算出的_id值的文档。如果插入成功,则循环结束。否则,循环将遍历可能的_id值,直到插入成功

1。存储功能

function getNextSequence(collectionName) {
   var ret = db.counters.findAndModify({
               query: { _id: collectionName },
               update: { $inc: { seq: 1 } },
               new: true,
               upsert: true
             });

   return ret.seq;
}
function insertDocument(doc, targetCollection) {

    while (1) {

        var cursor = targetCollection.find( {}, { _id: 1 } ).sort( { _id: -1 } ).limit(1);

        var seq = cursor.hasNext() ? cursor.next()._id + 1 : 1;

        doc._id = seq;

        var results = targetCollection.insert(doc);

        if( results.hasWriteError() ) {
            if( results.writeError.code == 11000 /* dup key */ )
                continue;
            else
                print( "unexpected error inserting data: " + tojson( results ) );
        }

        break;
    }
}
2。插入文档

db.users.insert({
  _id: getNextSequence("USER"),
  name: "Nishchit."
})
var myCollection = db.USERS;

insertDocument(
   {
     name: "Nishchit Dhanani"
   },
   myCollection
);
来自的官方文件