最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL自增列解析(Auto_increment)

 更新時間:2024年09月03日 08:33:41   作者:V1ncent Chen  
MySQL數(shù)據(jù)庫為列提供了一種自增屬性,本文主要介紹了MySQL自增列解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

MySQL數(shù)據(jù)庫為列提供了一種自增屬性,當(dāng)列被定義為自增時。Insert語句對該列即使不提供值,MySQL也會自動為該列生成遞增的唯一標(biāo)識,因此這個特性廣泛用于主鍵的自動生成。

一、自增列的用法

自增列具有自動生成序列值,整型,單調(diào)遞增這些特點,非常適合作為索引組織表的主鍵,新插入的數(shù)據(jù)會附加在已有的數(shù)據(jù)后面,不會出現(xiàn)頁分 裂現(xiàn)象,且整型的主鍵查找效率非常高。

1.1 基本用法

在創(chuàng)建表時,只需在某個整型列(tinyint,smallint, mediumint, int, bigint)上指定auto_increment,即可打開自增屬性。

一張表中只能指定一個自增列,且必須建立索引,示例中 id列沒有指定為索引列,建表報錯(must be defined as a key):

create table t2(
id int auto_increment,
name varchar(32));

在這里插入圖片描述

指定自增列為主鍵,創(chuàng)建成功:

create table t (
id int primary key auto_increment,
name varchar(32));

在這里插入圖片描述

插入數(shù)據(jù)時,即使insert語句未包含自增列,MySQL也會自動為該列生成值:

insert into t(name) values('Vincent'); -- 未指定id列
select * from t;

在這里插入圖片描述

如果指定了0或null,同樣也可以生成自增值:

insert into t values (0, 'Victor'), (null, 'Grace');  -- 指定0和null
select * from t;

在這里插入圖片描述

注意:由于0會觸發(fā)自增,如果ID列本來保存的數(shù)據(jù)就包含0,那么在數(shù)據(jù)導(dǎo)出和導(dǎo)入過程中,數(shù)字0可能會因此觸發(fā)自增而被修改,導(dǎo)致數(shù)據(jù)不一致。 這種情況可以打開sql_mode參數(shù)中的no_auto_value_on_zero選項(可以在會話和全局修改),打開該選項后,只有null可以觸發(fā)自增,0不再觸發(fā)。

set sql_mode=concat(@@session.sql_mode, ',no_auto_value_on_zero');
insert into t values(0, 'Tom');
select * from t;

在這里插入圖片描述

1.2 自增列特性

自增列除了讓其自動生成值之外,也可以顯式賦值,使用中注意以下幾點:

  • 顯式賦值可能導(dǎo)致大量值被浪費
  • 事務(wù)回滾不會回滾已使用的自增值
  • truncate table清除數(shù)據(jù)的同時也會讓自增值初始化
  • alter table … auto_increment=1 可以讓自增值恢復(fù)到最大可用值,消除間隙(并不會設(shè)定成1)

自增列可以顯式賦值,但如果指定的值超過目前auto_increment的最大值,則MySQL會從你指定的值之后開始繼續(xù)遞增,即使前面有可用的值也不再使用,示例中顯式指定id列為1000,那么下一條數(shù)據(jù)會從1001開始自增。

insert into t values(1000, 'Jerry');
insert into t values(null, 'Spike');

在這里插入圖片描述

事務(wù)中如果使用了自增值,即使回滾,自增值也不會恢復(fù),示例中的事務(wù)消耗了2個自增值(1002, 1003),然后事務(wù)回滾了,但是下一條insert語句自增值是從1004開始的:

begin;
insert into t values(null, 'Spike'); 
insert into t values(null, 'Spike');  
rollback;  -- 事務(wù)回滾
insert into t values(null, 'Tyke'); -- 自增值不會回滾
select * from t;

在這里插入圖片描述

示例刪除了id為1000及以上的數(shù)據(jù)后,使用alter table … auto_increment=1使自增值恢復(fù)到當(dāng)前數(shù)據(jù)的最大值:

delete from t where id>=1000;
alter table t auto_increment=1;
insert into t values(null, 'Jerry');
select * from t;

