日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
數(shù)據(jù)庫(kù)批量插入操作指南(數(shù)據(jù)庫(kù)批量插入怎么做)

在日常開(kāi)發(fā)工作中,我們常常需要向數(shù)據(jù)庫(kù)中插入大量數(shù)據(jù)。對(duì)于一次只能插入一條數(shù)據(jù)的操作,手動(dòng)添加顯然是個(gè)非常繁瑣的過(guò)程。此時(shí),批量插入就成為了更好的選擇。

目前創(chuàng)新互聯(lián)已為上千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站托管維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、正安網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶(hù)導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶(hù)和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

本文將介紹數(shù)據(jù)庫(kù)批量插入操作的基礎(chǔ)理論、使用方法以及需要注意的事項(xiàng),希望能夠?yàn)殚_(kāi)發(fā)者們提供一些實(shí)用的經(jīng)驗(yàn)。

一、什么是批量插入

批量插入,顧名思義就是一次性向數(shù)據(jù)庫(kù)中插入多條數(shù)據(jù)。通常情況下,批量插入的操作速度與單次插入相比要快得多。原因在于,多條數(shù)據(jù)的集中操作可以將多個(gè)查詢(xún)請(qǐng)求一次性發(fā)送給數(shù)據(jù)庫(kù),減少了連接和釋放時(shí)間。此外,批量插入還能夠減少數(shù)據(jù)庫(kù)日志記錄,避免了多余的系統(tǒng)開(kāi)銷(xiāo)。

二、批量插入的技術(shù)實(shí)現(xiàn)

1. 數(shù)據(jù)庫(kù)支持批量插入

首先要注意的是,不是所有數(shù)據(jù)庫(kù)都支持批量插入。在使用之前,需要先確認(rèn)數(shù)據(jù)庫(kù)是否支持批量插入操作。大多數(shù)主流的數(shù)據(jù)庫(kù)如MySQL、Oracle、SQLServer等都支持此操作。

2. 使用預(yù)編譯語(yǔ)句

批量插入需要使用到SQL語(yǔ)句,這些語(yǔ)句需要先解析成數(shù)據(jù)庫(kù)可以執(zhí)行的二進(jìn)制碼。預(yù)編譯語(yǔ)句可以將SQL語(yǔ)句預(yù)先編譯成二進(jìn)制碼,以減少每個(gè)插入操作的解析和編譯時(shí)間。

3. 使用事務(wù)處理

批量插入操作存在著一定的風(fēng)險(xiǎn):如果某一條插入操作失敗,整個(gè)插入操作將被中斷,同時(shí)之前已經(jīng)成功插入的數(shù)據(jù)也會(huì)被回滾,導(dǎo)致數(shù)據(jù)的不連續(xù)性。使用事務(wù)處理可以有效避免這種風(fēng)險(xiǎn)。通過(guò)事務(wù)處理,我們可以將多個(gè)插入操作統(tǒng)一到一個(gè)事務(wù)中,在所有操作執(zhí)行完畢后再一起提交到數(shù)據(jù)庫(kù)中。如果某個(gè)操作失敗,那么整個(gè)事務(wù)都將被回滾,保證了數(shù)據(jù)的一致性。

三、批量插入的實(shí)現(xiàn)方法

1. JDBC批量插入

JDBC是Java數(shù)據(jù)庫(kù)連接的標(biāo)準(zhǔn),通過(guò)JDBC可以實(shí)現(xiàn)Java程序與各種關(guān)系型數(shù)據(jù)庫(kù)的連接和操作。在JDBC中,批量插入需要使用到PreparedStatement類(lèi)。該類(lèi)可以通過(guò)addBatch()方法插入多個(gè)參數(shù),最后一次性將參數(shù)塞入到PreparedStatement中。

示例代碼:

// 插入數(shù)據(jù)

String sql = “INSERT INTO user (name, age, sex) VALUES (?, ?, ?)”;

PreparedStatement pstmt = conn.prepareStatement(sql); // 預(yù)編譯SQL

for (User u : userList) { // 模擬用戶(hù)數(shù)據(jù)

pstmt.setString(1, u.getName());

pstmt.setInt(2, u.getAge());

pstmt.setString(3, u.getSex());

pstmt.addBatch(); // 將操作添加到預(yù)編譯語(yǔ)句中

}

pstmt.executeBatch(); // 一次執(zhí)行多條SQL語(yǔ)句

conn.commit(); // 提交事務(wù)

2. MyBatis批量插入

MyBatis是一款優(yōu)秀的Java持久化框架,可以將Java對(duì)象映射到關(guān)系型數(shù)據(jù)庫(kù)中。在MyBatis中,批量插入需要使用到BatchExecutor類(lèi)。

示例代碼:

INSERT INTO user (name, age, sex) VALUES

