MySQL優化系列(四)--表的設計與優化(單表、多表)

一、單表設計與優化:
(1)設計規範化表,消除數據冗餘(以使用正確字段類型最明顯):

表設計三範式:
第一範式:字段的原子性約束,要求字段具有原子性,不可再分割。
第二範式:記錄的唯一性約束,要求記錄有唯一標識,每條記錄需要一個字段來作爲實體的唯一標識,即每列都要和主鍵相關
第三範式:字段冗餘性約束。主鍵沒有直接關係的數據列必須消除(再創建一個表來存放他們,外鍵除外)。
如果數據庫設計達到完全的標準化,則把所有表通過關鍵詞連接在一起,不會出現任何數據的複本。標準化的優點是避免了數據冗餘,節省存儲空間;也對數據的一致性提供了根本的保障,杜絕了數據不一致的現象,同時也提高了效率。
所有字段類型:
(一)整型數值:
在這裏插入圖片描述
(二)浮點數類型
在這裏插入圖片描述
(三)定點數類型
在這裏插入圖片描述
關於浮點數與定點數有點看法:
浮點數相對於定點數的優點是在長度一定的情況下,浮點數能夠表示更大的數據範圍;它的缺點是會引起精度問題。
使用時我們要注意:

  1. 浮點數存在誤差問題;
  2. 對貨幣等對精度敏感的數據,應該用定點數表示或存儲;
  3. 編程中,如果用到浮點數,要特別注意誤差問題,並儘量避免做浮點數比較;
  4. 要注意浮點數中一些特殊值的處理。
    (四)位類型
    在這裏插入圖片描述
    (五)日期時間類型
    在這裏插入圖片描述
    mysql中用now()寫入當前時間。
    (六)字符串類型:
    在這裏插入圖片描述
    針對常用的varchar,我們來思考幾個問題:
    1)varchar的長度?
    MySQL的文檔,其中對varchar字段類型這樣描述:varchar(m) 變長字符串。m 表示最大列長度。m的範圍是0到65,535。(VARCHAR的最大實際長度由最長的行的大小和使用的字符集確定,最大有效長度是65,532字節)。

mysql varchar(50) 不管中文 還是英文 都是存50個的,但是一個表中所有varchar字段的總長度跟編碼有關,如果是utf-8,那麼大概65535/3,如果是gbk,那麼大概65535/2.
2)存儲限制?編碼長度限制?行長度限制?超出了,會變成怎樣?
針對第一個問題:varchar 字段是將實際內容單獨存儲在聚簇索引之外,實際存儲從第二個字節開始,接着要用1到2個字節表示實際長度(長度超過255時需要2個字節),因此最大長度不能超過65535。

針對第二個問題:字符類型若爲gbk,每個字符最多佔2個字節。字符類型若爲utf8,每個字符最多佔3個字節。

針對第三個問題:導致實際應用中varchar長度限制的是一個行定義的長度。 MySQL要求一個行的定義長度不能超過65535。
若定義的時候超過上述限制,則varchar字段會被強行轉爲text類型,併產生warning。
3)與char的對比:
CHAR(M)定義的列的長度爲固定的,M取值可以爲0~255之間,當保存CHAR值時,在它們的右邊填充空格以達到指定的長度。當檢 索到CHAR值時,尾部的空格被刪除掉。在存儲或檢索過程中不進行大小寫轉換。CHAR存儲定長數據很方便,CHAR字段上的索引效率級高,比如定義 char(10),那麼不論你存儲的數據是否達到了10個字節,都要佔去10個字節的空間,不足的自動用空格填充。

CHAR和VARCHAR最大的不同就是一個是固定長度,一個是可變長度。由於是可變長度,因此實際存儲的時候是實際字符串再加上一個記錄 字符串長度的字節(如果超過255則需要兩個字節)。如果分配給CHAR或VARCHAR列的值超過列的最大長度,則對值進行裁剪以使其適合。如果被裁掉 的字符不是空格,則會產生一條警告。如果裁剪非空格字符,則會造成錯誤(而不是警告)並通過使用嚴格SQL模式禁用值的插入。

4)char、varchar與text的建議:
TEXT只能儲存純文本文件。

效率來說基本是char>varchar>text,但是如果使用的是Innodb引擎的話,推薦使用varchar代替char

char和varchar可以有默認值,text不能指定默認值