在這里插入圖片描述

1.3 通過last_insert_id()獲取自增值

MySQL提供了函數(shù)last_insert_id(),用于獲取上一個成功執(zhí)行的insert語句所生成的第一個自增值:

truncate table t;
insert into t values(null,'Vincent');
select last_insert_id();

在這里插入圖片描述

單一insert語句如果插入多行,獲取的是語句中第一個產(chǎn)生的自增值,而不是最后一個,下面insert語句插入了2條記錄,但last_insert_id()返回的是2而不是3(雖然表中id增長到3):

insert into t values(null,'Victor'),(null,'Grace');
select last_insert_id();
select * from t;

在這里插入圖片描述

如果在事務(wù)中手動回滾,last_insert_id()的值也是不會回滾的,其代表的是曾經(jīng)成功插入的自增值,而不判斷事務(wù)是否最終提交(有一定誤導(dǎo)性,不能用作判斷實際插入的值):

begin;
insert into t values(null,'Vincent');
insert into t values(null,'Vincent');  -- 成功插入,last_insert_id()為5
rollback;  -- 事務(wù)回滾
select last_insert_id();  -- last_insert_id()依然是5,但數(shù)據(jù)實際未插入

在這里插入圖片描述

last_insert_id(expr)還有個可選的參數(shù),如果提供參數(shù)expr,則會返回該值,并將expr記錄為下一個last_insert_id()的返回值:

select last_insert_id(100);
select last_insert_id();

在這里插入圖片描述

二、自增計數(shù)器

在MySQL8.0之前,對于auto_increment的值會在內(nèi)存中維護(hù)一個計數(shù)器(不保存在磁盤上),在服務(wù)器啟動時會對每張表執(zhí)行類似select max(auto_column) from t for update;語句獲取當(dāng)前表中的最大自增值,用于初始化這個計數(shù)器。

MySQL8.0以后,這個計數(shù)器的值會在每次變更時寫入重做日志和數(shù)據(jù)字典(保存到磁盤上)。服務(wù)器重啟時直接讀取數(shù)據(jù)字典即可,不必再通過查詢表初始化。

三、自增值生成模式

上面的都是單線程下自增值的生成示例,但在并發(fā)時,多個事務(wù)可能會同時向表中插入數(shù)據(jù),事務(wù)之間存在爭用。MySQL為并發(fā)場景下自增值的生成提供了3種不同的模式。3種模式由innodb_autoinc_lock_mode控制(只讀變量,修改需要重啟),對應(yīng)的值分別為0, 1, 2:

  • 0, 傳統(tǒng)模式(Traditional Lock Mode)
  • 1, 連續(xù)模式(Consecutive Lock Mode)
  • 2, 交錯模式(Interleaved Lock Mode)

在解釋3種模式的區(qū)別前,先了解一下insert語句的分類,insert語句可以分為以下3類:

  • 簡單插入(Simple Inserts),如單記錄insert,或者多記錄insert,在解析SQL時就可以確定要加載的記錄數(shù)(即要生成自增值數(shù)量)
  • 批量插入(Bulk Inserts),如insert … select, load data等,在解析SQL時不確定需要加載的記錄數(shù)
  • 混合插入(Mixed-Mode Inserts),在多記錄簡單插入中,為自增列顯式指定了部分值,如 insert into … values (null,‘a’), (5, ‘b’), (null, ‘c’)

3.1 傳統(tǒng)模式

在傳統(tǒng)模式下(innodb_autoinc_lock_mode=0),所有類型的insert都會使用表級X鎖,并且持有到insert語句結(jié)束,這意味著同一時間只有1條insert語句可以執(zhí)行,但可以保證單條insert語句產(chǎn)生的自增值是連續(xù)的。

在基于語句的主從復(fù)制(Statement-Based Replication)模式下insert語句在主從可以生成相同的值。傳統(tǒng)模式只是為了向前兼容,現(xiàn)在已經(jīng)不會使用了。

3.2 連續(xù)模式

