短 URL 系统设计
原理
通过发号策略,给每一个过来的长地址,发一个号即可,小型系统直接用mysql的自增索引就搞定了。如果是大型应用,可以考虑各种分布式key-value系统做发号器。不停的自增就行了。
实现方式
- 通过访问短连接获取到62进制字符串,转化为10进制,通过查询获得长链接进行跳转
这里有几个问题
- 1、62进制如何用数据库或者KV存储来做
这个问题就不展开了,自行解决
- 2、如何保证同一个长地址,每次转出来都是一样的短地址
上面的发号原理中,是不判断长地址是否已经转过的。同一个长地址,产生多条短地址记录,这明显是浪费空间的。 目前没有好的解决方法
3、跳转用301还是302
301是永久重定向,302是临时重定向。短地址一经生成就不会变化,所以用301是符合http语义的。同时对服务器压力也会有一定减少。
但是如果使用了301,我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。
对于搜索引擎SEO优化来说301跳转更合适
10进制62进制互转 (php实现)
这里用了php手册中的一个方法,支持任意进制的转换 点击跳转到php手册
1<?php2function convBase($numberInput, $fromBaseInput, $toBaseInput)3{4 if ($fromBaseInput==$toBaseInput) return $numberInput;5 $fromBase = str_split($fromBaseInput,1);6 $toBase = str_split($toBaseInput,1);7 $number = str_split($numberInput,1);8 $fromLen=strlen($fromBaseInput);9 $toLen=strlen($toBaseInput);10 $numberLen=strlen($numberInput);11 $retval='';12 if ($toBaseInput == '0123456789')13 {14 $retval=0;15 for ($i = 1;$i <= $numberLen; $i++)16 $retval = bcadd($retval, bcmul(array_search($number[$i-1], $fromBase),bcpow($fromLen,$numberLen-$i)));17 return $retval;18 }19 if ($fromBaseInput != '0123456789')20 $base10=convBase($numberInput, $fromBaseInput, '0123456789');21 else22 $base10 = $numberInput;23 if ($base10<strlen($toBaseInput))24 return $toBase[$base10];25 while($base10 != '0')26 {27 $retval = $toBase[bcmod($base10,$toLen)].$retval;28 $base10 = bcdiv($base10,$toLen,0);29 }30 return $retval;31}32?>
用法:
- 1、十进制转62进制
1<?php2echo convBase('1234567890987654321','0123456789','0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');3?>
- 2、62进制转十进制
1<?php2echo convBase('1tckI2JJZDz','0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ','0123456789');3?>
这只是一个基本的思路,对于一般的使用也够了
<!-- 测试缓存失效机制 -->
暂无评论,来抢沙发吧。