MySQL優化大全

 

1. 優化SQL前端

  1)經過show status瞭解各類sql的執行頻率mysql

        show status like 'Com_%'
        瞭解 Com_select,Com_insert 的執行次數
   2)  經過Explain分析低效的sql語句
   3)   創建合適的索引
   4)   經過show status like 'Handler_%'查看索引的使用狀況
         handler_read_key:根據索引讀取行的請求數。若是該值很大,說明你的查詢和表都創建了很好的索引,代表索引效率的很高
         Handler_read_rnd_key:根據固定位置讀取行的請求數。若是你執行不少須要排序的查詢,該值會很高。你可能有不少須要完整表掃描的查詢,或者你使用了不正確的索引用來多表查詢。
web

         Handler read rnd next:從數據文件中讀取行的請求數。若是你在掃描不少表,該值會很大。一般狀況下這意味着你的表沒有作好索引,或者你的查詢語句沒有使用好索引字段。算法

   5)   按期分析表和檢查表
         analyze table test_table和check table test_table
         而後查看Msg_text字段的值是不是ok
   6)按期優化表 optimize table test_table
         若是對錶的可變字段varchar blob,text等進行了不少更改, 則應用OPTIMIZE優化。
sql

         在多數的設置中,您根本不須要運行OPTIMIZE TABLE。即便您對可變長度的行進行了大量的更新,您也不須要常常運行,每週一次或每個月一次便可,只對特定的表運行。
       OPTIMIZE TABLE只對MyISAM, BDB和InnoDB表起做用。
       對於MyISAM表,OPTIMIZE TABLE按以下方式操做:
       若是表已經刪除或分解了行,則修復表。
       若是未對索引頁進行分類,則進行分類。
       若是表的統計數據沒有更新(而且經過對索引進行分類不能實現修復),則進行更新。
   7)  優化 order by orgroup by等
數據庫

    詳細內容:SQL優化大全緩存

 

 

2. 優化數據庫對象安全

 

1)選擇表合適存儲引擎:服務器

            MyISAM:  應用時以讀和插入操做爲主,只有少許的更新和刪除,而且對事務的完整性,併發性要求不是很高的.數據結構

            Innodb: 事務處理,以及併發條件下要求數據的一致性。除了插入和查詢外,包括不少的更新和刪除。(Innodb有效地下降刪除和更新致使的鎖定)。對於支持事務的InnoDB類型的表來講,影響速度的主要緣由是AUTOCOMMIT默認設置是打開的,並且程序沒有顯式調用BEGIN 開始事務,致使每插入一條都自動提交,嚴重影響了速度。能夠在執行sql前調用begin,多條sql造成一個事物(即便autocommit打開也能夠),將大大提升性能。

            Memory:數據保存在RAM,快速訪問數據。要求表不能太大或者對MySQL異常終止後不用恢復數據的

            Merge:      
2)優化表的數據類型,選擇合適的數據類型:

           原則:更小一般更好,簡單就好,全部字段都得有默認值,儘可能避免null:

           例如:數據庫表設計時候更小的佔磁盤空間儘量使用更小的整數類型.(mediumint就比int更合適)

           好比時間字段:datetime和timestamp, datetime佔用8個字節,而timestamp佔用4個字節,只用了一半,而timestamp表示的範圍是1970—2037適合作更新時間

  MySQL能夠很好的支持大數據量的存取,可是通常說來,數據庫中的表越小,在它上面執行的查詢也就會越快。所以,在建立表的時候,爲了得到更好的性能,咱們能夠將表中字段的寬度設得儘量小。例如,在定義郵政編碼這個字段時,若是將其設置爲CHAR(255),顯然給數據庫增長了沒必要要的空間,甚至使用VARCHAR這種類型也是多餘的,由於CHAR(6)就能夠很好的完成任務了。一樣的,若是能夠的話,咱們應該使用MEDIUMINT而不是BIGIN來定義整型字段。
  另一個提升效率的方法是在可能的狀況下,應該儘可能把字段設置爲NOT NULL,這樣在未來執行查詢的時候,數據庫不用去比較NULL值。
  對於某些文本字段,例如「省份」或者「性別」,咱們能夠將它們定義爲ENUM類型。由於在MySQL中,ENUM類型被看成數值型數據來處理,而數值型數據被處理起來的速度要比文本類型快得多。這樣,咱們又能夠提升數據庫的性能。