(一)數字類型:
1)不到不要使用DOUBLE,不僅僅只是存儲長度的問題,同時還會存在精確性的問題。
2)固定精度的小數,也不建議使用DECIMAL
建議乘以固定倍數轉換成整數存儲,可以大大節省存儲空間,且不會帶來任何附加維護成本。

3)對於整數的存儲,在數據量較大的情況下,建議區分開 TINYINT / INT / BIGINT 的選擇
因爲三者所佔用的存儲空間也有很大的差別,能確定不會使用負數的字段,建議添加unsigned定義。當然,如果數據量較小的數據庫,也可以不用嚴格區分三個整數類型。

4)對於整型數值,mysql支持在類型名稱後面的小括號內指定顯示寬度
例如int(5)表示當數值寬度小於5位時候在數值前面填滿寬度,一般配合zerofill屬性使用。如果一個列指定爲zerofill,則MySQL自動爲該列添加unsigned屬性。

5)在數據量較大時、建議把實數類型轉爲整數類型。
原因很簡單:1. 浮點不精確;2.定點計算代價昂貴。例如:要存放財務數據精確到萬分之一、則可以把所有金額乘以一百萬、然後存在BIGINT下。
(二)字符類型:
1)儘量不要使用 TEXT 數據類型,其處理方式決定了他的性能要低於char或者是varchar類型的處理。

定長字段,建議使用 CHAR 類型,不定長字段儘量使用 VARCHAR,且僅僅設定適當的最大長度,而不是非常隨意的給一個很大的最大長度限定,因爲不同的長度範圍,MySQL也會有不一樣的存儲處理。

2)char會刪除字符串尾部的空格,varchar不會,varchar向前補1-2字節;char定長。binary類似於char,binary只能保存二進制字符串。
char是固定長度,所以它的處理速度比varchar快得多,但缺點是浪費存儲空間,不能在行尾保存空格。在MySQL中,MyISAM建議使用固定長度代替可變長度列;InnoDB建議使用varchar類型,因爲在InnoDB中,內部行存儲格式沒有區分固定長度和可變長度。

3)enum類型忽略大小寫。
4)text與blob區別:

blob保存二進制數據;text保存字符數據,有字符集。text和blob不能有默認值。

應用:text與blob主要區別是text用來保存字符數據(如文章,日記等),blob用來保存二進制數據(如照片等)。blob與text在執行了大量刪除操作時候,有性能問題(產生大量的“空洞“),爲提高性能建議定期optimize table 對這類表進行碎片整理。

關於text與blob我們有些看法建議:
BLOB和TEXT值也會引起自己的一些問題,特別是執行了大量的刪除或更新操作的時候。刪除這種值會在數據表中留下很大的"空洞",以後填入這些"空洞"的記錄可能長度不同,爲了提高性能,建議定期使用 OPTIMIZE TABLE 功能對這類表進行碎片整理.

在不必要的時候避免檢索大型的BLOB或TEXT值。

把BLOB或TEXT列分離到單獨的表中。在某些環境中,如果把這些數據列移動到第二張數據表中,可以讓你把原數據表中 的數據列轉換爲固定長度的數據行格式,那麼它就是有意義的。這會減少主表中的碎片,使你得到固定長度數據行的性能優勢。它還使你在主數據表上運行 SELECT *查詢的時候不會通過網絡傳輸大量的BLOB或TEXT值。
(三)時間類型:
1)儘量使用TIMESTAMP類型

因爲其存儲空間只需要 DATETIME 類型的一半。對於只需要精確到某一天的數據類型,建議使用DATE類型,因爲他的存儲空間只需要3個字節,比TIMESTAMP還少。不建議通過INT類型類存儲一個unix timestamp 的值,因爲這太不直觀,會給維護帶來不必要的麻煩,同時還不會帶來任何好處。

2)根據實際需要選擇能夠滿足應用的最小存儲日期類型。
3)timestamp,日期類型中只有它能夠和實際時區相對應。

(四)ENUM & SET:
對於狀態字段,可以嘗試使用 ENUM 來存放,因爲可以極大的降低存儲空間,而且即使需要增加新的類型,只要增加於末尾,修改結構也不需要重建表數據。如果是存放可預先定義的屬性數據呢?可以嘗試使用SET類型,即使存在多種屬性,同樣可以遊刃有餘,同時還可以節省不小的存儲空間。

