回到目录

说一些关于ObjectId的事

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

ObjectId的组成

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

为何选择十六进制表示法

为什么在ObjectId里,将byte[]数组转为字符串时,使用十六进制而没有使用默认的十进制呢,居 我的研究,它应该是考虑字符串的长度一致性吧,因为byte取值为(0~255),如果使用默认的十进制那么它的值长度非常不规范,有1位,2位和3位, 而如果使用十六进制表示,它的长度都为2位,2位就可以表示0到255中的任何数字了,0对应0x00,255对应0xFF,呵呵,将它们转为字符串后,即可 以保证数据的完整性,又可以让它看上去长度是一致的,何乐不为呢,哈哈!

漂亮的设计,原自于扎实的基础!

在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客户端的学习,让我们的眼界放宽了许多,可能在思考问题时不局限于眼前,对于同一个问题可以会有更多的解决方法了,呵呵!

回到目录

MongoDB学习笔记~ObjectId主键的设计的更多相关文章

  1. EntityFramework Core 学习笔记 —— 添加主键约束

    原文地址:https://docs.efproject.net/en/latest/modeling/keys.html Keys (primary) Key 是每个实体例的主要唯一标识.EF Cor ...

  2. MongoDB学习笔记系列

    回到占占推荐博客索引 该来的总会来的,Ef,Redis,MVC甚至Sqlserver都有了自己的系列,MongoDB没有理由不去整理一下,这个系列都是平时在项目开发时总结出来的,希望可以为各位一些帮助 ...

  3. MongoDB学习笔记系列~目录

    MongoDB学习笔记~环境搭建 (2015-03-30 10:34) MongoDB学习笔记~MongoDBRepository仓储的实现 (2015-04-08 12:00) MongoDB学习笔 ...

  4. MongoDB学习笔记:快速入门

    MongoDB学习笔记:快速入门   一.MongoDB 简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能.M ...

  5. PHP操作MongoDB学习笔记

    <?php/*** PHP操作MongoDB学习笔记*///*************************//**   连接MongoDB数据库  **////*************** ...

  6. MongoDB 学习笔记(原创)

    MongoDB 学习笔记 mongodb 数据库 nosql 一.数据库的基本概念及操作 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table ...

  7. mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)

    最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...

  8. MongoDB学习笔记:MongoDB 数据库的命名、设计规范

    MongoDB学习笔记:MongoDB 数据库的命名.设计规范     第一部分,我们先说命名规范. 文档 设计约束 UTF-8 字符 不能包含 \0 字符(空字符),这个字符标识建的结尾 . 和 $ ...

  9. SQL反模式学习笔记5 外键约束【不用钥匙的入口】

    目标:简化数据库架构 一些开发人员不推荐使用引用完整性约束,可能不使用外键的原因有一下几点: 1.数据更新有可能和约束冲突: 2.当前的数据库设计如此灵活,以至于不支持引用完整性约束: 3.数据库为外 ...

随机推荐

  1. Windows Server 2008 下解析二级域名的方法

    昨天去了客户那里部署网站,用的是客户那边的windows server 2008. 本文主要以总结问题点的形式来说. 问题1:本机的数据库是SQL SERVER 2008R2,客户那边的数据库是SQL ...

  2. 【JUC】JUC锁框架综述

    一.前言 在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程.我们分为几个模块进行分析,首先是 ...

  3. Spring Scope:Web项目中如何安全使用有状态的Bean对象?

    Web系统是最常见的Java应用系统之一,现在流行的Web项目多使用ssm或ssh框架,使用spring进行bean的管理,这为我们编写web项目带来了很多方便,通常,我们的controler层使用注 ...

  4. TeamCity : 配置第一个工程

    前面我们已经创建了TeamCity Server 和一个 Agent,接下来我们为一个.net core 控制台程序配置自动化的编译. 创建 .net core 项目 我们在本地创建一个简单的 .ne ...

  5. asp.net教程:编译错误同时存在于不同dll中

    asp.net 编译错误类型“同时存在于”不同的dll中. 出现这种错误大概有三种情况: 1.ASPX页面,一个*.ASPX,对应着一个*.cs文件,两者其实是一个文件,通过两者实现代码分离,每个*. ...

  6. ASP.NET5,MVC 6,Beta 7与VS 2015 RTM的兼容问题

    温馨提示:本文杂而乱,最终不知所云. Visual Studio 2015 RTM已经于2015年7月20号正式发布,我也在第一时间下载安装了起来. 虽然在5月份就开始使用RC版本,但是还是很期待正式 ...

  7. Android实现侧边栏SlidingPaneLayout

    //主布局 1 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widg ...

  8. 13、ASP.NET MVC入门到精通——MVC请求管道

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 ASP.NET MVC的请求管道和ASP.NET请求管道基本上一模一样,如果你对ASP.NET请求管道十分熟悉的话,你只要关注一下不同点.看 ...

  9. 十一个行为模式之状态模式(State Pattern)

    定义: 当一个对象有多个状态,并且在每个状态下有不同的行为,可以使用状态模式来在其内部改变状态时改变其行为,而客户端不会察觉状态的改变,仍使用同样的方法或接口与对象进行交互. 结构图: Context ...

  10. 转载:C#中的泛型

    泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具 ...