资料排列组合 Data Permutations

Database 最佳化: 资料排列组合 Data Permutations

在使用 MySQL 或 PostgreSQL 资料库的时候,我们常常会使用 Auto Increment 的整数去当作我们的键值,Int 总共有 4294967295 种排列组合方式,而 BigInt 则总共有 18446744073709551615 种排列组合方式

使用 Auto Increment 的好处是:

  • 可以避免每次的键值都是不同的,不需要再做额外的栏位资料检查是否重複
  • 可以依照整数顺序去判断资料新增的顺序

但这样也有坏处:

  • 资料被删除后,空出来的键值很难被管理,会造成不必要的浪费
    • e.g. Queue 资料
  • 总资料量被限制,当我们预期资料很有可能超过整数栏位的限制时,资料量超过时还需要处理溢位问题
    • e.g. 很多的 Queue 资料

所以若预期资料量很大时,我们会倾向使用字串去当作资料表的键值,单一整数的资料排列组合有 10 种 (0-9),而单一字串的资料排列组合有 36 种(0-9 A-Z),虽然整数栏位在资料表搜寻的速度比字串快很多,但是这个是没办法的必要之恶。

字串排列组合

在资料库储存的字串资料是不区分大小写的,所以若有一个 Primary 或 Unique 的键值,裡面是没办法同时储存 AAAaaAaa 的,所以我们字串键值的排列组合只能用不区分大小写 36 种 (0-9 A-Z) 排列组合去计算。

字串长度 排列组合 (不区分大小写)
1 36
2 1,296
3 46,656
4 1,679,616
5 60,466,176
6 2,176,782,336
7 78,364,164,096
8 2,821,109,907,456
9 101,559,956,668,416
10 3,656,158,440,062,980
11 131,621,703,842,267,000
12 4,738,381,338,321,620,000
13 170,581,728,179,578,000,000
14 6,140,942,214,464,820,000,000
15 221,073,919,720,733,000,000,000
16 7,958,661,109,946,400,000,000,000
17 286,511,799,958,070,000,000,000,000
18 10,314,424,798,490,500,000,000,000,000
19 371,319,292,745,659,000,000,000,000,000
20 13,367,494,538,843,700,000,000,000,000,000
21 481,229,803,398,374,000,000,000,000,000,000
22 17,324,272,922,341,500,000,000,000,000,000,000
23 623,673,825,204,293,000,000,000,000,000,000,000
24 22,452,257,707,354,600,000,000,000,000,000,000,000
25 808,281,277,464,764,000,000,000,000,000,000,000,000
26 29,098,125,988,731,500,000,000,000,000,000,000,000,000
27 1,047,532,535,594,330,000,000,000,000,000,000,000,000,000
28 37,711,171,281,396,000,000,000,000,000,000,000,000,000,000
29 1,357,602,166,130,260,000,000,000,000,000,000,000,000,000,000
30 48,873,677,980,689,300,000,000,000,000,000,000,000,000,000,000
31 1,759,452,407,304,810,000,000,000,000,000,000,000,000,000,000,000
32 63,340,286,662,973,300,000,000,000,000,000,000,000,000,000,000,000
33 2,280,250,319,867,040,000,000,000,000,000,000,000,000,000,000,000,000
34 82,089,011,515,213,400,000,000,000,000,000,000,000,000,000,000,000,000
35 2,955,204,414,547,680,000,000,000,000,000,000,000,000,000,000,000,000,000
36 106,387,358,923,717,000,000,000,000,000,000,000,000,000,000,000,000,000,000
37 3,829,944,921,253,800,000,000,000,000,000,000,000,000,000,000,000,000,000,000
38 137,878,017,165,137,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
39 4,963,608,617,944,920,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
40 178,689,910,246,017,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000

只要字串长度大于 13 时,我们拥有的资料排列组合就会超过 BigInt 的 18446744073709551615 排列组合

在使用字串当做键值时,在我们每次新增资料手动产生字串键值时,我们都要再去资料库检查看看此键值是否存在,再新增进去,且我们需要额外做新增资料造成 Duplicate Key 的例外状况处理

在我们字串很长时虽然发生碰撞的机率很低,但为了系统资料的安全完整性,还是需要做检查的步骤,并在频繁被通知到键值冲突的状况时,就要考虑增加字串长度,减少键值碰撞机率了

参考资料