(五)LOB類型:
強烈反對在數據庫中存放 LOB 類型數據,雖然數據庫提供了這樣的功能,但這不是他所擅長的,我們更應該讓合適的工具做他擅長的事情,才能將其發揮到極致
(2) 適當的冗餘,增加計算列:
數據庫設計的使用原則是:在數據冗餘和處理速度之間找到合適的平衡點。
滿足範式的表一定是規範化的表,但不一定是最佳的設計。很多情況下會爲了提高數據庫的運行效率,常常需要降低範式標準:適當增加冗餘,達到以空間換時間的目的。比如我們有一個表,產品名稱,單價,庫存量,總價值。這個表是不滿足第三範式的,因爲“總價值”可以由“單價”乘以“數量”得到,說明“金額”是冗餘字段。但是,增加“總價值”這個冗餘字段,可以提高查詢統計的速度,這就是以空間換時間的作法。合理的冗餘可以分散數據量大的表的併發壓力,也可以加快特殊查詢的速度,冗餘字段可以有效減少數據庫表的連接,提高效率。
(3)索引的設計:
表優化的重要途徑,比如百萬級別的表沒有索引,註定卡死。

(4)主鍵和外鍵的必要性(實際項目開發的重要取捨)
概述:
主鍵和外鍵的設計,在全局數據庫的設計中,佔有重要地位。因爲主鍵是實體的抽象,主鍵與外鍵的配對,表示實體之間的連接。
主鍵:
標識某條記錄。對於數據量大,查詢頻繁的數據庫表,一定要有主鍵,主鍵可以增加效率、防止重複等優點。
主鍵一般選擇總的長度小的鍵,小的鍵比較速度快,同時小的鍵可以使主鍵的B樹結構的層次更少
主鍵的選擇還要注意組合主鍵的字段次序,對於組合主鍵來說,不同的字段次序的主鍵的性能差別可能會很大,一般選擇重複率低、單獨或者組合查詢可能性大的字段放在前面。
外鍵:
外鍵是最有效的一致性維護方法。
數據庫的一致性要求,一次可以用外鍵、check約束、規則約束、觸發器、客戶端程序來實現。一般,離數據越近的方法效率越高。但是!!!要謹慎使用級聯刪除和級聯更新,因爲級聯刪除和級聯更新有些突破了傳統對外鍵的定義,使用前必須確定自己已經把握好其功能範圍,否則,級聯刪除和級聯更新可能讓你的數據莫名其妙的被修改或者丟失。不過,從性能看級聯刪除和級聯更新是比其他更高效的方法。
實際項目中主外鍵的取捨設計:(在性能和可擴展性之間尋求平衡)
邊緣模塊值得是小功能不常用需求很少再giant的模塊;中心模塊指的是關聯的東西太多的模塊,是很多表的主表;物理鍵指的是在表建立主外鍵關聯;邏輯主外鍵指的是利用字段去實現邏輯主外鍵關聯;熱點模塊指的是需求經常要改的模塊。
大型系統:
1、針對性能要求不高、安全要求高的模塊,推薦使用物理主外鍵關聯;針對性能要求高、安全自己控制的模塊,推薦不用物理外鍵。
2、針對中心模塊的其他模塊的聯繫,主鍵使用物理主外鍵
3、針對熱點模塊,必須使用邏輯主外鍵
4、針對邊緣模塊,推薦使用物理主外鍵
小系統
推薦還是使用外鍵
注意:
不用外鍵而用程序控制數據一致性和完整性時,應該寫一層來保證,然後個個應用通過這個層來訪問數據庫。
外鍵是有性能問題的,不能過分追求。
(5)存儲過程、視圖、函數的適當使用(這些是優化的方法,這幾個後面會講):
很多人習慣將複雜操作都放在應用程序層,但如果你要優化數據訪問性能,將SQL代碼移植到數據庫上(使用存儲過程,視圖,函數和觸發器)也是一個很大的改進原因如下:

1)存儲過程減少了網絡傳輸、處理及存儲的工作量,且經過編譯和優化,執行速度快,易於維護,且表的結構改變時,不影響客戶端的應用程序
2)使用存儲過程,視圖,函數有助於減少應用程序中SQL複製的弊端,因爲現在只在一個地方集中處理SQL
3)使用數據庫對象實現所有的TSQL有助於分析TSQL的性能問題,同時有助於你集中管理TSQL代碼,更好的重構TSQL代碼。

(6)傳說中的‘三少原則’:
數據庫的表越少越好
表的字段月少越好
字段中的組合主鍵、組合索引越少越好
這裏的少是相對的,是減少數據冗餘的重要設計理念而已。