3) 字符串數據類型:char,varchar,text選擇區別
       (1)長度的區別
,char範圍是0~255,varchar最長是64k,可是注意這裏的64k是整個row的長度, 要考慮到其它的column,還有若是存在not null的時候也會佔用一位,對不一樣的字符集,有效長度還不同,好比utf8的,最多21845,還要除去別的column,可是varchar在通常 狀況下存儲都夠用了。若是遇到了大文本,考慮使用text,最大能到4G。 

      (2) 效率來講基本是char>varchar>text,可是若是使用的是Innodb引擎的話,推薦使用varchar代替

     (3)默認值  charchar和varchar能夠有默認值,text不能指定默認值

4)MySQL中float數據類型的問題

      (1) .FLOAT或DOUBLE列與具備數值類型的數值進行比較,不能使用等式(=)比較.這個是由於浮點數精度的問題,會產生偏差。

  (2)對貨幣等對精度敏感的數據,應該用定點數表示或存儲

      數據庫選擇合適的數據類型存儲仍是頗有必要的,對性能有必定影響。這裏在零碎記錄兩筆,對於int類型的,若是不須要存取負值,最好加上unsigned;對於常常出如今where語句中的字段,考慮加索引,整型的尤爲適合加索引。

 5)在InnoDB數據表設計中,咱們須要注意幾點:

    1. 顯式的定義一個 INT 類型自增字段的主鍵,這個字段能夠僅用於作主鍵,不作其餘用途
    2. 若是不顯式定義主鍵的話,可能會致使InnoDB每次都須要對新數據行進行排序,嚴重損害性能
    3. 儘可能保證不對主鍵字段進行更新修改,防止主鍵字段發生變化,引起數據存儲碎片,下降IO性能
    4. 若是須要對主鍵字段進行更新,請將該字段轉變成一個惟一索引約束字段,另外建立一個沒有其餘業務意義的自增字段作主鍵
    5. 主鍵字段類型儘量小,能用SMALLINT就不用INT,能用INT就不用BIGINT
    6. 主鍵字段放在數據表的第一順序

 

 

 

3. 優化索引

 

  索引是提升數據庫性能的經常使用方法,它能夠令數據庫服務器以比沒有索引快得多的速度檢索特定的行,尤爲是在查詢語句當中包含有MAX(), MIN()和ORDERBY這些命令的時候,性能提升更爲明顯.

    那該對哪些字段創建索引呢?通常說來,索引應創建在那些將用於JOIN, WHERE判斷和ORDER BY排序的字段上。儘可能不要對數據庫中某個含有大量重複的值的字段創建索引。對於一個ENUM類型的字段來講,出現大量重複值是頗有可能的狀況,例如customerinfo中的「province」..字段,在這樣的字段上創建索引將不會有什麼幫助;相反,還有可能下降數據庫的性能。咱們在建立表的時候能夠同時建立合適的索引,也可使用ALTER TABLE或CREATE INDEX在之後建立索引

1). 普通索引

        普通索引(由關鍵字KEY或INDEX定義的索引)的惟一任務是加快對數據的訪問速度。所以,應該只爲那些最常常出如今查詢條件(WHERE column = …)或排序條件(ORDER BY column)中的數據列建立索引。只要有可能,就應該選擇一個數據最整齊、最緊湊的數據列(如一個整數類型的數據列)來建立索引。

2). 惟一索引

        普通索引容許被索引的數據列包含重複的值。好比說,由於人有可能同名,因此同一個姓名在同一個」員工我的資料」數據表裏可能出現兩次或更屢次。
