回到目录

说一些关于ObjectId的事

MongoDB确实是最像关系型数据库的NoSQL,这在它主键设计上可以体现的出来,它并没有采用自动增长主键,因为在分布式服务器之间做数据同步很麻烦,而是采用了一种ObjectId的方式,它生成方便,占用空间比long多了4个字节,(12个字节)在数据表现层面也说的过去,它是一种以时间,机器,进程和自增几个因素组合的方式来体现的,可以近似看成是按时间的先后进行排序的,对于ObjectId的生成我们可以通过MongoDB服务端去获得,或者在客户端也有对它的集成,使用方便,一般情况下,在客户端实体类中只要定义一个ObjectId类型的属性,这个属性就默认被赋上值了,应该说,还是比较方便的,由于它存储是一种字符串,所以,一般客户端,像NoRM都为我们实现了对string类型的隐藏转换,应该说,还是比较友好的!

ObjectId的组成

aaarticlea/png;base64,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" alt="" />

为何选择十六进制表示法

在C#版的NoRM这样设计ObjectId

        /// <summary>
/// Generates a byte array ObjectId.
/// </summary>
/// <returns>
/// </returns>
public static byte[] Generate()
{
var oid = new byte[];
var copyidx = ;
//时间差
Array.Copy(BitConverter.GetBytes(GenerateTime()), , oid, copyidx, );
copyidx += ;
//机器码
Array.Copy(machineHash, , oid, copyidx, );
copyidx += ;
//进程码
Array.Copy(procID, , oid, copyidx, );
copyidx += ;
//自增值
Array.Copy(BitConverter.GetBytes(GenerateInc()), , oid, copyidx, );
return oid;
}

完整的ObjectId类型源代码

它重写的ToString()方法,为的是实现byte[]到string串之间的类型转换,并且为string和ObjectId对象实现 implicit的隐式类型转换,方便开发人员在实际中最好的使用它们,需要注意的是在byte[]中存储的数据都是以十六进制的形式体现的

    /// <summary>
/// Represents a Mongo document's ObjectId
/// </summary>
[System.ComponentModel.TypeConverter(typeof(ObjectIdTypeConverter))]
public class ObjectId
{
private string _string; /// <summary>
/// Initializes a new instance of the <see cref="ObjectId"/> class.
/// </summary>
public ObjectId()
{
} /// <summary>
/// Initializes a new instance of the <see cref="ObjectId"/> class.
/// </summary>
/// <param retval="value">
/// The value.
/// </param>
public ObjectId(string value)
: this(DecodeHex(value))
{
} /// <summary>
/// Initializes a new instance of the <see cref="ObjectId"/> class.
/// </summary>
/// <param retval="value">
/// The value.
/// </param>
internal ObjectId(byte[] value)
{
this.Value = value;
} /// <summary>
/// Provides an empty ObjectId (all zeros).
/// </summary>
public static ObjectId Empty
{
get { return new ObjectId(""); }
} /// <summary>
/// Gets the value.
/// </summary>
/// <value>The value.</value>
public byte[] Value { get; private set; } /// <summary>
/// Generates a new unique oid for use with MongoDB Objects.
/// </summary>
/// <returns>
/// </returns>
public static ObjectId NewObjectId()
{
// TODO: generate random-ish bits.
return new ObjectId { Value = ObjectIdGenerator.Generate() };
} /// <summary>
/// Tries the parse.
/// </summary>
/// <param retval="value">
/// The value.
/// </param>
/// <param retval="id">
/// The id.
/// </param>
/// <returns>
/// The try parse.
/// </returns>
public static bool TryParse(string value, out ObjectId id)
{
id = Empty;
if (value == null || value.Length != )
{
return false;
} try
{
id = new ObjectId(value);
return true;
}
catch (FormatException)
{
return false;
}
} /// <summary>
/// Implements the operator ==.
/// </summary>
/// <param retval="a">A.</param>
/// <param retval="b">The b.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(ObjectId a, ObjectId b)
{
if (ReferenceEquals(a, b))
{
return true;
} if (((object)a == null) || ((object)b == null))
{
return false;
} return a.Equals(b);
} /// <summary>
/// Implements the operator !=.
/// </summary>
/// <param retval="a">A.</param>
/// <param retval="b">The b.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(ObjectId a, ObjectId b)
{
return !(a == b);
} /// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
/// </returns>
public override int GetHashCode()
{
return this.Value != null ? this.ToString().GetHashCode() : ;
} /// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString()
{
if (this._string == null && this.Value != null)
{
this._string = BitConverter.ToString(this.Value).Replace("-", string.Empty).ToLower();
} return this._string;
} /// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
/// </summary>
/// <param retval="o">
/// The <see cref="System.Object"/> to compare with this instance.
/// </param>
/// <returns>
/// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(object o)
{
var other = o as ObjectId;
return this.Equals(other);
} /// <summary>
/// Equalses the specified other.
/// </summary>
/// <param retval="other">
/// The other.
/// </param>
/// <returns>
/// The equals.
/// </returns>
public bool Equals(ObjectId other)
{
return other != null && this.ToString() == other.ToString();
} /// <summary>
/// Decodes a HexString to bytes.
/// </summary>
/// <param retval="val">
/// The hex encoding string that should be converted to bytes.
/// </param>
/// <returns>
/// </returns>
protected static byte[] DecodeHex(string val)
{
var chars = val.ToCharArray();
var numberChars = chars.Length;
var bytes = new byte[numberChars / ]; for (var i = ; i < numberChars; i += )
{
bytes[i / ] = Convert.ToByte(new string(chars, i, ), );
} return bytes;
} /// <summary>TODO::Description.</summary>
public static implicit operator string(ObjectId oid)
{
return oid == null ? null : oid.ToString();
} /// <summary>TODO::Description.</summary>
public static implicit operator ObjectId(String oidString)
{
ObjectId retval = ObjectId.Empty;
if(!String.IsNullOrEmpty(oidString))
{
retval = new ObjectId(oidString);
}
return retval;
}
}

