【问题标题】:How to create Unique ID based on a pattern如何根据模式创建唯一 ID
【发布时间】:2015-10-17 18:49:03
【问题描述】:

我正在处理一个学生数据库项目,我必须生成一个基于模式的唯一 13 位 ID(在数据库中,而不是通用唯一 ID)。

模式

模式是这样的:前四位是州代码,后两位是学生的入学年份,其余七位是简单的序列代码,例如01031150000001。

问题

我不能使用 mysql 的自动增量功能,因为序列号必须独立于州代码和入学年份。

为了清楚起见,假设我只有三个州代码 State A=0101、State B=0102 和 State C=0103,让我们假设我们正在生成 2015 年的 ID,因此两位数的年份代码将为 15。

现在的问题是,在 A 州录取的第一个学生的 ID 应该是 0101150000001,同样,B 州的第一个学生应该被分配 ID 0102150000001,C 州的第一个学生应该被分配 ID 0103150000001,这些序列应该独立于其他状态以这个顺序继续。

问题还因为每年都必须重新启动序列这一事实而变得复杂。例如,2016 年 A 州的第一个学生应该得到 ID 0101160000001。更糟糕的是,过去的学生记录将随机输入数据库,这意味着可能有一个学生的入学日期是2015 年,这样的条目后面可能会跟着一个入学日期是 1998 年的学生,然后可能后面跟着一个入学日期是 2014 年的学生,依此类推。

我想说的是,数据条目不会按年排序,因此无法每年重置自动增量字段。

每个州每年的顺序必须保持开放或永远持续下去。

虽然我可以使用每个州每年的单独 ID 生成表来管理它,但我想知道是否有更专业的方法来有效地生成和管理此类 ID ????

请不要将其标记为重复,因为我已经在您的论坛和谷歌上搜索过,但找不到任何相关内容。谢谢。顺便说一句,我必须在 MySql 和 PHP 中实现它。

结构

目前,我需要将学生的数据存储在表中。将有 ID、名字、姓氏、地址、亲子关系等属性。还有其他表格,其中包含有关学校和其他实体的数据以及它们之间的关系。我已经准备好了一切。问题只是ID的问题。为此,我需要一个可靠的 ID 生成算法。即使在同一秒内同时创建了数千个条目,该算法也不应该生成两个相似的 ID。

【问题讨论】:

  • 有趣的帖子,你现在有什么数据库结构?我可以想到几种方法,但除非您发布到目前为止的内容,否则没有人会提供帮助

标签: php mysql unique-id


【解决方案1】:

最简单的解决方案是类似于以下的表格设计。

首先创建一个主表来填充学生记录;这仅使用student_id,但实际上会包含其他详细信息,例如名称等。

CREATE TABLE IF NOT EXISTS `students` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `student_id` BIGINT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTOINCREMENT=0;

现在您将拥有一个包含州代码、入学日期和唯一 ID 字段的一对一中间表。通过以这种方式设计它,您允许实现一个递归函数的简单方法,该函数将根据每个引用的student_id 记录处理identifier 字段的顺序值。哦,我更改了年份代码以处理 INT(4)(y2k 错误很多)并将七位数标识符扩展为 BIGINT 以处理增长。

CREATE TABLE IF NOT EXISTS `student_ids` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `student_id` BIGINT NOT NULL,
  `state` INT(4) NOT NULL,
  `year` INT(4) NOT NULL,
  `identifier` BIGINT NOT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `fk_students2student_ids` FOREIGN KEY (`student_id`)
    REFERENCES `students`(`id`)
      ON UPDATE CASCADE
      ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=0;

现在是一个递归函数,用于根据state + year + identifier 的组合组合并确定identifier 的最后一个数值。

<?php //pseudo-code, not tested
$states = array(0101, 0102, 0103);
$years = array(1999, 2000, 2001, 2002);

function robot_do_work() {
  foreach ($states as $st) {
    foreach ($years as $yr) {
      // Create PDO SQL statement
      $handle = $conn->pdo->prepare('SELECT SUM(MAX(`identfier`) + 1) FROM `student_id` WHERE `state` = :state AND `year` = :year DESC');

      // Execute PDO SQL statement with values for :state & :year
      $sth = $handle->execute(array(':state' => $st, ':year' => $yr));

      $record_incremented = $sth->fetchAll();
    }
  }
  return $record_incremented;
}
?>

不是我最好的作品,但它应该让你开始使用解决方案

【讨论】:

  • 我也是这么想的。
  • 感谢您的回复,但我认为这种方法存在问题。我的要求是每个州以及每年都应该有自己的连续序列。你的算法很棒,但它会创建一个在所有州和年份之间共享的公共序列。但要求的是每个州每年都应该有自己独立的连续序列。
  • 那听起来像你自己
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-20
  • 2014-04-17
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2010-11-07
相关资源
最近更新 更多