若是能肯定某個數據列將只包含彼此各不相同的值,在爲這個數據列建立索引的時候就應該用關鍵字UNIQUE把它定義爲一個惟一索引。這麼作的好處:一是簡 化了MySQL對這個索引的管理工做,這個索引也所以而變得更有效率;二是MySQL會在有新記錄插入數據表時,自動檢查新記錄的這個字段的值是否已經在 某個記錄的這個字段裏出現過了;若是是,MySQL將拒絕插入那條新記錄。也就是說,惟一索引能夠保證數據記錄的惟一性。事實上,在許多場合,人們建立惟 一索引的目的每每不是爲了提升訪問速度,而只是爲了不數據出現重複。

3). 主索引

        在前面已經反覆屢次強調過:必須爲主鍵字段建立一個索引,這個索引就是所謂的」主索引」。主索引與惟一索引的惟一區別是:前者在定義時使用的關鍵字是PRIMARY而不是UNIQUE。

 4). 外鍵索引

         若是爲某個外鍵字段定義了一個外鍵約束條件,MySQL就會定義一個內部索引來幫助本身以最有效率的方式去管理和使用外鍵約束條件。

 5). 複合索引

        索引能夠覆蓋多個數據列,如像INDEX(columnA, columnB)索引。這種索引的特色是MySQL能夠有選擇地使用一個這樣的索引。若是查詢操做只須要用到columnA數據列上的一個索引,就可使 用複合索引INDEX(columnA, columnB)。不過,這種用法僅適用於在複合索引中排列在前的數據列組合。好比說,INDEX(A, B, C)能夠當作A或(A, B)的索引來使用,但不能當作B、C或(B, C)的索引來使用。

 

 

4. 表鎖的問題

     跟性能相關的最重要的區別就是 MyISAM 和 InnoDB 實現的鎖機制不同! MyISAM 使用的是表鎖, 而 InnoDB實現的是行鎖。

1) MyISAM爲表級鎖

        因爲MyISAM寫進程優先得到鎖,使得讀鎖請求靠後等待隊列。不只如此,即便讀請求先到鎖等待隊列,寫請求後 到,寫鎖也會插到讀鎖請求以前!這是由於MySQL認爲寫請求通常比讀請求要重要。
        若是在大量更新操做的狀況下,使得很難得到讀鎖。從而形成阻塞。
        因此MyIsam不適合作大量更新操做的緣由

2 )INNODB的行鎖是基於索引實現,若是不經過索引訪問數據,Innodb會使用表鎖

 

表級鎖更適合以查詢爲主,只有少許按索引條件更新數據的應用。

行級鎖更適合於有大量按索引條件併發更新少許不一樣數據,同時又併發查詢。由於只鎖定要操做的行, 因此能夠多個線程同時操做不一樣的行(只要不操做其餘線程已經鎖定的行)。

 

 

5. MySQL server服務器配置優化

 

   1)使用show variables 瞭解服務器參數
   2)show status 瞭解服務器運行狀態,如鎖等待狀況,當前鏈接數等
   3)影響mysql性能的重要參數:

         key_buffer_size設置索引塊的緩存大小:key_buffer_size是對MyISAM表性能影響最大的一個參數

        經過:

    mysql> show global status like 'key_read%';
+-------------------+------------+
| Variable_name     | Value      |
+-------------------+------------+
| Key_read_requests | 3465117712 |
| Key_reads         | 624        |
+-------------------+------------+

   Key_read_requests:從緩存讀取索引的請求次數。
   Key_reads:從磁盤讀取索引的請求次數。

   一般人們認爲Key_read_requests / Key_reads越大越好

    須要適當加大key_buffer_size 

 

         table_cache數據庫打開表的緩存數量 ,每一個鏈接進來,都會至少打開一個表緩存。所以
         table_cache和max_connections有關, 例如 對於200個並行運行的鏈接,應該讓表的緩存至少是200 *N
         N 是能夠執行查詢的一個鏈接中的表的最大數

    4)  還有innodb_buffer_pool_size等innodb參數的設置

 

 

 

