【问题标题】:MySQL : incrementing text id in DBMySQL:在数据库中增加文本 ID
【发布时间】:2010-12-10 08:53:04
【问题描述】:

我的应用程序中需要有文本 ID。 例如,我们有可接受的字符集 azAZ09,以及允许的 ID 范围 [aaa] - [cZ9]。首先生成的 id 是 aaa,然后是 aab、aac、aad 等

如何以交易方式返回 ID 并增加下限? (前提是有数百个并发请求并且都应该有正确的结果)

为了降低负载,我想可以定义 20 个单独的范围,并从随机范围返回 id - 这应该可以减少争用,但首先不清楚如何进行单个操作。

另外,请注意范围内的 ID 数量可能超过 2^32。

另一个想法是拥有 64 位整数的范围,并在软件代码中转换整数->char id,这可以异步完成。

有什么想法吗?

【问题讨论】:

  • 不能只用整数类型,需要的时候转换一下吗?
  • 是的,我可以。这还不能解决任务——我仍然需要允许的范围支持——这意味着通常的自动增量无法完成这项工作。

标签: mysql auto-increment


【解决方案1】:

基于long (bigint) 数字的解决方案,在软件中完成字符到数字和数字到字符的转换,具有 - 比如说 - 32 个不同的范围,

  • 创建 32 个表 range0 .. range31 以降低负载(具有 32 个范围字段的唯一表将在每次写入范围时锁定其行)

  • 通过在 64 位上将 auto_increment 设置为一个非常高的值来开始范围 - 如果您想避免应用程序中的符号问题,可能是 63。理想情况下,5 位的范围值,从 0 到 31。1 位符号 + 5 位范围 = 6 位。您的计数器将从 1 到 (2^58-1) 或 10^17... 这应该足够了。

  • 在软件中,范围号是随机选择的,query 表名是根据rangei 构建的,其中 i 从 0 到 31。

创建表命令类似于 Java 中的命令

  String table;
  String query;
  long increment;

  for (long i=0 ; i<32 ; i++) {
    table = "range"+i;
    increment = (i<<58) + 1;
    query = "CREATE TABLE "+table+" (v bigint auto_increment primary key) auto_increment="+increment;

    do_query(query);
  }

【讨论】:

  • 嗯...有趣,但是我将如何处理具有 100 个数字的范围?
  • @BarsMonster 不是 32,而是 128、2^7 (0..127),(i&lt;&lt;58) 将是 (i&lt;&lt;56)(仍然是大约 10^16 个可能的值)。
  • 当然你可以只使用一张表...(将i&lt;32替换为i&lt;1 :-) - 2^x auto_increment 复杂性背后的想法是减少同时访问相同的自动递增表,因此 locks 频率。这样,您就有了多个键,尽管它们是唯一的。
【解决方案2】:

我会问一个不同的问题,以使相同的问题更容易解决:如何使用我的数据库的功能来实现我的要求。

查看您的数据库在管理序列方面提供的功能。他们中的一些人可能会处理这样的事情。如果您的数据库没有,我会在它的普通数字键上查看“piggy backing”,因为它们已经解决了您预期的所有问题。

我的意思是:让数据库像往常一样分发数字键,从 0 开始。然后编写两个函数在这些数字和文本键之间进行转换。您在这里有一些灵活性:您可以在数据库中实现此功能(使用第二列、触发器或一些很酷的数据库功能),或者在您的服务器层,如 Java。不会那么复杂。最后,无论如何都是比特......你的文本密钥只是分割比特的另一种方式。

祝你好运!

【讨论】:

  • 很棒的开始想法,只需要一张桌子,现在我看到了完美的解决方案:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
  • 2016-06-15
  • 2013-09-20
  • 1970-01-01
相关资源
最近更新 更多