将一张表的主键(ID)重置为从1开始自增排列

当表的主键ID不再连续时,可以通过在表中新增字段复制ID,删除旧ID字段,新建并设置新ID为主键自增,最后删除临时字段并调整新ID位置来重置ID。同时对比了Mysql中truncate和delete清空表数据的区别,truncate速度更快且不记录日志,适合全量删除,而delete则会记录日志,适合删除部分数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果你有一张表,你的主键是ID,然后由于测来测去的原因,你的ID不是从1开始连续的自增了。

终于有一天,使用这张表的某个系统要导入正式数据了,强迫症这时候就表现的明显了,浑身不自在,

这时候你就需要将这个主键ID重置一波了,方法是在这张表中新增一个字段,将ID里面的数据复制过去,

然后删除ID字段,接着新建一个ID字段,再接着将id字段自增且设为主键,最后将这个新增的ID列挪到第一列,

将那个用于复制最初ID内容的新增字段删除,一切OK.

1、在要操作的表 tablename 中新增一个字段 old_id;

     alter table  tablename  add old_id int(10) not null;

2、将 id 字段的数据复制给 old_id;

      update tablename set old_id=id;

3、删除 id 字段;

  alter table tablename drop id;

4、新增一个 id 字段;

  alter table tablename add id int(10) not null;

5、将这个新增的 id 字段设置为自增主键;

  alter table tablename modify column id int(10) not null auto_increment, add primary key (id);

6、删除 old_id 列;

  alter table tablename drop column old_id;

7、将最新的 id 列挪到最前面;

  alter table tablename modify id int(10) first;  

 

 

 

 

 

 

 

 

 

 

1.如果2张表的字段一致,并且希望插入全部数据,可以用这种方法:

INSERT INTO 目标表 SELECT * FROM 来源表;
    insert into insertTest select * from insertTest2;

2.如果只希望导入指定字段,可以用这种方法:

INSERT INTO 目标表 (字段1, 字段2, ...) SELECT 字段1, 字段2, ... FROM 来源表;(这里的话字段必须保持一致)
   insert into insertTest2(id) select id from insertTest2;

3.如果您需要只导入目标表中不存在的记录,可以使用这种方法:

复制代码

INSERT INTO 目标表  
 (字段1, 字段2, ...)  
 SELECT 字段1, 字段2, ...  
 FROM 来源表  
 WHERE not exists (select * from 目标表  
 where 目标表.比较字段 = 来源表.比较字段); 

复制代码

 1>.插入多条记录:

复制代码

insert into insertTest2
(id,name)
select id,name
from insertTest
where not exists (select * from insertTest2
where insertTest2.id=insertTest.id);

复制代码

 2>.插入一条记录:

复制代码

insert into insertTest    
(id, name)    
SELECT 100, 'liudehua'    
FROM dual    
WHERE not exists (select * from insertTest    
where insertTest.id = 100);

复制代码

 

Mysql清空表(truncate)与删除表中数据(delete)的区别

 

为某基于wordpress搭建的博客长久未除草,某天升级的时候发现已经被插入了几万条垃圾留言,如果一条条删除那可真是累人的活。遂考虑直接进入mysql直接清空表或者删除表中数据。

本文记录一下这2种操作模式的区别,目标对象是表wp_comments,里面的所有留言均是垃圾留言,均可删除。然后便有了以下2种方式(进入mysql操作界面后):

  1. truncate table wp_comments;
  2. delete * from wp_comments;

其中truncate操作中的table可以省略,delete操作中的*可以省略。这两者都是将wp_comments表中数据清空,不过也是有区别的,如下:

  • truncate是整体删除(速度较快), delete是逐条删除(速度较慢)。
  • truncate不写服务器log,delete写服务器log,也就是truncate效率比delete高的原因。
  • truncate不激活trigger(触发器),但是会重置Identity(标识列、自增字段),相当于自增列会被置为初始值,又重新从1开始记录,而不是接着原来的ID数。而delete删除以后,Identity依旧是接着被删除的最近的那一条记录ID加1后进行记录。
  • 如果只需删除表中的部分记录,只能使用DELETE语句配合where条件。 DELETE FROM wp_comments WHERE……

全文完。

