關於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,除了該方法帶來插入性能問題外,不確認是否會引起沖突。 需要等待確認!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM