以下是我對使用 php + mysql 處理負載過重的數據庫問題思考和總結,經驗方面一定有著不少欠缺的地方,歡迎高手前來指教:
在設計時考慮合理的表結構和相應大概要承受多少訪問壓力,需不需要分表,如果需要分表每個表放多少條記錄合適;
對于分表的實現可以采用 php 處理或是 mysql 自帶的 merge 表類型(即 mrg_myisam)來處理:
⑴如果是使用 php 處理有兩種情況:
①沒有數據的新庫新表要為抗壓做準備,比如一個聊天室一開始就要考慮可能有多個子聊天室,可以根據一些條件來進行,例如按照主鍵或是 id 的范圍得出一種算法在存儲時就按照相應算法分配存儲到同結構但不同名的表中;
②如果是對已經有大量數據需要減壓的數據庫可以按照一定規則,比如按照該表的訪問頻率多少,把常用的數據放到一個表中,很少訪問的數據放到另一張表中,訪問數據時先訪問常用表,找不到時再訪問非常用表。
⑵如果采用 mysql 自帶的分表方式處理,就是使用 mysql 的 merge 表類型(即 mrg_myisam)。這種時候一般是針對已有教多數據,單個數據表無法承受負載時才會使用這種方式,可以針對這個教大的表使用一些工具比如 phpmyadmin 來對相關表的類型進行修改,同時確定分表中每個表里的記錄數,不過這個操作需要慎重,除了首次分表外,以后的數據將加到最后一個子表中,想要再分時就需要手動處理,編輯相關的“表明 .mrg”文件了,同時還要處理新的子表的“alter table tablename auto_increment = xxx”。
采用 merge 表時需要注意手冊中提到的一些問題: ①如果你使用 alter table 來把 merge 表變為其它表類型,到底層表的映射就被丟失了。取而代之的,來自底層 myisam 表的行被復制到已更換的表中,該表隨后被指定新類型。
②replace 不起作用。
④一個 merge 表不能在整個表上維持 unique 約束。當你執行一個 insert,數據進入第一個或者最后一個 myisam 表(取決于 insert_method 選項的值)。mysql 確保唯一鍵值在那個 myisam 表里保持唯一,但不是跨集合里所有的表。
⑤當你創建一個 merge 表之時,沒有檢查去確保底層表的存在以及有相同的機構。當 merge 表被使用之時,mysql 檢查每個被映射的表的記錄長度是否相等,但這并不十分可靠。如果你從不相似的 myisam 表創建一個 merge 表,你非常有可能撞見奇怪的問題。
⑥在 merge 表中的索引的順序和它的底層表中的索引應該一樣。如果你使用 alter table 給一個被用在 merge 表中的表添加一個 unique 索引,然后使用 alter table 在 merge 表上添加一個非唯一索引,如果在底層表上已經有一個非唯一索引,對表的索引排序是不同的。(這是因為 alter table 把 unique 索引放在非唯一索引之前以利于重復鍵的快速檢測 )。因此對使用這樣索引的表的查詢可能返回不期望的結果。
⑦在 windows中,在一個被 merge 表使用的表上 drop table 不起作用,因為 merge 引擎的表映射對 mysql 的更上層隱藏。因為 windows 不允許已打開文件的刪除,你首先必須刷新所有 merge 表(使用 flush tables)或在移除該表之前移除 merge 表。
新聞熱點
疑難解答