<think>我们参考用户提供的引用资料,特别是引用[2]和引用[3]中的方法,来实现在没有主键中新主键并对所有字段进行排序。 步骤: 1. 备份原(结构和数据) 2. 创建一个新,结构类似于原,但加一个主键字段(自) 3. 将原的数据插入到新中(此时主键字段会自动生成) 4. 删除原 5. 将新重命名为原名 但是,用户还要求“对所有字段进行排序”。这里需要注意,数据库中的记录本身是无序的,我们通常通过ORDER BY子句来排序。如果用户希望数据按照某种顺序存储(虽然这通常不是必要的,因为查询时排序更常见),我们可以通过插入数据时按指定顺序插入来实现。 然而,在InnoDB中,的数据存储顺序通常由主键决定(聚集索引)。因此,如果我们按照某个字段的顺序插入数据,并且该是使用主键作为聚集索引,那么数据在物理存储上会按照主键顺序排列。但实际应用中,我们更关注查询时的排序。 所以,我们可以这样理解用户的需求: 1. 添加一个自主键(这样主键值就是顺序的,并且物理存储会按照主键顺序) 2. 如果用户希望数据按照其他字段排序,那么可以在插入新时使用ORDER BY,这样自主键就会按照那个顺序生成,从而在物理存储上接近该顺序(但注意,自主键是连续的,但物理存储顺序可能因为后续的删除和插入而改变,所以通常不依赖物理顺序)。 但是,引用[2]中并没有在插入数据时排序,而是直接插入。因此,我们可以在插入数据时使用ORDER BY来按照用户指定的字段排序,这样生成的主键就会按照这个顺序递,从而在物理存储上大致按照该顺序(聚集索引按主键排序)。 具体步骤: 假设原名为`student`,我们想要按照字段`name`进行排序(这里只是示例,用户可以根据需要选择排序字段)。 步骤: 1. 备份结构:创建新,结构同原,并加一个自主键字段(放在第一列)。 2. 备份数据:将原的数据按照指定字段(如`name`)排序后插入新(这样新主键会按照排序顺序生成)。 3. 删除原。 4. 重命名新为原名。 注意:如果中有外键约束,操作会复杂一些,需要先删除外键约束,操作完再添加。这里假设没有外键约束。 具体SQL操作: 1. 创建新(结构同原,并加自主键): ```sql CREATE TABLE new_student LIKE student; ``` 2. 修改新,删除原有的主键(如果有的话,但原没有主键,所以可能没有)并添加新的自主键字段(例如`id`)作为第一个字段: ```sql ALTER TABLE new_student DROP PRIMARY KEY; -- 如果原主键(但用户说没有,所以可能不需要),但为了安全,如果原主键约束,则删除 ALTER TABLE new_student ADD id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST; ``` 但是,由于原没有主键,第一步创建的新也不会有主键,所以我们可以直接添加主键字段。 然而,引用[2]中先创建了一个相同结构的(没有主键),然后删除可能存在的字段(这里假设原没有主键字段,所以不需要删除),然后添加自主键字段。 3. 插入数据,并按照指定字段排序(例如按照`name`字段升序): ```sql INSERT INTO new_student (col1, col2, ...) SELECT col1, col2, ... FROM student ORDER BY name; -- 这里按照name排序,其他字段按需列出 ``` 注意:这里需要列出原的所有字段(除了新id字段,因为id是自的,不需要插入值)。 4. 删除原: ```sql DROP TABLE student; ``` 5. 重命名新: ```sql ALTER TABLE new_student RENAME TO student; ``` 但是,上述步骤中,第一步创建的结构是原结构(没有主键),然后我们添加了主键字段。在插入数据时,我们按照指定字段排序,这样新中的数据就会按照排序顺序生成自主键,从而在物理存储上大致按照该顺序(因为主键是递的,聚集索引会按主键顺序存储)。 然而,引用[2]中的步骤是先备份结构和数据,然后在新中删除可能存在的旧主键字段,再添加新的自主键字段。但原没有主键,所以可以省略删除主键字段的步骤。 另外,引用[4]中提到排序字段的设计问题,但这里我们使用自主键作为排序的依据,并且由于主键是自的,每次插入都会递,所以删除记录后再插入,新记录的主键会继续递,不会重复使用已删除的主键值。这样,物理存储顺序会按照主键顺序,而主键顺序就是我们插入时的顺序(即我们指定的排序顺序)。 但是,如果用户希望以后插入数据时也能自动排序,那么需要在插入数据时指定位置(比如在中间插入),但自主键无法在中间插入,所以通常我们会让新插入的数据排在最后(自主键的最大值)。如果用户需要动态调整顺序,可能需要额外的排序字段(如一个位置字段),并在每次插入或移动时更新该字段,然后根据这个字段排序(引用[4]中讨论的排序字段设计)。但用户当前需求是“对所有字段进行排序”,可能只是希望初始时按照某个顺序,所以上述方法可以满足。 注意:在执行这些操作前,请务必备份整个数据库,以防操作失误。 下面是一个具体的例子: 假设原`student`有字段:`name`, `age`, `score`,没有主键。 步骤: 1. 创建新`new_student`,结构同原: ```sql CREATE TABLE new_student LIKE student; ``` 2. 在新中添加自主键字段`id`(放在第一列): ```sql ALTER TABLE new_student ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST; ``` 3. 将原数据按照`name`排序后插入新(注意:不插入idid会自动生成): ```sql INSERT INTO new_student (name, age, score) SELECT name, age, score FROM student ORDER BY name; -- 按照name升序排序 ``` 4. 删除原: ```sql DROP TABLE student; ``` 5. 重命名新: ```sql ALTER TABLE new_student RENAME TO student; ``` 这样,`student`就有主键`id`,并且数据按照`name`排序后插入,所以主键值从1开始,且物理存储大致按照`name`的顺序(因为主键顺序和插入顺序一致)。 注意:如果原数据量很大,插入操作可能会比较慢,并且会占用额外的磁盘空间。 另外,如果原有外键引用,那么需要先删除外键约束,完成后再重新添加。同时,如果有视图、存储过程等依赖于原,也需要重新创建。 因此,在实际操作中,建议在数据库维护时段进行,并确保有完整备份。 最后,生成相关问题:</think>### 在无主键中新主键并排序字段的实现步骤 #### 1. **备份原数据** ```sql -- 创建结构相同的备份 CREATE TABLE backup_table LIKE original_table; -- 复制数据到备份 INSERT INTO backup_table SELECT * FROM original_table; ``` > 📌 操作前务必备份数据,防止意外丢失[^2]。 --- #### 2. **添加自主键字段** ```sql -- 添加自主键列(作为第一列) ALTER TABLE original_table ADD COLUMN id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST; ``` > ✨ 主键特性: > - 唯一标识每条记录(`PRIMARY KEY`) > - 自动按插入顺序生成连续编号(`AUTO_INCREMENT`) > - 物理存储按主键值排序(聚集索引特性)[^3][^5] --- #### 3. **按需求排序字段** ```sql -- 重建数据(按指定字段排序) CREATE TABLE sorted_table LIKE original_table; -- 插入时按 name 字段升序排序 INSERT INTO sorted_table SELECT * FROM original_table ORDER BY name ASC; -- 替换为实际排序字段 ``` --- #### 4. **替换原并验证** ```sql -- 删除原 DROP TABLE original_table; -- 重命名排序后的 ALTER TABLE sorted_table RENAME TO original_table; -- 验证主键和排序 SHOW CREATE TABLE original_table; SELECT * FROM original_table LIMIT 10; ``` > ⚠️ **关键注意事项** > 1. **大操作**:数据量较大时建议分批操作,避免锁 > 2. **外键依赖**:若存在外键引用,需先解除约束 > 3. **自重置**:最后执行 `ALTER TABLE original_table AUTO_INCREMENT=1;` 重置计数 > 4. **排序逻辑**:物理存储顺序仅影响查询效率,业务排序仍需用 `ORDER BY`[^4] --- ### 主键设计建议(引用总结) | 方案 | 优点 | 缺点 | |---------------|-------------------------------|-------------------------------| | **自主键** | 高效易用,避免冲突[^5] | 分布式系统难扩展 | | **业务主键** | 天然唯一(如ISBN) | 字段较长影响索引效率 | | **组合主键** | 解决多维度唯一性 | 外键引用复杂 | > 推荐优先使用自主键,除非有明确业务标识需求[^1][^5] ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值