ObjectIdGenerator源代码

它主要实现了ObjectId串生成的规则及方式

    /// <summary>
/// Shameless-ly ripped off, then slightly altered from samus' implementation on GitHub
/// http://github.com/samus/mongodb-csharp/blob/f3bbb3cd6757898a19313b1af50eff627ae93c16/MongoDBDriver/ObjectIdGenerator.cs
/// </summary>
internal static class ObjectIdGenerator
{
/// <summary>
/// The epoch.
/// </summary>
private static readonly DateTime epoch = new DateTime(, , , , , , DateTimeKind.Utc); /// <summary>
/// The inclock.
/// </summary>
private static readonly object inclock = new object(); /// <summary>
/// The inc.
/// </summary>
private static int inc; /// <summary>
/// The machine hash.
/// </summary>
private static byte[] machineHash; /// <summary>
/// The proc id.
/// </summary>
private static byte[] procID; /// <summary>
/// Initializes static members of the <see cref="ObjectIdGenerator"/> class.
/// </summary>
static ObjectIdGenerator()
{
GenerateConstants();
} /// <summary>
/// Generates a byte array ObjectId.
/// </summary>
/// <returns>
/// </returns>
public static byte[] Generate()
{
var oid = new byte[];
var copyidx = ;
//时间差
Array.Copy(BitConverter.GetBytes(GenerateTime()), , oid, copyidx, );
copyidx += ;
//机器码
Array.Copy(machineHash, , oid, copyidx, );
copyidx += ;
//进程码
Array.Copy(procID, , oid, copyidx, );
copyidx += ;
//自增值
Array.Copy(BitConverter.GetBytes(GenerateInc()), , oid, copyidx, );
return oid;
} /// <summary>
/// Generates time.
/// </summary>
/// <returns>
/// The time.
/// </returns>
private static int GenerateTime()
{
var now = DateTime.Now.ToUniversalTime(); var nowtime = new DateTime(epoch.Year, epoch.Month, epoch.Day, now.Hour, now.Minute, now.Second, now.Millisecond);
var diff = nowtime - epoch;
return Convert.ToInt32(Math.Floor(diff.TotalMilliseconds));
} /// <summary>
/// Generate an increment.
/// </summary>
/// <returns>
/// The increment.
/// </returns>
private static int GenerateInc()
{
lock (inclock)
{
return inc++;
}
} /// <summary>
/// Generates constants.
/// </summary>
private static void GenerateConstants()
{
machineHash = GenerateHostHash();
procID = BitConverter.GetBytes(GenerateProcId());
} /// <summary>
/// Generates a host hash.
/// </summary>
/// <returns>
/// </returns>
private static byte[] GenerateHostHash()
{
using (var md5 = MD5.Create())
{
var host = Dns.GetHostName();
return md5.ComputeHash(Encoding.Default.GetBytes(host));
}
} /// <summary>
/// Generates a proc id.
/// </summary>
/// <returns>
/// Proc id.
/// </returns>
private static int GenerateProcId()
{
var proc = Process.GetCurrentProcess();
return proc.Id;
}
}

事实上,通过对NoRm这个MongoDB客户端的学习,让我们的眼界放宽了许多,可能在思考问题时不局限于眼前,对于同一个问题可以会有更多的解决方法了,呵呵!

回到目录

05-08 15:23