6. 磁盤IO優化

 

  對於咱們數據庫調優來講,磁盤I/O優化是數一數二的調優重點,咱們都知道木桶原理,短板絕對總體的好壞,而數據庫系統中這個短板正是因爲咱們 使用的硬件設備裏最弱的磁盤所致使。不少時候,咱們會發現系統中I/O累得要死,而CPU卻在那裏空閒等待,主要是因爲I/O執行響應時間太長,處理讀寫 的速度遠遠趕落後於CPU的處理速度,這時咱們會盡量的讓操做放到內存中進行,由磁盤與CPU的關係,轉變成內存與CPU的關係。可是,咱們始終不能回 避磁盤I/O的弱點,優化是必須的。

        磁盤搜索是巨大的性能瓶頸。當數據量變得很是大以至於緩存性能變得不可能有效時,該問題變得更加明顯。對於大數據庫,其中你或多或少地隨機訪問數據, 你能夠確 信對讀取操做須要至少一次硬盤搜索,寫操做須要屢次硬盤搜索。要想使該問題最小化, 應使用搜索次數較少的磁盤。

1)使用磁盤陣列  RAID (廉價磁盤冗餘陣列)

         RAID就是按照必定的策略將數據分佈到若干物理磁盤上,這樣不只加強了數據存儲的可靠性,並且提升數 據讀寫的性能 (RAID有不能的級別)
         1) 讀寫很頻繁的,可靠性要求也很高的,最好RAID 10
         2) 數據讀很頻繁,寫相對較少的,對可靠性必定要求的,選擇RAID 5

         3) 數據讀寫都很頻繁,可是可靠性要求不高的能夠選擇RAID 0

   
2) 使用符號連接 分佈I/O

          MYSQL在默認的狀況下,數據庫和數據表都存放在參數datadir定義的目錄下,這樣若是不使用RAID或者邏輯卷,全部的數據都存放在一個磁盤設備上,沒法發揮多磁盤並 行讀寫的優點。

         能夠將表和數據庫從數據庫目錄移動到其它的位置而且用指向新位置的符號連接進行替換。推薦的方法只須要將數據庫經過符號連接指到不一樣的磁盤。符號連接表僅做爲是 最後的辦法。

        符號連接一個數據庫的方法是,首先在一些有空閒空間的硬盤上建立一個目錄,而後從 MySQL 數據目錄中建立它的一個符號連接。

      例如:

 

[plain] view plain copy

print?

  1. $ mkdir /dr1/databases/test  
  2. $ ln -s /dr1/databases/test /path/to/datadir  

 

      注意:只有 MyISAM 表徹底支持符號連接。對於其它表類型,若是試圖在操做系統 中的文件上用前面的任何語句使用符號連接,可能會出現奇怪的問題。
對於 MyISAM 表的符號連接的處理以下:
     1. 在數據目錄指,必定會有表定義文件、數據文件和索引文件。數據文件和索引文件可 以移到別處和在數據目錄中符號連接替代。表定義文件不能進行符號連接替換。
     2. 能夠分別經過符號連接將數據文件和索引文件指到不一樣的目錄。

     3. 若是 mysqld 沒有運行,符號連接能夠從服務器命令行使用 ln -s 手動完成。一樣,經過使用 DATA DIRECTORY 和 INDEX DIRECTORY 選項建立表,你能夠指示運行的 MySQL 服務器執行符號連接。
     4. myisamchk 不用數據文件或索引文件替換符號連接。它直接工做在符號連接指向的文件。任何臨時文件建立在數據文件或索引文件所處的目錄中。
     5. 註釋:當你刪掉一個表時,若是該表使用了符號連接,符號連接和該符號連接指向的 文件都被刪除掉。這就是你不該以系統 root 用戶運行 mysqld 或容許系統用戶對 MySQL數據庫目錄有寫訪問權限的緣由。
     6. 若是你用 ALTER TABLE ... RENAME 重命名一個表而且不將表移到另外一個數據庫,數據庫目錄中的符號連接被從新命名爲一個新名字而且數據文件和索引文件也相應地從新命名。
     7. 若是你用 ALTER TABLE ... RENAME 移動一個表到另外一個數據庫,表移動到另外一個數據庫目錄。舊的符號連接和其所指向的文件被刪除。換句話說,新表再也不被連接。
     8. 若是不使用符號連接,你應對 mysqld 使用 --skip-symbolic-links 選項以確保沒有人可以使用 mysqld 來刪除或從新命名數據目錄以外的文件。

    表符號連接還不支持如下操做:
    1. ALTER TABLE 忽略 DATA DIRECTORY 和 INDEX DIRECTORY 表選項。
    2. BACKUP TABLE 和 RESTORE TABLE 不考慮符號連接。
    3. .frm 文件必須毫不能是一個符號連接(如前面所述,只有數據和索引文件能夠是符連接)。若是試圖這樣作(例如,生成符號連接)會產生不正確的結果。