(#{item.name}, #{item.age}, #{item.sex})

// 將數(shù)據(jù)封裝到List中

List userList = new ArrayList();

for (int i = 0; i

userList.add(new User(“test” + i, 18, “F”));

}

// 執(zhí)行批量插入

SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

for (int i = 0; i

List subList = userList.subList(i * 100, (i + 1) * 100);

userMapper.batchInsert(subList);

}

sqlSession.commit(); // 提交事務(wù)

四、批量插入的注意事項(xiàng)

1. 數(shù)據(jù)庫(kù)限制

不同的數(shù)據(jù)庫(kù)對(duì)于批量插入操作的限制不同。使用之前,需要確保數(shù)據(jù)庫(kù)對(duì)于一次插入操作的數(shù)據(jù)量不會(huì)超出限制。

2. 防止數(shù)據(jù)重復(fù)插入

在批量插入操作中,可能會(huì)產(chǎn)生重復(fù)數(shù)據(jù)的情況。為了避免出現(xiàn)這種情況,需要在插入之前進(jìn)行數(shù)據(jù)去重操作。

3. 注意執(zhí)行過(guò)程中的異常處理

批量插入是一次性操作大量數(shù)據(jù)的過(guò)程,如果在此過(guò)程中出現(xiàn)異常,必須進(jìn)行及時(shí)處理以避免數(shù)據(jù)丟失或不完整的情況。

相關(guān)問(wèn)題拓展閱讀:

  • mysql 怎么用insert批量插入數(shù)據(jù)

mysql 怎么用insert批量插入數(shù)據(jù)

這就是自己實(shí)現(xiàn)一個(gè)id自增的東西。

比如的你有個(gè)公用冊(cè)襲類(lèi)專(zhuān)門(mén)用來(lái)生成后面的數(shù)字州灶兄,所有需要用到的方法都調(diào)用這個(gè)類(lèi)的一辯鉛個(gè)方法我們就叫它nextid吧,只要這個(gè)方法是線程安全的就可以了。

idutils.nextid()

int

nextid()

{

lock(this){

return

this.id++;

}

}

應(yīng)用啟動(dòng)的時(shí)候從數(shù)據(jù)庫(kù)查詢(xún)一下id的更大值并設(shè)置給工具類(lèi)的id,讓它接著增長(zhǎng)就行了。

具體實(shí)現(xiàn)看你用什么語(yǔ)言。

請(qǐng)仔細(xì)閱讀別人回答的是什么意思。想想oracle的sequence的實(shí)現(xiàn),是不是類(lèi)似?

一次插入多行數(shù)據(jù)

insert

into

表名

values(值列表1),(值列表2),…(值列表n);

例如:

insert

into

students(sid,sname,dob)

values

(‘001′,’張三核銀’,”),

(‘002′,’李四’,”),

(‘宴配003′,’王五’,”);

將一張表或查詢(xún)中的改祥宴數(shù)據(jù)插入到另一張表里

insert

into

表名(字段列表)

select

(字段列表)

from

源表

where

篩選表達(dá)式;

例如將表2中的記錄全部插入到表1,假設(shè)它們的結(jié)構(gòu)一樣

insert

into

表1(*)

select

*

from

表2;

加鎖情況與死鎖原因分析

為方便大家復(fù)現(xiàn),完整表結(jié)構(gòu)和數(shù)據(jù)如下:

CREATE TABLE `t3` (

`c1` int(11) NOT NULL AUTO_INCREMENT,

`c2` int(11) DEFAULT NULL,

PRIMARY KEY (`c1`),

UNIQUE KEY `c2` (`c2`)

) ENGINE=InnoDB

insert into t3 values(1,1),(15,15),(20,20);

在 session1 執(zhí)行 commit 的瞬間,我們會(huì)看到 session2、session3 的其中一個(gè)報(bào)死鎖。這個(gè)死鎖是這樣產(chǎn)生的:

1. session1 執(zhí)行 delete  會(huì)在唯一索引 c2 的 c2 = 15 這一記錄上加 X lock(也就是在MySQL 內(nèi)部觀測(cè)到的:X Lock but not gap);

2. session2 和 session3 在執(zhí)行 insert 的時(shí)候,由于唯一約束檢測(cè)發(fā)生唯一沖突,會(huì)加 S Next-Key Lock,即對(duì) (1,15> 這個(gè)區(qū)間加鎖包括間隙,并且被 seesion1 的 X Lock 阻塞,進(jìn)入等待;

3. session1 在執(zhí)行模世 commit 后,會(huì)釋放 X Lock,session2 和 session3 都獲得 S Next-Key Lock;

4. session2 和 session3 繼續(xù)執(zhí)行插入操作,這個(gè)時(shí)候 INSERT INTENTION LOCK(插入意向鎖)出現(xiàn)了,并且由于插入意向鎖會(huì)被 gap 鎖阻塞,所以 session2 和 session3 互相等待,造成死鎖。

死鎖日志如下: 

INSERT INTENTION LOCK

在之前的死鎖分析第四點(diǎn),如果不分析插入意向鎖,也是會(huì)造成死鎖的,因?yàn)椴迦胱罱K還是要對(duì)記錄加 X Lock 的,session2 和 session3 還是會(huì)互相阻塞互相等待。

但是插入意向鎖是客觀存在的,我們可以在官方手冊(cè)中查到,不可忽略:

Prior to inserting the row, a type of gap lock called an insert intention gap lock is set. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap.

插入意向鎖其實(shí)是一種特殊的 gap lock,但是它不會(huì)阻塞其他鎖。假設(shè)存在值為 4 和 7 的索引記錄,嘗試插入值 5 和 6 的兩個(gè)事務(wù)在獲取插入行上的排它鎖之前使用插入意向鎖鎖定間隙,即在(4,7)上加 gap lock,但是這兩個(gè)事務(wù)不會(huì)互相沖突等待。

當(dāng)插入一條記錄時(shí),會(huì)去檢查當(dāng)前插入位置的下一條記錄上是否存在鎖對(duì)象,如果下一條記錄上存在鎖對(duì)象,就需要判斷該鎖對(duì)象是否鎖住了 gap。如果 gap 被鎖住了,則插入意向鎖與之沖突,進(jìn)入等待狀態(tài)(插入意向鎖之間并不互斥)。總結(jié)一下這把鎖的屬性:

1. 它不會(huì)阻塞其他任何鎖;

2. 它本身僅會(huì)被 gap lock 阻塞。

在學(xué)習(xí) MySQL 過(guò)程中,一般只有在它被阻塞的時(shí)候才能觀察到,所以這也是它常常被忽略的原因吧…

GAP LOCK

在此例中,另外一個(gè)重要的點(diǎn)就是 gap lock,通常情況下我們說(shuō)到 gap lock 都只會(huì)聯(lián)想到 REPEATABLE-READ 隔離級(jí)別利用其解決幻讀。但實(shí)際上在 READ-COMMITTED 隔離級(jí)別,也會(huì)存在 gap lock ,只發(fā)生在:唯一約束檢查到有唯一沖突的時(shí)候,會(huì)加 S Next-key Lock,即對(duì)記錄以及與和上一條記錄之間的間隙加共享鎖。

通過(guò)下面這個(gè)例子就能驗(yàn)證:

這余碼橋里 session1 插入數(shù)據(jù)遇到唯一沖突,雖然報(bào)錯(cuò),但是對(duì) (15,20> 加的 S Next-Key Lock 并不會(huì)馬上釋放,所以豎猛 session2 被阻塞。另外一種情況就是本文開(kāi)始的例子,當(dāng) session2 插入遇到唯一沖突但是因?yàn)楸?X Lock 阻塞,并不會(huì)立刻報(bào)錯(cuò) “Duplicate key”,但是依然要等待獲取 S Next-Key Lock 。

有個(gè)困惑很久的疑問(wèn):出現(xiàn)唯一沖突需要加 S Next-Key Lock 是事實(shí),但是加鎖的意義是什么?還是說(shuō)是通過(guò) S Next-Key Lock 來(lái)實(shí)現(xiàn)的唯一約束檢查,但是這樣意味著在插入沒(méi)有遇到唯一沖突的時(shí)候,這個(gè)鎖會(huì)立刻釋放,這不符合二階段鎖原則。這點(diǎn)希望能與大家一起討論得到好的解釋。

如果是在 REPEATABLE-READ,除以上所說(shuō)的唯一約束沖突外,gap lock 的存在是這樣的:

普通索引(非唯一索引)的S/X Lock,都帶 gap 屬性,會(huì)鎖住記錄以及前1條記錄到后1條記錄的左閉右開(kāi)區(qū)間,比如有記錄,delete 6,則會(huì)鎖住

對(duì)于 gap lock,相信 DBA 們的心情是一樣一樣的,所以我的建議是:

1. 在絕大部分的業(yè)務(wù)場(chǎng)景下,都可以把 MySQL 的隔離界別設(shè)置為 READ-COMMITTED;

2. 在業(yè)務(wù)方便控制字段值唯一的情況下,盡量減少表中唯一索引的數(shù)量。

鎖沖突矩陣

關(guān)于數(shù)據(jù)庫(kù)批量插入怎么做的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。

香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開(kāi)通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開(kāi)發(fā)經(jīng)驗(yàn)。專(zhuān)業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。


分享文章:數(shù)據(jù)庫(kù)批量插入操作指南(數(shù)據(jù)庫(kù)批量插入怎么做)
URL標(biāo)題:http://www.dlmjj.cn/article/djhpdci.html