使用主键/ID 字段作为 URL 中的标识符
使用数据库主键作为 URL 标识符有哪些优点和缺点? 例如, http://localhost/post/view/13 - 13 是我的主键帖子表。
像 reddit 这样的一些网站使用我认为是唯一的 id,它不是主键,但仍然是唯一的,以帮助识别链接:
http://www.reddit.com/r/funny/comments/7ynin/the_mystery_of_irelands_worst_driver/
您可以将 URL 的最后部分更改为您想要的任何内容,只要 /7ynin/ 相同即可。
Digg 似乎使用链接标题的 slug 来标识链接:
http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars
如果我没记错的话,默认的 WordPress 安装会使用 index.php?p=# 作为其 id,直到启用奇特的 url。
我可以理解为什么为了 SEO 的缘故,您可能希望拥有信息最丰富的 url,但我只是想看看使用主键是否存在安全风险,或者只是一种不好的形式。
What are the pros and cons of using your databases primary key as a URL identifier? As an example, http://localhost/post/view/13 - 13 being my primary key for my posts table.
Some sites like reddit use what I assume is a unique id that is not the primary key but still unique to help identify the link:
http://www.reddit.com/r/funny/comments/7ynin/the_mystery_of_irelands_worst_driver/
You can change the last part of the URL to whatever you want as long as the /7ynin/ is the same.
Digg seems to use a slug of the links title to id a link:
http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars
While if i recall correctly a default WordPress install uses index.php?p=# as their id until fancy urls are enabled.
I can see why for SEO's sake you would want to have the most informative url possible but I am just trying to see if using the primary key is a security risk or simply just bad form.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您总是希望向用户提供一个漂亮的 URL,而不是一些令人讨厌的自动生成的 ID。 但我认为你不应该将“友好网址”作为主键。 您仍然应该使用“经典”自动递增的数字 PK,并拥有第二列,该列是唯一的“友好 url”。 为什么?
表,任何有
与内容表的关系
可以使用数字主键。
这意味着更小的索引和更低的
内存使用。
更改友好网址。 如果你有
有一个数字主键,但你没有
必须更新您的任何受抚养人
表(或者让数据库通过
级联更新)。
你可以抽象出 URL 位
到另一个表中。 说表可以
然后存储“旧”URL 映射
该问题重定向到主要问题
“真实”URL 映射。 那么当用户
想要更改友好的 URL,
你不必打破所有
入站旧 URL。 做不到
如果您的主键是
“友好的网址”。
底线:友好的 URL? 是啊。 使用它们作为主键? 一定不行。
You always want to present the user with a nice URL-not some nasty auto-generated ID. But I dont think you should make said "friendly url" the primary key. You should still use a "classic" auto-incremented, numeric PK and have a second column that is a unique "friendly url". Why?
tables, whatever tables that have a
relationship with your content table
can use the numeric primary key.
This means smaller indexes and lower
memory use.
change the friendly url. If you've
got a numeric primary key, you don't
have to update any of your dependent
tables (or have the DB do it via a
cascading update).
you can abstract out the URL bits
into another table. Said table can
then store "legacy" URL mappings
that issue redirects to the primary
"real" URL map. Then when the user
wants to change the friendly URL,
you don't have to break the all the
inbound legacy URL's. Couldn't do
this if your primary key was the
"friendly URL".
Bottom line: Friendly URL's? Hell yeah. Using them as the primary key? Hell no.
正如您所说,将标题直接放在 URL 中的目的是 SEO。 URL 中包含关键字会对搜索引擎结果产生重大影响。
但是,还有一些与您的示例相关的其他想法:
Digg 实际上强制了标题的唯一性(也许只是在特定类别内,我已经很多年没有去过 Digg,所以我不记得了)。 我以前经常看到这样的重复故事,其 URL 如下:
<前><代码>http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars_2
这意味着标题至少是主键的一部分,因为这是识别链接旨在针对哪个故事的唯一方法。
正如 pantulis 提到的,除了人们猜测/预测其他主键的能力之外,在 URL 中使用主键实际上并没有任何重大的安全风险。 但无论如何,您不应该依赖“没有人会猜到这一点”作为安全措施。
As you said, the point of putting titles directly in the URL is SEO. Having keywords in the URL has a significant effect on search engine results.
However, a few other thoughts related to your examples:
Digg actually enforces uniqueness of titles (perhaps just inside a particular category, I haven't been to Digg in years, so I can't recall). I used to see this fairly often with a duplicate story having a URL like:
This implies that the title is at least part of the primary key, since that's the only way to identify which story the link was intending to be aimed at.
There isn't really any significant security risk with using the primary key in the URL, other than the ability for people to guess/predict other ones, as pantulis mentioned. But you shouldn't be relying on "nobody will guess this" as a security measure anyway.
如果您不在URL/链接中包含主键,那么您必须创建某种临时合成键,并且,然后,您必须保存该键的映射在用户的会话中。 这会为您的应用程序添加更多状态/内存使用/需要中断的内容。
如果该值确实敏感,那么隐藏它的成本可能是值得的。 然而,隐藏密钥并不能真正保证其安全,不是吗? 在授予对项目的访问权限之前,您需要检查任何“控制器”(servlet、代码隐藏等)中的用户角色。
If you don't include the primary key(s) in the URL/link, then you have to make some kind of temporary synthetic key, AND, then, you have to save the mapping of that key in the session for the user. This adds more state / memory usage / something to break to your application.
If the value is truly sensitive, this might be worth the cost of hiding it. However, obscuring the key doesn't really make it secure, does it? You need to check user roles in whatever "controller" (servlet, code-behind, whatever) before granting access to the item.
它本质上并不是一个安全风险,尽管它确实告诉外部实体有关您的系统的信息,这通常是避免的好习惯。
It isn't inherently a security risk, though it does tell external entities things about your system, which is generally good practice to avoid.
Reddit 也使用数字 ID,但使用 Base 36 进行转换,因此它显示为字符串。 它就像十六进制数,实际上也是一个字符串。 唯一的区别是基础。
Base 36 是“使用 ASCII 字符的最紧凑的不区分大小写的字母数字系统”,并且它很容易编码和解码。 为什么是36? AZ = 26 + 0-9 = 10。
Reddit use numeric ID as well, but converted using Base 36, so it appears as a string. It's like hexadecmial number, which in fact is a string as well. The only difference is the base.
Base 36 is "the most compact case-insensitive alphanumeric numeral system using ASCII characters" and it's easily encodable and decodable. Why 36? A-Z = 26 + 0-9 = 10.
缺点:任何访问者都可以轻松尝试并猜测其他 ID,这可能不是您想要的。
A con: any visitor can easily try and guess other IDs, which may not be what you want.