我自己记得起来就一直在使用LAMP(Linux+Apache+MySQL+PHP)进行开发。但是有一个问题困扰了我多年。希望你能帮我找到答案并指引我正确的方向。以下是我的挑战:
假设我们正在创建一个社区网站,允许用户注册。我们存储所有用户的MySQL表格如下:
CREATE TABLE `users` (
`uid` int(2) unsigned NOT NULL auto_increment COMMENT 'User ID',
`name` varchar(20) NOT NULL,
`password` varchar(32) NOT NULL COMMENT 'Password is saved as a 32-bytes hash, never in plain text',
`email` varchar(64) NOT NULL,
`created` int(11) unsigned NOT NULL default '0' COMMENT 'Timestamp of registration',
`updated` int(11) unsigned NOT NULL default '0' COMMENT 'Timestamp of profile update, e.g. change of email',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
因此,从这个片段中,您可以看到我们为每个新用户创建了一个独特且自动递增的“uid”字段。在每个良好和忠诚的社区网站上,我们需要为用户提供完全删除其个人资料的可能性,以便取消他们在我们社区的参与。
现在出现了我的问题。假设我们有3个注册用户:Alice(uid = 1),Bob(uid = 2)和Chris(uid = 3)。现在Bob想删除他的个人资料并停止使用我们的社区。如果我们从“users”表中删除Bob的个人资料,则他缺失的'uid'将会创建一个间隙,将永远不会再被填补。我认为这是uid浪费的巨大损失。我看到以下3种可能的解决方案:
1)将我们表中的“uid”字段容量从SMALLINT(int(2))增加到例如BIGINT(int(8)),并忽略一些uid将被浪费的事实。
2)引入新字段“is_deleted”,用于标记已删除的个人资料(但将它们保留在表中,而不是删除它们),以重新利用其uid为新注册用户所用。然后,该表看起来像这样:
CREATE TABLE `users` (
`uid` int(2) unsigned NOT NULL auto_increment COMMENT 'User ID',
`name` varchar(20) NOT NULL,
`password` varchar(32) NOT NULL COMMENT 'Password is saved as a 32-bytes hash, never in plain text',
`email` varchar(64) NOT NULL,
`is_deleted` int(1) unsigned NOT NULL default '0' COMMENT 'If equal to "1" then the profile has been deleted and will be re-used for new registrations',
`created` int(11) unsigned NOT NULL default '0' COMMENT 'Timestamp of registration',
`updated` int(11) unsigned NOT NULL default '0' COMMENT 'Timestamp of profile update, e.g. change of email',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
3)编写一个脚本,在删除先前的记录后,将所有以下用户记录移位。例如,在我们的情况下,当Bob(uid = 2)决定删除他的个人资料时,我们将用Chris(uid = 3)的记录替换他的记录,以便Chris的uid变为2,并将Chris的旧记录标记为“1”为空闲状态供新用户使用。在这种情况下,我们保持uid的时间顺序按照注册时间进行排序,以便较早的用户具有较低的uid。
请告诉我现在处理auto_increment字段中间空缺的正确方法。这只是用户的一个示例,但这种情况在我的编程经验中经常发生。
提前感谢!