如何基于模式创建唯一ID

时间:2015-10-17 18:49:04

标签: php mysql unique-id

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

模式

模式是这样的:前四个数字是状态代码,接下来的两个数字是学生的入学年份,剩下的7个数字是简单的序列代码,例如01031150000001.

问题

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

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

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

由于每年必须重新启动序列,因此问题也变得复杂。例如,2016年A州的第一名学生应该获得ID 0101160000001.为了更加混乱,过去的学生记录将被随机输入数据库,这意味着可能有一个学生的入学日期是2015年和这样的参赛作品可能会跟随一名入学日期为1998年的学生,然后可能会有一名入学日期为2014年的学生,依此类推。

我想说的是,数据输入不会按年分类,因此无法每年重置自动增量字段。

每年每个州的顺序必须保持开放或永远不变。

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

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

结构

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

1 个答案:

答案 0 :(得分:0)

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

首先创建一个主表来填充学生记录;这仅使用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的字段。通过以这种方式设计它,您可以实现一个简单的方法来实现递归函数,该函数将根据每个引用的identifier记录处理​​student_id字段的顺序值。哦,我改变了年份代码以处理INT(4)(y2k bug)&将七位数标识符扩展为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;

现在是一个递归函数,用于组合并确定identifier + state + year每个组合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;
}
?>

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