比如在一个分布式的用户系统中,如何各自生成用户的唯一数字ID。首先没有办法用MYSQL的自增,用GUID或UUID的话又不是数字,而且很长,兼容性不好。

2010-11-17 20:21:36

12 Answers

用memcache来存储最新的数字ID,为防止多台服获取到相同的ID值,可以在加一字段来表明此条数据的状态,如果状态是锁定状态,则sleep一段时间后再来获取此ID,获取到以后将此条数据的状态更新成使用中,当完成数据插入以后,再将更新ID值及释放数据锁定状态。

如果还想利用MYSQL的自增,就需要在在执行插入数据命令前执行类似:

ALTER TABLE auto_test AUTO_INCREMENT=MAX(ID)+1;

的sql语句,结合以上memcache的存储方案即可

2010-11-18 07:15:17

用于注册的实现方法可以根据服务器本身的机器码或MAC地址等唯一不可更改的编码和服务器时间作为参数生成一个唯一的序列号头,而客户端发送请求的时候将自己的机器码传给服务器端,服务器端将其结合起来,这样还可以根据code统计并分析注册的时间规律从而调整硬件资源的分配。也可以锁定同一客户端多次注册的异常情况。因为序列号头的生成方式和硬件相关,注册工作可以分流多个服务器同时完成,也不冲突。我能想到的就是这些。

2010-11-18 09:42:40

增加一张表,专门生成id的表是不是可以啊

2010-11-18 10:41:09

下面这个方法 在单服务器上能确保唯一 如果是多服务器 可以在前面加上 服务器唯一标识 这样应该可以确保唯一性

/** * fast_uuid 为模型生成 64 位整数或混淆字符串的不重复 ID * * 感谢“Ivan Tan|谭俊青 DrinChing (at) Gmail.com”提供的算法。 * * 通常我们习惯使用自增字段来做主键,简单易用。 * * 但在于大规模应用中,使用自增字段将难以实现分布式数据库架构。 * 并且对数据进行纵向和横向分割(分表分库)造成障碍。 * 此时最好的解决方案是使用 UUID。 * * 但 UUID 不是每一种数据库都支持,用字符串来模拟效率太低。 * 并且如果通过 URL 传递,UUID 也显得太长。 * * fast_uuid 方法提供了另一种解决方案: * 使用 64bit 整数存储主键,主键由 fast_uuid 方法在创建记录时调用生成。 * * 参数 suffix_len指定 生成的 ID 值附加多少位随机数,默认值为 3。 * 即便不附加随机数也不会生成重复 ID,但附加的随机数可以让 ID 更难被猜测。 * * @param int suffix_len * * @return string */ function fast_uuid($suffix_len=3){ //! 计算种子数的开始时间 static $being_timestamp = 1336681180;// 2012-5-10 $time = explode(' ', microtime()); $id = ($time[1] - $being_timestamp) . sprintf('%06u', substr($time[0], 2, 6)); if ($suffix_len > 0) { $id .= substr(sprintf('%010u', mt_rand()), 0, $suffix_len); } return $id; }

2010-11-18 12:28:09

MongoDB中,_objectid的生成方式很好,专为分布式而设计的ID生成:
机器编号+进程PID+当前时间戳+自增

2010-11-18 13:54:48

若能获取用户的网卡MAC地址,把十六进制中的ABCDEF转换为十进制的10、11、12、13、14、15。因为全球MAC地址都是唯一的,虽然本机MAC地址可以修改,但通过系统函数是可以从网卡芯片获得真实MAC地址的。
若不能获得用户本机信息,采用"服务器时间+用户IP"生成散列值的方法,产生唯一字ID,散列算法使用新版的MD5和SHA2算法。

2010-11-18 15:42:31
您不能回答该问题或者回答已经关闭!

相关文章推荐

  • C#中using指令的几种用法

    using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到

  • C#实例解析适配器设计模式

    将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作

  • C#运行时相互关系

    C#运行时相互关系,包括运行时类型、对象、线程栈和托管堆之间的相互关系,静态方法、实例方法和虚方法的区别等等

  • 使用托管C++粘合C#和C++代码(二)

    本文实现一下C++代码调用C#代码的过程。我构造一个简单并且直观的例子:通过C++ UI 触发C# UI.

  • C#开发高性能Log Help类设计开发

    项目中要在操作数据库的异常处理中加入写Log日志,对于商业上有要求,写log时对其它操作尽可能影响小,不能因为加入log导致耗时太多

  • Async和Await使异步编程更简单

    C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作

  • C#开发中的反射机制

    反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等

  • C#协变和逆变

    “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型,“逆变”则是指能够使用派生程度更小的类型

  • C#基础概念之延迟加载

    延迟加载(lazy load)是Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作

  • C#中的索引器的简单理解和用法

    C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作

  • 使用托管C++粘合C#和C++代码(一)

    C#在xml读写,数据库操纵,界面构造等很多方面性能卓越;C++的效率高,是底层开发的必备武器

  • 深入C# 序列化(Serialize)、反序列化(Deserialize)

    C#中的序列化和反序列化,序列化是.NET运行时环境用来支持用户定义类型的流化的机制