當前位置:首頁 » 數據倉庫 » 資料庫高並發寫入
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

資料庫高並發寫入

發布時間: 2023-06-26 05:05:39

『壹』 一直在說的高並發,多少QPS才算高並發

首先是無狀態前端機器不足以承載請求流量,需要進行水平擴展,一般QPS是千級。 然後是關系型資料庫無法承載讀取或寫入峰值,需要資料庫橫向擴展或引入nosql,一般是千到萬級。 之後是單機nosql無法承載,需要nosql橫向擴展,一般是十萬到百萬QPS。

高並發通常是指我們提供的系統服務能夠同時並行處理很多請求。並發是指,某個時刻有多少個訪問同時到來。QPS是指秒鍾響應的請求數量。那麼這里就肯容易推算出一個公式:QPS = 並發數 / 平均響應時間

如果你發現自己高並發,一定要及時就醫,尋求正規醫生的幫助。

『貳』 怎麼提高資料庫高峰時訪問的並發能力

1:首先需要有非常良好的網路帶寬,若有上萬人同時錄入數據的普通的Web信息管理系統,至少需要10M左右的網路帶寬,而且網通、電信的主幹網都有接入比較好,否則全國各地的網路情況都不太一樣,有的城市錄入數據時可能會遇到網路非常緩慢的情況,甚至到無法忍受的程度。

2:須有一台牛X的Web伺服器 + 一台牛X的資料庫伺服器(備注接近頂配的奢侈硬體伺服器非個人PC),由於是需要錄入1000萬條以上數據,最好採用Oracle資料庫比較理想一些,經得起考驗一些。

3:需要進行適當的內存緩存優化策略,不能所有的資料庫都依靠SQL資料庫的方式把壓力放在資料庫伺服器上,盡量多使用內存的方式處理數據。

4:需要一個牛X的,經得起考驗的資料庫訪問層,因為每秒都有可能成千上萬的人在訪問,若是質量不良好的資料庫訪問組件、或者不穩定的資料庫訪問組件,更容易導致系統崩潰、或者佔用非常龐大的內存,最後容易導致整個系統的崩潰。

5:需要優化分頁存取數據功能,應為有可能會有1000萬條數據,若分頁讀取數據的功能沒能優化到最高,也很容易導致系統的崩潰,因為上萬人萬一在同一時間,或者接近同一時間點了查詢某頁數據時,那系統就真崩潰了,分頁存取數據一定需要做到極致才可以。

6:需要進行資料庫索引優化,有索引和沒索引的性能差距有時候會是100倍,大數據量時可能會有1000倍都有可能,資料庫索引優化到極致了更容易得到運行順暢的信息管理系統。

7:嚴謹高效的資料庫事務處理,由於高並發,並且有些單據是需要同時寫入多個表,需要保證資料庫的一致性,要麼全部成功,要麼全部失敗重新錄入數據,所以需要一個高效的資料庫事務處理機制的配合。

8:所有的系統的操作日誌、異常信息都需要完整的記錄下來,當系統發生一些故障時,可以快速排查問題,對正確診斷系統發生的故障的原因做分析參考用。

9:需要經常檢測系統的各項指標、例如各伺服器的內存使用情況、CPU使用情況、網路帶寬使用情況,高峰時的各個參數是什麼情況、系統不繁忙時的情況等,若伺服器快承受不了壓力了,就得馬上增加負載均衡的伺服器,網路帶寬不夠了需要增加等等,總不能等系統崩潰了再去做這些事情。

10:每個頁面的HTML、JS都進行優化,若某個頁面多餘發了100個字元的垃圾HTML代碼,那1萬人每天獲得100次,那得佔用多少網路帶寬,100×100×1萬個字元的多餘HTML被網路上傳輸了,要知道接入主幹網的網路資源是多麼寶貴,費用是多麼昂貴。

11:HTML、JS等都可以考慮用壓縮模式傳輸,那樣網路傳輸效率會更高一些。

12:由於全國各地上萬人,會有各種各樣的人,這些人也未必全是好人,可能某些人心情不好,或者其他什麼的,可能就會攻擊我們的軟體系統破壞數據,這些也可能是由於好奇心導致的,所以系統需要有嚴格的許可權管理控制,不應該進入的頁面絕對不能進入,不應該看的數據絕對不讓看,不能操作的功能絕對不讓多操作,一方面防止沒必要的多餘的麻煩,另一方面也可以減少系統被攻擊破壞的可能性。