連續(xù)模式(innodb_autoinc_lock_mode=1)是對傳統(tǒng)模式的優(yōu)化,對于批量插入這種不確定需要需要多少自增值的insert,會和傳統(tǒng)模式一樣,使用表級鎖直至insert語句執(zhí)行完成。

而對于可以事先確定插入記錄數(shù)的簡單插入,MySQL會用mutex(閂,更輕量級的鎖)僅在預(yù)先分配自增值時鎖定,在insert語句執(zhí)行完成前就已經(jīng)釋放了。連續(xù)模式也可以保證基于語句的復(fù)制主從可以生成相同的自增值,但性能比傳統(tǒng)模式更好。

對于混合插入類型(多行簡單插入中,部分行顯式指定自增值,部分行未指定),連續(xù)模式下會預(yù)先生成比要插入行更多的自增值,然后以連續(xù)方式分配給需要自增的行,多余的值就丟棄了。

MySQL8.0以前的版本默認(rèn)為連續(xù)模式。

3.3 交錯模式

交錯模式下(innodb_autoinc_lock_mode=2),不使用表鎖,任何并發(fā)insert都可以同時執(zhí)行,這意味著多條insert語句生成的自增值是可能是交錯的,單條insert語句無法保證生成連續(xù)的自增值,但這種模式并發(fā)性能是最好的。

因為缺乏了表鎖控制,多條insert并發(fā)插入,在主從執(zhí)行時無法保證自增值完全相同,此模式對基于語句的復(fù)制(應(yīng)該沒人用了吧?)是不安全的,建議配合基于行的復(fù)制(Row-Based Replication)使用(MySQL8.0默認(rèn))。

MySQL8.0默認(rèn)為交錯模式。

四、調(diào)整自增偏移

自增列的默認(rèn)初始值為1,步長為1。但在多主復(fù)制、組復(fù)制這類可以多點寫入的環(huán)境,可能會產(chǎn)生沖突。

為了保證不出現(xiàn)沖突,可以設(shè)置auto_increment_offset和auto_increment_increment來修改自增的初始值和步長,使各個寫入點產(chǎn)生的自增值不重疊(可以在會話和全局級別修改)。

例如現(xiàn)在有一個雙主環(huán)境,可以在一臺主機(jī)上配置初始值為1(默認(rèn)),步長為2,這樣生成的自增值都是單數(shù):

set auto_increment_increment=2;

在這里插入圖片描述

而在另一臺主機(jī)上配置初始值為2,步長為2,生成自增值都是雙數(shù),這樣可以避免并發(fā)寫入時發(fā)生沖突:

set auto_increment_offset=2;
set auto_increment_increment=2;

在這里插入圖片描述

五、監(jiān)控自增值的使用比例

由于數(shù)據(jù)類型最大值的限制,自增并不是沒有上限的。當(dāng)?shù)竭_(dá)上限時數(shù)據(jù)無法繼續(xù)插入,導(dǎo)致業(yè)務(wù)中斷,因此DBA需要監(jiān)控自增值的使用情況,在達(dá)到上限之前及時采取擴(kuò)容措施。

示例:這里又新建2張表,設(shè)置自增列類型為tinyint(8位有符號整數(shù),范圍為-128~127),然后將自增值分別設(shè)置為64和127

create table t2(id tinyint primary key auto_increment);
create table t3(id tinyint primary key auto_increment);

alter table t2 auto_increment=64;
alter table t3 auto_increment=127;

在這里插入圖片描述

