【问题标题】:Add a date prefix on mysql id在 mysql id 上添加日期前缀
【发布时间】:2014-11-19 05:36:49
【问题描述】:

我有一个 ID 字段,我希望它具有以下格式: YYMMDDXXXXXXXXX,其中 YY 是年,MM 是月,DD 是日,XXXXXXXX 是带有前导零的实际 ID 号。此外,当日期更改时,ID 号应重置为 0。

首先,对于同时作为主键的 ID 字段,这是不是一个不太好的做法/格式?

实施:

我将数据插入到我的数据库中,抛出了 php,我想出了 2 种方法来实现上述格式。

  • 使用 php 插入查询手动插入(没有 AUTO_INCREMENT 字段),我选择MAX(id),拆分它(date-id),检查当天是否有 更改,然后将其增加一或将其替换为 新日期+0s。这种方式的问题是我必须做一个额外的 选择并检查/更改字符串,如果我有超过 20 个,SELECT 可能会返回相同的 MAX(id) requests/sec 和 date('Ymd') 导致 apache 崩溃 超过 60 个请求/秒。
  • 在 ID 字段上添加 AUTO_INCREMENT 并将 AUTO_INCREMENT 设置为 YYMMDD00000000 当一天改变时,然后让 auto_increment 做这项工作。我试过ALTER TABLE foo AUTO_INCREMENT=(SELECT CURDATE()*100000000) 但正如我所料 CURDATE() 不能 像这样使用。

对我的尝试有任何想法和/或帮助都会很棒,感谢您的宝贵时间。

【问题讨论】:

  • 您应该将此数据分成两列
  • 我已经有一个日期列,但我还需要将它作为前缀存储在 id 列上。
  • @tsta 为什么?我们无法判断这里是否有真正的理由,是否是XY Problem,或者是否可以通过不同的方式更有效地解决问题。现在所有可见的都是一个坏主意。

标签: php mysql sql auto-increment prefix


【解决方案1】:

理智的方式:

  1. 告诉您的团队经理,这种设计存在很大缺陷。
  2. 改为呈现以下架构:

    CREATE TABLE foo (
      id INTEGER AUTO_INCREMENT,
      date DATETIME DEFAULT=NOW(),
      PRIMARY KEY (id),
      INDEX (date)
    );
    
  3. 如有必要,使用查询生成类似样式的 ID:

    SELECT CAST(DATE_FORMAT(date,'%Y%m%d') AS UNSIGNED)*100000000 + id AS 'weird_id'
    

    虽然如果您的 ID 大于 10,000,000,这将偏离轨道,但我的测试表明,使用 BIGINT 来处理这个 sheme 应该能够处理一两个更多的零。您还可以通过将此 ID 选择为字符串来绕过整数类型限制,例如:

    SELECT CONCAT(DATE_FORMAT(date, '%Y%m%d'), LPAD(id,10,'0')) AS 'weird_id'
    

    LPAD() 中的10 可以是任意多位数字。

不理智、面子、未来噩梦的方式:

你几乎拥有它。 CURDATE() 返回一个字符串,而 ALTER TABLE foo AUTO_INCREMENT= 需要一个整数,而且只有一个整数。没有函数、变量等。以下将起作用:

重击:

mysql -u root -e "ALTER TABLE dbname.foo AUTO_INCREMENT = $(date +%Y%m%d0000000000);"

PHP:

$query = sprintf("ALTER TABLE dbname.foo AUTO_INCREMENT = %s;", str_pad(date("Ymd", time()), 18, '0'));

这将打破:

  • 每当 crond 打嗝时
  • 可能在夏令时更改期间
  • 随机且无明显原因
  • 9999 年 12 月 31 日午夜之后

做你自己,以及从你那里继承这个项目的人,帮个忙,并在此表中保留一个单独的 DATETIME 列,以便将来仍然可以从中收集到有意义的、完整的信息。

【讨论】:

  • 感谢您抽出宝贵的时间来帮助我,我尝试了您的最后一个查询来更改 AUTO_INCREMENT,但我仍然遇到与查询相同的错误,从“=”之后开始象征。我们已经有另一列用于单独的时间戳,如果变量类型是文本而不是日期/时间,是否有任何实际区别?此外,在一张相当大的桌子上如此频繁地更改 AUTO_INCREMENT 是否还有其他可能的副作用?
  • @tsta 显然 MySQL 不喜欢其中的整数以外的任何东西,我已经更新了我的答案。至于性能问题,应该没有。 ALTER 所做的只是更改表元数据中的值。请确保永远不要将 AUTO_INCREMENT 更改为 lower 值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多