mysql自增字段怎么取 mysql 自增

如何获取Mysql里面auto increment的字段值

1、创建表格时添加: create table table1(id int auto_increment primary key,…)

创新互联建站专业为企业提供南江网站建设、南江做网站、南江网站设计、南江网站制作等企业网站建设、网页设计与制作、南江企业网站模板建站服务,10多年南江做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。

2、创建表格后添加: alter table table1 add id int auto_increment primary key 自增字段,一定要设置为primary key.

附:mysql 中的alter table mysql alter table employee change depno depno int(5) not null;

加索引 mysql alter table 表名 add index 索引名 (字段名1[,字段名2 …]);

例子: mysql alter table employee add index emp_name (name);

加主关键字的索引 mysql alter table 表名 add primary key (字段名);

例子: mysql alter table employee add primary key(id);

加唯一限制条件的索引 mysql alter table 表名 add unique 索引名 (字段名);

例子: mysql alter table employee add unique emp_name2(cardnumber);

查看某个表的索引 mysql show index from 表名; 例子: mysql show index from employee;

删除某个索引 mysql alter table 表名 drop index 索引名; 例子: mysqlalter table employee drop index emp_name;

修改表:增加字段:mysql ALTER TABLE table_name ADD field_name field_type;

查看表:mysql SELECT * FROM table_name;

修改原字段名称及类型:mysql ALTER TABLE table_name CHANGE old_field_name new_field_name field_type;

删除字段:ALTER TABLE table_name DROP field_name;

一文让你彻底弄懂MySQL自增列

MYSQL的自增列在实际生产中应用的非常广泛,相信各位所在的公司or团队,MYSQL开发规范中一定会有要求尽量使用自增列去充当表的主键,为什么DBA会有这样的要求,各位在使用MYSQL自增列时遇到过哪些问题?这些问题是由什么原因造成的呢?本文由浅入深,带领大家彻底弄懂MYSQL的自增机制。

1.  通过auto_increment关键字来指定自增的列,并指定自增列的初始值为1。

[root@localhost][test1]Create table t(id int auto_increment ,namevarchar(10),primary key(id))auto_increment=1;

QueryOK, 0 rows affected (0.63 sec)

2.  自增列上必须有索引,将t表的主键索引删除掉,会报错

[root@localhost][test1]alter table t drop primary key;

ERROR1075 (42000): Incorrect table definition; there can be only one auto column andit must be defined as a key

3.  设定auto_increment_increment参数,可以调整自增步长,该参数有session级跟global级,在分库分表以及双主or多主的模式下比较有用。

4.  一个表上只能有一个自增列

5.  Mysql5.7及以下版本,innodb表的自增值保存在内存中,重启后表的自增值会设为max(id)+1,而myisam引擎的自增值是保存在文件中,重启不会丢失。Mysql8.0开始,innodb的自增id能持久化了,重启mysql,自增ID不会丢。

首先:表中自增列的上限是根据自增列的字段类型来定的。

若设定了自增id充当主键,当达到了自增id的上限值时,会发生什么样的事情呢?还是以上面创建的 t表为例, 先回顾它的表结构:

CREATETABLE `t` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(10) COLLATE utf8mb4_binDEFAULT NULL,

PRIMARY KEY (`id`)

)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

无符号的int类型,上限是2147483647。这里我们将表的自增值设为2147483647,再插入两行数据:

[root@localhost][test1]alter table t auto_increment=2147483647;

QueryOK, 0 rows affected (0.01 sec)

Records:0  Duplicates: 0  Warnings: 0

[root@localhost][test1]insert into t(name) values ('test');          

QueryOK, 1 row affected (0.01 sec)

[root@localhost][test1]insert into t(name) values ('test');

ERROR 1062 (23000): Duplicate entry '2147483647' for key 'PRIMARY'

