萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mysql教程 >> 高手談數據庫設計優化策略教程

高手談數據庫設計優化策略教程

數據庫設計是建立數據庫及其應用系統的技術,是信息系統開發和建設中的核心技術。由於數據庫應用系統的復雜性,為了支持相關程序運行,數據庫設計就變得異常復雜,因此最佳設計不可能一蹴而就,而只能是一種“反復探尋,逐步求精”的過程,

1)范式和反范式

第一范式:每一列都是一個不可分割的原子數據項。

第二范式:第一范式基礎上消除部分依賴。

第三范式:第二范式基礎上消除傳遞依賴。

反范式是針對第三范式來說的,通過添加冗余的方式破壞了第三范式,前兩個范式還是要遵循的。

范式的優點:

a.寫入快,因為不需要寫冗余數據,所以減少了寫的負擔。

b.更新快,因為通常只需要更新更少的數據。

c.由於沒有冗余,所以不會造成數據不一致。

d.更少的需要GROUP BY和DISTINCT。

缺點是:需要關聯。

范式的缺點,就是反范式的優點,不需要關聯,並且因為在同一個表中,可以設計合適的索引。

實際應用中通常不會采用完成的范式,而是放置一些冗余,以減少表與表的關聯,加快查詢速度。

筆者之前所從事的項目中,數據包含定義態的和實例態的,實例態的冗余了定義態的數據,實例態又分多個級別,低級別的實例表,冗余了高級別表的數據,這樣在一個事務中都是單表查詢,減少了表關聯。

2)分表

如果表中的數據有狀態,比如完成態和運行態,那麼可以考慮將表分為運行態和完成態數據,數據轉換到完成態時可以將數據歸檔到完成態表中,由於數據總是要運轉到完成態,所以這樣無論系統運行多長時間,運行態表中的數據幾乎都是恆定的,而且完成態的數據除了統計分析用外,幾乎不不需要查詢,這樣就大大提高了系統運行的速度,表中的數據量得到了控制。

另外對於統計分析的場景,為了減少表的union 可以要求業務查詢從運行態和完成態兩種狀態中二選一。

對於一些海量數據,也可以考慮根據某個字段的值做hash,來分表存儲,當然這加大了應用的復雜度,這沒辦法,通常沒有十全十美的辦法,架構就是根據實際應用場景做權衡,正所謂忠孝不能兩全,只是某種辦法更合適而已。

另外可以通過分布式數據庫解決分表的問題,由分布式數據庫自動分表存儲,查詢時自動合並,由分布式數據庫中間件類屏蔽復雜性,各種髒活、累活交給它就是了。

3)匯總表

對於一些大數據量的報表統計工作,如果不是要求實時的話,可以定期匯總,比如每小時匯總一次或者每天匯總一次,如果要求實時的話,由於各種大表,各種group by,不但統計非常慢,而且容易影響正常的業務操作。筆者之前待的公司,每天晚上都開各種各樣的定時任務進行數據匯總,在數據庫不太忙的晚上,從12點干到早上6點,定時任務排的滿滿的,真是累死它的節奏啊,還好計算機不會鬧脾氣,發飙。。當然這樣報表統計的數據是截止到昨天的,每次都晚一天,通常這是允許的。

4)計數器表

web應用為了記錄點擊次數,可以設計一個點擊次數表,

create table hit_counter(cnt int unsigned not null);

由於只有一條記錄這樣鎖爭用太嚴重,想到了什麼解決方案,同concurrenthashmap一樣做鎖拆分。

表結構修改為:

create table hit_counter(slot tinyint unsigned not null primary key,cnt int unsigned not null);

預先放入100條數據,這樣修改的時候可以使用如下語句,

update hit_counter set cnt = cnt+1 where slot = RAND()*100;

獲取的時候求和就可以了,select sum(cnt) cnt from hit_counter;

不知道iteye的博客計數是不是也采用了類似的設計。

copyright © 萬盛學電腦網 all rights reserved