實際上,我們爲了減少單表查詢壓力,會把去分表,從而分發記錄量,避免一個超級表的誕生。
(7)分隔你的表,減小表尺寸
如果發現某個表的記錄太多,例如超過一千萬跳,則要對該表進行水平分隔。水平分隔的做法是:以該表主鍵的某個值外界限,將該表的記錄水平分隔爲兩個表
若果你若發現某個表的字段太多,例如超過八十個,則垂直分隔該表,將原來的一個表分隔爲兩個表。
(8)、字段設計原則
字段是數據庫最基本的單位,其設計對性能的影響很大的。需要注意如下:
1)數據類型儘量用數字型,數字型的字段比字符型的快很多
2)在可以滿足可預見的未來需求的前提下,數據類型儘量小,
3)儘量不要允許null,除非必要,可以用not null +default代替

NULL 類型比較特殊,SQL 難優化。雖然 MySQL NULL類型和 Oracle 的NULL 有差異,會進入索引中,但如果是一個組合索引,那麼這個NULL 類型的字段會極大影響整個索引的效率。此外,NULL 在索引中的處理也是特殊的,也會佔用額外的存放空間。
4)少用text和image,二進制字段的讀寫是比較慢的,而且,讀取的方法也不多,大部分情況下最好不用
5)自增字段要慎用,不利於數據遷移。

二、基於單標設計的奪標設計原則:
(1)表關係:
一)一對一關係:
定義:

在這種關係中,關係表的每一邊都只能存在一個記錄。每個數據表中的關鍵字在對應的關係表中只能存在一個記錄或者沒有對應的記錄。這種關係和一對配偶之間的關係非常相似——要麼你已經結婚,你和你的配偶只能有一個配偶,要麼你沒有結婚沒有配偶。大多數的一對一的關係都是某種商業規則約束的結果,而不是按照數據的自然屬性來得到的。如果沒有這些規則的約束,你通常可以把兩個數據表合併進一個數據表,而且不會打破任何規範化的規則。

一對一關係又分爲:一對一外鍵關聯和一對一主鍵關聯。
一對一主鍵關聯:要求兩個表的主鍵必須完全一致,通過兩個表的主鍵建立關聯關係。

可以看到下圖,很明顯的,班級編號作爲主鍵的話,就是一個主鍵關聯了。
在這裏插入圖片描述
一對一外鍵關聯:
下面又很明顯看到,以班主任ID作爲外鍵關聯起來的一個表。
在這裏插入圖片描述
二)一對多關係(多對一):
定義:

主鍵數據表中只能含有一個記錄,而在其關係表中這條記錄可以與一個或者多個記錄相關,也可以沒有記錄與之相關。這種關係類似於你和你的父母之間的關係。你只有一位母親,但是你母親可以有幾個孩子。
三)多對多關係:
定義:

兩個數據表裏的每條記錄都可以和另一個數據表裏任意數量的記錄(或者沒有記錄)相關。例如,如果你有多個兄弟姐妹,這對你的兄弟姐妹也是一樣(有多個兄弟姐妹),多對多這種關係需要引入第三個數據表,這種數據表稱爲聯繫表或者連接表,因爲關係型系統不能直接實現這種關係。

在RDBMS中,必須使用中間表來表示多對多的關係。中間表我們可以分成兩種,一種是純粹表示關係的中間表,一種是表示中間實體的中間表。

純粹表示關係的中間表很簡單,只需要兩列:AID和BID,AID以外鍵關聯到A表的主鍵,BID以外鍵關聯到B表的主鍵,然後這兩個列組成聯合主鍵。這個中間表純粹是表示多對多關係而存在,在業務上不會有對應的實體與之對應。比如前面提到的學生和課程的關係,如果我們只需要知道哪些學生上哪些課,哪些課有哪些學生選,不需要有更多的信息的情況下,我們就可以建立“學生課程”中間表,裏面只有學生ID和課程ID兩個字段。
在這裏插入圖片描述
中間實體是在純粹的中間關係表的基礎上,加上了更多的屬性,從而形成了一個新的實體。比如上面提到的學生和課程的關係,如果我們需要記錄學生選課的時間、學生選擇這門課程後的考試成績,那麼我們就像建立一個“選課”實體,
該實體具有如下屬性:
選課ID,主鍵
學生ID,與學生表做外鍵關聯
課程ID,與課程表做外鍵關聯
選課時間,DateTime類型
考試成績,記錄選修該課程後考試的最終成績
注意:
一)外鍵與索引:

