Answers:
您可以删除主键列并重新创建它。然后应按顺序重新分配所有ID。
但是,在大多数情况下,这可能不是一个好主意。如果您还有其他具有此表外键的表,则绝对不能使用。
即使这个问题似乎已经很老了,也将为到达此处搜索的人发布答案。
SET @count = 0;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;
如果该列在其他表中用作外键,请确保在这些表中使用外键关系ON UPDATE CASCADE
而不是默认值ON UPDATE NO ACTION
。
此外,为了重置AUTO_INCREMENT
计数,您可以立即发出以下语句。
ALTER TABLE `users` AUTO_INCREMENT = 1;
对于MySQL,它将值重置为MAX(id) + 1
。
.
id` = @count:= @count + 1` ,表达式的计算注定会以预定义的顺序发生。在文档中:“右侧的值可能是文字值,另一个存储值的变量或任何产生标量值的合法表达式”
要重置用户表的ID,请使用以下SQL查询。上面已经说过,这将破坏您与其他任何表的任何关系。
ALTER TABLE `users` DROP `id`;
ALTER TABLE `users` AUTO_INCREMENT = 1;
ALTER TABLE `users` ADD `id` int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
您可以简单地使用此查询
alter table abc auto_increment = 1;
SELECT * from `user` ORDER BY `user_id`;
SET @count = 0;
UPDATE `user` SET `user_id` = @count:= @count + 1;
ALTER TABLE `user_id` AUTO_INCREMENT = 1;
如果你想 order by
在phpmyadmin中
注意:如果您删除最后一行而不是中间行,这将起作用。
转到表格->单击操作菜单->转到表格选项->将AUTO_INCREMENT更改为您要从其开始的位置。
您的表自动增量从此开始。
您可以删除该列的主键自动递增功能,然后在每次更新该列时先进行查询,该查询将对表中的所有行进行计数,然后运行循环遍历该行计数的循环,将每个值插入到相应的行,最后运行查询以插入新行,该列的值为总行数加一。这将完美地工作,并且是尝试实现您的目标的人的绝对解决方案。这是您可以用于该函数的代码示例:
$table_row_count = mysql_result(mysql_query("SELECT COUNT(`field_1`) FROM `table`"), 0);
$viewsrowsdata = mysql_query("
SELECT `rank`, `field1`, `field2`, `field3`, `field4`
FROM (SELECT (@rank:=@rank+1) as `rank`, `field1`, `field2`, `field3`, `field4`
FROM (SELECT * FROM `views`) a
CROSS JOIN (SELECT @rank:=0) b
ORDER BY rank ASC) c
");
while ($row = mysql_fetch_assoc($viewsrowsdata)) {
$data[] = $row;
}
foreach ($data as $row) {
$new_field_1 = (int)$row['rank'];
$old_field_1 = (int)$row['field1'];
mysql_query("UPDATE `table` SET `field_1` = $new_field_1 WHERE `field_1` = $old_field_1");
}
mysql_query("INSERT INTO `table` (`field1`, `field2`, `field3`, `field4`) VALUES ('$table_row_count' + 1, '$field_2_value', 'field_3_value', 'field_4_value')");
在这里,我创建了一个关联数组,该数组已添加到选择查询中的查询的等级列上,该查询为每一行提供了一个以1开头的等级值。然后,我遍历了关联数组。
另一个选择是获取行数,运行基本的选择查询,获取关联数组并以相同的方式对其进行迭代,但要添加一个在每次迭代中都会更新的变量。这不太灵活,但会完成相同的操作。
$table_row_count = mysql_result(mysql_query("SELECT COUNT(`field_1`) FROM `table`"), 0);
$viewsrowsdata = mysql_query("SELECT * FROM `table`");
$updated_key = 0;
while ($row = mysql_fetch_assoc($viewsrowsdata)) {
$data[] = $row;
}
foreach ($data as $row) {
$updated_key = $updated_key + 1;
mysql_query("UPDATE `table` SET `field_1` = '$updated_key' WHERE `field_1` = '$row['field_1']'");
}
mysql_query("INSERT INTO `table` (`field1`, `field2`, `field3`, `field4`) VALUES ('$table_row_count' + 1, '$field_2_value', 'field_3_value', 'field_4_value')");
对于InnoDB,请执行以下操作(这将从表中删除所有记录,首先进行bakcup):
SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS ;
SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION ;
SET NAMES utf8 ;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 ;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 ;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' ;
SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 ;
/* ================================================= */
drop table tablename;
CREATE TABLE `tablename` (
table structure here!
) ENGINE=InnoDB AUTO_INCREMENT= ai number to reset DEFAULT CHARSET= char set here;
/* ================================================= */
SET SQL_MODE=@OLD_SQL_MODE ;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS ;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS ;
SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT ;
SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS ;
SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION ;
SET SQL_NOTES=@OLD_SQL_NOTES ;
我也有同样的疑问,但是无法在表上进行任何更改,因此,在看到我的ID未超过变量@count中设置的最大数目之后,我决定进行以下操作:
SET @count = 40000000;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;
SET @count = 0;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;
ALTER TABLE `users` AUTO_INCREMENT = 1;
该解决方案可以解决问题,但这是安全的,而且是必需的,因为我的表拥有外键,而另一个表中的数据也是如此。
我的意见是创建一个名为row_order的新列。然后重新排序该列。我不接受主键的更改。例如,如果订单列是banner_position,我已经做了类似的事情,这是为了删除,更新,创建标题位置列。调用此函数分别对其重新排序。
public function updatePositions(){
$offers = Offer::select('banner_position')->orderBy('banner_position')->get();
$offersCount = Offer::max('banner_position');
$range = range(1, $offersCount);
$existingBannerPositions = [];
foreach($offers as $offer){
$existingBannerPositions[] = $offer->banner_position;
}
sort($existingBannerPositions);
foreach($existingBannerPositions as $key => $position){
$numbersLessThanPosition = range(1,$position);
$freshNumbersLessThanPosition = array_diff($numbersLessThanPosition, $existingBannerPositions);
if(count($freshNumbersLessThanPosition)>0) {
$existingBannerPositions[$key] = current($freshNumbersLessThanPosition);
Offer::where('banner_position',$position)->update(array('banner_position'=> current($freshNumbersLessThanPosition)));
}
}
}
此作品- https://stackoverflow.com/a/5437720/10219008.....but如果你遇到一个问题“错误代码:1265年数据被截断为列‘’第1行”身份证......然后运行下列。在更新查询上添加忽略。
SET @count = 0;
set sql_mode = 'STRICT_ALL_TABLES';
UPDATE IGNORE web_keyword SET id = @count := (@count+1);
您也可以简单地避免使用数字ID作为主键。如果表格中包含国家/地区信息,则可以使用国家/地区代码作为主要ID;例如,如果表格中包含文章,则可以使用永久链接。
您也可以简单地使用随机值或MD5值。所有这些选项都有其自身的优势,特别是在IT sec方面。数字ID易于枚举。