zoukankan      html  css  js  c++  java
  • MYSQL培训准备(2):MYSQL自增长陷阱

        MYSQL中,在数据库中创建表的语法如下:

    1 CREATE TABLE tablename(
    2 column_name_1 column_type_1 constraints,
    3 column_name_2 column_type_2 constraints,
    4 ...
    5 column_name_n column_type_n constraints,
    6 PRIMARY KEY (column_name)
    7 );

        其中,tablename为表名,column_name为列名,column_type为列的数据类型,constraints为相关的约束条件。在所有的约束条件中,有一个AUTO_INCREMENT的条件,表示自增长列,根据设置的步长自动增长。

        今天我们聊聊MYSQL中的自增长列。
        在MS SQL SERVER中,我们知道自增长列是严格按照步长实现自动增长。而MYSQL中却有个则增长的陷阱。对于单条记录,一条一条insert into,确实是自增长的。但如果我们批量插入,自增长列就不是连续的。请看下面实例。

        首先,我们创建一张部门表,语句如下:

    CREATE TABLE `ivr`.`t_dept` (
      `f_id` INT Not NULL AUTO_INCREMENT,
      `f_areaid` INT NULL,
      `f_dept` VARCHAR(45) NULL,
      PRIMARY KEY (`f_id`));
    

        当我们逐条插入数据时,自增长列是连续的。如下:

    insert into t_dept(f_areaid,f_dept) values(2,'网优' );
    insert into t_dept(f_areaid,f_dept) values(2,'传输' );
    insert into t_dept(f_areaid,f_dept) select 2,'数据'; 
    insert into t_dept(f_areaid,f_dept) select 2,'家宽'; 
    

        查询结果如下:

    mysql> select * from t_dept;
    +------+----------+--------+
    | f_id | f_areaid | f_dept |
    +------+----------+--------+
    |    1 |        2 | 网优   |
    |    2 |        2 | 传输   |
    |    3 |        2 | 数据   |
    |    4 |        2 | 家宽   |
    +------+----------+--------+
    4 rows in set (0.00 sec)
    

        当我们批量插入时,问题就出现了,请看下面:

    insert into t_dept(f_areaid,f_dept) 
    select 3,'网优' 
    union
    select 3,'传输'; 
    

        结果如下:

    mysql> select * from t_dept;
    +------+----------+--------+
    | f_id | f_areaid | f_dept |
    +------+----------+--------+
    |    1 |        2 | 网优   |
    |    2 |        2 | 传输   |
    |    3 |        2 | 数据   |
    |    4 |        2 | 家宽   |
    |    5 |        3 | 网优   |
    |    6 |        3 | 传输   |
    +------+----------+--------+
    6 rows in set (0.00 sec)
    

        此时f_id还是连续的。当我们再插入记录时,问题出现的。

    insert into t_dept(f_areaid,f_dept) 
    select 3,'数据' 
    union
    select 3,'家宽' ;
    

        我们再看结果,7不见了:

    mysql> select * from t_dept;
    +------+----------+--------+
    | f_id | f_areaid | f_dept |
    +------+----------+--------+
    |    1 |        2 | 网优   |
    |    2 |        2 | 传输   |
    |    3 |        2 | 数据   |
    |    4 |        2 | 家宽   |
    |    5 |        3 | 网优   |
    |    6 |        3 | 传输   |
    |    8 |        3 | 数据   |
    |    9 |        3 | 家宽   |
    +------+----------+--------+
    8 rows in set (0.00 sec)
    

        为什么会出现这种情况呢,我查看了手册,MYSQL中,自增长列只保证字段的唯一性。当批量插入n条记录时,MYSQL需要n-1条记录缓存,此时会默认为插入了2n-1条记录,从而造成了记录的不连续性。

  • 相关阅读:
    JAVA中线程同步的方法(4种)汇总
    java
    指定的元素已经是另一个元素的逻辑子元素。请先将其断开连接。(解决问题总结)
    无法将类型为“System.Windows.Controls.SelectedItemCollection”的对象强制转换为类型“System.Collections.Generic.IList`1
    foreach---集合已修改;可能无法执行枚举操作。
    WPF_View中控件使用单例ViewModel
    判断s2是否能够被通过s1做循环移位(rotate)得到的字符串是否包含
    多列转1列 SqlServer 实现oracle10g的 wmsys.wm_concat()--for xml path('')
    异步对象(XMLHttpRequest)的帮助脚本
    在vs2010使用EF出现CS0012: 类型“System.Data.Objects.DataClasses.EntityObject”在未被引用的程序集中定义
  • 原文地址:https://www.cnblogs.com/haoge520/p/7216975.html
Copyright © 2011-2022 走看看