使用下面的SQL即可查詢test數(shù)據(jù)庫下所有表的自增列使用比例(可根據(jù)情況調(diào)整,去除t.table_schema='test’可以查詢所有庫):

select
t.table_schema,
t.table_name,
t.auto_increment,
c.column_type,
concat(round((t.auto_increment /
(case data_type
when 'tinyint'then if(column_type like '%unsigned', 255, 127)
when 'smallint' then if(column_type like '%unsigned', 65535, 32767)
when 'mediumint' then if(column_type like '%unsigned', 16777215, 8388607)
when 'int'then if(column_type like '%unsigned', 4294967295, 2147483647)
when 'bigint' then if(column_type like '%unsigned',18446744073709551615,9223372036854775807)
end))*100,2),'%') used_percentage
from information_schema.tables t
join information_schema.columns c on t.table_schema = c.table_schema and t.table_name = c.table_name
where t.auto_increment is not null and c.extra='auto_increment' and t.table_schema='test';

在這里插入圖片描述

從結(jié)果可以看到t3表的自增列已經(jīng)使用100%,再插入新的數(shù)據(jù)就會報錯了。

insert into t3 values(null);

在這里插入圖片描述

到此這篇關(guān)于MySQL自增列解析(Auto_increment)的文章就介紹到這了,更多相關(guān)MySQL 自增列 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • MySQL多表鏈接查詢核心優(yōu)化

    MySQL多表鏈接查詢核心優(yōu)化

    本篇文章主要介紹了MySQL多表鏈接查詢核心優(yōu)化,數(shù)據(jù)庫對數(shù)據(jù)表的多表查詢是必不可少的,所以涉及到性能優(yōu)化,有需要的可以了解一下。
    2016-11-11
  • 一篇文章帶你了解MySQL之undo日志

    一篇文章帶你了解MySQL之undo日志

    Undo日志也叫做回滾日志,是MySQL數(shù)據(jù)庫當(dāng)中一種重要的日志,用于記錄更新操作之前的數(shù)據(jù)狀態(tài),這篇文章主要給大家介紹了關(guān)于如何通過一篇文章帶你了解MySQL之undo日志的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • mysql分區(qū)表學(xué)習(xí)之日期分區(qū)

    mysql分區(qū)表學(xué)習(xí)之日期分區(qū)

    這篇文章主要給大家介紹了關(guān)于mysql分區(qū)表學(xué)習(xí)之日期分區(qū)的相關(guān)資料,分區(qū)是一種表的設(shè)計模式,通俗地講表分區(qū)是將一大表,根據(jù)條件分割成若干個小表,需要的朋友可以參考下
    2023-08-08
  • CentOS7.4手動安裝MySQL5.7的方法

    CentOS7.4手動安裝MySQL5.7的方法

    這篇文章主要介紹了CentOS7.4手動安裝MySQL5.7的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • MySQL數(shù)據(jù)庫中表的操作詳解

    MySQL數(shù)據(jù)庫中表的操作詳解

    這篇文章主要為大家詳細(xì)介紹了MySQL數(shù)據(jù)庫中表常用的一些操作方法,文中的示例代碼講解詳細(xì),?對我們學(xué)習(xí)MySQL有一定幫助,需要的可以參考一下
    2022-08-08
  • 一文詳解MySQL?Binlog日志與主從復(fù)制

    一文詳解MySQL?Binlog日志與主從復(fù)制

    這篇文章主要介紹了一文詳解MySQL?Binlog日志與主從復(fù)制,Binlog是Binary?log的縮寫,即二進(jìn)制日志,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07
  • MySQL用戶權(quán)限設(shè)置保護(hù)數(shù)據(jù)庫安全

    MySQL用戶權(quán)限設(shè)置保護(hù)數(shù)據(jù)庫安全

    MySQL用戶權(quán)限設(shè)置是保護(hù)數(shù)據(jù)庫安全的重要措施之一。通過為用戶設(shè)置不同的權(quán)限,可以控制用戶對數(shù)據(jù)庫的訪問能力,包括讀取、修改、刪除、創(chuàng)建等操作。合理設(shè)置用戶權(quán)限可以避免誤操作、非法訪問等安全問題
    2023-05-05
  • 最新評論

    宝兴县| 贵溪市| 南靖县| 浠水县| 庆安县| 宜宾县| 稻城县| 汝南县| 安化县| 丹江口市| 安阳县| 锦屏县| 黄大仙区| 布拖县| 彩票| 临沭县| 东平县| 邹平县| 西乡县| 集贤县| 青川县| 金秀| 奉节县| 吉隆县| 淮安市| 江阴市| 巴彦淖尔市| 神农架林区| 台州市| 堆龙德庆县| 井冈山市| 龙南县| 石棉县| 新平| 正安县| 杨浦区| 宾阳县| 北票市| 枞阳县| 南木林县| 珠海市|