11

使用数据库主键作为 URL 标识符的优缺点是什么?例如,http://localhost/post/view/13 - 13 是我的帖子表的主键。

像reddit这样的一些网站使用我认为不是主键但仍然是唯一的唯一ID来帮助识别链接:

http://www.reddit.com/r/funny/comments/7ynin/the_mystery_of_irelands_worst_driver/

只要 /7ynin/ 相同,您就可以将 URL 的最后一部分更改为您想要的任何内容。


Digg 似乎使用链接标题的 slug 来标识链接:

http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars

如果我没记错的话,默认的 WordPress 安装使用 index.php?p=# 作为他们的 id,直到启用花哨的 url。


我可以理解为什么为了 SEO 的缘故,您可能希望获得信息量最大的 url,但我只是想看看使用主键是否存在安全风险,或者只是形式不佳。

4

6 回答 6

15

您总是希望向用户呈现一个漂亮的 URL,而不是一些讨厌的自动生成的 ID。但我认为您不应该将所说的“友好 url”作为主键。您仍然应该使用“经典”自动递增的数字 PK,并有第二列是唯一的“友好 url”。为什么?

  1. 所有评论表、评级表,以及与您的内容表有关系的任何表都可以使用数字主键。这意味着更小的索引和更低的内存使用。
  2. 有人会想要更改友好的网址。如果您有一个数字主键,则不必更新任何依赖表(或让数据库通过级联更新来完成)。
  3. 将来,您可以将 URL 位抽象到另一个表中。然后,所述表可以存储发出重定向到主要“真实”URL映射的“遗留”URL映射。然后,当用户想要更改友好 URL 时,您不必破坏所有入站旧 URL。如果您的主键是“友好 URL”,则无法执行此操作。
  4. 我仍然倾向于在我的所有 AJAX goo 中使用数字主键(例如,post_new_comment() javascript 函数将采用主键,而不是一些友好的 URL)。我唯一一次使用友好 URL 是在任何面向用户的 URL 结构中。
  5. 至于安全?如果您的内容受访问控制,则无论它是主键还是某个友好 URL,您都必须检查访问权限。
  6. 如果您允许通过主键访问内容,人们可能会尝试插入随机 ID。如果您不仅要求限制对内容的访问,而且拒绝所述内容存在,那是您的错误措辞的问题。这与登录失败是一样的——你没有说“找不到用户名”,而是说“用户名或密码错误”。插入随机值来查找内容对于您采用的任何方法都是一个问题,只是使用数字键可以尝试的值更少。

底线:友好的 URL?地狱是的。使用它们作为主键?一定不行。

于 2009-03-02T16:05:35.393 回答
3

正如您所说,将标题直接放在 URL 中的目的是 SEO。在 URL 中包含关键字对搜索引擎结果有重大影响。

但是,与您的示例相关的其他一些想法:

  • 我不确定你为什么认为 reddit 字母数字键不是主键,没有什么可以强制主键为数字键。如果它是帖子的唯一标识符,则没有理由不将其用作主键(或至少是其中的一部分)。
  • Digg 实际上强制标题的唯一性(也许只是在特定类别中,我已经很多年没有去过 Digg,所以我不记得了)。我曾经经常看到这个重复的故事,其 URL 如下:

    http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars_2
    

    这意味着标题至少是主键的一部分,因为这是识别链接打算针对哪个故事的唯一方法。

正如 pantulis 所提到的,除了人们猜测/预测其他主键的能力之外,在 URL 中使用主键并没有任何重大的安全风险。但无论如何,您不应该依赖“没人会猜到这一点”作为安全措施。

于 2009-02-19T20:38:59.987 回答
3

如果您没有在 URL/链接中包含主键,那么您必须制作某种临时合成键,然后,您必须在会话中为用户保存该键的映射。这会增加更多的状态/内存使用/破坏您的应用程序的东西。

如果该值真的很敏感,那么隐藏它可能是值得的。但是,隐藏密钥并不能真正使其安全,不是吗?在授予对项目的访问权限之前,您需要检查任何“控制器”(servlet、代码隐藏等)中的用户角色。

于 2009-02-19T21:11:58.033 回答
2

它本质上不是安全风险,尽管它确实告诉外部实体有关您的系统的信息,这通常是避免的好习惯。

于 2009-02-19T20:34:28.730 回答
2

Reddit 也使用数字 ID,但使用Base 36进行转换,因此它显示为字符串。它就像十六进制数,实际上也是一个字符串。唯一的区别是基础。

Base 36 是“使用 ASCII 字符的最紧凑的不区分大小写的字母数字系统”,它易于编码和解码。为什么是36?AZ = 26 + 0-9 = 10。

于 2013-01-23T18:48:10.333 回答
1

一个缺点:任何访问者都可以轻松尝试并猜测其他 ID,这可能不是您想要的。

于 2009-02-19T20:30:25.790 回答