我正在开发一个学生数据库项目,我必须生成一个基于模式的唯一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。
答案 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;
}
?>
不是我最好的工作,但它应该让你开始使用解决方案