『叄』 關系型資料庫的局限性有哪些難以滿足高並發讀寫的需求

隨著互聯網web2.0網站的興起,非關系型的資料庫現在成了一個極其熱門的新領域,非關系資料庫產品的發展非常迅速。而傳統的關系資料庫在應付web2.0網站,特別是超大規模和高並發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了很多難以克服的問題,例如:

1、High performance——對資料庫高並發讀寫的需求

Web2.0網站要根據用戶個性化信息來實時生成動態頁面和提供動態信息,所以基本上無法使用動態頁面靜態化技術,因此資料庫並發負載非常高,往往要達到每秒上萬次讀寫請求。關系資料庫應付上萬次SQL查詢還勉強頂得住,但是應付上萬次SQL寫數據請求,硬碟IO就已經無法承受了。其實對於普通的BBS網站,往往也存在對高並發寫請求的需求,例如像JavaEye網站的實時統計在線用戶狀態,記錄熱門帖子的點擊次數,投票計數等,因此這是一個相當普遍的需求。

2、Huge Storage——對海量數據的高效率存儲和訪問的需求

類似Facebook,twitter,Friendfeed這樣的SNS網站,每天用戶產生海量的用戶動態,以Friendfeed為例,一個月就達到了2.5億條用戶動態,對於關系資料庫來說,在一張2.5億條記錄的表裡面進行SQL查詢,效率是極其低下乃至不可忍受的。再例如大型web網站的用戶登錄系統,例如騰訊,盛大,動輒數以億計的帳號,關系資料庫也很難應付。

3、High Scalability && High Availability——對資料庫的高可擴展性和高可用性的需求

在基於web的架構當中,資料庫是最難進行橫向擴展的,當一個應用系統的用戶量和訪問量與日俱增的時候,你的資料庫卻沒有辦法像web server和app server那樣簡單的通過添加更多的硬體和服務節點來擴展性能和負載能力。對於很多需要提供24小時不間斷服務的網站來說,對資料庫系統進行升級和擴展是非常痛苦的事情,往往需要停機維護和數據遷移,為什麼資料庫不能通過不斷的添加伺服器節點來實現擴展呢?

在上面提到的「三高」需求面前,關系資料庫遇到了難以克服的障礙,而對於web2.0網站來說,關系資料庫的很多主要特性卻往往無用武之地,例如:

1. 資料庫事務一致性需求

很多web實時系統並不要求嚴格的資料庫事務,對讀一致性的要求很低,有些場合對寫一致性要求也不高。因此資料庫事務管理成了資料庫高負載下一個沉重的負擔。

2. 資料庫的寫實時性和讀實時性需求

對關系資料庫來說,插入一條數據之後立刻查詢,是肯定可以讀出來這條數據的,但是對於很多web應用來說,並不要求這么高的實時性,比方說我(JavaEye的robbin)發一條消息之後,過幾秒乃至十幾秒之後,我的訂閱者才看到這條動態是完全可以接受的。

3、對復雜的SQL查詢,特別是多表關聯查詢的需求

任何大數據量的web系統,都非常忌諱多個大表的關聯查詢,以及復雜的數據分析類型的復雜SQL報表查詢,特別是SNS類型的網站,從需求以及產品設計角度,就避免了這種情況的產生。往往更多的只是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能被極大的弱化了。

因此,關系資料庫在這些越來越多的應用場景下顯得不那麼合適了,為了解決這類問題的非關系資料庫應運而生,現在這兩年,各種各樣非關系資料庫,特別是鍵值資料庫(Key-Value Store DB)風起雲涌,多得讓人眼花繚亂。前不久國外剛剛舉辦了NoSQL Conference,各路NoSQL資料庫紛紛亮相,加上未亮相但是名聲在外的,起碼有超過10個開源的NoSQLDB,例如:

Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud, KiokuDB,Scalaris, Kai, ThruDB, ......

