Hack ObjectId表示对象类型

时间:2012-12-07 18:37:12

标签: mongodb bson objectid

我想通过像这样操作machineId来破解ObjectId:

         <timestamp> <machineId> <processId> <inc>
UserId   XXXXXXXX    XXXX01      XXXX        XXXXXX
OrderId  XXXXXXXX    XXXX02      XXXX        XXXXXX
CardId   XXXXXXXX    XXXX03      XXXX        XXXXXX
...

基本思路是使用1字节的machineId来区分对象类型,我的问题是:这样做有什么问题(考虑唯一性和分片)?

--- 12月9日更新---

由于规范和实现Why the bson java implementation uses 4 bytes inc field?之间存在差异,我将稍微改变我的解决方案风格:

         <timestamp> <machineId> <processId> <inc>
UserId   XXXXXXXX    XXXX        XXXX        01XXXXXX
OrderId  XXXXXXXX    XXXX        XXXX        02XXXXXX
CardId   XXXXXXXX    XXXX        XXXX        03XXXXXX
...

2 个答案:

答案 0 :(得分:2)

假设两个字节的机器ID对于您的部署来说足够独特,那应该没问题。干净的想法!

答案 1 :(得分:1)

只要你没有违反规范,并且ObjectID仍然是正确的形式,你没有理由不能这样做,它当然会为你节省一些空间。

但有几点注意事项:

首先,如果您计划通过重载驱动程序中的代码并更改ObjectID的生成方式来执行此操作,那么您将按原样插入修改后的ObjectID,而旧的“普通”ID将永远不会插入(大多数驱动程序是实际生成ObjectID的驱动程序,而不是服务器,但它也可以是服务器)。

首选插入已经改变的情况将是首选。原因?

如果更改并更改生成的ObjectID,或者稍后更改类型并且必须更改ObjectID,如果您尝试将该字段用作分片键(或其中的一部分),则可能会遇到问题道路(分片键是不可变的)。在必须更新分片键时,在分片环境中解决此问题的方法是删除有问题的文档并重新添加而不是更新。

此外,更新方法是您可以避免的不必要的操作(可能或可能不是您的担忧)。

最后,还有唯一性 - 因为机器ID无论如何都不会发生很大变化,我认为你不会在这里遇到任何问题,inc领域应该在一秒内处理碰撞,但是如果你用来改变ObjectID的方法导致奇怪的事情发生,请小心。