数据库专题(三) ——Mysql ID生成器

数据库专题(三)——Mysql ID生成器

(原创内容,转载请注明来源,谢谢)

注:本文是我对ID生成器的见解,如果有偏差欢迎指正。

一、需求

在数据库中,ID作为记录表每一行数据唯一性的重要元素,其重要性不言而喻。在普通网站的业务场景中,可以使用数据库的自增的方式生成id,则在新增数据的时候不需要定义id,插入数据的过程中数据库自己会生成id。

但是,当网站业务量大,并发量大,如果使用数据库自增的方式,则可能会出现多个请求需要新增数据同时发送给mysql,则会发生异常。

另外,由于数据传输过程中,可以通过fiddler等工具查看发送给后台的post,可以在url上直接看到get请求(即使浏览器加密也可以解密),如果id是订单信息等,如果此时用自增id,则其他竞争对手可以通过查看隔一天、一周或一段时间的id的差,估算出订单数。这样使得不具有保密性。

为了避免上述情况,则需要适当的ID生成器以解决问题。

二、设计方案

1、设计分析

ID生成器需要保证在高并发的情况下,仍然可以实现数据的正确插入,ID仍能保证不重复,且具有保密性。

设计ID生成器需要下列内容:

1)PHP内置函数uniqid()

         stringuniqid ([ string $prefix = "" [, bool $more_entropy = false ]] )

该函数以微秒计算,返回一个基于当前时间微秒数的唯一ID。其中第一个参数是返回结果的前缀,第二个参数如果设置成true,会在返回的字符串结尾增加额外的熵,使得唯一ID更具唯一性。

通常时间有可能存在波动,因此第二个参数要设置成true增加ID的唯一性。

2)PHP加密函数md5()

         stringmd5 ( string $str [, bool $raw_output = false ] )

该函数返回一个加密后的字符串。md5是单向加密,没有办法解密,如果需要破解需要将待测试的字符串也经过md5返回加密结果,进行比对,即只能暴力破解。当进行一系列的变动后,需要破解的成本已经很高,因此md5已经可以满足要求。

当然,也可以使用password_hash、crypt、sha1等其他加密算法。

2、设计内容

1)创建ID生成器类。

2)编写一个生成[0-9a-zA-Z!@#$%^&*()_+-=|/?]共79个字符(也可以根据需要再添加其他的字符,增加随机性)可能性的随机字符串,长度为5(可以自行设定),用于作为uniqid的前缀,进一步避免生成过程中的冲突,且使得破解ID的可能性更低。

3)将uniqid的结果,后面跟上长度为3位的随机字符串。将此值用md5的方式加密。

4)根据业务场景需求,可以将数据库的表设置成16个或更多,因为md5的结果是16进制的值,即0-9a-f,则可以根据首位(或末位、或中间固定的任一位),将结果插入到相应的表中,保证平均将数据插入到各表,以确保每个表的存储量均匀,保证删改查的速度。

5)在表的创建时,也可以采用数据库分区,将表按照id的首位(如果第四步取的是首位则选择末位)的值,分散到4个分区中,以保证删改查的速度。