外鍵是一種約束,與索引的概念不一樣,只是大多數情況下,我們建立外鍵時,都會在外鍵列上建立對應的索引。外鍵的存在會在每一次數據插入、修改時進行約束檢查,如果不滿足外鍵約束,則禁止數據的插入或修改。這必然帶來一個問題,就是在數據量特別大的情況下,每一次約束檢查必然導致性能的下降。索引其實也有類似的問題,索引如果鍵多了,那麼在插入刪除修改時也要去維護對應的索引,所以索引的存在也會導致數據操作變慢。
不過外鍵與索引的優點不同,外鍵只是保證數據的一致性,並不能給系統性能帶來任何好處,所以由於外鍵導致的插入數據變慢會隨着數據量的增長而越來越嚴重。而索引的目的性是爲了索引數據更快,維護數據時導致的索引數據的變更,對性能的影響不會像外鍵那樣隨着數據量增長而變得驗證(當然大數據量時的索引樹維護迴避小數據量的索引樹維護更麻煩,但至少不會像外鍵那樣)。
初語性能的考慮,如果我們的系統完全由我們開發的程序使用,而不需要提供數據庫給其他應用系統寫入數據,而且對性能要求較高,那麼我們可以考慮在生產環境中不適用外鍵,只需要建立能夠提高性能的索引。由於整個數據庫的操作都是由我們開發的程序來完成的,所以我們程序可以再開發過程中做好各方面的一致性檢查,保證操作的數據時滿足外鍵約束的,而不需要真正的存在這樣一個外鍵約束。具體做法爲:我們在建立數據庫時有多個腳本,包括創建表、初始化數據、創建索引、外鍵等,我們在開發和測試環境中,都把這些腳本運行了,使得開發測試環境中的數據庫時完整的,經過大量測試保證營養程序能夠維護數據之間的約束的情況下,那麼我們在生產時,不需要運行創建外鍵這個腳本文件,只需要創建表、初始化數據、索引就可以了。
二)建立關係
在開始着手考慮建立關係表之間的關係之前,你可能需要對數據非常熟悉。只有在熟悉數據之後,關聯會比你剛開始的時候更明顯。你的數據庫系統依賴於在兩個數據表中找到的匹配值來建立關係。

進行匹配的值都是主鍵和外鍵的值。(關係模型不要求一個關係必須對應的使用一個主鍵來確定。你可以使用數據表中的任何備選關鍵字來建立關係,但是使用主鍵是大家都已經接受的標準。)主鍵(primary key)唯一的識別表中的每個記錄。而外鍵(foreign key)只是簡單的將一個數據表中的主鍵存放在另外一個數據表中。同樣地,對於你來說也不需要做太多的工作——只是簡單地將主鍵加到關係表中,並將其定義爲外鍵。
(2)分表原則:
分表主要目的是爲突破單節點數據庫服務器的I/O能力限制,解決數據庫擴展性問題。同時分庫分表等思想也將引出以後的數據庫集羣、主從複製、讀寫分離方案。。。
爲什麼我們要分表分區??
日常開發中我們經常會遇到大表的情況,所謂的大表是指存儲了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,導致數據庫在查詢和插入的時候耗時太長,性能低下,如果涉及聯合查詢的情況,性能會更加糟糕。分表和表分區的目的就是減少數據庫的負擔,提高數據庫的效率,通常點來講就是提高表的增刪改查效率。
(一)表拆分方式:
1)垂直切分:

定義:
把主鍵和一些數據表的列放在一個表中,然後把主鍵和另一些數據表的列放在一個表中。
如果一個表的某些列常用,另一些不常用,則可以採用垂直拆分。
優點:可以使數據行變小,一個數據也就可以存放更多的數據,在查詢時候可以減少I/O次數;可以最大化利用cache的目的。
缺點:主碼(主鍵)出現冗餘,需要管理冗餘;查詢所有數據時需要join操作(增加CPU開銷),需要從業務上規避。
2)水平拆分(分表,分區)–按表中某一字段值的範圍劃分:
定義:
根據列的範圍值進行合理切分,放在多個獨立的表或分區中。

