什么时候使用长字符串ID而不是简单的整数?[关闭]


54

我想以Youtube为例:他们使用ID的形式PEckzwggd78

他们为什么不使用简单的整数?

或imgur.com-他们还使用ID,例如9b6tMZS图像和画廊。不是连续的整数。

  • 他们为什么不使用整数(尤其是顺序整数)?

  • 在什么情况下使用这样的字符串ID而不是整数是明智的决定?


47
是什么让您相信ID不仅仅是简单的整数?我知道很多Web服务都在DB中使用整数,但是以某种base64编码显示它们,因此URL看起来更好。有趣的是,YouTube ID几乎映射为64位整数。
约瑟夫(Josef)

2
@rwong但是OP的问题是为什么他们不使用数字ID,答案可能是:他们使用数字ID,它们只是在base64中显示而不是在base10或base2中显示。我不确定,但是,所以我问OP是什么让他们认为ID不是base64中的简单64位整数。
约瑟夫(Josef)


3
是不是一样的这个
the_lotus

Answers:


101

由于以下两个原因,Youtube无法使用顺序ID:

  1. 几乎可以肯定其数据库是分布式的,这使得顺序编号变得复杂。

  2. 它具有一个隐私选项“不公开的视频”:那些不会显示在搜索结果中的视频,但是如果您知道ID,则可以使用。

因此,视频ID应该合理地随机且不可预测。ID是仅由数字表示还是由字母和数字的组合表示都是无关紧要的:从一种表示形式到另一种表示形式的映射很简单。


11
数字ID不必是连续的
Sopel

28
@Sopel我认为IMil的观点是,Youtube需要生成稀疏的ID。换句话说,如果估计您只需要存储2^40项目,则在某些体系结构中,有合理的理由选择空格2^802^120位。原因示例包括:在没有技术检查碰撞的情况下减少碰撞;使用密钥的稀疏性来使秘密难以发现(“未公开的视频”)等
。– rwong

13
@Sopel的问题是“为什么他们不使用整数(尤其是顺序的整数)?” 我解释说:1)顺序ID是不希望的;2)整数和字符串基本上是同一件事
IMil

3
“ therethe”子句在逻辑上不遵循,但是两个编号的点是正确的。举例说明为什么不需要随机性的原因:具有均匀间隔的顺序编号将在多个独立的数据库中提供唯一的ID,以便可以在数据仓库中组合结果-这是分片的一种形式。也就是说,假设您预期区域数据库不超过10000个(也许您现在只有10个,那么10000个就足够了)。然后,每个数据库都可以有一个标识列,该标识列由10000计数,后四个数字唯一,合并时不会发生冲突。
davidbak

2
@davidbak对随机性的要求从(2)开始。确实可以通过将非重叠范围分配给不同的数据库实例来获得唯一性,但这会使ID可预测。
IMil

75
  • 在ID的形式:他们使用的Base64(使用字符a- zA- Z0- 9-_)。这使他们每个字符有6位信息。YouTube使用11个字符的视频ID,这意味着它们可以生成2个6 * 11或超过7 * 10 19个 ID。正如汤姆·斯科特(Tom Scott)所说,“在地球上,每个人都可以在大约18,000年的时间里每分钟上传视频。Base64也很容易使用,因为64是2的幂,这意味着每个字符都代表确切的位数。出于相同的原因,我们使用十六进制(以16为底)。

  • 关于ID的非顺序性质:这意味着它们在为视频分配ID的所有服务器之间不需要同步计数器。他们可以生成一个随机数,检查它是否已被使用,然后从那里去。他们甚至可以为每个服务器分配一个ID块以进行选择,并消除重复检查。我不知道他们是否这样做,但是可以。

  • 使用非顺序ID的另一个原因是,它使“不公开”的视频起作用。这些视频不会显示在搜索结果中或作为建议,但是如果您具有链接,便可以访问。如果您使用的是顺序计数,则只需观看视频,将ID增加1,就可以打破不公开视频的想法。

  • 非顺序ID还可帮助向竞争对手隐藏信息,例如视频总数或每个时间段上载的视频数量。

我强烈推荐汤姆·斯科特(Tom Scott)的视频。他的信息几乎总是有趣且准确的。


6
我们还要指出,base64编码的11个字符存储66位信息,这意味着它们可以轻松地将64位整数映射到这样的字符串中。即在内部,他们无论如何都可以使用64位int(但不必这样做)。
伯恩哈德·希勒

1
为了进行比较,常规的十进制表示形式可能需要多达20个字符,与Base64相比,“浪费”多达9个字符。
dan04 '17

汤姆·斯科特(Tom Scott)的视频完美地说明了这一点。
AGB

13
  • 整数不能很好地扩展,一个“正常”的32位无符号整数将最多超过40亿。

  • 他们可能不想让您知道他们在线上有多少物品或跟踪他们的增长率。

  • 字母比数字可以容纳更多的信息,表示相同的“数字”所需的字母更少。对于大型索引器数据库,这可能加起来。


