URL shortener: best encoding method?
我正在创建链接缩短服务,并且正在使用递增ID字段的base64编码/解码来创建我的网址。 ID为" 6"的网址为:http://mysite.com/Ng==
我还需要允许用户创建自定义网址名称,例如http://mysite.com/music
到目前为止,这是我的方法(可能是错误的)。帮助修复它,将不胜感激。
当有人创建新链接时:
-
我从数据库中获得最大的链接ID(不会自动递增)
-
将ID递增1
-
通过base64_encoding该ID生成短URL代码(http://website.com/ [短URL名称])
-
插入链接表:id,short_url_code,destination_url
当有人创建新链接并传递自定义短网址时:
-
我的计划是base64_decode他们的自定义字符串并将其用作链接ID,但我没有意识到您不能只base64_decode任何字母数字字符串并将其转换为数字。
是否有更好的编码方法,使我可以将任何数字转换为短字符串,并将任何字符串转换为数字,所以我始终可以通过将名称转换为数字并查询链接来查找短网址(无论是自定义还是自动生成) ID等于该数字的ID?
-
另请参阅stackoverflow.com/questions/561486/ re。 URL中的Base64编码
首先,请确保在ID和short_url_code列上具有唯一性约束。
当有人创建新链接时:
从数据库中获取下一个最大的链接ID(出于性能原因,您应该真正使用autoincrement或SEQUENCE,具体取决于您的RDBMS提供的内容;否则继续选择MAX(ID)+1)
使用base64_encode或任何其他自定义或标准编码方案从ID生成短URL代码(http://website.com/[short url name])
插入links表:ID, short_url_code, destination_url
如果由于违反约束而导致插入失败,请返回步骤1尝试新的ID;否则,请执行步骤3。您可能有违规行为,因为:
相同的ID已经被另一个线程/进程等并行使用(即插入)(如果您使用autoincrement或SEQUENCE则不会发生,否则可能会经常发生),和/或
相同的short_url_code已被用作自定义URL(除非有人试图在您的网站上造成麻烦,否则这种情况很少发生)
如果插入成功,则提交并返回短网址给用户
当有人创建新链接并传递自定义短网址时:
执行与上述相同的步骤1
而不是像上面的步骤2一样从ID生成短URL部分,而是使用用户提供的自定义short_url_code
执行与上述相同的步骤3
如果插入由于以下原因而失败:
ID上的约束违例:返回步骤1尝试新的ID
short_url_code上的约束违反:向用户返回错误,要求他选择其他自定义URL,因为他/她提供的短URL已被使用
执行与上述相同的步骤5
-
谢谢弗拉德。我应该提到我已经在处理约束违例。我已经切换到base32,这使我可以将自定义网址转换为数字并将其作为ID插入。这使操作变得容易,因为我只需要将ID作为主键即可。如果自定义名称的base32表示存在约束违规,它将告诉他们该名称已被使用。如果非自定义网址存在违反约束的情况,它只会不断增加ID,直到可以插入为止。听起来像是一个不错的解决方案?
-
取决于您愿意做出的权衡;大多数数据库本机int类型的最长长度为64位(bigint或等效类型),这意味着如果我为您提供的自定义短URL的长度大于64/5 = 12(5 = log2(32) )字符,您将无法适应我。不允许用户提供超过12个字符的自定义URL是否可以接受?
-
好点子。我确实需要超过12个字符。怎么样:创建链接时,如果自定义名称超过12个字符,那么我仅使用下一个最大的ID(不包括自定义名称链接的ID)。如果少于12个字符,则会在ID中编码自定义名称。然后,当通过其短名称查找链接时,如果在数据库中找不到该ID,则表示该ID超过12个字符,因此我仅通过其短名称查找它。
-
虽然有点复杂,但是这将保持递增系统(有利于使网址简短),并且仍然允许我利用快速选择低于12个字符的自定义名称的优势。
-
没关系,只是决定通过链接名称(而不是ID)查找链接并放弃整个基本编码。
-
就个人而言,Id而不是base64编码,而更喜欢PHP的base_convert(nl2.php.net/manual/en/function.base-convert.php)。您可以将base10转换为base36,然后再无问题地返回。对于较高的基数(即区分大小写的A-Za-z0-9),您需要自定义函数,尽管我认为base36可以很好地工作。
base64可用于创建短网址,但也可以使网址更长。例如,数字1的base64_encode是'MQ ==',是大小的4倍。 Base64将始终有2个字符来获取64位,这对于短URL而言并不理想。
如果大小是最重要的因素,那么您可以依靠国际化来生成最短的网址。
This can make a URI rather long (up to 9 ASCII characters for a single Unicode character), but the intention is that browsers only need to display the decoded form, and many protocols can send UTF-8 without the %HH escaping.
请记住,浏览器在UTF-8上可以很好地工作,twitter在使用这些URL时不会有任何问题。