缩短数据表键以保持唯一性

时间:2013-08-15 14:01:32

标签: mysql regex key unique

我有一个相当普遍的问题,我道歉它很冗长。它不仅与MySQL有关,而且可以用任何脚本语言完成,但我找不到更好的解释方法。我有一个独特的单词列表。现在他们在MySQL的表中,但实现并不重要,它们也可以在文本文件中。每个单词都是6个字符。单词遵循几种略有不同的格式。我的目标是将每个单词从6个字符缩短为4个字符,保留唯一性。

我搜索了主题,所有数据最小化/优化/碰撞都没有提供有用的结果:(所以我在这里。

以下是一个示例:

--------------
words
--------------
word     short
------   ----
1A0001
1A0002
1A0003
AA0001
AA1001
AB0001
2BAC11
2BAC34
--------------

正如您所看到的,有三种格式可以用以下通用正则表达式表示:

^[0-9][A-Z][0-9][0-9][0-9][0-9]$  - matches  1A0001 1A0002 1A0003
^[A-Z][A-Z][0-9][0-9][0-9][0-9]$  - matches  AA0001 AA1001 AB0001
^[0-9][A-Z][A-Z][A-Z][0-9][0-9]$  - matches  2BAC11 2BAC34

因此,根据格式,可以删除不同的字符,使单词4个字符长,并使它们保持唯一。

^[0-9][A-Z][0-9][0-9][0-9][0-9]$  - drop 1, 3
^[A-Z][A-Z][0-9][0-9][0-9][0-9]$  - drop 3, 4
^[0-9][A-Z][A-Z][A-Z][0-9][0-9]$  - drop 1, 4

我使用short创建regexp/concat/substring的值,并使用临时表对words进行更新。正如我所说,实施对解释并不重要。它几乎归结为:

select concat(substring(word,2,1), substring(word,4,3)) from words where word regexp '^[0-9][A-Z][0-9][0-9][0-9][0-9]$';
select concat(substring(word,1,3), substring(word,6,1)) from words where word regexp '^[A-Z][A-Z][0-9][0-9][0-9][0-9]$';
select concat(substring(word,2,2), substring(word,5,2)) from words where word regexp '^[0-9][A-Z][A-Z][A-Z][0-9][0-9]$';

这就是表格最终的样子:

--------------
words
--------------
word     short
------   ----
1A0001   A001
1A0002   A002
1A0003   A003
AA0001   AA01
AA1001   AA11
AB0001   AB01
2BAC11   BA11
2BAC34   BA34
--------------

我可以使用以下方式验证short的唯一性:

mysql> select short from words group by short having count(short) > 1;
Empty set (0.00 sec)

mysql>

这是非常简化的方案。实际上,单词更长,格式更多。有时即使格式相同,删除相同的字符也会产生冲突,这意味着两个不同的word会导致相同的short,这是不可接受的。因此需要修改short以使其成为唯一的。最大的困难来自于所有word实际上都是人类可理解的事实,因此short版本应该是人类可理解的并且与原始word相似。这意味着我无法创建某种散列算法来确保短版本的唯一性,这还不够,它必须有点像原始单词。现在我正在考虑用0替换O,依此类推。

我猜你觉得这更像是一个科学问题,而不是一个实施问题。实施的唯一重要方面是性能。我希望有一个好的表现,所以我不必永远等待。

有人见过类似的东西吗?

我会从哪里开始寻找方法呢?

0 个答案:

没有答案