7
1)一个人可以使用int 64
Rakori

4
2)为什么?........无论如何他们都是公开的。那些不公开的-无法访问。就是这样
Rakori

3
3)你能详细说明吗?表达什么信息?
Rakori

2
对于1:int32和int64同样适用。尽管int64可能更大,但可能还不够大。
Nepho

3
在数据库中,您将数字存储为数字。因此,一个32位int将占用32位。文本的密度较小(取决于编码方式,较差的文本多少)
Taemyr

8

1)为什么某些网站在ID中使用字母?他们是琴弦吗?

我们不知道这些网站是否将ID作为字符串存储在其数据库中。数字和字符串对于计算机而言实际上是相同的。字符串只是一个数字,只是以不同的底数显示。'A' = 0x41 = 65 = 0b1000001,到计算机都一样。但是,如果显示它,则基数越大,表示形式越短,URL越短,人类就越容易阅读和共享。像YouTube和Imgur这样的网站使用的基数为62(字母,大写和小写字母以及数字)或更大(添加破折号或其他有效的URL字符),这对于大数字而言相对较短。你喜欢什么用,youtu.be/23489234892348234933还是youtu.be/B9k6KMrv8vh

2)为什么使用非顺序ID?

IMil的回答很好地解释了这一点:

由于以下两个原因,Youtube无法使用顺序ID:

  • 几乎可以肯定其数据库是分布式的,这使得顺序编号变得复杂。

  • 它具有一个隐私选项“不公开的视频”:那些不会显示在搜索结果中的视频,但是如果您知道ID,则可以使用。

这些也解释了为什么ID这么大的原因:(YouTube显然没有托管23,489,234,892,348,234,933,933个不同的视频)

  • 生成ID时,如果不小心两次生成相同的ID,就会出现问题,因此您需要较大的ID空间以防止生日问题

  • 如果用于视频的任何给定有效ID的机会不是很小,那么人们只能猜测未公开视频的URL。


3
>“显然,YouTube不会托管23,489,234,892,348,234,933个不同的视频”,我不确定这是否显而易见;)
unperson325680

People can just guess the URL of unlisted videos if the chance of any given valid ID being used for a video isn't very, very small.-您如何知道除作者以外的所有人是否都无法访问未公开的视频?即使其他人已经猜到了它的ID
Rakori也会


2
@progo我的意思是,如果世界上每个人平均都向YouTube上传了33亿个视频...;)
Jasmijn

5

为什么不只是整数,尤其是顺序整数?在什么情况下,明智的决定是使用这种字符串ID而不是整数?

  • 更好的UTF-8空间-将数字转换为字符串时,每个字符最多可获得10个组合(0-9),但是如果允许任何字母数字字符,则每个字符可获得62个组合(az,AZ,0-9) ),因此与使用数字字符串相比,使用字母数字字符串可以生成较短的网址。这对于用户共享网址的网站(例如Youtube和Imgur)非常重要。
  • 顺序整数更难产生。要生成连续递增的整数,您必须具有单个线程来生成数字,或者必须协调分布式系统中的许多主机,并且在运行诸如Youtube或Imgur之类的大容量应用程序时,其扩展性不如随机生成的字符串好(并不是说它们随机生成的)

顺便说一句,内部表示形式不一定字符串。他们很可能将数字标识符编码为较短网址的字母数字字符串。


1
2)如果是字符串ID,但是在将新记录插入数据库之前,您需要验证是否已经生成了字符串ID。那么,与int ID有什么区别?
Rakori

@Rakorin即使使用UUIDv4这样简单的方法,发生碰撞的可能性也很小。使用足够的随机性,机会几乎不存在,因此确实不需要验证重复性。
安迪

1
@davidpacker,与生成更长的整数有何不同?
Sopel

正如Samuel指出的那样,整数比字符串要占用更多的空间,即更长。否则,确实没有任何区别。
安迪

1
@davidpacker仅在印刷时
Sopel

2

正如您所指出的那样,仅使用数字就可以使用通用唯一ID,因为在幕后一切都是正义的01并且您可以将数字扩展到更高的精度,最高可达128位或更高。

我认为主要原因是,假设有一些任意固定范围uint32(仅出于示例目的),如果您也使用字母,则总共可以使用较短的ID。

我认为这是URL的美学原因。而不是4,129,873,773带有字母,它要短得多Fu837t(由我虚构)。用户甚至可以记住将其提供给朋友的URL。像Youtube这样的平台通常具有比32位更长的UUID,因为它们会很快耗尽空间。


3
我认为这就是答案。使用字符串既不高效也不容易维护唯一性。原因是它更易于表示为网址
Sopel

如果用户能够记住Fu837t,但他不记得2390吗?
Rakori

4
@Rakori:Fu837t可以与2223955238相比,所以是的。2390将被编码为“ Vg”,因此:也可以。
Mooing Duck's

