當前位置:首頁 » 數據倉庫 » 基於海量數據的資料庫設計與優化
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

基於海量數據的資料庫設計與優化

發布時間: 2023-03-03 22:13:28

『壹』 資料庫表結構設計,常見的資料庫管理系統

一、數據場景 1、表結構簡介 任何工具類的東西都是為了解決某個場景下的問題,比如Redis緩存系統熱點數據,ClickHouse解決海量數據的實時分析,Mysql關系型資料庫存儲結構化數據。數據的存儲則需要設計對應的表結構,清楚的表結構,有助於快速開發業務,和理解系統。表結構的設計通常從下面幾個方面考慮:業務場景、設計規范、表結構、欄位屬性、數據管理。
2、用戶場景
例如存儲用戶基礎信息數據,通常都會下面幾個相關表結構:用戶信息表、單點登錄表、狀態管理表、支付賬戶表等。
用戶信息表
存儲用戶三要素相關信息:姓名,手機號,身份證,登錄密碼,郵箱等。
CREATE TABLE `ms_user_center` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶ID', `user_name` varchar(20) NOT NULL COMMENT '用戶名', `real_name` varchar(20) DEFAULT NULL COMMENT '真實姓名', `pass_word` varchar(32) NOT NULL COMMENT '密碼', `phone` varchar(20) NOT NULL COMMENT '手機號', `email` varchar(32) DEFAULT NULL COMMENT '郵箱', `head_url` varchar(100) DEFAULT NULL COMMENT '用戶頭像URL', `card_id` varchar(32) DEFAULT NULL COMMENT '身份證號', `user_sex` int(1) DEFAULT '1' COMMENT '用戶性別:0-女,1-男', `create_time` datetime DEFAULT NULL COMMENT '創建時間', `update_time` datetime DEFAULT NULL COMMENT '更新時間', `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶表'; 單點登錄表
用意是在多個業務系統中,用戶登錄一次就可以訪問所有相互信任的業務子系統,是聚合業務平台常用的解決方案。
CREATE TABLE `ms_user_sso` ( `user_id` int(11) NOT NULL COMMENT '用戶ID', `sso_id` varchar(32) NOT NULL COMMENT '單點信息編號ID', `sso_code` varchar(32) NOT NULL COMMENT '單點登錄碼,唯一核心標識', `log_ip` varchar(32) DEFAULT NULL COMMENT '登錄IP地址', `create_time` datetime DEFAULT NULL COMMENT '創建時間', `update_time` datetime DEFAULT NULL COMMENT '更新時間', `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶單點登錄表'; 狀態管理表
系統用戶在使用時候可能出現多個狀態,例如賬戶凍結、密碼鎖定等,把狀態聚合到一起,可以更加方便的管理和驗證。
CREATE TABLE `ms_user_status` ( `user_id` int(11) NOT NULL COMMENT '用戶ID', `account_status` int(1) DEFAULT '1' COMMENT '賬戶狀態:0-凍結,1-未凍結', `real_name_status` int(1) DEFAULT '0' COMMENT '實名認證狀態:0-未實名,1-已實名', `pay_pass_status` int(1) DEFAULT '0' COMMENT '支付密碼是否設置:0-未設置,1-設置', `wallet_pass_status` int(1) DEFAULT '0' COMMENT '錢包密碼是否設置:0-未設置,1-設置', `wallet_status` int(1) DEFAULT '1' COMMENT '錢包是否凍結:0-凍結,1-未凍結', `email_status` int(1) DEFAULT '0' COMMENT '郵箱狀態:0-未激活,1-激活', `message_status` int(1) DEFAULT '1' COMMENT '簡訊提醒開啟:0-未開啟,1-開啟', `letter_status` int(1) DEFAULT '1' COMMENT '站內信提醒開啟:0-未開啟,1-開啟', `emailmsg_status` int(1) DEFAULT '0' COMMENT '郵件提醒開啟:0-未開啟,1-開啟', `create_time` datetime DEFAULT NULL COMMENT '創建時間', `update_time` datetime DEFAULT NULL COMMENT '更新時間', `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶狀態表'; 支付賬戶表
用戶交易的核心表,存儲用戶相關的賬戶資金信息。
CREATE TABLE `ms_user_wallet` ( `wallet_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '錢包ID', `user_id` int(11) NOT NULL COMMENT '用戶ID', `wallet_pwd` varchar(32) DEFAULT NULL COMMENT '錢包密碼', `total_account` decimal(20,2) DEFAULT '0.00' COMMENT '賬戶總額', `usable_money` decimal(20,2) DEFAULT '0.00' COMMENT '可用余額', `freeze_money` decimal(20,2) DEFAULT '0.00' COMMENT '凍結金額', `freeze_time` datetime DEFAULT NULL COMMENT '凍結時間', `thaw_time` datetime DEFAULT NULL COMMENT '解凍時間', `create_time` datetime DEFAULT NULL COMMENT '創建時間', `update_time` datetime DEFAULT NULL COMMENT '更新時間', `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用', PRIMARY KEY (`wallet_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶錢包'; 二、設計規范 1、涉及模塊
通過上面幾個表設計的案例,可以看到表設計關聯到資料庫的各個方面知識:數據類型,索引,編碼,存儲引擎等。表設計是一個很大的命題,不過也遵循一個基本規范:三範式。
2、三範式 基礎概念
一範式

表的列的具有原子性,不可再分解,即列的信息,不能分解,關系型資料庫MySQL、Oracle等自動的滿足。

二範式

每個事實的數據記錄只會出現一次, 不會冗餘, 通常設計一個主鍵來實現。

三範式

要求一個表中不包含已經存在於其它表的非主鍵信息,例如部門和員工的信息,員工表包含部門表的主鍵ID,則可以關聯獲取相關信息,沒必要在員工表保存相關信息。
優缺點對比
範式化設計

範式化結構設計通常更新快,因為冗餘數據較少,表結構輕巧,也更好的寫入內存中。但是查詢起來涉及到關聯,代價非常高,非常損耗查詢性能。

反範式化設計

所有的數據都在一張表中,避免關聯查詢,索引的有效性更高,但是數據的冗餘性極高。
建議結論
上述的兩種設計方式在實際開發中都是不存在的,在實際開發中都是混合使用。比如匯總統計,緩存數據,都會基於反範式化的設計。
三、欄位屬性
合適的欄位類型對於高性能來說非常重要,基本原則如下:簡單的類型佔用資源更少;在可以正確存儲數據的情況下,選最小的數據類型。
1、數據類型選擇 整數類型
TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,根據數據類型範圍合理選擇即可。
實數類型
FLOAT、DOUBLE、DECIMAL,建議資金貨幣相關類型使用高精度DECIMAL存儲,或者把數據成倍擴大為整數,採用BIGINT存儲,不過處理相對麻煩。
字元類型
CHAR、VARCHAR,長度不確定建議採用VARCHAR存儲,不過VARCHAR類型需要額外開銷記錄字元串長度。CHAR適合存儲短字元,或者定長字元串,例如MD5的加密結構。
時間類型
DATETIME、TIMESTAMP,DATETIME保存大范圍的值,精度秒。TIMESTAMP以時間戳的格式,范圍相對較小,效率也相對較高,所以通常情況建議使用。

MySQL的欄位類型有很多種,可以根據數據特性選擇合適的,這里只描述常見的幾種類型。
2、基礎用法操作 數據類型
修改欄位類型
ALTER TABLE ms_user_sso MODIFY state CHAR(1) DEFAULT '0' ; ALTER TABLE ms_user_sso MODIFY state INT(1) DEFAULT '1' COMMENT '狀態:0不可用,1可用';
修改名稱位置
ALTER TABLE ms_user_sso CHANGE log_ip login_ip VARCHAR(32) AFTER update_time ; 索引使用
索引類型:主鍵索引,普通索引,唯一索引,組合索引,全文索引。這里演示普通索引的操作。MySQL的核心模塊,後續詳說。

添加索引
ALTER TABLE ms_user_wallet ADD INDEX user_id_index(user_id) ; CREATE INDEX state_index ON ms_user_wallet(state) ;
查看索引
SHOW INDEX FROM ms_user_wallet;
刪除索引
DROP INDEX state_index ON ms_user_wallet ;
修改索引

不具有真正意義上的修改,可以把原有的索引刪除之後,再次添加索引。
外鍵關聯
用處:外鍵關聯的作用保證多個數據表的數據一致性和完整性,建表時先有主表,後有從表;刪除數據表,需要先刪從表,再刪主表。復雜場景不建議使用,實際開發中用的也不多。

添加外鍵
ALTER TABLE ms_user_wallet ADD CONSTRAINT user_id_out_key FOREIGN KEY(user_id) REFERENCES ms_user_center(id) ;
刪除外鍵
ALTER TABLE ms_user_wallet DROP FOREIGN KEY user_id_out_key ; 四、表結構管理 1、查看結構 DESC ms_user_status ; SHOW CREATE TABLE ms_user_status ; 2、欄位結構 添加欄位 ALTER TABLE ms_user_status ADD `delete_time` datetime DEFAULT NULL COMMENT '刪除時間' ; 刪除欄位 ALTER TABLE ms_user_status DROP COLUMN delete_time ; 3、修改表名 ALTER TABLE ms_user_center RENAME ms_user_info ; 4、存儲引擎 存儲引擎 SELECT VERSION() ; SHOW ENGINES ;
MySQL 5.6 支持的存儲引擎有InnoDB、MyISAM、Memory、Archive、CSV、BLACKHOLE等。一般默認使用InnoDB,支持事務管理。該模塊MySQL核心,後續詳解。
修改引擎
數據量大的場景下,存儲引擎修改是一個難度極大的操作,容易會導致表的特性變動,引起各種後續反應,後續會詳說。
ALTER TABLE ms_user_sso ENGINE = MyISAM ; 5、修改編碼
表字元集默認使用utf8,通用,無亂碼風險,漢字3位元組,英文1位元組,utf8mb4是utf8的超集,有存儲4位元組例如表情符號時使用。
查看編碼 SHOW VARIABLES LIKE 'character%'; 修改編碼 ALTER TABLE ms_user_sso DEFAULT CHARACTER SET utf8mb4; 五、數據管理 1、增刪改查
添加數據
INSERT INTO ms_user_sso ( user_id,sso_id,sso_code,create_time,update_time,login_ip,state ) VALUES ( '1','SSO7637267','SSO78631273612', '2019-12-24 11:56:57','2019-12-24 11:57:01','127.0.0.1','1' );
更新數據
UPDATE ms_user_sso SET user_id = '1',sso_id = 'SSO20191224',sso_code = 'SSO20191224', create_time = '2019-11-24 11:56:57',update_time = '2019-11-24 11:57:01', login_ip = '127.0.0.1',state = '1' WHERE user_id = '1';
查詢數據

一般情況下都是禁止使用 select* 操作。
SELECT user_id,sso_id,sso_code,create_time,update_time,login_ip,state FROM ms_user_sso WHERE user_id = '1';
刪除數據
DELETE FROM ms_user_sso WHERE user_id = '2' ;
不帶where條件,就是刪除全部數據。原則上不允許該操作,優化篇會詳解。TRUNCATE TABLE也是清空表數據,但是佔用的資源相對較少。
2、數據安全 不可逆加密
這類加密演算法,多用來做數據驗證操作,比如常見的密碼驗證。
SELECT MD5('cicada')='' ; SELECT SHA('cicada')=''; SELECT PASSWORD('smile')='*' ; 可逆加密
安全性要求高的系統,需要做三級等保,對數據的安全性極高,數據在存儲時必須加密入庫,取出時候需要解密,這些就需要可逆加密。
SELECT DECODE(ENCODE('123456','key_salt'),'key_salt') ; SELECT AES_DECRYPT(AES_ENCRYPT('cicada','salt123'),'salt123');
上述數據安全的管理,也可以基於應用系統的服務(代碼)層進行處理,相對專業的流程是從數據生成源頭處理,規避數據傳遞過程泄露,造成不必要的風險。

『貳』 如何處理海量數據

在實際的工作環境下,許多人會遇到海量數據這個復雜而艱巨的問題,它的主要難點有以下幾個方面:
一、數據量過大,數據中什麼情況都可能存在。
如果說有10條數據,那麼大不了每條去逐一檢查,人為處理,如果有上百條數據,也可以考慮,如果數據上到千萬級別,甚至 過億,那不是手工能解決的了,必須通過工具或者程序進行處理,尤其海量的數據中,什麼情況都可能存在,例如,數據中某處格式出了問題,尤其在程序處理時, 前面還能正常處理,突然到了某個地方問題出現了,程序終止了。
二、軟硬體要求高,系統資源佔用率高。
對海量的數據進行處理,除了好的方法,最重要的就是合理使用工具,合理分配系統資源。一般情況,如果處理的數據過TB級,小型機是要考慮的,普通的機子如果有好的方法可以考慮,不過也必須加大CPU和內存,就象面對著千軍萬馬,光有勇氣沒有一兵一卒是很難取勝的。
三、要求很高的處理方法和技巧。
這也是本文的寫作目的所在,好的處理方法是一位工程師長期工作經驗的積累,也是個人的經驗的總結。沒有通用的處理方法,但有通用的原理和規則。
下面我們來詳細介紹一下處理海量數據的經驗和技巧:
一、選用優秀的資料庫工具
現在的資料庫工具廠家比較多,對海量數據的處理對所使用的資料庫工具要求比較高,一般使用Oracle或者DB2,微軟 公司最近發布的SQL Server 2005性能也不錯。另外在BI領域:資料庫,數據倉庫,多維資料庫,數據挖掘等相關工具也要進行選擇,象好的ETL工具和好的OLAP工具都十分必要, 例如Informatic,Eassbase等。筆者在實際數據分析項目中,對每天6000萬條的日誌數據進行處理,使用SQL Server 2000需要花費6小時,而使用SQL Server 2005則只需要花費3小時。
二、編寫優良的程序代碼
處理數據離不開優秀的程序代碼,尤其在進行復雜數據處理時,必須使用程序。好的程序代碼對數據的處理至關重要,這不僅僅是數據處理准確度的問題,更是數據處理效率的問題。良好的程序代碼應該包含好的演算法,包含好的處理流程,包含好的效率,包含好的異常處理機制等。
三、對海量數據進行分區操作
對海量數據進行分區操作十分必要,例如針對按年份存取的數據,我們可以按年進行分區,不同的資料庫有不同的分區方式,不 過處理機制大體相同。例如SQL Server的資料庫分區是將不同的數據存於不同的文件組下,而不同的文件組存於不同的磁碟分區下,這樣將數據分散開,減小磁碟I/O,減小了系統負荷, 而且還可以將日誌,索引等放於不同的分區下。
四、建立廣泛的索引
對海量的數據處理,對大表建立索引是必行的,建立索引要考慮到具體情況,例如針對大表的分組、排序等欄位,都要建立相應 索引,一般還可以建立復合索引,對經常插入的表則建立索引時要小心,筆者在處理數據時,曾經在一個ETL流程中,當插入表時,首先刪除索引,然後插入完 畢,建立索引,並實施聚合操作,聚合完成後,再次插入前還是刪除索引,所以索引要用到好的時機,索引的填充因子和聚集、非聚集索引都要考慮。
五、建立緩存機制
當數據量增加時,一般的處理工具都要考慮到緩存問題。緩存大小設置的好差也關繫到數據處理的成敗,例如,筆者在處理2億條數據聚合操作時,緩存設置為100000條/Buffer,這對於這個級別的數據量是可行的。
六、加大虛擬內存
如果系統資源有限,內存提示不足,則可以靠增加虛擬內存來解決。筆者在實際項目中曾經遇到針對18億條的數據進行處理, 內存為1GB,1個P42.4G的CPU,對這么大的數據量進行聚合操作是有問題的,提示內存不足,那麼採用了加大虛擬內存的方法來解決,在6塊磁碟分區 上分別建立了6個4096M的磁碟分區,用於虛擬內存,這樣虛擬的內存則增加為 4096*6 + 1024 =25600 M,解決了數據處理中的內存不足問題。
七、分批處理
海量數據處理難因為數據量大,那麼解決海量數據處理難的問題其中一個技巧是減少數據量。可以對海量數據分批處理,然後處 理後的數據再進行合並操作,這樣逐個擊破,有利於小數據量的處理,不至於面對大數據量帶來的問題,不過這種方法也要因時因勢進行,如果不允許拆分數據,還 需要另想辦法。不過一般的數據按天、按月、按年等存儲的,都可以採用先分後合的方法,對數據進行分開處理。
八、使用臨時表和中間表
數據量增加時,處理中要考慮提前匯總。這樣做的目的是化整為零,大表變小表,分塊處理完成後,再利用一定的規則進行合 並,處理過程中的臨時表的使用和中間結果的保存都非常重要,如果對於超海量的數據,大表處理不了,只能拆分為多個小表。如果處理過程中需要多步匯總操作, 可按匯總步驟一步步來,不要一條語句完成,一口氣吃掉一個胖子。
九、優化查詢SQL語句
在對海量數據進行查詢處理過程中,查詢的SQL語句的性能對查詢效率的影響是非常大的,編寫高效優良的SQL腳本和存儲 過程是資料庫工作人員的職責,也是檢驗資料庫工作人員水平的一個標准,在對SQL語句的編寫過程中,例如減少關聯,少用或不用游標,設計好高效的資料庫表 結構等都十分必要。筆者在工作中試著對1億行的數據使用游標,運行3個小時沒有出結果,這是一定要改用程序處理了。
十、使用文本格式進行處理
對一般的數據處理可以使用資料庫,如果對復雜的數據處理,必須藉助程序,那麼在程序操作資料庫和程序操作文本之間選擇, 是一定要選擇程序操作文本的,原因為:程序操作文本速度快;對文本進行處理不容易出錯;文本的存儲不受限制等。例如一般的海量的網路日誌都是文本格式或者 csv格式(文本格式),對它進行處理牽扯到數據清洗,是要利用程序進行處理的,而不建議導入資料庫再做清洗。
十一、定製強大的清洗規則和出錯處理機制
海量數據中存在著不一致性,極有可能出現某處的瑕疵。例如,同樣的數據中的時間欄位,有的可能為非標準的時間,出現的原因可能為應用程序的錯誤,系統的錯誤等,這是在進行數據處理時,必須制定強大的數據清洗規則和出錯處理機制。
十二、建立視圖或者物化視圖
視圖中的數據來源於基表,對海量數據的處理,可以將數據按一定的規則分散到各個基表中,查詢或處理過程中可以基於視圖進行,這樣分散了磁碟I/O,正如10根繩子吊著一根柱子和一根吊著一根柱子的區別。
十三、避免使用32位機子(極端情況)
目前的計算機很多都是32位的,那麼編寫的程序對內存的需要便受限制,而很多的海量數據處理是必須大量消耗內存的,這便要求更好性能的機子,其中對位數的限制也十分重要。
十四、考慮操作系統問題
海量數據處理過程中,除了對資料庫,處理程序等要求比較高以外,對操作系統的要求也放到了重要的位置,一般是必須使用伺服器的,而且對系統的安全性和穩定性等要求也比較高。尤其對操作系統自身的緩存機制,臨時空間的處理等問題都需要綜合考慮。
十五、使用數據倉庫和多維資料庫存儲
數據量加大是一定要考慮OLAP的,傳統的報表可能5、6個小時出來結果,而基於Cube的查詢可能只需要幾分鍾,因此處理海量數據的利器是OLAP多維分析,即建立數據倉庫,建立多維數據集,基於多維數據集進行報表展現和數據挖掘等。
十六、使用采樣數據,進行數據挖掘
基於海量數據的數據挖掘正在逐步興起,面對著超海量的數據,一般的挖掘軟體或演算法往往採用數據抽樣的方式進行處理,這樣 的誤差不會很高,大大提高了處理效率和處理的成功率。一般采樣時要注意數據的完整性和,防止過大的偏差。筆者曾經對1億2千萬行的表數據進行采樣,抽取出 400萬行,經測試軟體測試處理的誤差為千分之五,客戶可以接受。
還有一些方法,需要在不同的情況和場合下運用,例如使用代理鍵等操作,這樣的好處是加快了聚合時間,因為對數值型的聚合比對字元型的聚合快得多。類似的情況需要針對不同的需求進行處理。
海量數據是發展趨勢,對數據分析和挖掘也越來越重要,從海量數據中提取有用信息重要而緊迫,這便要求處理要准確,精度要高,而且處理時間要短,得到有價值信息要快,所以,對海量數據的研究很有前途,也很值得進行廣泛深入的研究。

『叄』 誰知道資料庫優化設計方案有哪些

本文首先討論了基於第三範式的資料庫表的基本設計,著重論述了建立主鍵和索引的策略和方案,然後從資料庫表的擴展設計和庫表對象的放置等角度概述了資料庫管理系統的優化方案。
關鍵詞: 優化(Optimizing) 第三範式(3NF) 冗餘數據(Rendant Data) 索引(Index) 數據分割(Data Partitioning) 對象放置(Object Placement)
1 引言
資料庫優化的目標無非是避免磁碟I/O瓶頸、減少CPU利用率和減少資源競爭。為了便於讀者閱讀和理解,筆者參閱了Sybase、Informix和Oracle等大型資料庫系統參考資料,基於多年的工程實踐經驗,從基本表設計、擴展設計和資料庫表對象放置等角度進行討論,著重討論了如何避免磁碟I/O瓶頸和減少資源競爭,相信讀者會一目瞭然。
2 基於第三範式的基本表設計
在基於表驅動的信息管理系統(MIS)中,基本表的設計規范是第三範式(3NF)。第三範式的基本特徵是非主鍵屬性只依賴於主鍵屬性。基於第三範式的資料庫表設計具有很多優點:一是消除了冗餘數據,節省了磁碟存儲空間;二是有良好的數據完整性限制,即基於主外鍵的參照完整限制和基於主鍵的實體完整性限制,這使得數據容易維護,也容易移植和更新;三是數據的可逆性好,在做連接(Join)查詢或者合並表時不遺漏、也不重復;四是因消除了冗餘數據(冗餘列),在查詢(Select)時每個數據頁存的數據行就多,這樣就有效地減少了邏輯I/O,每個Cash存的頁面就多,也減少物理I/O;五是對大多數事務(Transaction)而言,運行性能好;六是物理設計(Physical Design)的機動性較大,能滿足日益增長的用戶需求。
在基本表設計中,表的主鍵、外鍵、索引設計佔有非常重要的地位,但系統設計人員往往只注重於滿足用戶要求,而沒有從系統優化的高度來認識和重視它們。實際上,它們與系統的運行性能密切相關。現在從系統資料庫優化角度討論這些基本概念及其重要意義:
(1)主鍵(Primary Key):主鍵被用於復雜的SQL語句時,頻繁地在數據訪問中被用到。一個表只有一個主鍵。主鍵應該有固定值(不能為Null或預設值,要有相對穩定性),不含代碼信息,易訪問。把常用(眾所周知)的列作為主鍵才有意義。短主鍵最佳(小於25bytes),主鍵的長短影響索引的大小,索引的大小影響索引頁的大小,從而影響磁碟I/O。主鍵分為自然主鍵和人為主鍵。自然主鍵由實體的屬性構成,自然主鍵可以是復合性的,在形成復合主鍵時,主鍵列不能太多,復合主鍵使得Join*作復雜化、也增加了外鍵表的大小。人為主鍵是,在沒有合適的自然屬性鍵、或自然屬性復雜或靈敏度高時,人為形成的。人為主鍵一般是整型值(滿足最小化要求),沒有實際意義,也略微增加了表的大小;但減少了把它作為外鍵的表的大小。
(2)外鍵(Foreign Key):外鍵的作用是建立關系型資料庫中表之間的關系(參照完整性),主鍵只能從獨立的實體遷移到非獨立的實體,成為後者的一個屬性,被稱為外鍵。
(3)索引(Index):利用索引優化系統性能是顯而易見的,對所有常用於查詢中的Where子句的列和所有用於排序的列創建索引,可以避免整表掃描或訪問,在不改變表的物理結構的情況下,直接訪問特定的數據列,這樣減少數據存取時間;利用索引可以優化或排除耗時的分類*作;把數據分散到不同的頁面上,就分散了插入的數據;主鍵自動建立了唯一索引,因此唯一索引也能確保數據的唯一性(即實體完整性);索引碼越小,定位就越直接;新建的索引效能最好,因此定期更新索引非常必要。索引也有代價:有空間開銷,建立它也要花費時間,在進行Insert、Delete和Update*作時,也有維護代價。索引有兩種:聚族索引和非聚族索引。一個表只能有一個聚族索引,可有多個非聚族索引。使用聚族索引查詢數據要比使用非聚族索引快。在建索引前,應利用資料庫系統函數估算索引的大小。
① 聚族索引(Clustered Index):聚族索引的數據頁按物理有序儲存,佔用空間小。選擇策略是,被用於Where子句的列:包括范圍查詢、模糊查詢或高度重復的列(連續磁碟掃描);被用於連接Join*作的列;被用於Order by和Group by子句的列。聚族索引不利於插入*作,另外沒有必要用主鍵建聚族索引。
② 非聚族索引(Nonclustered Index):與聚族索引相比,佔用空間大,而且效率低。選擇策略是,被用於Where子句的列:包括范圍查詢、模糊查詢(在沒有聚族索引時)、主鍵或外鍵列、點(指針類)或小范圍(返回的結果域小於整表數據的20%)查詢;被用於連接Join*作的列、主鍵列(范圍查詢);被用於Order by和Group by子句的列;需要被覆蓋的列。對只讀表建多個非聚族索引有利。索引也有其弊端,一是創建索引要耗費時間,二是索引要佔有大量磁碟空間,三是增加了維護代價(在修改帶索引的數據列時索引會減緩修改速度)。那麼,在哪種情況下不建索引呢?對於小表(數據小於5頁)、小到中表(不直接訪問單行數據或結果集不用排序)、單值域(返回值密集)、索引列值太長(大於20bitys)、容易變化的列、高度重復的列、Null值列,對沒有被用於Where子語句和Join查詢的列都不能建索引。另外,對主要用於數據錄入的,盡可能少建索引。當然,也要防止建立無效索引,當Where語句中多於5個條件時,維護索引的開銷大於索引的效益,這時,建立臨時表存儲有關數據更有效。
批量導入數據時的注意事項:在實際應用中,大批量的計算(如電信話單計費)用C語言程序做,這種基於主外鍵關系數據計算而得的批量數據(文本文件),可利用系統的自身功能函數(如Sybase的BCP命令)快速批量導入,在導入資料庫表時,可先刪除相應庫表的索引,這有利於加快導入速度,減少導入時間。在導入後再重建索引以便優化查詢。
(4)鎖:鎖是並行處理的重要機制,能保持數據並發的一致性,即按事務進行處理;系統利用鎖,保證數據完整性。因此,我們避免不了死鎖,但在設計時可以充分考慮如何避免長事務,減少排它鎖時間,減少在事務中與用戶的交互,杜絕讓用戶控制事務的長短;要避免批量數據同時執行,尤其是耗時並用到相同的數據表。鎖的徵用:一個表同時只能有一個排它鎖,一個用戶用時,其它用戶在等待。若用戶數增加,則Server的性能下降,出現「假死」現象。如何避免死鎖呢?從頁級鎖到行級鎖,減少了鎖徵用;給小表增加無效記錄,從頁級鎖到行級鎖沒有影響,若在同一頁內競爭有影響,可選擇合適的聚族索引把數據分配到不同的頁面;創建冗餘表;保持事務簡短;同一批處理應該沒有網路交互。
(5)查詢優化規則:在訪問資料庫表的數據(Access Data)時,要盡可能避免排序(Sort)、連接(Join)和相關子查詢*作。經驗告訴我們,在優化查詢時,必須做到:
① 盡可能少的行;
② 避免排序或為盡可能少的行排序,若要做大量數據排序,最好將相關數據放在臨時表中*作;用簡單的鍵(列)排序,如整型或短字元串排序;
③ 避免表內的相關子查詢;
④ 避免在Where子句中使用復雜的表達式或非起始的子字元串、用長字元串連接;
⑤ 在Where子句中多使用「與」(And)連接,少使用「或」(Or)連接;
⑥ 利用臨時資料庫。在查詢多表、有多個連接、查詢復雜、數據要過濾時,可以建臨時表(索引)以減少I/O。但缺點是增加了空間開銷。
除非每個列都有索引支持,否則在有連接的查詢時分別找出兩個動態索引,放在工作表中重新排序。
3 基本表擴展設計
基於第三範式設計的庫表雖然有其優越性(見本文第一部分),然而在實際應用中有時不利於系統運行性能的優化:如需要部分數據時而要掃描整表,許多過程同時競爭同一數據,反復用相同行計算相同的結果,過程從多表獲取數據時引發大量的連接*作,當數據來源於多表時的連接*作;這都消耗了磁碟I/O和CPU時間。
尤其在遇到下列情形時,我們要對基本表進行擴展設計:許多過程要頻繁訪問一個表、子集數據訪問、重復計算和冗餘數據,有時用戶要求一些過程優先或低的響應時間。
如何避免這些不利因素呢?根據訪問的頻繁程度對相關表進行分割處理、存儲冗餘數據、存儲衍生列、合並相關表處理,這些都是克服這些不利因素和優化系統運行的有效途徑。
3.1 分割表或儲存冗餘數據
分割表分為水平分割表和垂直分割表兩種。分割表增加了維護數據完整性的代價。
水平分割表:一種是當多個過程頻繁訪問數據表的不同行時,水平分割表,並消除新表中的冗餘數據列;若個別過程要訪問整個數據,則要用連接*作,這也無妨分割表;典型案例是電信話單按月分割存放。另一種是當主要過程要重復訪問部分行時,最好將被重復訪問的這些行單獨形成子集表(冗餘儲存),這在不考慮磁碟空間開銷時顯得十分重要;但在分割表以後,增加了維護難度,要用觸發器立即更新、或存儲過程或應用代碼批量更新,這也會增加額外的磁碟I/O開銷。
垂直分割表(不破壞第三範式),一種是當多個過程頻繁訪問表的不同列時,可將表垂直分成幾個表,減少磁碟I/O(每行的數據列少,每頁存的數據行就多,相應佔用的頁就少),更新時不必考慮鎖,沒有冗餘數據。缺點是要在插入或刪除數據時要考慮數據的完整性,用存儲過程維護。另一種是當主要過程反復訪問部分列時,最好將這部分被頻繁訪問的列數據單獨存為一個子集表(冗餘儲存),這在不考慮磁碟空間開銷時顯得十分重要;但這增加了重疊列的維護難度,要用觸發器立即更新、或存儲過程或應用代碼批量更新,這也會增加額外的磁碟I/O開銷。垂直分割表可以達到最大化利用Cache的目的。
總之,為主要過程分割表的方法適用於:各個過程需要表的不聯結的子集,各個過程需要表的子集,訪問頻率高的主要過程不需要整表。在主要的、頻繁訪問的主表需要表的子集而其它主要頻繁訪問的過程需要整表時則產生冗餘子集表。
注意,在分割表以後,要考慮重新建立索引。
3.2 存儲衍生數據
對一些要做大量重復性計算的過程而言,若重復計算過程得到的結果相同(源列數據穩定,因此計算結果也不變),或計算牽扯多行數據需額外的磁碟I/O開銷,或計算復雜需要大量的CPU時間,就考慮存儲計算結果(冗餘儲存)。現予以分類說明:
若在一行內重復計算,就在表內增加列存儲結果。但若參與計算的列被更新時,必須要用觸發器更新這個新列。
若對表按類進行重復計算,就增加新表(一般而言,存放類和結果兩列就可以了)存儲相關結果。但若參與計算的列被更新時,就必須要用觸發器立即更新、或存儲過程或應用代碼批量更新這個新表。
若對多行進行重復性計算(如排名次),就在表內增加列存儲結果。但若參與計算的列被更新時,必須要用觸發器或存儲過程更新這個新列。
總之,存儲冗餘數據有利於加快訪問速度;但違反了第三範式,這會增加維護數據完整性的代價,必須用觸發器立即更新、或存儲過程或應用代碼批量更新,以維護數據的完整性。
3.3 消除昂貴結合
對於頻繁同時訪問多表的一些主要過程,考慮在主表內存儲冗餘數據,即存儲冗餘列或衍生列(它不依賴於主鍵),但破壞了第三範式,也增加了維護難度。在源表的相關列發生變化時,必須要用觸發器或存儲過程更新這個冗餘列。當主要過程總同時訪問兩個表時可以合並表,這樣可以減少磁碟I/O*作,但破壞了第三範式,也增加了維護難度。對父子表和1:1關系表合並方法不同:合並父子表後,產生冗餘表;合並1:1關系表後,在表內產生冗餘數據。
4 資料庫對象的放置策略
資料庫對象的放置策略是均勻地把數據分布在系統的磁碟中,平衡I/O訪問,避免I/O瓶頸。
⑴ 訪問分散到不同的磁碟,即使用戶數據盡可能跨越多個設備,多個I/O運轉,避免I/O競爭,克服訪問瓶頸;分別放置隨機訪問和連續訪問數據。
⑵ 分離系統資料庫I/O和應用資料庫I/O。把系統審計表和臨時庫表放在不忙的磁碟上。
⑶ 把事務日誌放在單獨的磁碟上,減少磁碟I/O開銷,這還有利於在障礙後恢復,提高了系統的安全性。
⑷ 把頻繁訪問的「活性」表放在不同的磁碟上;把頻繁用的表、頻繁做Join*作的表分別放在單獨的磁碟上,甚至把把頻繁訪問的表的欄位放在不同的磁碟上,把訪問分散到不同的磁碟上,避免I/O爭奪;
⑸ 利用段分離頻繁訪問的表及其索引(非聚族的)、分離文本和圖像數據。段的目的是平衡I/O,避免瓶頸,增加吞吐量,實現並行掃描,提高並發度,最大化磁碟的吞吐量。利用邏輯段功能,分別放置「活性」表及其非聚族索引以平衡I/O。當然最好利用系統的默認段。另外,利用段可以使備份和恢復數據更加靈活,使系統授權更加靈活。

『肆』 mysql資料庫要放1億條信息怎樣分表

mysql資料庫對1億條數據的分表方法設計:

目前針對海量數據的優化有兩種方法:

(1)垂直分割

如果單表的IO壓力大,可以考慮用水平分割,其原理就是通過hash演算法,將一張表分為N多頁,並通過一個新的表(總表),記錄著每個頁的的位置。


假如一個門戶網站,它的資料庫表已經達到了1億條記錄,那麼此時如果通過select去查詢,必定會效率低下(不做索引的前提下)。為了降低單表的讀寫IO壓力,通過水平分割,將這個表分成10個頁,同時生成一個總表,記錄各個頁的信息,那麼假如我查詢一條id=100的記錄,它不再需要全表掃描,而是通過總表找到該記錄在哪個對應的頁上,然後再去相應的頁做檢索,這樣就降低了IO壓力。

『伍』 海量資料庫解決方案的作者簡介

作者:(韓國)李華植 譯者:鄭保衛 蓋國強
李華植
代表韓國的資料庫技術先驅
集基於EA(Enterprise Architecture)的數據架構(Data Architecture)
方法論之大成
在韓國最早提出了數據專家顧問的概念
現任EN-CORE CONSULTING總經理及代表顧問
曾在韓國Oracle公司擔任200多家企業的技術顧問
論文:《構建海量數據系統時的RDB Performance問題解決方案》
書籍:《Data Modeling&Database Design》(1995)
《Oracle Server Tuning}(1995)
《海量資料庫解決方案》(1996)
《海量資料庫解決方案Ⅱ》(1998)
《數據架構解決方案I》(2003)
譯者簡介:
鄭保衛,於韓國國立釜慶大學信息工學系獲得工學博士,現任職於韓國最權威的資料庫公司EN-CORE CONSULTING,並兼任企業研究所研究員及資料庫電子商務研究所主要研究員。研究方向包括數據模型設計、海量資料庫解決方案、數據架構、基於資料庫技術的專家智能系統、ITA/EA(Infomation Technology Architecture/Enterprise Architecture)。
蓋國強(網名Eygle),Oracle ACE總監,恩墨科技創始人,ITPUB論壇超級版主,遠程DBA服務的倡導者和實踐者,致力於以技術服務客戶。著有《深入解析Orade》、《循序漸進Oracle》、《深入淺出Oracle》等書:從2010年開始,致力於《OracleDBA手記》的撰寫與編輯工作,並與張樂奕共同創立了ACOUG用戶組,在國內推進公益自由的Oracle技術交流活動。張樂奕(網名Kamus),恩墨科技技術總監,Oracle ACE,ITPUB資料庫管理版版主。他曾先後於北京某大型軟體公司、外資電信企業、咨詢公司任首席DBA。後任職於北京甲骨文軟體系統有限公司,高級顧問。他熱切關注Oracle資料庫及其他相關技術,對於Oracle資料庫RAC及高可用解決方案具有豐富的實踐經驗,長於資料庫故障診斷、資料庫性能調優。他還是各類技術會議的熱心分享者,2010年3月創建ACOUG用戶組。
崔華(網名Dbsnake),2004年開始從事DBA工作,在Oracle的安裝、升級、開發、性能調整、故障處理方面有豐富的經驗,對Oracle的體系結構具有深入了解:深入理解Oracle的內存結構、物理存儲(各種塊格式)、鎖機制、優化機制等:深入了解Oracle的備份恢復機制,熟悉Oracle的各種備份方法,能夠處理各種情況下的復雜數據恢復情況。
崔華也是熱心的技術分享者,多次在ACOUG的活動上與技術愛好者分享技術心得。