3) 禁止操做系統更新文件的atime屬性

 

 

 

7. 應用優化

1 )使用鏈接池
對於訪問數據庫來講,創建鏈接的代價比較昂貴,所以,咱們有必要創建 " 鏈接池 " 以提升訪問的性能。咱們能夠把鏈接看成對象或者設備,池中又有許多已經創建的鏈接,訪 問原本須要與數據庫的鏈接的地方,都改成和池相連,池臨時分配鏈接供訪問使用,結果返 回後,訪問將鏈接交還。

2)減小對mysql的訪問,使用mem緩存等

3)負載均衡,複製分流查詢操做
           利用mysql的主從複製,分流更新操做和查詢操做
          1), 建立複製帳號:Gran replication slave on *.* to 'rel'@'10.0.1.2' identified by '123456'
          2), 修改主服務器的配置my.conf 開啓binlog和設置server-id
          3), 將主服務器的數據一致性恢復到從服務器,保證將要複製的數據時一隻的,不然出問題
          4), 在從服務器上修改配置my.conf
               server-id=2
               master-host=10.0.1.3
               master-user='rel'
               master-password='123456'
               master-port='3306'

          5), 從服務器啓動slave線程: start slave
          show processlist 查看。

4) 分佈式cluster 數據庫架構

 

 

 

8. 分庫分表

1)水平劃分
    若是某個表的數據太多,預期有上千條甚至上億以上,咱們能夠化整爲0:拆表。
    這裏就涉及到拆表的算法:
    記錄日誌的表,也能夠按周或者按月來拆。
    記錄用戶信息的表,按用戶id的hash算法來拆。

2)垂直拆分
  若是表記錄數並很少,可能也就二、3萬條,可是字段卻很長,表佔用空間很大,檢索表時須要執行大量I/O,嚴重下降了性能。這個時候須要把大的字段拆分到另外一個表,而且該表與原表是一對一的關係。  

 

分庫解決方案原則:

n安全性拆分:

將高安全性數據與低安全性數據分庫,這樣的好處第一是便於維護,第二是高安全性數據的數據庫參數配置能夠以安全優先,而低安全性數據的參數配置以性能優先。參見運維優化相關部分。

n基於業務邏輯拆分

1)根據數據表的內容構成,業務邏輯拆分,便於平常維護和前端調用。

2)基於業務邏輯拆分,能夠減小前端應用請求發送到不一樣數據庫服務器的頻次,從而減小連接開銷。

3)基於業務邏輯拆分,可保留部分數據關聯,前端web工程師可在限度範圍內執行關聯查詢。

n基於負載壓力拆分

           1)基於負載壓力對數據結構拆分,便於直接將負載分擔給不一樣的服務器。

2)基於負載壓力拆分,可能拆分後的數據庫包含不一樣業務類型的數據表,平常維護會有必定的煩惱。

n混合拆分組合

1)基於安全與業務拆分爲數據庫實例,可是可使用不一樣端口放在同一個服務器上。

2)基於負載能夠拆分爲更多數據庫實例分佈在不一樣數據庫上

如:

 