這些NoSQL資料庫,有的是用C/C++編寫的,有的是用Java編寫的,還有的是用Erlang編寫的,每個都有自己的獨到之處,看都看不過來了,我(robbin)也只能從中挑選一些比較有特色,看起來更有前景的產品學習和了解一下。

『肆』 高並發下,資料庫成最大問題怎麼辦

一、資料庫結構的設計

為了保證資料庫的一致性和完整性,在邏輯設計的時候往往會設計過多的表間關聯,盡可能的降低數據的冗餘。(例如用戶表的地區,我們可以把地區另外存放到一個地區表中)如果數據冗餘低,數據的完整性容易得到保證,提高了數據吞吐速度,保證了數據的完整性,清楚地表達數據元素之間的關系。不要用自增屬性欄位作為主鍵與子表關聯。不便於系統的遷移和數據恢復。對外統計系統映射關系丟失。
表的設計具體注意的問題:
1、數據行的長度不要超過8020位元組,如果超過這個長度的話在物理頁中這條數據會佔用兩行從而造成存儲碎片,降低查詢效率。
2、能夠用數字類型的欄位盡量選擇數字類型而不用字元串類型的(電話號碼),這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接回逐個比較字元串中每一個字元,而對於數字型而言只需要比較一次就夠了。
3、對於不可變字元類型char和可變字元類型varchar都是8000位元組,char查詢快,但是耗存儲空間,varchar查詢相對慢一些但是節省存儲空間。在設計欄位的時候可以靈活選擇,例如用戶名、密碼等長度變化不大的欄位可以選擇CHAR,對於評論等長度變化大的欄位可以選擇VARCHAR。
4、欄位的長度在最大限度的滿足可能的需要的前提下,應該盡可能的設得短一些,這樣可以提高查詢的效率,而且在建立索引的時候也可以減少資源的消耗。

二、查詢的優化

在數據窗口使用SQL時,盡量把使用的索引放在選擇的首列;演算法的結構盡量簡單;
在查詢時,不要過多地使用通配符如SELECT* FROM T1語句,要用到幾列就選擇幾列如:SELECT COL1,COL2 FROMT1;在可能的情況下盡量限制盡量結果集行數如:SELECT TOP 300 COL1,COL2,COL3 FROMT1,因為某些情況下用戶是不需要那麼多的數據的。
在沒有建索引的情況下,資料庫查找某一條數據,就必須進行全表掃描了,對所有數據進行一次遍歷,查找出符合條件的記錄。在數據量比較小的情況下,也許看不出明顯的差別,但是當數據量大的情況下,這種情況就是極為糟糕的了。
SQL語句在SQL SERVER中是如何執行的,他們擔心自己所寫的SQL語句會被SQLSERVER誤解。比如:
select * from table1 where name='zhangsan' and tID >10000和執行:
select * from table1 where tID > 10000 andname='zhangsan'
一些人不知道以上兩條語句的執行效率是否一樣,因為如果簡單的從語句先後上看,這兩個語句的確是不一樣,如果tID是一個聚合索引,那麼後一句僅僅從表的10000條以後的記錄中查找就行了;而前一句則要先從全表中查找看有幾個name='zhangsan'的,而後再根據限制條件條件tID>10000來提出查詢結果。
事實上,這樣的擔心是不必要的。SQLSERVER中有一個「查詢分析優化器」,它可以計算出where子句中的搜索條件並確定哪個索引能縮小表掃描的搜索空間,也就是說,它能實現自動優化。雖然查詢優化器可以根據where子句自動的進行查詢優化,但有時查詢優化器就會不按照您的本意進行快速查詢。

所以,優化查詢最重要的就是,盡量使語句符合查詢優化器的規則避免全表掃描而使用索引查詢。
具體要注意的:
1.應盡量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:

select id from t where num is null

可以在num上設置默認值0,確保表中num列沒有null值,然後這樣查詢:

select id from t where num=0
2.應盡量避免在 where子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。優化器將無法通過索引來確定將要命中的行數,因此需要搜索該表的所有行。
3.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:

select id from t where num=10 or num=20

可以這樣查詢:

select id from t where num=10
union all
select id from t where num=20s
4.in 和 not in 也要慎用,因為IN會使系統無法使用索引,而只能直接搜索表中的數據。如:

