如何根据模式创建唯一 ID

How to create Unique ID based on a pattern

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

模式

格式是这样的:前四位是国家代码,后两位是学生入学年份,剩下的七位是简单的序列码,例如01031150000001。

问题

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

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

现在的问题是,A州第一个录取的学生ID应该是0101150000001,B州第一个学生的ID应该是0102150000001,C州第一个学生的ID应该是0103150000001并且这些序列应该独立于其他状态按此顺序继续。

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

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

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

虽然我可以通过每年为每个州生成 table 的个人 ID 来管理它,但我想知道是否有更专业的方法来有效地生成和管理此类类型的 ID ????

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

中实现它

结构

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

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

首先创建一个小学 table 来填充学生记录;这只使用 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;

现在您将拥有一个一对一的中介 table,其中包含州代码、入院日期和唯一 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;
}
?>

这不是我最好的作品,但它应该可以帮助您找到解决方案