基於安全拆分出A數據庫實例,
基於業務拆分出B,C數據庫實例,
數據庫存在較高負載,基於負載拆分爲C1,C2,C3,C4等實例。
數據庫服務器徹底能夠作到 A+B+C1 爲一臺,C2,C3,C4各單獨一臺。

 


分表方案解決原則

一、通常數據量過大或者訪問壓力過大的數據表須要切分

          二、表的字段不宜過多。

n縱向分表

   單數據表字段過多,可將頻繁更新的整數數據與非頻繁更新的字符串數據切分

範例user表 ,我的簡介,地址,QQ號,聯繫方式,頭像 這些字段爲字符串類型,更新請求少; 最後登陸時間,在線時常,訪問次數,信件數這些字段爲整數型字段,更新頻繁,能夠將後面這些更新頻繁的字段獨立拆出一張數據表,表內容變少,索引結構變少,讀寫請求變快。

n橫向切表

1)等分切表,如哈希切表或其餘基於對某數字取餘的切表。等分切表的優勢是負載很方便的分佈到不一樣服務器;缺點是當容量繼續增長時沒法方便的擴容,須要從新進行數據的切分或轉表。並且一些關鍵主鍵不易處理。

2)遞增切表,好比每1kw用戶開一個新表,優勢是能夠適應數據的自增趨勢;缺點是每每新數據負載高,壓力分配不平均。

3)日期切表,適用於日誌記錄式數據,優缺點等同於遞增切表。

4)我的傾向於遞增切表,具體根據應用場景決定。

 

n熱點數據分表

1)將數據量較大的數據表中將讀寫頻繁的數據抽取出來,造成熱點數據表。一般一個龐大數據表常常被讀寫的內容每每具備必定的集中性,若是這些集中數據單獨處理,就會極大減小總體系統的負載。

2)熱點數據表與舊有數據關係

能夠是一張冗餘表,即該表數據丟失不會妨礙使用,因源數據仍存在於舊有結構中。優勢是安全性高,維護方便,缺點是寫壓力不能分擔,仍須要同步寫回原系統。

能夠是非冗餘表,即熱點數據的內容原有結構再也不保存,優勢是讀寫效率所有優化;缺點是當熱點數據發生變化時,維護量較大。

具體方案選擇須要根據讀寫比例決定,在讀頻率遠高於寫頻率狀況下,優先考慮冗餘表方案。

3)熱點數據表能夠用單獨的優化的硬件存儲,好比昂貴的閃存卡或大內存系統。

4)熱點數據表的重要指標

熱點數據的定義須要根據業務模式自行制定策略,常見策略爲,按照最新的操做時間;按照內容豐富度等等。
數據規模,好比從1000萬條數據,抽取出100萬條熱點數據。
熱點命中率,好比查詢10次,多少次命中在熱點數據內。
理論上,數據規模越小,熱點命中率越高,說明效果越好。須要根據業務自行評估。

5)熱點數據表的動態維護
加載熱點數據方案選擇
定時從舊有數據結構中按照新的策略獲取
在從舊有數據結構讀取時動態加載到熱點數據
剔除熱點數據方案選擇
基於特定策略,定時將熱點數據中訪問頻次較少的數據剔除
如熱點數據是冗餘表,則直接刪除便可,如不是冗餘表,須要回寫給舊有數據結構。
6)一般,熱點數據每每是基於緩存或者key-value方案冗餘存儲,因此這裏提到的熱點數據表,其實更可能是理解思路,用到的場合可能並很少….

 

 

 

9. 反範式設計(冗餘結構設計)

 

反範式設計的概念

無外鍵,無連表查詢。
便於分佈式設計,容許適度冗餘,爲了容量擴展容許適度開銷。
基於業務自由優化,基於i/o 或查詢設計,無須遵循範式結構設計。

冗餘結構設計所面臨的典型場景

原有展示程序涉及多個表的查詢,但願精簡查詢程序
數據表拆分每每基於主鍵,而原有數據表每每存在非基於主鍵的關鍵查詢,沒法在分表結構中完成。
存在較多數據統計需求(count, sum等),效率低下。