3、PHP实现

         classIDGenerator{
         private$uniqidNum;//uniqid前缀长度
         private $md5Num;//md5后缀长度
         public function__construct($uniqidNum = 5, $md5Num = 3){
                   if(is_numeric($uniqidNum)){
                            $this->uniqidNum= $uniqidNum;
                   }
                   if(is_numeric($md5Num)){
                            $this->md5Num= $md5Num;
                   }                
         }
         //只能设置为数值
         public function__set($prop, $val){
                   if(property_exists('IDGenerator',$prop) && is_numeric($val) && 0 < $val){
                            $this->$prop= $val;
                   }
         }
         public function__get($prop){
                   if(property_exists('IDGenerator',$prop)){
                            $this->$prop= $val;
                   }                
         }
         //随机生成内容
         private functiongenerateRandomSting($num){
                   if(!is_numeric($num)|| 1 > $num){
                            return'';
                   }
                   $str ='0123456789qwertyuiopasdfghjklzxcvbnm!@#$%^&*()_+-=|/?';
                   $len =strlen($str);
                   $res = '';
                   for($i=0;$i<$num;$i++){
                            $randNum= mt_rand(0, $len-1);
                            $res.= $str[$randNum];
                   }
                   return $res;
         }
         //id生成
         public functiongetId(){
                   $uid = uniqid($this->generateRandomSting($this->uniqidNum),true);
                   returnmd5($uid.$this->generateRandomSting($this->md5Num));
         }
}
$idgen = new IDGenerator();
for($i=0;$i<10;$i++){
         echo$idgen->getId();
         echo '<br />';
}
//输出
c37276addc92003e7acbfbf3e283e491
f22e69f2b65f3e9ae3fe05769e8bf06d
943a5d7f05443f481a24e565a5286899
07b70aee6d661c56dc7492aa961b787d
681aec954133dbdc493f781ed8bb828d
bf104d7c937a518a66f7702d0e50dba7
9f3c7606fb083b4b5e5aa5874977801a
fee83e49f3e165a092bf2ba2c808cbf7
6200d63f91503c31ab642749d3858e0c
dca0a0811f7a7a631ad181765299367d

不断的刷新页面,输出的结果也不一样,且同时执行时也保证输出的结果不一样。因此,此ID生成器可以满足高并发下的生成id,且有保密性。

本文是我对ID生成器的见解,如果有偏差欢迎指正。

——written by linhxx 2017.07.31

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-07-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小曾

.Net 如何模拟会话级别的信号量,对http接口调用频率进行限制(有demo)

现在,因为种种因素,你必须对一个请求或者方法进行频率上的访问限制。 比如, 你对外提供了一个API接口,注册用户每秒钟最多可以调用100次,非注册用户每秒钟最...

752
来自专栏QQ音乐前端团队专栏

前端水印生成方案

安全问题不能大意,对于一些比较敏感的内容,我们可以通过组合使用上述的水印方案,这样才能最大程度给浏览者警示的作用,减少泄密的情况,即使泄密了,也有可能追踪到泄密...

2773
来自专栏编程

身为程序猿,怎能不懂RegExp?

正则表达式是程序猿的好朋友。这体现在两个方面:一、在我们敲的代码里面,可以用正则表达式非常轻巧、灵便、快捷的完成字符串的操作,比如匹配、搜索、提取子串等。二、我...

1895
来自专栏菩提树下的杨过

velocity模板引擎学习(1)

velocity与freemaker、jstl并称为java web开发三大标签技术,而且velocity在codeplex上还有.net的移植版本NVeloc...

1845
来自专栏阿凯的Excel

小小查找键、大大大乐趣

你是不是在高速路口堵车的时候看到本文章呢? 不要问我在干嘛! 今天和大家愉快的分享的是查找键!! 神马?查找键还需要分享? 查找键其实分两类,一种是Ctr...

2014
来自专栏波比

$.ajax使用Form提交与Payload提交

Form解析可以直接从Request对象中获取请求参数,这样对象转换与处理相对容易,但在大批JSON数据需要提交时,可能会出现大量的数据拆分与处理工作,另外针对...

1228
来自专栏Java学习网

Java中MD5加密算法实现方法——附上具体代码

MD5是哈希散列算法,对于MD5而言,有两个特性是很重要的,第一:明文数据经过散列以后的值是定长的;第二:是任意一段明文数据,经过散列以后,其结果必须永远是不...

28210
来自专栏点滴积累

geotrellis使用(二十二)实时获取点状目标对应的栅格数据值

目录 前言 实现方法 总结 一、前言        其实这个功能之前已经实现,今天将其采用1.0版的方式进行了重构与完善,现将该内容进行总结。        其...

3525
来自专栏沃趣科技

事件统计 | performance_schema全方位介绍

在上一篇 《事件记录 | performance_schema全方位介绍"》中,我们详细介绍了performance_schema的事件记录表,恭喜大家在学习p...

1343
来自专栏技术博文

php性能监测模块XHProf

一,什么是XHProf XHProf是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。一个函数的开销,可...

3488

扫描关注云+社区