select id from t where num in(1,2,3)
對於連續的數值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
6.必要時強制查詢優化器使用某個索引,如在 where子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變數,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變數的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:

select id from t where num=@num
可以改為強制查詢使用索引:
select id from t with(index(索引名)) where num=@num
7.應盡量避免在 where 子句中對欄位進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:

SELECT * FROM T1 WHERE F1/2=100
應改為:
SELECT * FROM T1 WHERE F1=100*2
SELECT * FROM RECORD WHERESUBSTRING(CARD_NO,1,4)=』5378』
應改為:
SELECT * FROM RECORD WHERE CARD_NO LIKE 『5378%』
SELECT member_number, first_name, last_name FROMmembers
WHERE DATEDIFF(yy,datofbirth,GETDATE()) >21
應改為:
SELECT member_number, first_name, last_name FROMmembers
WHERE dateofbirth <DATEADD(yy,-21,GETDATE())
即:任何對列的操作都將導致表掃描,它包括資料庫函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。
8.應盡量避免在where子句中對欄位進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:

select id from t wheresubstring(name,1,3)='abc'--name以abc開頭的id
select id from t wheredatediff(day,createdate,'2005-11-30')=0--『2005-11-30』生成的id
應改為:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' andcreatedate<'2005-12-1'
9.不要在 where 子句中的「=」左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。
10.在使用索引欄位作為條件時,如果該索引是復合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應盡可能的讓欄位順序與索引順序相一致。
11.很多時候用 exists是一個好的選擇:

elect num from a where num in(select num from b)
用下面的語句替換:
select num from a where exists(select 1 from b where num=a.num)
但是後者的效率顯然要高於前者。因為後者不會產生大量鎖定的表掃描或是索引掃描。
如果你想校驗表裡是否存在某條紀錄,不要用count(*)那樣效率很低,而且浪費伺服器資源。可以用EXISTS代替。如:
IF (SELECT COUNT(*) FROM table_name WHERE column_name ='xxx')
可以寫成:
IF EXISTS (SELECT * FROM table_name WHERE column_name = 'xxx')
12.盡量使用表變數來代替臨時表。如果表變數包含大量數據,請注意索引非常有限(只有主鍵索引)。
13.避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。
14.臨時表並不是不可使用,適當地使用它們可以使某些常式更有效,例如,當需要重復引用大型表或常用表中的某個數據集時。但是,對於一次性事件,最好使用導出表。
15.在新建臨時表時,如果一次性插入數據量很大,那麼可以使用 select into 代替 create table,避免造成大量log ,以提高速度;如果數據量不大,為了緩和系統表的資源,應先create table,然後insert。
16.如果使用到了臨時表,在存儲過程的最後務必將所有的臨時表顯式刪除,先 truncate table ,然後 drop table,這樣可以避免系統表的較長時間鎖定。
17.在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF。無需在執行存儲過程和觸發器的每個語句後向客戶端發送 DONE_IN_PROC 消息。
18.盡量避免大事務操作,提高系統並發能力。
19.盡量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。

20.避免使用不兼容的數據類型。例如float和int、char和varchar、binary和varbinary是不兼容的。數據類型的不兼容可能使優化器無法執行一些本來可以進行的優化操作。例如:

SELECT name FROM employee WHERE salary >60000
在這條語句中,如salary欄位是money型的,則優化器很難對其進行優化,因為60000是個整型數。我們應當在編程時將整型轉化成為錢幣型,而不要等到運行時轉化。

23、能用DISTINCT的就不用GROUP BY

SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BYOrderID
可改為:
SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10
24.能用UNION ALL就不要用UNION

UNION ALL不執行SELECTDISTINCT函數,這樣就會減少很多不必要的資源

35.盡量不要用SELECT INTO語句。

SELECT INOT 語句會導致表鎖定,阻止其他用戶訪問該表。

