數據庫設計調優(二)

五  分表技術

     分表技術有水平分割和垂直分割php

     水平分割:當一張愈來愈大時候,即便添加索引還慢的話,咱們可使用水平分表,以qq用戶表簡單舉例來具體的說明一下水平分表的操做思路.如咱們在一個互聯網上註冊一個賬號,賬號不少,可能賬號表不止一個(如table1,table2,table3)。能夠在咱們進行註冊的時候生成一個標識,而後對這個標識經過程序邏輯進行處理(如生成的是一個隨機整數,對該整數進行除3求餘的方式,如餘1放到table1,餘2放到table2,餘0放到table3),放到相應的表中。訪問該信息的時候,也經過註冊的隨機標識處理知道在哪一個表,在相應的表中進行檢索便可。mysql

以下一個php代碼:sql

首先我建立三張表 user0 / user1 /user2 , 而後我再建立 uuid表,該表的做用就是提供自增的id,數據庫

create table user0(編程

id int unsigned primary key ,安全

name varchar(32) not null default '',服務器

pwd  varchar(32) not null default '')框架

engine=myisam charset utf8;異步

 

create table user1(數據庫設計

id int unsigned primary key ,

name varchar(32) not null default '',

pwd  varchar(32) not null default '')

engine=myisam charset utf8;

 

create table user2(

id int unsigned primary key ,

name varchar(32) not null default '',

pwd  varchar(32) not null default '')

engine=myisam charset utf8;

create table uuid(

id int unsigned primary key auto_increment)engine=myisam charset utf8;

編寫addUser.php

<?php

      //註冊一個用戶

      $con=mysql_connect("localhost","root","root");

      if(!$con){

           die("鏈接失敗!");

      }

      mysql_select_db("temp",$con);

      $name=$_GET['name'];

      $pwd=$_GET['pwd'];

      //這時咱們先獲取用戶id,id是從uuid表獲取

      $sql="insert into uuid values(null)";

      if(mysql_query($sql,$con)){ 

           $id=mysql_insert_id();

      }

      //計算表名,就是,你應該把這個用戶放入到哪一個表

      $talname='user'.$id%3;

 

      $sql="insert into {$talname} values ($id,'$name','$pwd')";

      if(mysql_query($sql,$con)){ 

           echo '添加用戶到 '.$talname.'ok';

      }

      mysql_close($con); 

<?php

      //註冊一個用戶

      $con=mysql_connect("localhost","root","root");

      if(!$con){

           die("鏈接失敗!");

      }

      mysql_select_db("temp",$con);

      $id=intval($_GET['id']);

      //計算表名

      $tabname='user'.$id%3;

      $sql="select pwd from {$tabname} where id=$id";

      $res=mysql_query($sql,$con);

      if($row=mysql_fetch_assoc($res)){

           echo "在{$tabname}. 中發現 id號爲 {$id}";

      }

      垂直分割:若是一張表某個字段,信息量大,可是咱們不多查詢,則能夠考慮把這些字段,單獨的放入到一張表中,這種方式稱爲垂直分割.這個舉個簡單的例子,NP的一張表有300個字段,在系統的實現中,常常select的字段都基本在100個固定的字段上,這樣咱們進行查詢檢索的時候會使用較多的IO,影響性能。建議把不常用的字段單獨放到一張表中,有須要時,經過連表也可實現。這樣便可大幅提升性能。

六  讀寫分離

     隨着一個網站的業務不斷擴展,數據不斷增長,數據庫的壓力也會愈來愈大,對數據庫或者SQL的基本優化可能達不到最終的效果,咱們能夠採用讀寫分離的策略來改變現狀。讀寫分離如今被大量應用於不少大型網站,這個技術也不足爲奇了。

    讀寫分離簡單的說是把對數據庫讀和寫的操做分開對應不一樣的數據庫服務器,這樣能有效地減輕數據庫壓力,也能減輕io壓力。主數據庫提供寫操做,從數據庫提供讀操做,其實在不少系統中,主要是讀的操做。當主數據庫進行寫操做時,數據要同步到從的數據庫,這樣纔能有效保證數據庫完整性。經過日誌在從數據庫重複主數據庫的操做達到複製數據目的。這個複製比較好的就是經過異步方法,把數據同步到從數據庫。主數據庫同步到從數據庫後,從數據庫通常由多臺數據庫組成這樣才能達到減輕壓力的目的。讀的操做怎麼樣分配到從數據庫上?應該根據服務器的壓力把讀的操做分配到服務器,而不是簡單的隨機分配。mysql提供了MySQL-Proxy實現讀寫分離操做。

七  存儲過程

在應用中能夠的話儘可能多,使用模塊化編程,能夠提升速度。

最後分享一個在網上找的20條數據庫設計最佳實踐

1.使用明確、統一的標明和列名,例如 School, SchoolCourse, CourceID。

2.數據表名使用單數而不是複數,例如 StudentCourse,而不是StudentCourses。

3.數據表名不要使用空格。

4.數據表名不要使用沒必要要的前綴或者後綴,例如使用School,而不是TblSchool,或者SchoolTable等等。

5.數據庫中的密碼要加密,到應用中再解密。(其實就是散列存儲、單向加密)

6.使用整數做爲ID字段,也許如今沒有這個必要,可是未來須要,例如關聯表,索引等等。

7.使用整數字段作索引,不然會帶來很大的性能問題。

8.使用 bit 做爲布爾字段,使用整數或者varcha是浪費。同時,這類字段應該以「Is」開頭。

9.要通過認證才能訪問數據庫,不要給每個用戶管理員權限。

10.儘可能避免使用「select *」,而使用「select [required_column_list]」以得到更好的性能。

11.假如程序代碼比較複雜,使用ORM框架,例如hibernate,iBatis。ORM框架的性能問題能夠經過詳細的配置去解決。

12.分割不常使用的數據表到不一樣的物理存儲以得到更好的性能。

13.對於關鍵數據庫,使用安全備份系統,例如集羣,同步等等。

14.使用外鍵,非空等限制來保證數據的完整性,不要把全部的東西都扔給程序。

15.缺少數據庫文檔是致命的。你應該爲你的數據庫設計寫文檔,包括觸發器、存儲過程和其餘腳本。

16.對於常用的查詢和大型數據表,要使用索引。數據分析工具能夠幫助你決定如何創建索引。

17.數據庫服務器和網頁服務器應該放在不一樣的機器上。這回提升安全性,並減輕CPU壓力。

18.Image和blob字段不該該定義在經常使用的數據表中,不然會影響性能。

19.範式(Normalization)要按照要求使用以提升性能。Normalization作的不夠會致使數據冗餘,而過分Normalization 會致使太多的join和數據表,這兩種狀況都會影響性能。

20.多花點時間在數據庫設計上,不然你未來會付出加倍的時間來償還。

相關文章
相關標籤/搜索