TinyURL设计方案
现在貌似TinyURL很火爆,也逐渐成为一种流行趋势。
对应于PHP版本的TinyURL也有一些算法,其实本质上来说是一种hash。
除此之外,还有另外一种TinyURL方案 ,类似于http://img.ly 。
其实这种设计 是最简单的,没有使用hash,而是递增,这种的好 处就是数据库 可以无限扩展,并且不会重复。
我们可以想想一下,我们只用大小写字母来表示,如果三位的话,就可以存储52*52*52=140608的URL,如果是4位的话就成了 52*52*52*52=7311616,这个数量是几何级增长,并且搜索速度非常快。
PS:如果你觉得这不够用的话,你还可以把数字加进去:)
我刚才测试了下,我新建了一个表:
1.
CREATE
TABLE
IF
NOT
EXISTS `url` (
2.
`id`
int
(11)
NOT
NULL
auto_increment,
3.
`tiny`
char
(10)
character
set
utf8
collate
utf8_bin
NOT
NULL
default
''
,
4.
`url` text
NOT
NULL
,
5.
PRIMARY
KEY
(`id`),
6.
UNIQUE
KEY
`tiny` (`tiny`)
7.
) ENGINE=MyISAM
DEFAULT
CHARSET=utf8 AUTO_INCREMENT=1;
注: 使用utf8_bin是为了区分大小写。
然后我往表中添加了100w条数据 ,下面是我的算法,非常简单,还可以再优化:
01.
function
getTinyUrl(
$num
) {
02.
$alpha
=
array_merge
(range(65, 90), range(97, 122));
03.
if
(
$num
< 52) {
04.
return
chr
(
$alpha
[
$num
]);
05.
}
else
{
06.
$tiny
=
chr
(
$alpha
[
$num
%52]);
07.
while
((
$num
= (int)(
$num
/52)) >= 1) {
08.
if
(
$num
<=52) {
09.
$tiny
.=
chr
(
$alpha
[
$num
-1]);
10.
}
else
{
11.
$tiny
.=
chr
(
$alpha
[
$num
%52]);
12.
}
13.
}
14.
return
strrev
(
$tiny
);
15.
}
16.
}
从 1开始,每个数字就可以生成一个唯一的标识符,然后插入到数据库中。
这时候我执行了一条SQL 语句:
1.
SELECT
*
FROM
`url`
WHERE
tiny =
'DzPM'
在PHPMyAdmin中 显示此条SQL执行耗费的时间是0.0003秒。
那如何运用在实际的项目 中呢?
你可以每次执行插入SQL语句后,把返回的mysql _insert_id存到一个文件 中,下次再读取一下,用这个数字来生成 TinyURL。
当然,如果你有Memcached的话,直接放到这里面速度会更快。