可以看到,第一个插入没问题,因为自增列的值为2147483647,这是达到了上限,还没有超过,第二行数据插入时,则报出主键重复,在达到上限后,无法再分配新的更大的自增值,也没有从1开始从头分配,在这里表的auto_increment值会一直是2147483647。

对于写入量大,且经常删除数据的表,自增id设为int类型还是偏小的,所以我们为了避免出现自增id涨满的情况,这边统一建议自增id的类型设为unsigned bingint,这样基本可以保障表的自增id是永远够用的。

这里内容比较多,innodb是索引组织表,所以涉及到索引的知识,但这不是本文的重点,我们快速回顾索引知识:

1.  Innodb索引分为主键跟辅助索引,主键即全表,辅助索引叶子节点保存主键的值,而主键的叶子节点保存数据行,中间节点存着叶子节点的路由值。

2.  Innodb存储数据(索引)的单位是页,这里默认是16K,这也意味着,数据本身越小,一个页中能存数据的量越多,而检索效率不仅仅由索引的层数来决定,更是由一次能够缓存的数据量来定,也就是说数据本身越小,则一次IO能够提取到缓冲区的数据越多(OS每次IO的量是固定的4K),查询的效率越好。

其实能够理解索引的结构及索引写入插入、更新的原理,则自然就明白为何建议使用自增id。这里我直接列出使用自增id 当主键的好处吧:

1.  顺序写入,避免了叶的分裂,数据写入效率好

2.  缩小了表的体积,特别是相比于UUID当主键,甚至组合字段当主键时,效果更明显

3.  查询效率好,原因就是我上面说到索引知识的第二点。

4.  某些情况下,我们可以利用自增id来统计大表的大致行数。

5.  在数据归档or垃圾数据清理时,也可方便的利用这个id去操作,效率高。

容易出现不连续的id

有的同志会发现,自己的表中id值存在空洞,如类似于1、2、3、8、9、10这样,有的适合有想依赖于自增id的连续性来实现业务逻辑,所以会想方设法去修改id让其变的连续,其实,这是没有必要的,这一块的业务逻辑交由MySQL实现是很不理智的,表的记录小还好,要是表的数据量很大,修改起来就糟糕了。那么,为什么自增id会容易出现空洞呢?

自增id的修改机制如下:

在MySQL里面,如果字段id被定义为AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:

1. 如果插入数据时id字段指定为0、null 或未指定值,那么就把这个表当前的

AUTO_INCREMENT值填到自增字段;

2. 如果插入数据时id字段指定了具体的值,就直接使用语句里指定的值。

根据要插入的值和当前自增值的大小关系,自增值的变更结果也会有所不同。假设,某次要插入的值是X,当前的自增值是Y。

1. 如果XY,那么这个表的自增值不变;

2. 如果X≥Y,就需要把当前自增值修改为 新的自增值 。

新的自增值生成算法是:从auto_increment_offset开始,以auto_increment_increment为步长,持续叠加,直到找到第一个大于X的值,作为新的自增值。

Insert、update、delete操作会让id不连续。

Delete、update:删除中间数据,会造成空动,而修改自增id值,也会造成空洞(这个很少)。

Insert:插入报错(唯一键冲突与事务回滚),会造成空洞,因为这时候自增id已经分配出去了,新的自增值已经生成,如下面例子:

[root@localhost][test1] select * fromt;

+----+------+

| id | name |

+----+------+

|  1| aaa  |

|  2| aaa  |

|  3| aaa  |

|  4| aaa  |

+----+------+

4 rows in set (0.00 sec)