@MooingDuck,不。您如何知道生成该字符串ID的算法是什么?
Rakori

3
@Rakori不是算法,而是编码。有一些算法可以在不同的编码之间传输数字,但是只要编码定义明确,使用哪种算法都没关系。网址安全的base64编码是众所周知的和标准化的
约瑟夫(Josef)

2

最好使用短URL,因为它使链接和共享更简单(例如,您可以在SMS中共享链接,键入速度更快,依此类推)。诸如Youtube或Imgurl之类的服务希望您随便共享URL,因此这是一个重要的考虑因素。

使用字母数字ID而不是数字意味着您需要更少的字符来表示相同位长的ID。例如,6位数字为您提供一百万个唯一ID,而6个字母数字字符(使用base64集)为您提供680 亿个唯一标识符。

就我们所知,字母数字标识符可以是序号,只是以字母数字格式(如base64)编码。但是商业服务通常避开顺序代码,以防止人们猜测ID,并避免泄露诸如客户数量之类的商业信息。


1

使用非数字ID的原因有多种,但也可以理解并非所有带字母字符的值都是真正的字符串。YouTube以令人难以置信的视频数量而闻名,每分钟上传300个小时的视频(参考)。代表这些视频的唯一整数可能会变得很长,因此请使用诸如Base64 URL编码的数字(ref)之类的东西。

标识符表示的类型:

  • 简单整数:(12345,981027489382493)
  • 以16为基数的整数:123456789abcdef-也称为十六进制
  • 基数64个整数:9b6tMZS
  • 可读字符串:12032017-Read-my-awesome-article-01

他们都有自己的优点和缺点。可用于标识符的唯一字符越多,表示数字所需的字符越少。基数64是一个很好的折衷方案,因为存在一个确定的变体,该变体适用于URL,并压缩表示6到8的数字(即大小的3/4)所需的字符数。

可读的字符串可用于博客,因为它们可以提高可搜索性,并且当记录数较少时,生成唯一的标题要容易得多。


1

内容散列

在现有的不错的答案中找不到“哈希”一词,因此我们开始:

通常,数据可以通过其内容哈希而不是独立的人工ID来识别。这在git像ZFS这样的软件或文件系统中尤为明显,其中使用内容散列的这一特殊属性不仅使内容变得更容易(例如重复数据删除),而且还具有其他一些不错的属性,例如琐碎的缓存,安全的历史记录,检测位腐烂等等

哈希通常以十六进制数字(或更大的字母空间)的形式出现,因此这就是为什么看不到整数ID的原因。在这些情况下,根本没有整数。

如果您的数据对象是不可变的(例如,在ZFS或中git),则哈希值很好。它们非常适合将图像存储在例如大型CDN上。我不知道这些特定的ID是否实际上哈希,但是这确实是有道理的(正如MichaelKjörling所评论的那样, ID可能不是哈希的原因很明显-相比之下,git使用的SHA-1值是20字节或40十六进制数字)。


1
至少YouTube视频ID太短而无法散列。生日悖论适用;简而言之,平均而言,使用n位的哈希空间,您将在看到2 ^(n / 2)个输入Blob之后开始看到冲突。ID中有约60-70位,即30-35位的唯一性,即数十亿个条目。我敢肯定,到现在为止,他们托管的视频更多。而且,当然,大多数哈希都是整数就可以了;它们通常不是以十进制形式打印的,与它们是否为整数无关。诚然,相同的数据可能会被解释为浮点二进制数据……
CVn

3
@MichaelKjörling:嗯,YouTube视频ID太短而不能成为加密散列,但是有很多散列函数具有64位或更少的输出-CRC-16 / 32/64,Java hashCode()等。当然,哈希,随机碰撞的可能性就更高。
dan04 '17

如果您希望人们记住该URL,则不会使其具有区分大小写的意义。而且,在每个字母前都必须说“大写”或“小写”,这比仅说数字要有效得多。
Lenne

0

好的原因之一是,无论如何,字符都是作为字符而不是整数发送的。这是因为HTTP Get的工作原理。

当您说“为什么不使用整数?” 好了,然后将整数切碎,然后将每个数字作为字符发送,无论如何,您最终都会得到一串字符。那么,为什么不对角色使用所有选项呢?

还有人为因素:

以imgur为例:https : //imgur.com/ ***** / s6UqP

s6UqP,

每个字符的范围是:a到z的大写字母,a到z的小写字母,字符串中每个位置的0到9 = 26+ 26+ 10 = 62个选项。五个位置即916132832的可能组合。如果仅使用数字,则需要9位数字。

人们可以在内存中容纳大约7个对象,9位数字太多,5个字符是可行的。

魔数7


它记得Gfycat:他们使用三个词,两个形容词和一个动物名。因为存在多种可能性(1502形容词1751种动物),所以仅使用三个对象就拥有超过30亿种组合。
古斯塔沃·罗德里格斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.