关于MongoDB的主键Id

MongoDB默认用的是自己的ObjectId,详细信息参见http://www.mongodb.org/display/DOCS/Object+IDs。可以自定义,详见http://www.mongodb.org/display/DOCS/CSharp+Driver+Serialization+Tutorial#CSharpDriverSerializationTutorial-WriteacustomIdgenerator 。

从官方的文档,可以看到他们还是倾向于用ObjectId。虽然可以用Guid,但是Guid会消耗更多的空间,性能可能也会受到一些影响。同时,如果使用Guid,请注意下一段,(原文地址 http://stackoverflow.com/questions/11355792/with-mongodb-and-guids-for-the-id-of-documents-what-is-efficient-way-to-store-th ):

Working with GUIDs has a few pitfalls, mostly related to how to work with the binary representation in the mongo shell and also to historical accidents which resulted in different drivers storing GUIDs using different byte orders.

I used the following code to illustrate the issues:

var document = new BsonDocument { { "_id", Guid.NewGuid() }, { "x", 1 } };
collection
.Drop();
collection
.Insert(document);
Console.WriteLine("Inserted GUID: {0}", document["_id"].AsGuid);

which when I ran it output:

Inserted GUID: 2d25b9c6-6d30-4441-a360-47e7804c62be

when I display this in the mongo shell I get:

> var doc = db.test.findOne()
> doc
{ "_id" : BinData(3,"xrklLTBtQUSjYEfngExivg=="), "x" : 1 }
> doc._id.hex()
c6b9252d306d4144a36047e7804c62be
>

Notice that even when displayed as hex the byte order doesn't match the original GUID. That's the historical accident I was talking about. All the bytes are there, they're just in an unusual order thanks to Microsoft's implementation of Guid.ToByteArray().

To help you work with GUIDs in the mongo shell you could copy the following file of helper functions to the directory where mongo.exe is stored:

https://github.com/rstam/mongo-csharp-driver/blob/master/uuidhelpers.js

The file has some brief documentation comments at the top that you might find helpful. To make these functions available in the mongo shell you need to tell the mongo shell to read this file as it starts up. See the following sample session:

C:\mongodb\mongodb-win32-x86_64-2.0.6\bin>mongo --shell uuidhelpers.js
MongoDB shell version: 2.0.6
connecting to
: test
type
"help" for help
> var doc = db.test.findOne()
> doc
{ "_id" : BinData(3,"xrklLTBtQUSjYEfngExivg=="), "x" : 1 }
> doc._id.hex()
c6b9252d306d4144a36047e7804c62be
> doc._id.toCSUUID()
CSUUID
("2d25b9c6-6d30-4441-a360-47e7804c62be")
>

You could also use another of the helper functions to query for the GUIDs:

> db.test.find({_id : CSUUID("2d25b9c6-6d30-4441-a360-47e7804c62be")})
{ "_id" : BinData(3,"xrklLTBtQUSjYEfngExivg=="), "x" : 1 }
>

As far as storing your GUIDs as strings, that's not an unheard of thing to do and it definitely makes viewing and querying the data in the mongo shell easier and avoids all the issues with different byte orders. The only disadvantage is that it uses more space (roughly double).

当然了,也可以hack实现自增长数字,类似于传统DB的自增长主键机制。方法见http://www.mongodb.org/display/DOCS/Object+IDs。但园内有人说,如果用到Sharding时,该方法失效。 貌似我还是没有搞懂Sharding,除了该方法带来插入性能问题外,不确认是否会引起冲突。 需要等待确认!

原文地址:https://www.cnblogs.com/Langzi127/p/2656681.html