適用場景:
表很大,分隔後可以降低查詢時候需要讀取的數據和索引的頁數,同時降低索引的層數,提高查詢速度。
表中的數據時獨立的,例如表中分別記錄各個地區的數據或者不同時期的數據,特別是有些數據常用,而另一些數據不常用。
需要把數據放在多個存儲介質上
需要把歷史數據和當前數據拆分開
例子:
當伴隨着某一個表的數據量越來越大,以至於不能承受的時候,就需要對它進行進一步的切分。一種選擇是根據key 的範圍來做切分,譬如ID 爲 1-10000的放到表A上,ID 爲10000~20000的放到表B。這樣的擴展就是可預見的。另一種是根據某一字段值來劃分,譬如根據用戶名的首字母,如果是A-D,就屬於表A,E-H就屬於表B。這樣做也存在不均衡性,當某個範圍超出了單點所能承受的範圍就需要繼續切分。還有按日期切分等等。
可以使用Mrg_Myisam引擎實現水平分表
優點:
單表大小可控,天然水平擴展。降低在查詢時需要讀的數據和索引的頁數,同時也降低了索引的層數,加快了查詢速度。

缺點:
無法解決集中寫入瓶頸的問題。同時,水平分割會給應用增加複雜度,它通常在查詢時需要多個表名,查詢所有數據需要union操作。在許多數據庫應用中,這種複雜性會超過它帶來的優點,因爲只要索引關鍵字不大,則在索引用於查詢時,表中增加兩到三倍數據量,查詢時也就增加讀一個索引層的磁盤次數。
3)散列庫表(基於hash算法的切分):
定義:
表散列與水平分割相似,但沒有水平分割那樣的明顯分割界限,採用Hash算法把數據分散到各個分表中, 這樣IO更加均衡。一般採用mod來切分,一開始確定切分數據庫的個數,通過hash取模來決定使用哪臺。這種方法能夠平均地來分配數據,但是伴隨着數據量的增大,需要進行擴展的時候,這種方式無法做到在線擴容。每增加節點的時候,就需要對hash 算法重新運算。
我們會按照業務或者功能模塊將數據庫進行分離,不同的模塊對應不同的數據庫或者表,再按照一定的策略對某個頁面或者功能進行更小的數據庫散列,比如用戶表,按照用戶ID進行表散列,散列128張表,則應就能夠低成本的提升系統的性能並且有很好的擴展性

優點:
數據分佈均勻

缺點:
數據遷移的時候麻煩,不能按照機器性能分攤數據(可用一致性哈希解決這個問題)
(二)在瞭解完分表了,我們先來理解區分分區與分表吧。
分區:
定義:

分區和分表相似,都是按照規則分解表。不同在於分表將大表分解爲若干個獨立的實體表,而分區是將數據分段劃分在多個位置存放,可以是同一塊磁盤也可以在不同的機器。分區後,表面上還是一張表,但數據散列到多個位置了。app讀寫的時候操作的還是大表名字,db自動去組織分區的數據。

分表定義:
分表是將一個大表按照一定的規則分解成多張具有獨立存儲空間的實體表,我們可以稱爲子表,每個表都對應三個文件,MYD數據文件,.MYI索引文件,.frm表結構文件。這些子表可以分佈在同一塊磁盤上,也可以在不同的機器上。app讀寫的時候根據事先定義好的規則得到對應的子表名,然後去操作它。

mysql分表和分區有什麼聯繫呢?:
1.都能提高mysql的性高,在高併發狀態下都有一個良好的表現。
2.分表和分區不矛盾,可以相互配合
,對於那些大訪問量,並且表數據比較多的表,我們可以採取分表和分區結合的方式(如果merge這種分表方式,不能和分區配合的話,可以用其他的分表試),訪問量不大,但是表數據很多的表,我們可以採取分區的方式等。
3.分表技術是比較麻煩的,需要手動去創建子表,app服務端讀寫時候需要計算子表名。採用merge好一些,但也要創建子表和配置子表間的union關係。
4.表分區相對於分表,操作方便,不需要創建子表。

(三)表拆分建議:(針對大系統)
其實這點沒有明確的判斷標準,比較依賴實際業務情況和經驗判斷。一般MySQL單表1000W左右的數據是沒有問題的(前提是應用系統和數據庫等層面設計和優化的比較好)。

1)對記錄多的表進行拆分。(幾百-上千萬級別的表)
2)需要拆分的表分爲動態表和相對靜態表。動態表拆分到不同庫,靜態表存在於公共庫。從公共庫同步到分庫。實現表的連接。
3)按照年、月、地域等來分割,或者根據時間範圍、和很固定又清晰的字段值範圍等,具有確定的分割標誌來分割。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章