大數據量的資料庫表設計技巧
即使是一個非常簡單的資料庫應用系統,它的數據量增加到一定程度也會引起發一系列問題。如果在設計資料庫的時候,就提前考慮這些問題,可以避免由於系統反映遲緩而引起的用戶抱怨。
技巧1:盡量不要使用代碼。比如性別這個欄位常見的做法:1代表男,0代表女。這樣的做法意味著每一次查詢都需要關聯代碼表。
技巧2:歷史數據中所有欄位與業務表不要有依賴關系。如保存列印發票的時候,不要只保留單位代碼,而應當把單位名稱也保存下來。
技巧3:使用中間表。比如職工工資,可以把每一位職工工資的合計保存在一張中間表中,當職工某一工資項目發生變化的時候,同時對中間表的數據做相應更新。
技巧4:使用統計表。需要經常使用的統計數據,生成之後可以用專門的表來保存。
技巧5:分批保存歷史數據。歷史數據可以分段保存,比如2003年的歷史數據保存在 《2003表名》中,而2004年的歷史數據則保存在《2004表名》中。
技巧6:把不常用的數據從業務表中移到歷史表。比如職工檔案表,當某一職工離開公司以後,應該把他的職工檔案表中的信息移動到《離職職工檔案表》中。
1、經常查詢的和不常用的分開幾個表,也就是橫向切分
2、把不同類型的分成幾個表,縱向切分
3、常用聯接的建索引
4、伺服器放幾個硬碟,把數據、日誌、索引分盤存放,這樣可以提高IO吞吐率
5、用優化器,優化你的查詢
6、考慮冗餘,這樣可以減少連接
7、可以考慮建立統計表,就是實時生成總計表,這樣可以避免每次查詢都統計一次
8、用極量數據測試一下數據
速度,影響它的因數太多了,且數據量越大越明顯。
1、存儲將硬碟分成NTFS格式,NTFS比FAT32快,並看你的數據文件大小,1G以上你可以採用多資料庫文件,這樣可以將存取負載分散到多個物理硬碟或磁碟陣列上。
2、tempdbtempdb也應該被單獨的物理硬碟或磁碟陣列上,建議放在RAID0上,這樣它的性能最高,不要對它設置最大值讓它自動增長
3、日誌文件日誌文件也應該和數據文件分開在不同的理硬碟或磁碟陣列上,這樣也可以提高硬碟I/O性能。
4、分區視圖就是將你的數據水平分割在集群伺服器上,它適合大規模OLTP,SQL群集上,如果你資料庫不是訪問特別大不建議使用。
5、簇索引你的表一定有個簇索引,在使用簇索引查詢的時候,區塊查詢是最快的,如用between,應為他是物理連續的,你應該盡量減少對它的updaet,應為這可以使它物理不連續。
6、非簇索引非簇索引與物理順序無關,設計它時必須有高度的可選擇性,可以提高查詢速度,但對表update的時候這些非簇索引會影響速度,且佔用空間大,如果你願意用空間和修改時間換取速度可以考慮。
7、索引視圖如果在視圖上建立索引,那視圖的結果集就會被存儲起來,對與特定的查詢性能可以提高很多,但同樣對update語句時它也會嚴重減低性能,一般用在數據相對穩定的數據倉庫中。
8、維護索引你在將索引建好後,定期維護是很重要的,用dbccshowcontig來觀察頁密度、掃描密度等等,及時用dbccindexdefrag來整理表或視圖的索引,在必要的時候用dbccdbreindex來重建索引可以受到良好的效果。
不論你是用幾個表1、2、3點都可以提高一定的性能,5、6、8點你是必須做的,至於4、7點看你的需求,我個人是不建議的。
B. 大數據量高並發訪問資料庫結構的設計
大數據量高並發訪問資料庫結構的設計
如果不能設計一個合理的資料庫模型,不僅會增加客戶端和伺服器段程序的編程和維護的難度,而且將會影響系統實際運行的性能。所以,在一個系統開始實施之前,完備的資料庫模型的設計是必須的。
在一個系統分析、設計階段,因為數據量較小,負荷較低。我們往往只注意到功能的實現,而很難注意到性能的薄弱之處,等到系統投入實際運行一段時間後,才發現系統的性能在降低,這時再來考慮提高系統性能則要花費更多的人力物力,而整個系統也不可避免的形成了一個打補丁工程。
所以在考慮整個系統的流程的時候,我們必須要考慮,在高並發大數據量的訪問情況下,我們的系統會不會出現極端的情況。(例如:對外統計系統在7月16日出現的數據異常的情況,並發大數據量的的訪問造成,資料庫的響應時間不能跟上數據刷新的速度造成。具體情況是:在日期臨界時(00:00:00),判斷資料庫中是否有當前日期的記錄,沒有則插入一條當前日期的記錄。在低並發訪問的情況下,不會發生問題,但是當日期臨界時的訪問量相當大的時候,在做這一判斷的時候,會出現多次條件成立,則資料庫里會被插入多條當前日期的記錄,從而造成數據錯誤。),資料庫的模型確定下來之後,我們有必要做一個系統內數據流向圖,分析可能出現的瓶頸。
為了保證資料庫的一致性和完整性,在邏輯設計的時候往往會設計過多的表間關聯,盡可能的降低數據的冗餘。(例如用戶表的地區,我們可以把地區另外存放到一個地區表中)如果數據冗餘低,數據的完整性容易得到保證,提高了數據吞吐速度,保證了數據的完整性,清楚地表達數據元素之間的關系。而對於多表之間的關聯查詢(尤其是大數據表)時,其性能將會降低,同時也提高了客戶端程序的編程難度,因此,物理設計需折衷考慮,根據業務規則,確定對關聯表的數據量大小、數據項的訪問頻度,對此類數據表頻繁的關聯查詢應適當提高數據冗餘設計但增加了表間連接查詢的操作,也使得程序的變得復雜,為了提高系統的響應時間,合理的數據冗餘也是必要的。設計人員在設計階段應根據系統操作的類型、頻度加以均衡考慮。
另外,最好不要用自增屬性欄位作為主鍵與子表關聯。不便於系統的遷移和數據恢復。對外統計系統映射關系丟失(******************)。
原來的表格必須可以通過由它分離出去的表格重新構建。使用這個規定的好處是,你可以確保不會在分離的表格中引入多餘的列,所有你創建的表格結構都與它們的實際需要一樣大。應用這條規定是一個好習慣,不過除非你要處理一個非常大型的數據,否則你將不需要用到它。(例如一個通行證系統,我可以將USERID,USERNAME,USERPASSWORD,單獨出來作個表,再把USERID作為其他表的外鍵)
表的設計具體注意的問題:
1、數據行的長度不要超過8020位元組,如果超過這個長度的話在物理頁中這條數據會佔用兩行從而造成存儲碎片,降低查詢效率。
2、能夠用數字類型的欄位盡量選擇數字類型而不用字元串類型的(電話號碼),這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接回逐個比較字元串中每一個字元,而對於數字型而言只需要比較一次就夠了。
3、對於不可變字元類型char和可變字元類型varchar都是8000位元組,char查詢快,但是耗存儲空間,varchar查詢相對慢一些但是節省存儲空間。在設計欄位的時候可以靈活選擇,例如用戶名、密碼等長度變化不大的欄位可以選擇CHAR,對於評論等長度變化大的欄位可以選擇VARCHAR。
4、欄位的長度在最大限度的滿足可能的需要的前提下,應該盡可能的設得短一些,這樣可以提高查詢的效率,而且在建立索引的時候也可以減少資源的消耗。
5、基本表及其欄位之間的關系, 應盡量滿足第三範式。但是,滿足第三範式的資料庫設計,往往不是最好的設計。為了提高資料庫的運行效率,常常需要降低範式標准:適當增加冗餘,達到以空間換時間的目的。
6、若兩個實體之間存在多對多的關系,則應消除這種關系。消除的辦法是,在兩者之間增加第三個實體。這樣,原來一個多對多的關系,現在變為兩個一對多的關系。要將原來兩個實體的屬性合理地分配到三個實體中去。這里的第三個實體,實質上是一個較復雜的關系,它對應一張基本表。一般來講,資料庫設計工具不能識別多對多的關系,但能處理多對多的關系。
7、主鍵PK的取值方法,PK是供程序員使用的表間連接工具,可以是一無物理意義的數字串, 由程序自動加1來實現。也可以是有物理意義的欄位名或欄位名的組合。不過前者比後者好。當PK是欄位名的組合時,建議欄位的個數不要太多,多了不但索引佔用空間大,而且速度也慢。
8、主鍵與外鍵在多表中的重復出現, 不屬於數據冗餘,這個概念必須清楚,事實上有許多人還不清楚。非鍵欄位的重復出現, 才是數據冗餘!而且是一種低級冗餘,即重復性的冗餘。高級冗餘不是欄位的重復出現,而是欄位的派生出現。
〖例4〗:商品中的「單價、數量、金額」三個欄位,「金額」就是由「單價」乘以「數量」派生出來的,它就是冗餘,而且是一種高級冗餘。冗餘的目的是為了提高處理速度。只有低級冗餘才會增加數據的不一致性,因為同一數據,可能從不同時間、地點、角色上多次錄入。因此,我們提倡高級冗餘(派生性冗餘),反對低級冗餘(重復性冗餘)。
9、中間表是存放統計數據的表,它是為數據倉庫、輸出報表或查詢結果而設計的,有時它沒有主鍵與外鍵(數據倉庫除外)。臨時表是程序員個人設計的,存放臨時記錄,為個人所用。基表和中間表由DBA維護,臨時表由程序員自己用程序自動維護。
10、防止資料庫設計打補丁的方法是「三少原則」
(1) 一個資料庫中表的個數越少越好。只有表的個數少了,才能說明系統的E--R圖少而精,去掉了重復的多餘的實體,形成了對客觀世界的高度抽象,進行了系統的數據集成,防止了打補丁式的設計;
(2) 一個表中組合主鍵的欄位個數越少越好。因為主鍵的作用,一是建主鍵索引,二是做為子表的外鍵,所以組合主鍵的欄位個數少了,不僅節省了運行時間,而且節省了索引存儲空間;
(3) 一個表中的欄位個數越少越好。只有欄位的個數少了,才能說明在系統中不存在數據重復,且很少有數據冗餘,更重要的是督促讀者學會「列變行」,這樣就防止了將子表中的欄位拉入到主表中去,在主表中留下許多空餘的欄位。所謂「列變行」,就是將主表中的一部分內容拉出去,另外單獨建一個子表。這個方法很簡單,有的人就是不習慣、不採納、不執行。
資料庫設計的實用原則是:在數據冗餘和處理速度之間找到合適的平衡點。「三少」是一個整體概念,綜合觀點,不能孤立某一個原則。該原則是相對的,不是絕對的。「三多」原則肯定是錯誤的。試想:若覆蓋系統同樣的功能,一百個實體(共一千個屬性) 的E--R圖,肯定比二百個實體(共二千個屬性)的E--R圖,要好得多。
提倡「三少」原則,是叫讀者學會利用資料庫設計技術進行系統的數據集成。數據集成的步驟是將文件系統集成為應用資料庫,將應用資料庫集成為主題資料庫,將主題資料庫集成為全局綜合資料庫。集成的程度越高,數據共享性就越強,信息孤島現象就越少,整個企業信息系統的全局E—R圖中實體的個數、主鍵的個數、屬性的個數就會越少。
提倡「三少」原則的目的,是防止讀者利用打補丁技術,不斷地對資料庫進行增刪改,使企業資料庫變成了隨意設計資料庫表的「垃圾堆」,或資料庫表的「大雜院」,最後造成資料庫中的基本表、代碼表、中間表、臨時表雜亂無章,不計其數,導致企事業單位的信息系統無法維護而癱瘓。
「三多」原則任何人都可以做到,該原則是「打補丁方法」設計資料庫的歪理學說。「三少」原則是少而精的原則,它要求有較高的資料庫設計技巧與藝術,不是任何人都能做到的,因為該原則是杜絕用「打補丁方法」設計資料庫的理論依據。
11、在給定的系統硬體和系統軟體條件下,提高資料庫系統的運行效率的辦法是:
(1) 在資料庫物理設計時,降低範式,增加冗餘, 少用觸發器, 多用存儲過程。
(2) 當計算非常復雜、而且記錄條數非常巨大時(例如一千萬條),復雜計算要先在資料庫外面,以文件系統方式用編程語言計算處理完成之後,最後才入庫追加到表中去。
(3) 發現某個表的記錄太多,例如超過一千萬條,則要對該表進行水平分割。水平分割的做法是,以該表主鍵PK的某個值為界線,將該表的記錄水平分割為兩個表。若發現某個表的欄位太多,例如超過八十個,則垂直分割該表,將原來的一個表分解為兩個表。
(4) 對資料庫管理系統DBMS進行系統優化,即優化各種系統參數,如緩沖區個數。
(5) 在使用面向數據的SQL語言進行程序設計時,盡量採取優化演算法。
總之,要提高資料庫的運行效率,必須從資料庫系統級優化、資料庫設計級優化、程序實現級優化,這三個層次上同時下功夫。
主鍵設計:
1、不建議用多個欄位做主鍵,單個表還可以,但是關聯關系就會有問題,主鍵自增是高性能的。
2、一般情況下,如果有兩個外鍵,不建議採用兩個外鍵作為聯合住建,另建一個欄位作為主鍵。除非這條記錄沒有邏輯刪除標志,且該表永遠只有一條此聯合主鍵的記錄。
3、一般而言,一個實體不能既無主鍵又無外鍵。在E—R 圖中, 處於葉子部位的實體, 可以定義主鍵,也可以不定義主鍵(因為它無子孫), 但必須要有外鍵(因為它有父親)。
主鍵與外鍵的設計,在全局資料庫的設計中,佔有重要地位。當全局資料庫的設計完成以後,有個美國資料庫設計專家說:「鍵,到處都是鍵,除了鍵之外,什麼也沒有」,這就是他的資料庫設計經驗之談,也反映了他對信息系統核心(數據模型)的高度抽象思想。因為:主鍵是實體的高度抽象,主鍵與、外鍵的配對,表示實體之間的連接。
C. 資料庫如何設計
資料庫設計的基本步驟
按照規范設計的方法,考慮資料庫及其應用系統開發全過程,將資料庫設計分為以下6個階段
1.需求分析
2.概念結構設計
3.邏輯結構設計
4.物理結構設計
5.資料庫實施
6.資料庫的運行和維護
資料庫設計通常分為6個階段1分析用戶的需求,包括數據、功能和性能需求;2概念結構設計:主要採用E-R模型進行設計,包括畫E-R圖;3邏輯結構設計:通過將轉換成表,實現從E-R模型到關系模型的轉換;4:主要是為所設計的資料庫選擇合適的和存取路徑;5資料庫的實施:包括編程、測試和試運行;6資料庫運行與維護:系統的運行與資料庫的日常維護。),主要討論其中的第3個階段,即邏輯設計。
在資料庫設計過程中,需求分析和概念設計可以獨立於任何資料庫管理系統進行,邏輯設計和物理設計與選用的DAMS密切相關。
1.需求分析階段(常用自頂向下)
進行資料庫設計首先必須准確了解和分析用戶需求(包括數據與處理)。需求分析是整個設計過程的基礎,也是最困難,最耗時的一步。需求分析是否做得充分和准確,決定了在其上構建資料庫大廈的速度與質量。需求分析做的不好,會導致整個資料庫設計返工重做。
需求分析的任務,是通過詳細調查現實世界要處理的對象,充分了解原系統工作概況,明確用戶的各種需求,然後在此基礎上確定新的系統功能,新系統還得充分考慮今後可能的擴充與改變,不僅僅能夠按當前應用需求來設計。
調查的重點是,數據與處理。達到信息要求,處理要求,安全性和完整性要求。
分析方法常用SA(Structured Analysis) 結構化分析方法,SA方法從最上層的系統組織結構入手,採用自頂向下,逐層分解的方式分析系統。
數據流圖表達了數據和處理過程的關系,在SA方法中,處理過程的處理邏輯常常藉助判定表或判定樹來描述。在處理功能逐步分解的同事,系統中的數據也逐級分解,形成若干層次的數據流圖。系統中的數據則藉助數據字典(data dictionary,DD)來描述。數據字典是系統中各類數據描述的集合,數據字典通常包括數據項,數據結構,數據流,數據存儲,和處理過程5個階段。
2.概念結構設計階段(常用自底向上)
概念結構設計是整個資料庫設計的關鍵,它通過對用戶需求進行綜合,歸納與抽象,形成了一個獨立於具體DBMS的概念模型。
設計概念結構通常有四類方法:
自頂向下。即首先定義全局概念結構的框架,再逐步細化。
自底向上。即首先定義各局部應用的概念結構,然後再將他們集成起來,得到全局概念結構。
逐步擴張。首先定義最重要的核心概念結構,然後向外擴張,以滾雪球的方式逐步生成其他的概念結構,直至總體概念結構。
混合策略。即自頂向下和自底向上相結合。
3.邏輯結構設計階段(E-R圖)
邏輯結構設計是將概念結構轉換為某個DBMS所支持的數據模型,並將進行優化。
在這階段,E-R圖顯得異常重要。大家要學會各個實體定義的屬性來畫出總體的E-R圖。
各分E-R圖之間的沖突主要有三類:屬性沖突,命名沖突,和結構沖突。
E-R圖向關系模型的轉換,要解決的問題是如何將實體性和實體間的聯系轉換為關系模式,如何確定這些關系模式的屬性和碼。
4.物理設計階段
物理設計是為邏輯數據結構模型選取一個最適合應用環境的物理結構(包括存儲結構和存取方法)。
首先要對運行的事務詳細分析,獲得選擇物理資料庫設計所需要的參數,其次,要充分了解所用的RDBMS的內部特徵,特別是系統提供的存取方法和存儲結構。
常用的存取方法有三類:1.索引方法,目前主要是B+樹索引方法。2.聚簇方法(Clustering)方法。3.是HASH方法。
5.資料庫實施階段
資料庫實施階段,設計人員運營DBMS提供的資料庫語言(如sql)及其宿主語言,根據邏輯設計和物理設計的結果建立資料庫,編制和調試應用程序,組織數據入庫,並進行試運行。
6.資料庫運行和維護階段
資料庫應用系統經過試運行後,即可投入正式運行,在資料庫系統運行過程中必須不斷地對其進行評價,調整,修改。
資料庫設計5步驟
Five Steps to design the Database
1.確定entities及relationships
a)明確宏觀行為。資料庫是用來做什麼的?比如,管理雇員的信息。
b)確定entities。對於一系列的行為,確定所管理信息所涉及到的主題范圍。這將變成table。比如,僱用員工,指定具體部門,確定技能等級。
c)確定relationships。分析行為,確定tables之間有何種關系。比如,部門與雇員之間存在一種關系。給這種關系命名。
d)細化行為。從宏觀行為開始,現在仔細檢查這些行為,看有哪些行為能轉為微觀行為。比如,管理雇員的信息可細化為:
· 增加新員工
· 修改存在員工信息
· 刪除調走的員工
e)確定業務規則。分析業務規則,確定你要採取哪種。比如,可能有這樣一種規則,一個部門有且只能有一個部門領導。這些規則將被設計到資料庫的結構中。
====================================================================
範例:
ACME是一個小公司,在5個地方都設有辦事處。當前,有75名員工。公司准備快速擴大規模,劃分了9個部門,每個部門都有其領導。
為有助於尋求新的員工,人事部門規劃了68種技能,為將來人事管理作好准備。員工被招進時,每一種技能的專業等級都被確定。
定義宏觀行為
一些ACME公司的宏觀行為包括:
● 招聘員工
● 解僱員工
● 管理員工個人信息
● 管理公司所需的技能信息
● 管理哪位員工有哪些技能
● 管理部門信息
● 管理辦事處信息
確定entities及relationships
我們可以確定要存放信息的主題領域(表)及其關系,並創建一個基於宏觀行為及描述的圖表。
我們用方框來代表table,用菱形代表relationship。我們可以確定哪些relationship是一對多,一對一,及多對多。
這是一個E-R草圖,以後會細化。
細化宏觀行為
以下微觀行為基於上面宏觀行為而形成:
● 增加或刪除一個員工
● 增加或刪除一個辦事處
● 列出一個部門中的所有員工
● 增加一項技能
● 增加一個員工的一項技能
● 確定一個員工的技能
● 確定一個員工每項技能的等級
● 確定所有擁有相同等級的某項技能的員工
● 修改員工的技能等級
這些微觀行為可用來確定需要哪些table或relationship。
確定業務規則
業務規則常用於確定一對多,一對一,及多對多關系。
相關的業務規則可能有:
● 現在有5個辦事處;最多允許擴展到10個。
● 員工可以改變部門或辦事處
● 每個部門有一個部門領導
● 每個辦事處至多有3個電話號碼
● 每個電話號碼有一個或多個擴展
● 員工被招進時,每一種技能的專業等級都被確定。
● 每位員工擁有3到20個技能
● 某位員工可能被安排在一個辦事處,也可能不安排辦事處。
2.確定所需數據
要確定所需數據:
a)確定支持數據
b)列出所要跟蹤的所有數據。描述table(主題)的數據回答這些問題:誰,什麼,哪裡,何時,以及為什麼
c)為每個table建立數據
d)列出每個table目前看起來合適的可用數據
e)為每個relationship設置數據
f)如果有,為每個relationship列出適用的數據
確定支持數據
你所確定的支持數據將會成為table中的欄位名。比如,下列數據將適用於表Employee,表Skill,表Expert In。
Employee
Skill
Expert In
ID
ID
Level
Last Name
Name
Date acquired
First Name
Description
Department
Office
Address
如果將這些數據畫成圖表,就像:
3.標准化數據
標准化是你用以消除數據冗餘及確保數據與正確的table或relationship相關聯的一系列測試。共有5個測試。本節中,我們將討論經常使用的3個。
關於標准化測試的更多信息,請參考有關資料庫設計的書籍。
標准化格式
標准化格式是標准化數據的常用測試方式。你的數據通過第一遍測試後,就被認為是達到第一標准化格式;通過第二遍測試,達到第二標准化格式;通過第三遍測試,達到第三標准化格式。
如何標准格式:
1. 列出數據
2. 為每個表確定至少一個鍵。每個表必須有一個主鍵。
3. 確定relationships的鍵。relationships的鍵是連接兩個表的鍵。
4. 檢查支持數據列表中的計算數據。計算數據通常不保存在資料庫中。
5. 將數據放在第一遍的標准化格式中:
6. 從tables及relationships除去重復的數據。
7. 以你所除去數據創建一個或更多的tables及relationships。
8. 將數據放在第二遍的標准化格式中:
9. 用多於一個以上的鍵確定tables及relationships。
10. 除去只依賴於鍵一部分的數據。
11. 以你所除去數據創建一個或更多的tables及relationships。
12. 將數據放在第三遍的標准化格式中:
13. 除去那些依賴於tables或relationships中其他數據,並且不是鍵的數據。
14. 以你所除去數據創建一個或更多的tables及relationships。
數據與鍵
在你開始標准化(測試數據)前,簡單地列出數據,並為每張表確定一個唯一的主鍵。這個鍵可以由一個欄位或幾個欄位(連鎖鍵)組成。
主鍵是一張表中唯一區分各行的一組欄位。Employee表的主鍵是Employee ID欄位。Works In relationship中的主鍵包括Office Code及Employee ID欄位。給資料庫中每一relationship給出一個鍵,從其所連接的每一個table中抽取其鍵產生。
RelationShip
Key
Office
*Office code
Office address
Phone number
Works in
*Office code
*Employee ID
Department
*Department ID
Department name
Heads
*Department ID
*Employee ID
Assoc with
*Department ID
*EmployeeID
Skill
*Skill ID
Skill name
Skill description
Expert In
*Skill ID
*Employee ID
Skill level
Date acquired
Employee
*Employee ID
Last Name
First Name
Social security number
Employee street
Employee city
Employee state
Employee phone
Date of birth
將數據放在第一遍的標准化格式中
● 除去重復的組
● 要測試第一遍標准化格式,除去重復的組,並將它們放進他們各自的一張表中。
● 在下面的例子中,Phone Number可以重復。(一個工作人員可以有多於一個的電話號碼。)將重復的組除去,創建一個名為Telephone的新表。在Telephone與Office創建一個名為Associated With的relationship。
將數據放在第二遍的標准化格式中
● 除去那些不依賴於整個鍵的數據。
● 只看那些有一個以上鍵的tables及relationships。要測試第二遍標准化格式,除去那些不依賴於整個鍵的任何數據(組成鍵的所有欄位)。
● 在此例中,原Employee表有一個由兩個欄位組成的鍵。一些數據不依賴於整個鍵;例如,department name只依賴於其中一個鍵(Department ID)。因此,Department ID,其他Employee數據並不依賴於它,應移至一個名為Department的新表中,並為Employee及Department建立一個名為Assigned To的relationship。
將數據放在第三遍的標准化格式中
● 除去那些不直接依賴於鍵的數據。
● 要測試第三遍標准化格式,除去那些不是直接依賴於鍵,而是依賴於其他數據的數據。
● 在此例中,原Employee表有依賴於其鍵(Employee ID)的數據。然而,office location及office phone依賴於其他欄位,即Office Code。它們不直接依賴於Employee ID鍵。將這組數據,包括Office Code,移至一個名為Office的新表中,並為Employee及Office建立一個名為Works In的relationship。
4.考量關系
當你完成標准化進程後,你的設計已經差不多完成了。你所需要做的,就是考量關系。
考量帶有數據的關系
你的一些relationship可能集含有數據。這經常發生在多對多的關系中。
遇到這種情況,將relationship轉化為一個table。relationship的鍵依舊成為table中的鍵。
考量沒有數據的關系
要實現沒有數據的關系,你需要定義外部鍵。外部鍵是含有另外一個表中主鍵的一個或多個欄位。外部鍵使你能同時連接多表數據。
有一些基本原則能幫助你決定將這些鍵放在哪裡:
一對多在一對多關系中,「一」中的主鍵放在「多」中。此例中,外部鍵放在Employee表中。
一對一在一對一關系中,外部鍵可以放進任一表中。如果必須要放在某一邊,而不能放在另一邊,應該放在必須的一邊。此例中,外部鍵(Head ID)在Department表中,因為這是必需的。
多對多在多對多關系中,用兩個外部鍵來創建一個新表。已存的舊表通過這個新表來發生聯系。
5.檢驗設計
在你完成設計之前,你需要確保它滿足你的需要。檢查你在一開始時所定義的行為,確認你可以獲取行為所需要的所有數據:
● 你能找到一個路徑來等到你所需要的所有信息嗎?
● 設計是否滿足了你的需要?
● 所有需要的數據都可用嗎?
如果你對以上的問題都回答是,你已經差不多完成設計了。
最終設計
最終設計看起來就像這樣:
設計資料庫的表屬性
資料庫設計需要確定有什麼表,每張表有什麼欄位。此節討論如何指定各欄位的屬性。
對於每一欄位,你必須決定欄位名,數據類型及大小,是否允許NULL值,以及你是否希望資料庫限制欄位中所允許的值。
選擇欄位名
欄位名可以是字母、數字或符號的任意組合。然而,如果欄位名包括了字母、數字或下劃線、或並不以字母打頭,或者它是個關鍵字(詳見關鍵字表),那麼當使用欄位名稱時,必須用雙引號括起來。
為欄位選擇數據類型
SQL Anywhere支持的數據類型包括:
整數(int, integer, smallint)
小數(decimal, numeric)
浮點數(float, double)
字元型(char, varchar, long varchar)
二進制數據類型(binary, long binary)
日期/時間類型(date, time, timestamp)
用戶自定義類型
關於數據類型的內容,請參見「SQL Anywhere數據類型」一節。欄位的數據類型影響欄位的最大尺寸。例如,如果你指定SMALLINT,此欄位可以容納32,767的整數。INTEGER可以容納2,147,483,647的整數。對CHAR來講,欄位的最大值必須指定。
長二進制的數據類型可用來在資料庫中保存例如圖像(如點陣圖)或者文字編輯文檔。這些類型的信息通常被稱為二進制大型對象,或者BLOBS。
關於每一數據類型的完整描述,見「SQL Anywhere數據類型」。
D. 數據量大,列比較多,請問資料庫表該如何設計
基本的建立主鍵,索引什麼的,我就不說了,
表設計可以採取拆分表的方式
縱向拆分表:根據欄位拆分為多個表,每個表都有關聯欄位,可以將他們關聯起來
(例如:訂單表,幾個根據欄位拆分的表中都有1個訂單號欄位)
橫向拆分表:不知道你具體什麼數據,假定其中有時間欄位,根據時間來拆分
(例如:1年有12個月,1個月的數據放入一個表中)
E. 大型資料庫設計原則
一個好的資料庫產品不等於就有一個好的應用系統 如果不能設計一個合理的資料庫模型 不僅會增加客戶端和伺服器段程序的編程和維護的難度 而且將會影響系統實際運行的性能 一般來講 在一個MIS系統分析 設計 測試和試運行階段 因為數據量較小 設計人員和測試人員往往只注意到功能的實現 而很難注意到性能的薄弱之處 等到系統投入實際運行一段時間後 才發現系統的性能在降低 這時再來考慮提高系統性能則要花費更多的人力物力 而整個系統也不可避免的形成了一個打補丁工程 筆者依據多年來設計和使用資料庫的經驗 提出以下一些設計准則 供同仁們參考
命名的規范
不同的資料庫產品對對象的命名有不同的要求 因此 資料庫中的各種對象的命名 後台程序的代碼編寫應採用大小寫敏感的形式 各種對象命名長度不要超過 個字元 這樣便於應用系統適應不同的資料庫
游標(Cursor)的慎用
游標提供了對特定集合中逐行掃描的手段 一般使用游標逐行遍歷數據 根據取出的數據不同條件進行不同的操作 尤其對多表和大表定義的游標(大的數據集合)循環很容易使程序進入一個漫長的等特甚至死機 筆者在某市《住房公積金管理系統》進行日終帳戶滾積數計息處理時 對一個 萬個帳戶的游標處理導致程序進入了一個無限期的等特(後經測算需 個小時才能完成)(硬體環境 Alpha/ Mram Sco Unix Sybase ) 後根據不同的條件改成用不同的UPDATE語句得以在二十分鍾之內完成 示例如下
Declare Mycursor cursor for select count_no from COUNT
Open Mycursor
Fetch Mycursor into @vcount_no
While (@@sqlstatus= )
Begin
If @vcount_no= 條件
操作
If @vcount_no= 條件
操作
Fetch Mycursor into @vcount_no
End
改為
Update COUNT set 操作 for 條件
Update COUNT set 操作 for 條件
在有些場合 有時也非得使用游標 此時也可考慮將符合條件的數據行轉入臨時表中 再對臨時表定義游標進行操作 可時性能得到明顯提高 筆者在某地市〈電信收費系統〉資料庫後台程序設計中 對一個表( 萬行中符合條件的 多行數據)進行游標操作(硬體環境 PC伺服器 PII Mram NT Ms Sqlserver ) 示例如下
Create #tmp /* 定義臨時表 */
(欄位
欄位
)
Insert into #tmp select * from TOTAL where
條件 /* TOTAL中 萬行 符合條件只有幾十行 */
Declare Mycursor cursor for select * from #tmp
/*對臨時表定義游標*/
索引(Index)的使用原則
創建索引一般有以下兩個目的 維護被索引列的唯一性和提供快速訪問表中數據的策略 大型資料庫有兩種索引即簇索引和非簇索引 一個沒有簇索引的表是按堆結構存儲數據 所有的數據均添加在表的尾部 而建立了簇索引的表 其數據在物理上會按照簇索引鍵的順序存儲 一個表只允許有一個簇索引 因此 根據B樹結構 可以理解添加任何一種索引均能提高按索引列查詢的速度 但會降低插入 更新 刪除操作的性能 尤其是當填充因子(Fill Factor)較大時 所以對索引較多的表進行頻繁的插入 更新 刪除操作 建表和索引時因設置較小的填充因子 以便在各數據頁中留下較多的自由空間 減少頁分割及重新組織的工作
數據的一致性和完整性
為了保證資料庫的一致性和完整性 設計人員往往會設計過多的表間關聯(Relation) 盡可能的降低數據的冗餘 表間關聯是一種強制性措施 建立後 對父表(Parent Table)和子表(Child Table)的插入 更新 刪除操作均要佔用系統的開銷 另外 最好不要用Identify 屬性欄位作為主鍵與子表關聯 如果數據冗餘低 數據的完整性容易得到保證 但增加了表間連接查詢的操作 為了提高系統的響應時間 合理的數據冗餘也是必要的 使用規則(Rule)和約束(Check)來防止系統操作人員誤輸入造成數據的錯誤是設計人員的另一種常用手段 但是 不必要的規則和約束也會佔用系統的不必要開銷 需要注意的是 約束對數據的有效性驗證要比規則快 所有這些 設計人員在設計階段應根據系統操作的類型 頻度加以均衡考慮
事務的陷阱
事務是在一次性完成的一組操作 雖然這些操作是單個的操作 SQL Server能夠保證這組操作要麼全部都完成 要麼一點都不做 正是大型資料庫的這一特性 使得數據的完整性得到了極大的保證
眾所周知 SQL Server為每個獨立的SQL語句都提供了隱含的事務控制 使得每個DML的數據操作得以完整提交或回滾 但是SQL Server還提供了顯式事務控制語句
BEGIN TRANSACTION 開始一個事務
MIT TRANSACTION 提交一個事務
ROLLBACK TRANSACTION 回滾一個事務
事務可以嵌套 可以通過全局變數@@trancount檢索到連接的事務處理嵌套層次 需要加以特別注意並且極容易使編程人員犯錯誤的是 每個顯示或隱含的事物開始都使得該變數加 每個事務的提交使該變數減 每個事務的回滾都會使得該變數置 而只有當該變數為 時的事務提交(最後一個提交語句時) 這時才把物理數據寫入磁碟
資料庫性能調整
在計算機硬體配置和網路設計確定的情況下 影響到應用系統性能的因素不外乎為資料庫性能和客戶端程序設計 而大多數資料庫設計員採用兩步法進行資料庫設計 首先進行邏輯設計 而後進行物理設計 資料庫邏輯設計去除了所有冗餘數據 提高了數據吞吐速度 保證了數據的完整性 清楚地表達數據元素之間的關系 而對於多表之間的關聯查詢(尤其是大數據表)時 其性能將會降低 同時也提高了客 戶端程序的編程難度 因此 物理設計需折衷考慮 根據業務規則 確定對關聯表的數據量大小 數據項的訪問頻度 對此類數據表頻繁的關聯查詢應適當提高數據冗餘設計
數據類型的選擇
數據類型的合理選擇對於資料庫的性能和操作具有很大的影響 有關這方面的書籍也有不少的闡述 這里主要介紹幾點經驗
Identify欄位不要作為表的主鍵與其它表關聯 這將會影響到該表的數據遷移
Text 和Image欄位屬指針型數據 主要用來存放二進制大型對象(BLOB) 這類數據的操作相比其它數據類型較慢 因此要避開使用
日期型欄位的優點是有眾多的日期函數支持 因此 在日期的大小比較 加減操作上非常簡單 但是 在按照日期作為條件的查詢操作也要用函數 相比其它數據類型速度上就慢許多 因為用函數作為查詢的條件時 伺服器無法用先進的性能策略來優化查詢而只能進行表掃描遍歷每行
例如 要從DATA_TAB 中(其中有一個名為DATE的日期欄位)查詢 年的所有記錄
lishixin/Article/program/Oracle/201311/17929
F. 一文總結高並發大數據量下MySQL開發規范「軍規」
在互聯網公司中,MySQL是使用最多的資料庫,那麼在並發量大、數據量大的互聯網業務中,如果高效的使用MySQL才能保證服務的穩定呢?根據本人多年運維管理經驗的總結,梳理了一些核心的開發規范,希望能給大家帶來一些幫助。
一、基礎規范
二、庫表設計
問題:使用VARCHAR(5) 和VARCHAR(200) 存儲』hello』的磁碟空間開銷是一樣的,使用更短的列表有什麼優勢嗎?
更大的定義列會消耗更多的內存,因為MySQL通常會分配固定大小的內存塊來保存內部值,尤其是使用內存臨時表進行排序或操作時會特別糟糕
三、索引設計
基本規則:索引不是越多越好,能不添加的索引盡量不要添加,過多的索引會嚴重降低數據插入和更新的效率,並帶來更多的讀寫沖突和死鎖!
示例:假設在表tab中id建立了索引
四、SQL優化
示例:
欄位: code varchar(50) NOT NULL COMENT 『編碼』 #code上建立了索引
SELECT id,name,addr from tab_name where code=10001; 不會使用索引
SELECT id,name,addr from tab_name where code=' 會使用索引
Select * from table limit 10000,10;
LIMIT原理:
Limit 10000,10 偏移量越大則越慢
Select * from table WHERE id>=23423 limit 11; #10+1 (每頁10條)
Select * from table WHERE id>=23434 limit 11;
Select * from table WHERE id >= ( select id from table limit 10000,1 ) limit 10;
Select * from table INNER JOIN (SELECT id from table limit 10000,10) USING(id)
最後說明:
上述規范是多年MySQL資料庫使用的經驗總結,希望能給大家帶來一些啟發和幫助!