PHP生成唯一ID之SnowFlake算法


Posted in PHP onDecember 17, 2016

前言:最近需要做一套CMS系统,由于功能比较单一,而且要求灵活,所以放弃了WP这样的成熟系统,自己做一套相对简单一点的。文章的详情页URL想要做成url伪静态的格式即xxx.html 其中xxx考虑过直接用自增主键,但是感觉这样有点暴露文章数量,有同学说可以把初始值设高一点,可是还是可以通过ID差算出一段时间内的文章数量,所以需要一种可以生成唯一ID的算法。

考虑过的方法有

  1. 直接用时间戳,或者以此衍生的一系列方法
  2. Mysql自带的uuid

以上两种方法都可以查到就不多做解释了

最终选择了Twitter的SnowFlake算法

这个算法的好处很简单可以在每秒产生约400W个不同的16位数字ID(10进制)

原理很简单

ID由64bit组成

其中 第一个bit空缺

41bit用于存放毫秒级时间戳

10bit用于存放机器id

12bit用于存放自增ID

除了最高位bit标记为不可用以外,其余三组bit占位均可浮动,看具体的业务需求而定。默认情况下41bit的时间戳可以支持该算法使用到2082年,10bit的工作机器id可以支持1023台机器,序列号支持1毫秒产生4095个自增序列id。
下面是PHP源码

<?php
namespace App\Services;

abstract class Particle {
  const EPOCH = 1479533469598;
  const max12bit = 4095;
  const max41bit = 1099511627775;

  static $machineId = null;

  public static function machineId($mId = 0) {
    self::$machineId = $mId;
  }

  public static function generateParticle() {
    /*
    * Time - 42 bits
    */
    $time = floor(microtime(true) * 1000);

    /*
    * Substract custom epoch from current time
    */
    $time -= self::EPOCH;

    /*
    * Create a base and add time to it
    */
    $base = decbin(self::max41bit + $time);


    /*
    * Configured machine id - 10 bits - up to 1024 machines
    */
    if(!self::$machineId) {
      $machineid = self::$machineId;
    } else {
      $machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT);
    }
    
    /*
    * sequence number - 12 bits - up to 4096 random numbers per machine
    */
    $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT);

    /*
    * Pack
    */
    $base = $base.$machineid.$random;

    /*
    * Return unique time id no
    */
    return bindec($base);
  }

  public static function timeFromParticle($particle) {
    /*
    * Return time
    */
    return bindec(substr(decbin($particle),0,41)) - self::max41bit + self::EPOCH;
  }
}

?>

调用方法如下

Particle::generateParticle($machineId);//生成ID
Particle::timeFromParticle($particle);//反向计算时间戳

这里我做了改良 如果机器ID传0 就会去掉这10bit 因为有些时候我们可能用不到这么多ID

PHP 相关文章推荐
PHP 和 HTML
Oct 09 PHP
php读取数据库信息的几种方法
May 24 PHP
phpmyadmin 常用选项设置详解版
Mar 07 PHP
PHP+ACCESS 文章管理程序代码
Jun 21 PHP
PHP 数据结构 算法 三元组 Triplet
Jul 02 PHP
查找mysql字段中固定字符串并替换的几个方法
Sep 23 PHP
php检查日期函数checkdate用法实例
Mar 19 PHP
WordPress特定文章对搜索引擎隐藏或只允许搜索引擎查看
Dec 31 PHP
Zend Framework框架路由机制代码分析
Mar 22 PHP
基于PHP微信红包的算法探讨
Jul 21 PHP
完美解决在ThinkPHP控制器中命名空间的问题
May 05 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
Aug 20 PHP
简单解决微信文章图片防盗链问题
Dec 17 #PHP
PHP 7.1新特性的汇总介绍
Dec 16 #PHP
浅谈PHP命令执行php文件需要注意的问题
Dec 16 #PHP
PHP+Ajax 检测网络是否正常实例详解
Dec 16 #PHP
php微信公众号开发(4)php实现自定义关键字回复
Dec 15 #PHP
php微信公众号开发(3)php实现简单微信文本通讯
Dec 15 #PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
Dec 15 #PHP
You might like
PHP 递归效率分析
2009/11/24 PHP
PHP curl CURLOPT_RETURNTRANSFER参数的作用使用实例
2015/02/07 PHP
php的无刷新操作实现方法分析
2020/02/28 PHP
php swoft框架实例用法
2020/12/22 PHP
Jquery 绑定时间实现代码
2011/05/03 Javascript
最佳6款用于移动网站开发的jQuery 图片滑块插件小结
2012/07/20 Javascript
jquery使用jquery.zclip插件复制对象的实例教程
2013/12/04 Javascript
iframe里面的元素触发父窗口元素事件的jquery代码
2014/10/19 Javascript
JavaScript实现按照指定长度为数字前面补零输出的方法
2015/03/19 Javascript
JavaScript实现仿淘宝商品购买数量的增减效果
2016/01/22 Javascript
微信小程序 生命周期和页面的生命周期详细介绍
2017/01/19 Javascript
使用BootStrap实现标签切换原理解析
2017/03/14 Javascript
详解webpack进阶之loader篇
2017/08/23 Javascript
JS禁止浏览器右键查看元素或按F12审查元素自动关闭页面示例代码
2017/09/07 Javascript
创建nuxt.js项目流程图解
2020/03/13 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
JavaScript对象访问器Getter及Setter原理解析
2020/12/08 Javascript
Python找出文件中使用率最高的汉字实例详解
2015/06/03 Python
python 3.7.0 安装配置方法图文教程
2018/08/27 Python
解决Python 命令行执行脚本时,提示导入的包找不到的问题
2019/01/19 Python
搞清楚 Python traceback的具体使用方法
2019/05/13 Python
使用Python-OpenCV向图片添加噪声的实现(高斯噪声、椒盐噪声)
2019/05/28 Python
Gauss-Seidel迭代算法的Python实现详解
2019/06/29 Python
python笔记之mean()函数实现求取均值的功能代码
2019/07/05 Python
Python 最强编辑器详细使用指南(PyCharm )
2019/09/16 Python
Django admin 实现search_fields精确查询实例
2020/03/30 Python
Python分类测试代码实例汇总
2020/07/23 Python
英国家用电器折扣网站:Electrical Discount UK
2018/09/17 全球购物
经典的班主任推荐信
2013/10/28 职场文书
课程设计的心得体会
2014/09/03 职场文书
教师党员个人自我剖析材料
2014/09/29 职场文书
党风廉政建设调研报告
2015/01/01 职场文书
公司出纳岗位职责
2015/03/31 职场文书
人身损害赔偿协议书
2016/03/22 职场文书
详解ZABBIX监控ESXI主机的问题
2022/06/21 Servers