重新整理AUTO_INCREMENT字段

重新整理AUTO_INCREMENT字段

2016-01-21 Netkiller Netkiller

节选择《Netkiller MySQL 手札》

 

13.9. 重新整理AUTO_INCREMENT字段

AUTO_INCREMENT 并非按照我们意愿,顺序排列,经常会跳过一些数字,例如当插入失败的时候,再次插入会使用新的值。有时会造成浪费,我们可以使用下面SQL重新编排AUTO_INCREMENT序列。

SET @newid=0;
UPDATE mytable SET id = (SELECT @newid:=@newid+ 1);		

使用max()查看最大值,然后使用 alter修改起始位置。

select max(id) from mytable;
ALTER TABLE mytable AUTO_INCREMENT = 1000;
		

注意外键,需要 ON UPDATE CASCADE 支持,否则无法更新。CONSTRAINT `FK_group_has_contact_contact` FOREIGN KEY (`contact_id`) REFERENCES `contact` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,

CREATE TABLE `contact` (
	`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '唯一ID',
	`name` VARCHAR(50) NOT NULL COMMENT '姓名',
	`mobile` VARBINARY(32) NULL DEFAULT NULL COMMENT '手机号码',
	`email` VARBINARY(50) NULL DEFAULT NULL COMMENT '电子邮件',
	`mobile_digest` VARCHAR(32) NULL DEFAULT NULL COMMENT '摘要',
	`email_digest` VARCHAR(32) NULL DEFAULT NULL COMMENT '邮件摘要',
	`birthday` DATE NULL DEFAULT NULL COMMENT '生日',
	`description` VARCHAR(255) NULL DEFAULT NULL COMMENT '备注描述',
	`status` ENUM('Subscription','Unsubscribe') NOT NULL DEFAULT 'Subscription' COMMENT '订阅状态',
	`ctime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
	`mtime` TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
	PRIMARY KEY (`id`),
	UNIQUE INDEX `digest` (`mobile_digest`, `email_digest`)
)
COMMENT='会员手机短信与电子邮件映射表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=43642;

CREATE TABLE `group` (
	`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(50) NOT NULL,
	`description` VARCHAR(512) NOT NULL,
	`ctime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`),
	UNIQUE INDEX `name` (`name`)
)
COMMENT='短信分组'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=8;

CREATE TABLE `group_has_contact` (
	`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`group_id` INT(10) UNSIGNED NOT NULL,
	`contact_id` INT(10) UNSIGNED NOT NULL,
	`ctime` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`),
	UNIQUE INDEX `group_contact` (`group_id`, `contact_id`),
	INDEX `FK_group_has_contact_contact` (`contact_id`),
	CONSTRAINT `FK_group_has_contact_contact` FOREIGN KEY (`contact_id`) REFERENCES `contact` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
	CONSTRAINT `FK_group_has_contact_group` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COMMENT='N:M'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=55764;
时间: 2024-10-07 10:38:22

重新整理AUTO_INCREMENT字段的相关文章

【整理】MySQL 之 日志

MySQL 中的各种日志文件  1. 错误日志 --log-error[=file_name]       错误日志记录了 mysql server 运行过程中所有较为严重的警告和错误信息,以及 mysql 每次启动和关闭的详细信息.       错误日志默认放在数据目录下,以 hostname.err 命名.但是可以使用命令 --log-error[=file_name] 修改其存放目录和文件名.       有时候,希望将错误日志做备份并重新开始记录,使用 flush logs 命令备份文件

mysql auto_increment 与 联合主键冲突问题

mysql 5.5之前,auto_increment字段必须为主键,有的时候,这种自增字段,并没有多大的实际意义,而我们需要多个字段组成主键. 例如: 用户只能对购买的商品,进行一次评价,评价的自增ID,没什么用处,用户的ID和商品ID组成的联合主键,意义就大的多了.如果想保留auto_increment字段,就要使用高版本的mysql了. mysql> ALTER TABLE `order` DROP PRIMARY KEY ,ADD PRIMARY KEY ( `user_id` , `or

mysql数据库如何设置一个字段不重复,一个字段自增?

问题描述 mysql数据库如何设置一个字段不重复,一个字段自增? 如题. mysql数据库如何设置一个字段不重复,一个字段自增? 解决方案 CREATE TABLE t_user (Id int(11) NOT NULL AUTO_INCREMENT, -- 自增username varchar(18) NOT NULL unique, -- 唯一性约束password varchar(18) NOT NULL, PRIMARY KEY (Id) ) ENGINE=InnoDB AUTO_INC

mysql中null,not null,default,auto_increment详解

NULL 和 NOT NULL 修饰符: 可以在每个字段后面都加上这NULL 或 NOT NULL 修饰符来指定该字段是否可以为空(NULL),还是说必须填上数据(NOT NULL).MySQL默认情况下指定字段为NULL修饰符,如果一个字段指定为NOT NULL,MySQL则不允许向该字段插入空值(这里面说的空值都为NULL),因为这是"龟定".  代码如下 复制代码 /* 创建好友表,其中id ,name ,pass都不能为空 */ create table friends ( i

mysql dba系统学习(6)二进制日志之二

MySQL 5.5 中对于二进制日志 (binlog) 有 3 种不同的格式可选:Mixed,Statement,Row,默认格式是 Statement.总结一下这三种格式日志的优缺点. MySQL Replication 复制可以是基于一条语句 (Statement Level) ,也可以是基于一条记录 (Row Level),可以在 MySQL 的配置参数中设定这个复制级别,不同复制级别的设置会影响到 Master 端的 bin-log 日志格式. 1. Row 日志中会记录成每一行数据被修

深度分析:找到MySQL的优点

第一步--安装MySQL 到http://dev.mysql.com/downloads/ 下载这个服务器.MySQL GUI工具和MySQL ODBC驱动.你可以选择的服务器有:5.0, 5.1或6.0.然后安装它们. 安装过程中的注意事项: 你的防火墙应该设置为允许通过3306端口连接. 将MySQL作为一个服务来运行(可以选择命令行方式). MySQL安装默认username/login = root和server = localhost. MySQL提供了对存储引擎/表类型的选择--主要

MySQL中在查询结果集中得到记录行号的方法

 如果需要在查询语句返回的列中包含一列表示该条记录在整个结果集中的行号, ISO SQL:2003 标准提出的方法是提供 ROW_NUMBER() / RANK() 函数. Oracle 中可以使用标准方法(8i版本以上),也可以使用非标准的 ROWNUM : MS SQL Server 则在 2005 版本中提供了 ROW_NUMBER() 函数:但在MySQL 中似乎还没有这样的系统自带功能.虽然 LIMIT 可以很方便的对返回的结果集数量和位置进行过滤,但过滤出来的记录的行号却没办法被 S

我的MYSQL学习心得(一) 简单语法

使用MYSQL有一段时间了,由于公司使用SQLSERVER和MYSQL,而且服务器数量和数据库数量都比较多 管理起来比较吃力,在学习MYSQL期间我一直跟SQLSERVER进行对比   第一期主要是学习MYSQL的基本语法,陆续还有第二.第三.第四期,大家敬请期待o(∩_∩)o  语法的差异 我这里主要说语法的不同 1.默认约束 区别:mysql里面DEFAULT关键字后面是不用加括号的 --sqlserver CREATE TABLE emp ( id INT DEFAULT(12) ) --

MySQL/MariaDB的binlog二进制日志模式及删除方法

有时候会发现binlog突然间变得的很大,导致磁盘分区都满了,这时候就需首先需要对binlog做清除,清除binlog时,如果有一个活性的从属服务器,该服务器当前正在读取您正在试图删除的日志之一,则本语句不会起作用,而是会失败,并伴随一个错误.不过,如果从属服务器是休止的,并且您碰巧清理了其想要读取的日志之一,则从属服务器启动后不能复制.当从属服务器正在复制时,本语句可以安全运行.您不需要停止它们,当然清除binlog只是临时的动作,我更应该需要查出是什么东西导致了binlog的猛然增长.这个可