四、建立高效的索引
創建索引一般有以下兩個目的:維護被索引列的唯一性和提供快速訪問表中數據的策略。
大型資料庫有兩種索引即簇索引和非簇索引,一個沒有簇索引的表是按堆結構存儲數據,所有的數據均添加在表的尾部,而建立了簇索引的表,其數據在物理上會按照簇索引鍵的順序存儲,一個表只允許有一個簇索引,因此,根據B樹結構,可以理解添加任何一種索引均能提高按索引列查詢的速度,但會降低插入、更新、刪除操作的性能,尤其是當填充因子(FillFactor)較大時。所以對索引較多的表進行頻繁的插入、更新、刪除操作,建表和索引時因設置較小的填充因子,以便在各數據頁中留下較多的自由空間,減少頁分割及重新組織的工作。
索引是從資料庫中獲取數據的最高效方式之一。95%的資料庫性能問題都可以採用索引技術得到解決。作為一條規則,我通常對邏輯主鍵使用唯一的成組索引,對系統鍵(作為存儲過程)採用唯一的非成組索引,對任何外鍵列[欄位]採用非成組索引。不過,索引就象是鹽,太多了菜就咸了。你得考慮資料庫的空間有多大,表如何進行訪問,還有這些訪問是否主要用作讀寫。
實際上,您可以把索引理解為一種特殊的目錄。微軟的SQL SERVER提供了兩種索引:聚集索引(clusteredindex,也稱聚類索引、簇集索引)和非聚集索引(nonclusteredindex,也稱非聚類索引、非簇集索引)。
聚集索引和非聚集索引的區別:
其實,我們的漢語字典的正文本身就是一個聚集索引。比如,我們要查「安」字,就會很自然地翻開字典的前幾頁,因為「安」的拼音是「an」,而按照拼音排序漢字的字典是以英文字母「a」開頭並以「z」結尾的,那麼「安」字就自然地排在字典的前部。如果您翻完了所有以「a」開頭的部分仍然找不到這個字,那麼就說明您的字典中沒有這個字;同樣的,如果查「張」字,那您也會將您的字典翻到最後部分,因為「張」的拼音是「zhang」。也就是說,字典的正文部分本身就是一個目錄,您不需要再去查其他目錄來找到您需要找的內容。
我們把這種正文內容本身就是一種按照一定規則排列的目錄稱為「聚集索引」。
如果您認識某個字,您可以快速地從自動中查到這個字。但您也可能會遇到您不認識的字,不知道它的發音,這時候,您就不能按照剛才的方法找到您要查的字,而需要去根據「偏旁部首」查到您要找的字,然後根據這個字後的頁碼直接翻到某頁來找到您要找的字。但您結合「部首目錄」和「檢字表」而查到的字的排序並不是真正的正文的排序方法,比如您查「張」字,我們可以看到在查部首之後的檢字表中「張」的頁碼是672頁,檢字表中「張」的上面是「馳」字,但頁碼卻是63頁,「張」的下面是「弩」字,頁面是390頁。很顯然,這些字並不是真正的分別位於「張」字的上下方,現在您看到的連續的「馳、張、弩」三字實際上就是他們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我們可以通過這種方式來找到您所需要的字,但它需要兩個過程,先找到目錄中的結果,然後再翻到您所需要的頁碼。

『伍』 如何處理高並發

處理高並發的六種方法

1:系統拆分,將一個系統拆分為多個子系統,用bbo來搞。然後每個系統連一個資料庫,這樣本來就一個庫,現在多個資料庫,這樣就可以抗高並發。

2:緩存,必須得用緩存。大部分的高並發場景,都是讀多寫少,那你完全可以在資料庫和緩存里都寫一份,然後讀的時候大量走緩存不就得了。畢竟人家redis輕輕鬆鬆單機幾萬的並發啊。沒問題的。所以你可以考的慮考慮你的項目里,那些承載主要請求讀場景,怎麼用緩存來抗高並發。

3:MQ(消息隊列),必須得用MQ。可能你還是會出現高並發寫的場景,比如說一個業務操作里要頻繁搞資料庫幾十次,增刪改增刪改,瘋了。那高並發絕對搞掛你的系統,人家是緩存你要是用redis來承載寫那肯定不行,數據隨時就被LRU(淘汰掉最不經常使用的)了,數據格式還無比簡單,沒有事務支持。所以該用mysql還得用mysql啊。那你咋辦?用MQ吧,大量的寫請求灌入MQ里,排隊慢慢玩兒,後邊系統消費後慢慢寫,控制在mysql承載范圍之內。所以你得考慮考慮你的項目里,那些承載復雜寫業務邏輯的場景里,如何用MQ來非同步寫,提升並發性。MQ單機抗幾萬並發也是ok的。

