-2

我正在研究一个学生数据库项目,我必须生成一个基于模式的唯一 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。

4

1 回答 1

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 字段的一对一中间表。identifier通过以这种方式设计它,您可以使用一种简单的方法来实现递归函数,该函数将根据每个引用的student_id记录处理字段的顺序值。哦,我更改了年份代码以处理INT(4)(y2k 错误很多)并将七位数标识符扩展为 aBIGINT以处理增长。

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每个组合的最后一个数值。stateyearidentifier

<?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;
}
?>

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

于 2015-10-17T19:35:20.413 回答