[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';

+----------------+

| Auto_increment |

+----------------+

|              5 |

+----------------+

1 row in set (0.00 sec)

[root@localhost][test1] begin;

Query OK, 0 rows affected (0.00 sec)

[root@localhost][test1] insert intot(name) values('aaa');

Query OK, 1 row affected (0.00 sec)

[root@localhost][test1] select * fromt;

+----+------+

| id | name |

+----+------+

|  1| aaa  |

|  2| aaa  |

|  3| aaa  |

|  4| aaa  |

|  5| aaa  |

+----+------+

5 rows in set (0.00 sec)

[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';

+----------------+

| Auto_increment |

+----------------+

|              6 |

+----------------+

1 row in set (0.00 sec)

[root@localhost][test1] rollback;

Query OK, 0 rows affected (0.00 sec)

[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';

+----------------+

| Auto_increment |

+----------------+

|              6 |

+----------------+

1 row in set (0.01 sec)

[root@localhost][test1] select * fromt;

+----+------+

| id | name |

+----+------+

|  1| aaa  |

|  2| aaa  |

|  3| aaa  |

|  4| aaa  |

+----+------+

4 rows in set (0.00 sec)

可以看到,虽然事务回滚了,但自增id已经回不到从前啦,唯一键冲突也是这样的,这里就不做测试了。

在批量插入时(insert select等),也存在空洞的问题。看下面实验:

[root@localhost][test1] select * fromt;

+----+------+

| id | name |

+----+------+

|  1| aaa  |

|  2| aaa  |

|  3| aaa  |

|  4| aaa  |

+----+------+

4 rows in set (0.00 sec)

[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';

+----------------+

| Auto_increment |

+----------------+

|              5 |

+----------------+

1 row in set (0.00 sec)

[root@localhost][test1] insert intot(name) select name from t;                      

Query OK, 4 rows affected (0.04 sec)

Records: 4 Duplicates: 0  Warnings: 0

[root@localhost][test1] select * fromt;

+----+------+

| id | name |

+----+------+

|  1| aaa  |

|  2| aaa  |

|  3| aaa  |

|  4| aaa  |

|  5| aaa  |

|  6| aaa  |

|  7| aaa  |

|  8| aaa  |

+----+------+

8 rows in set (0.00 sec)

[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';

+----------------+

| Auto_increment |

+----------------+

|             12 |

+----------------+

1 row in set (0.00 sec)

可以看到,批量插入,导致下一个id值不为9了,再插入数据,即产生了空洞,这里是由mysql申请自增值的机制所造成的,MySQL在批量插入时,若一个值申请一个id,效率太慢,影响了批量插入的速度,故mysql采用下面的策略批量申请id。

1.  语句执行过程中,第一次申请自增id,会分配1个;

2.  1个用完以后,这个语句第二次申请自增id,会分配2个;

3.  2个用完以后,还是这个语句,第三次申请自增id,会分配4个;

4.  依此类推,同一个语句去申请自增id,每次申请到的自增id个数都是上一次的两倍。

在对自增列进行操作时,存在着自增锁,mysql的innodb_autoinc_lock_mode参数控制着自增锁的上锁机制。该参数有0、1、2三种模式:

0:语句执行结束后释放自增锁,MySQL5.0时采用这种模式,并发度较低。

1:mysql的默认设置。普通的insert语句申请后立马释放,insert select、replace insert、load data等批量插入语句要等语句执行结束后才释放,并发读得到提升

2:所有的语句都是申请后立马释放,并发度大大提升!但是在binlog为statement格式时,主从数据会发生不一致。这一块网上有很多介绍,我不做介绍了。

在彻底了解了MYSQL的自增机制以后,在实际生产中就能灵活避坑,这里建议不要用自增id值去当表的行数,当需要对大表准确统计行数时,可以去count(*)从库,如果业务很依赖大表的准确行数,直接弄个中间表来统计,或者考虑要不要用mysql的innodb来存储数据,这个是需要自己去权衡。另外对于要求很高的写入性能,但写入量又比较大的业务,自增id的使用依然存在热点写入的问题,存在性能瓶颈,这时候可通过分库分表来解决。

如何获得mysql数据库自增长主键的值?

this.employee_id = employee_id;}} 其它几个属性的getter和setter省略,这里我们要用到ejb3-persistence.jar,JPA的注解类就在这个包中,下面详细说明上面使用到的注解。 @Entity:通过@Entity注解将一个类声明为一个实体bean @Table:通过 @Table注解可以为实体bean映射指定表,name属性表示实体所对应表的名称,如果没有定义 @Table,那么系统自动使用默认值:实体的类名(不带包名) @Id:用于标记属性的主键 @Column:表示持久化属性所映射表中的字段,如果属性名与表中的字段名相同,则可以省略@Column注解,另外有两种方式标记,一是放在属性前,另一种是放在getter方法前,例如: @Column(name = EMPLOYEE_NAME) private String employee_name; 或者 @Column(name = EMPLOYEE_NAME) public String getEmployee_name() { return employee_name; } 这两种方式都是正解的,根据个人喜好来选择。大象偏向于第二种,并且喜欢将属性名与字段名设成一样的,这样可以省掉@Column注解,使代码更简洁。 @TableGenerator:表生成器,将当前主键的值单独保存到一个数据库表中,主键的值每次都是从指定的表中查询来获得,这种生成主键的方式是很常用的。这种方法生成主键的策略可以适用于任何数据库,不必担心不同数据库不兼容造成的问题。大象推荐这种方式管理主键,很方便,集中式管理表的主键,而且更换数据库不会造成很大的问题。各属性含义如下: name:表示该表主键生成策略的名称,这个名字可以自定义,它被引用在@GeneratedValue中设置的generator值中 table:表示表生成策略所持久化的表名,说简单点就是一个管理其它表主键的表,本例中,这个表名为GENERATOR_TABLE pkColumnName:表生成器中的列名,用来存放其它表的主键键名,这个列名是与表中的字段对应的 pkColumnValue:实体表所对应到生成器表中的主键名,这个键名是可以自定义滴 valueColumnName:表生成器中的列名,实体表主键的下一个值,假设EMPLOYEE表中的EMPLOYEE_ID最大为2,那么此时,生成器表中与实体表主键对应的键名值则为3 allocationSize:表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50@GeneratedValue:定义主键生成策略,这里因为使用的是TableGenerator,所以,主键的生成策略为GenerationType.TABLE,生成主键策略的名称则为前面定义的”tab-store”。 这里大象想说下,网上有很多文章写的是strategy = GenerationType.AUTO或是strategy = GenerationType.SEQUENCE,采用SEQUENCE序列是因为Oracle数据中不支持identity自动增长,要想使用它,还得在数据库中创建一个序列,如果要更换数据库,那将是一个非常麻烦的事情。SEQUENCE生成方式我们暂且不谈,这里说下采用AUTO和IDENTITY的生成方式,本例采用的是SQL Server 2000作为数据库,所以如果想使用AUTO或是IDENTITY生成策略,则一定要对主键加上identity标识,如identity(1,1)。不过对于AUTO来说,是根据不同的数据库选择最合适的自增主键生成策略。如果使用MySQL,则主键要定义AUTO_INCREMENT,如果是Oracle,则要创建Sequence来实现自增。不管采用何种生成策略,增、删、改这些方法中一定要加入事务,否则数据是不会添加到数据库中滴~~~这是大象反复测试过的结果!


网页名称:mysql自增字段怎么取 mysql 自增
链接分享:http://bzwzjz.com/article/dddiisd.html

其他资讯

Copyright © 2007-2020 广东宝晨空调科技有限公司 All Rights Reserved 粤ICP备2022107769号
友情链接: 成都商城网站建设 成都网站建设 成都网站设计 四川成都网站建设 高端网站设计 品牌网站建设 网站建设方案 成都网站设计 网站建设公司 网站建设公司 企业网站设计 高端网站建设 专业网站设计 重庆网站建设 成都网站建设公司 重庆企业网站建设 外贸网站建设 重庆网站制作 企业网站建设 成都网站设计公司 企业网站设计 网站建设公司