4:分庫分表,可能到了最後資料庫層面還是免不了抗高並發的要求,好吧,那麼就將一個資料庫拆分為多個庫,多個庫來抗更高的並發;然後將一個表拆分為多個表,每個表的數據量保持少一點,提高sql跑的性能。

5:讀寫分離,這個就是說大部分時候資料庫可能也是讀多寫少,沒必要所有請求都集中在一個庫上吧,可以搞個主從架構,主庫寫入,從庫讀取,搞一個讀寫分離。讀流量太多的時候,還可以加更多的從庫。

6:solrCloud:
SolrCloud(solr 雲)是Solr提供的分布式搜索方案,可以解決海量數據的 分布式全文檢索,因為搭建了集群,因此具備高可用的特性,同時對數據進行主從備份,避免了單點故障問題。可以做到數據的快速恢復。並且可以動態的添加新的節點,再對數據進行平衡,可以做到負載均衡:

『陸』 高並發下資料庫插入重復數據,有什麼好方法

MySql避免重復插入記錄的幾種方法
本文章來給大家提供三種在mysql中避免重復插入記錄方法,主要是講到了ignore,Replace,ON DUPLICATE KEY UPDATE三種方法,有需要的朋友可以參考一下

方案一:使用ignore關鍵字
如果是用主鍵primary或者唯一索引unique區分了記錄的唯一性,避免重復插入記錄可以使用:
復制代碼 代碼如下:

INSERT IGNORE INTO `table_name` (`email`, `phone`, `user_id`) VALUES ('[email protected]', '99999', '9999');

這樣當有重復記錄就會忽略,執行後返回數字0

還有個應用就是復製表,避免重復記錄:
復制代碼 代碼如下:

INSERT IGNORE INTO `table_1` (`name`) SELECT `name` FROM `table_2`;

方案二:使用Replace

語法格式:
復制代碼 代碼如下:

REPLACE INTO `table_name`(`col_name`, ...) VALUES (...);
REPLACE INTO `table_name` (`col_name`, ...) SELECT ...;
REPLACE INTO `table_name` SET `col_name`='value',

...演算法說明:
REPLACE的運行與INSERT很相像,但是如果舊記錄與新記錄有相同的值,則在新記錄被插入之前,舊記錄被刪除,即:

嘗試把新行插入到表中
當因為對於主鍵或唯一關鍵字出現重復關鍵字錯誤而造成插入失敗時:
從表中刪除含有重復關鍵字值的沖突行
再次嘗試把新行插入到表中
舊記錄與新記錄有相同的值的判斷標准就是:
表有一個PRIMARY KEY或UNIQUE索引,否則,使用一個REPLACE語句沒有意義。該語句會與INSERT相同,因為沒有索引被用於確定是否新行復制了其它的行。
返回值:
REPLACE語句會返回一個數,來指示受影響的行的數目。該數是被刪除和被插入的行數的和
受影響的行數可以容易地確定是否REPLACE只添加了一行,或者是否REPLACE也替換了其它行:檢查該數是否為1(添加)或更大(替換)。
示例:
# eg:(phone欄位為唯一索引)
復制代碼 代碼如下:

REPLACE INTO `table_name` (`email`, `phone`, `user_id`) VALUES ('test569', '99999', '123');

另外,在 SQL Server 中可以這樣處理:

復制代碼 代碼如下:

if not exists (select phone from t where phone= '1') insert into t(phone, update_time) values('1', getdate()) else update t set update_time = getdate() where phone= '1'

更多信息請看:http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#replace

方案三:ON DUPLICATE KEY UPDATE
如‍上所寫,你也可以在INSERT INTO…..後面加上 ON DUPLICATE KEY UPDATE方法來實現。如果您指定了ON DUPLICATE KEY UPDATE,並且插入行後會導致在一個UNIQUE索引或PRIMARY KEY中出現重復值,則執行舊行UPDATE。
例如,如果列a被定義為UNIQUE,並且包含值1,則以下兩個語句具有相同的效果:
復制代碼 代碼如下:

INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE `c`=`c`+1;
UPDATE `table` SET `c`=`c`+1 WHERE `a`=1;

如果行作為新記錄被插入,則受影響行的值為1;如果原有的記錄被更新,則受影響行的值為2。

注釋:如果列b也是唯一列,則INSERT與此UPDATE語句相當:
復制代碼 代碼如下:

UPDATE `table` SET `c`=`c`+1 WHERE `a`=1 OR `b`=2 LIMIT 1;

如果a=1 OR b=2與多個行向匹配,則只有一個行被更新。通常,您應該盡量避免對帶有多個唯一關鍵字的表使用ON DUPLICATE KEY子句。

您可以在UPDATE子句中使用VALUES(col_name)函數從INSERT…UPDATE語句的INSERT部分引用列值。換句話說,如果沒有發生重復關鍵字沖突,則UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函數特別適用於多行插入。VALUES()函數只在INSERT…UPDATE語句中有意義,其它時候會返回NULL。
復制代碼 代碼如下:

INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3), (4, 5, 6) ON DUPLICATE KEY UPDATE `c`=VALUES(`a`)+VALUES(`b`);

本語句與以下兩個語句作用相同:

復制代碼 代碼如下:

INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE `c`=3;
INSERT INTO `table` (`a`, `b`, `c`) VALUES (4, 5, 6) ON DUPLICATE KEY UPDATE c=9;

注釋:當您使用ON DUPLICATE KEY UPDATE時,DELAYED選項被忽略。

示例:
這個例子是我在實際項目中用到的:是將一個表的數據導入到另外一個表中,數據的重復性就得考慮(如下),唯一索引為:email:
復制代碼 代碼如下:

INSERT INTO `table_name1` (`title`, `first_name`, `last_name`, `email`, `phone`, `user_id`, `role_id`, `status`, `campaign_id`)
SELECT '', '', '', `table_name2`.`email`, `table_name2`.`phone`, NULL, NULL, 'pending', 29 FROM `table_name2`
WHERE `table_name2`.`status` = 1
ON DUPLICATE KEY UPDATE `table_name1`.`status`='pending'

再貼一個例子:

復制代碼 代碼如下:

INSERT INTO `class` SELECT * FROM `class1` ON DUPLICATE KEY UPDATE `class`.`course`=`class1`.`course`

其它關鍵:DELAYED 做為快速插入,並不是很關心失效性,提高插入性能。
IGNORE 只關注主鍵對應記錄是不存在,無則添加,有則忽略。

特別說明:在MYSQL中UNIQUE索引將會對null欄位失效,也就是說(a欄位上建立唯一索引):
復制代碼 代碼如下:

INSERT INTO `test` (`a`) VALUES (NULL);

是可以重復插入的(聯合唯一索引也一樣)。

『柒』 資料庫高並發寫入,怎麼降低資料庫的壓力

主要通過架構設計來減少高並發對資料庫的壓力;
比如 在資料庫和應用程序之間,增加 DAL層,通過代理,連接池等,保證資料庫與業務程序由一定的緩沖和關系梳理;
在資料庫前面,加一個緩存層,讓大部分數據訪問,都直接在緩存層獲取數據,不用訪問到後端的MySQL資料庫;

『捌』 高並發,寫入頻繁的評論系統有必要加緩存么

如果並發真到幾萬的話,緩存肯定是要加的。
具體加緩存的策略,看想要什麼效果,可以對查詢最頻繁的一類請求先加緩存。
保證mongo處於一個合理的負載。

『玖』 java多用戶同時訪問和資料庫進行交互,如何能夠高並發

我覺得1萬的數據並發量並不大,想oracle資料庫,mysql承載這些並發是沒有問題的

我覺得,主要的問題在於你GPS是一直在修改的,因為車輛在不斷的行駛,這樣的話,可能會影響資料庫的性能
我覺得,你可以用一個內存行的資料庫,比如,redis,用這個來存放GPS信息,redis是基於內存的,讀寫要比關系資料庫速度快(忽略網路因素),你可能要問GPS入庫怎麼弄,可以做一個定時任務,每隔多少時間來將redis的數據寫入到資料庫中,當然,redis也支持一些演算法,比如LRU,來設置何時將數據同步到資料庫