資料庫表格分割區可提升插入效率;資料庫表格分割區可提高表格增刪改查的效率。資料庫表分區進行插入操作的原理:當寫入一筆記錄時,分區層會開啟並鎖住所有的底層表,然後確定哪個分區接受這條記錄,再將記錄寫入對應的底層表。
什麼是分割區?
分割區是依照規則分解表,將資料分段分割在多個位置存放,可以是同一塊磁碟也可以在不同的機器。分區後,表面上還是一張表,但資料散列到多個位置了。 app讀寫的時候操作的還是大表名字,db自動去組織分區的資料。
分區又可以分為兩種:
#1、水平分區(Horizontal Partitioning)
這種形式分區是將表格的行進行分區,透過這樣的方式不同分組裡面的物理列分割的資料集得以組合,從而進行個體分割(單分區)或集體分割(1個或多個分區) 。所有在表中定義的列在每個資料集中都能找到,
所以表的特性依然得以維持。
舉個簡單例子:一個包含十年發票記錄的表可以被分區為十個不同的分區,每個分區包含的是其中一年的記錄。 (註:這裡具體使用的分區方式我們後面再說,可以先說一點,一定要透過某個屬性列來分割,譬如這裡使用的列就是年份)
2、垂直分區( Vertical Partitioning)
這種分區方式一般來說是透過對錶的垂直劃分來減少目標表的寬度,使某些特定的列被劃分到特定的分區,每個分區都包含了其中的列所對應的行。
舉個簡單例子:一個包含了大text和BLOB列的表,這些text和BLOB列又不常被訪問,這時候就要把這些不常使用的text和BLOB了劃分到另一個分區,在保證它們資料相關性的同時還能提高存取速度。
分區表的原理
分區表是由多個相關的底層表實現,這些底層表也是由句柄物件表示,所以我們也可以直接存取各個分區,儲存引擎管理分區的各個底層表和管理普通表一樣(所有的底層表都必須使用相同的儲存引擎),分區表的索引只是在各個底層表上各自加上一個相同的索引,從儲存引擎的角度來看,底層表和一個普通表沒有任何不同,儲存引擎也無須知道這是一個普通表還是一個分區表的一部分。
在分區表上的操作按照下面的操作邏輯進行:
select查詢:
當查詢一個分區表的時候,分區層先打開並鎖住所有的底層表,優化器判斷是否可以過濾部分分區,然後再調用對應的儲存引擎介面存取各個分區的資料
insert操作:
當寫入一條記錄時,分區層打開並鎖住所有的底層表,然後確定哪個分區接受這條記錄,再將記錄寫入對應的底層表
delete操作:
當刪除一筆記錄時,分區層先打開並鎖住所有的底層表,然後確定資料對應的分區,最後對相應底層表進行刪除操作
update操作:
當更新一條資料時,分區層先打開並且鎖住所有的底層表,mysql先確定需要更新的記錄在哪個分區,然後取出數據並更新,再判斷更新後的數據應該放在哪個分區,然後對底層表進行寫入操作,並對原數據所在的底層表進行刪除操作
雖然每個操作都會打開並鎖住所有的底層表,但這並不是說分區表在處理過程中是鎖住全表的,如果存儲引擎能夠自己實現行級鎖,如:innodb,則會在分區層釋放對應的表鎖,這個加鎖和解鎖過程與普通Innodb上的查詢類似。
在下面的場景中,分割區可以起到非常大的作用:
A:表非常大以至於無法全部都放在記憶體中,或只在表的最後部分有熱點數據,其他都是歷史數據
B:分區表的數據更容易維護,如:想批量刪除大量數據可以使用清除整個分區的方式。另外,還可以對一個獨立分區進行最佳化、檢查、修復等操作
C:分區表的資料可以分佈在不同的實體設備上,從而有效率地利用多個硬體設備
#D:可以使用分區表來避免某些特殊的瓶頸,如:innodb的單一索引的互斥訪問,ext3檔案系統的inode鎖定競爭等
E:如果需要,還可以備份和恢復獨立的分區,這在非常大的資料集的場景下效果非常好
F:最佳化查詢,在where字句中包含分區列時,可以只使用必要的分區來提高查詢效率,同時在涉及sum()和count()這類聚合函數的查詢時,可以在每個分區上面並行處理,最終只需要總結所有分區得到的結果。
mysql資料庫的分區總是把null當作比任何非null更小的值,這和資料庫中處理null值的order by操作是一樣的,升序排序時null總是在最前面,因此對於不同的分割區類型,mysql資料庫對於null的處理也各不相同。
對於range分割區,如果向分割區列插入了null,則mysql資料庫會將該值放入最左邊的分割區,注意,如果刪除分割區,分割區下的所有內容都從磁碟中刪掉了,null所在分割區被刪除,null值也跟著被刪除了。
在list分割區下要使用null,則必須明確定義在分割區的雜湊值中,否則插入null時會報錯。 hash和key分割區對於null的處理方式和range,list分割區不一樣,任何分割函數都會將null傳回為0.
分區就是將資料庫或其構成元素分割成不同的獨立部分
-是一種預先組織表格儲存的方法
##mysql支援水平分割區
#將特定表行指派為行的子集分區的分佈是跨實體儲存進行的
—根據使用者在需要時設定的指定規則——每個分區儲存為其自己的單元資料的分割
—根據分區功能將資料分割為子集——分區類型和表達式是表定義的一部分——表達式可以是整數或傳回整數值的函數。 ——此值根據定義決定將每個記錄儲存在哪個分區中1.primary key和unique key必須包含在分區key的一部分,否則在建立primary key和unique index時會報”ERROR 1503 (HY000)“2.範圍分區添加分區只能在最大值後面追加分區3.所有分區的engine必須一樣4.範圍分區分區字段:integer、數值表達式、日期列,日期函數表達式(如year(),to_days(),to_seconds(),unix_timestamp())#分割區管理
新增分割區
ALTER TABLE sale_data ADD PARTITION (PARTITION p201010 VALUES LESS THAN (201011));
#刪除分割區
–當刪除了一個分區,也同時刪除了該分割區中所有的資料。ALTER TABLE sale_data DROP PARTITION p201010;
分區的合併
下面的SQL,將p201001 – p201009 合併為3個分割區p2010Q1 – p2010Q3ALTER TABLE sale_data REORGANIZE PARTITION p201001,p201002,p201003, p201004,p201005,p201006, p201007,p201008,p201009 INTO ( PARTITION p2010Q1 VALUES LESS THAN (201004), PARTITION p2010Q2 VALUES LESS THAN (201007), PARTITION p2010Q3 VALUES LESS THAN (201010) );
以上是資料庫表格分割區可提升插入效率嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!