冗餘設計方案

1)基於展示的冗餘設計

 

爲了簡化展示程序,在一些數據表中每每存在冗餘字段:

舉例,信息表message,存在字段fromuid,touid,msg,sendtime四個字段,其中touid+sendtime是複合索引。存在查詢爲select * from message where touid=$uid order by sendtime desc limit 0,30;

展現程序須要顯示發送者姓名,此時一般會在message表中增長字段fromusername,甚至有的會增長fromusersex,從而無需連表查詢直接輸出信息的發送者姓名和性別。這就是一種簡單的,爲了不連表查詢而使用的冗餘字段設計。

2)基於展示的冗餘設計

涉及分表操做後,一些常見的索引查詢可能須要跨表,帶來沒必要要的麻煩。確認查詢請求遠大於寫入請求時,應設置便於查詢項的冗餘表。
冗餘表要點:
數據一致性,簡單說,同增,同刪,同更新。
能夠作全冗餘,或者只作主鍵關聯的冗餘,好比經過用戶名查詢uid,再基於uid查詢源表。

實戰範例1
用戶分表,將用戶庫分紅若干數據表
基於用戶名的查詢和基於uid的查詢都是高併發請求。
用戶分表基於uid分紅數據表,同時基於用戶名作對應冗餘表。
若是容許多方式登錄,能夠有以下設計方法
nuid,passwd,用戶信息等等,主數據表,基於uid分表
nukey,ukeytype,uid基於ukey分表,便於用戶登錄的查詢。分解成以下兩個SQL。
uselect uid from ulist_key_13 where ukey=’$username’ and ukeytype=‘login’;
uselect * from ulist_uid_23 where uid=$uid and passwd=’$passwd’;
nukeytype定義用戶的登錄依據,好比用戶名,手機號,郵件地址,網站暱稱等。Ukey+ukeytype 必須惟一。
n此種方式須要登錄密碼統一,對於第三方connect接入模式,能夠經過引伸額外字段完成。


實戰範例2:用戶遊戲積分排名
表結構uid,gameid,score參見前文實時積分排行。表內容巨大,須要拆表。
需求1:基於遊戲id查詢積分排行
需求2:基於用戶id查詢遊戲積分記錄
解決方案:創建徹底相同的兩套表結構,其一以uid爲拆表主鍵,其二以gameid爲拆表主鍵,用戶提交積分時,向兩個數據結構同時提交。

 

實戰範例3:全冗餘查詢結構
主信息表僅包括 主鍵及備註memo字段(text類型),只支持主鍵查詢,能夠基於主鍵拆表。因此須要展示和存儲的內容均在memo字段重體現。
對每個查詢條件,創建查詢冗餘表,以查詢條件字段爲主鍵,以主信息表主鍵id爲內容。
平常查詢只基於查詢冗餘表,而後經過in的方式從主信息表得到內容。
優勢是結構擴展很是方便,只須要擴展新的查詢信息表便可,核心思路是,只有查詢才須要獨立的索引結構,展示無需獨立字段。
缺點是隻適合於相對固定的查詢架構,對於更加靈活的組合查詢一籌莫展。

 

3)基於統計的冗餘結構

爲了減小會涉及大規模影響結果集的表數據操做,好比count,sum操做。應將一些統計類數據經過冗餘數據結構保存。
冗餘數據結構可能以字段方式存在,也可能以獨立數據表結構存在,可是都應能經過源數據表恢復。
實戰範例:
論壇板塊的發帖量,回帖量,每日新增數據等。
網站每日新增用戶數等。
參見Discuz論壇系統數據結構,有較多相關結構。
參見前文分段積分結構,是典型用於統計的冗餘結構。

後臺能夠經過源數據表更新該數字。
Redis的Zset類型能夠理解爲存在一種冗餘統計結構。

 

4)歷史數據表 歷史數據表對應於熱點數據表,將需求較少又不能丟棄的數據存入,僅在少數狀況下被訪問。

相關文章
相關標籤/搜索