熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

新手淺談數據庫中的設計技巧(一)

2013-11-13 15:36:38  來源: Oracle 

  說到數據庫我認為不能不先談數據結構在我初入大學學習計算機編程時當時的老師就告訴我們說計算機程序=數據結構+算法盡管現在的程序開發已由面向過程為主逐步過渡到面向對象為主但我還是深深贊同年前老師的告訴我們的公式計算機程序=數據結構+算法面向對象的程序開發要做的第一件事就是先分析整個程序中需處理的數據從中提取出抽象模板以這個抽象模板設計類再在其中逐步添加處理其數據的函數(即算法)最後再給類中的數據成員和函數劃分訪問權限從而實現封裝
  
  數據庫的最初雛形據說源自美國一個奶牛場的記賬薄(紙質的由此可見數據庫並不一定是存儲在電腦裡的數據^_^)裡面記錄的是該奶牛場的收支賬目程序員在將其整理錄入到電腦中時從中受到啟發當按照規定好的數據結構所采集到的數據量大到一定程度後出於程序執行效率的考慮程序員將其中的檢索更新維護等功能分離出來做成單獨調用的模塊這個模塊後來就慢慢發展演變成現在我們所接觸到的數據庫管理系統(dbms)——程序開發中的一個重要分支
  
  下面進入正題首先按我個人所接觸過的程序給數據庫設計人員的功底分一下類
  
  1沒有系統學習過數據結構的程序員這類程序員的作品往往只是他們的即興玩具他們往往習慣只設計有限的幾個表實現某類功能的數據全部塞在一個表中各表之間幾乎毫無關聯網上不少的免費管理軟件都是這樣的東西當程序功能有限數據量不多的時候其程序運行起來沒有什麼問題但是如果用其管理比較重要的數據風險性非常大
  
  2系統學習過數據結構但是還沒有開發過對程序效率要求比較高的管理軟件的程序員這類人多半剛從學校畢業不久他們在設計數據庫表結構時嚴格按照教科書上的規定死扣er圖和nf(別灰心所有的數據庫設計高手都是從這一步開始的)他們的作品對於一般的access型輕量級的管理軟件已經夠用但是一旦該系統需要添加新功能原有的數據庫表差不多得進行大換血
  
  3第二類程序員在經歷過數次程序效率的提升以及功能升級的折騰後終於升級成為數據庫設計的老鳥第一類程序員眼中的高人這類程序員可以勝任二十個表以上的中型商業數據管理系統的開發工作他們知道該在什麼樣的情況下保留一定的冗余數據來提高程序效率而且其設計的數據庫可拓展性較好當用戶需要添加新功能時原有數據庫表只需做少量修改即可
  
  4在經歷過上十個類似數據庫管理軟件的重復設計後第三類程序員中堅持下來沒有轉行而是希望從中找出偷懶竅門的有心人會慢慢覺悟從而完成量變到質變的轉換他們所設計的數據庫表結構有一定的遠見能夠預測到未來功能升級所需要的數據從而預先留下伏筆這類程序員目前大多晉級成數據挖掘方面的高級軟件開發人員
  
  5第三類程序員或第四類程序員在對現有的各家數據庫管理系統的原理和開發都有一定的鑽研後要麼在其基礎上進行二次開發要麼自行開發一套有自主版權的通用數據庫管理系統
  
  我個人正處於第三類的末期所以下面所列出的一些設計技巧只適合第二類和部分第三類數據庫設計人員同時由於我很少碰到有興趣在這方面深鑽下去的同行所以文中難免出現錯誤和遺漏在此先行聲明歡迎大家指正不要藏私哦)
  
  樹型關系的數據表
  
  不少程序員在進行數據庫設計的時候都遇到過樹型關系的數據例如常見的類別表即一個大類下面有若干個子類某些子類又有子類這樣的情況當類別不確定用戶希望可以在任意類別下添加新的子類或者刪除某個類別和其下的所有子類而且預計以後其數量會逐步增長此時我們就會考慮用一個數據表來保存這些數據按照教科書上的教導第二類程序員大概會設計出類似這樣的數據表結構
  
  類別表_(type_table_)
  
  名稱          類型約束條件  說明
  
  type_id    int     無重復     類別標識主鍵
  
  type_name char()   不允許為空   類型名稱不允許重復
  
  type_father  int    不允許為空   該類別的父類別標識如果是頂節點的話設定為某個唯一值
  
  這樣的設計短小精悍完全滿足nf而且可以滿足用戶的所有要求是不是這樣就行呢?答案是no!why?
  
  我們來估計一下用戶希望如何羅列出這個表的數據的對用戶而言他當然期望按他所設定的層次關系一次羅列出所有的類別例如這樣
  
  總類別
  
  類別
  
  類別
  
  類別
  
  類別
  
  類別
  
  類別
  
  類別
  
  類別
  
  類別
  
  ……
  
  看看為了實現這樣的列表顯示(樹的先序遍歷)要對上面的表進行多少次檢索?注意盡管類別可能是在類別之後添加的記錄答案仍然是n 次這樣的效率對於少量的數據沒什麼影響但是日後類型擴充到數十條甚至上百條記錄後單單列一次類型就要檢索數十次該表整個程序的運行效率就不敢恭維了或許第二類程序員會說那我再建一個臨時數組或臨時表專門保存類型表的先序遍歷結果這樣只在第一次運行時檢索數十次再次羅列所有的類型關系時就直接讀那個臨時數組或臨時表就行了其實用不著再去分配一塊新的內存來保存這些數據只要對數據表進行一定的擴充再對添加類型的數量進行一下約束就行了要完成上面的列表只需一次檢索就行了下面是擴充後的數據表結構
  
  類別表_(type_table_)
  
  名稱          類型約束條件         說明
  
  type_id    int    無重復           類別標識主鍵
  
  type_name char()   不允許為空         類型名稱不允許重復
  
  type_father  int    不允許為空         該類別的父類別標識如果是頂節點的話設定為某個唯一值
  
  type_layer  char()  限定初始值為   類別的先序遍歷主要為減少檢索數據庫的次數
  
  按照這樣的表結構我們來看看上面例子記錄在表中的數據是怎樣的
  
  type_id   type_name    type_father    type_layer
  
        總類別              
  
        類別               
  
        類別              
  
        類別              
  
        類別               
  
        類別              
  
        類別               
  
        類別              
  
        類別              
  
        類別             
  
  ……
  
  現在按type_layer的大小來檢索一下select * from type_table_ order by type_layer
  
  列出記錄集如下
  
  type_id   type_name    type_father    type_layer
  
        總類別              
  
        類別              
  
        類別             
  
        類別            
  
        類別             
  
        類別              
  
        類別             
  
        類別              
  
        類別             
  
        類別             
  
  ……
  
  現在列出的記錄順序正好是先序遍歷的結果在控制顯示類別的層次時只要對type_layer字段中的數值進行判斷位一組如大於則向右移 個空格當然我這個例子中設定的限制條件是最多每層最多可設個子類別只要按用戶的需求情況修改一下type_layer的長度和位數即可更改限制層數和子類別數其實上面的設計不單單只在類別表中用到網上某些可按樹型列表顯示的論壇程序大多采用類似的設計
  
  或許有人認為type_table_中的type_father字段是冗余數據可以除去如果這樣在插入刪除某個類別的時候就得對 type_layer 的內容進行比較繁瑣的判定所以我並沒有消去type_father字段這也正符合數據庫設計中適當保留冗余數據的來降低程序復雜度的原則後面我會舉一個故意增加數據冗余的案例
  
  商品信息表的設計
  
  假設你是一家百貨公司電腦部的開發人員某天老板要求你為公司開發一套網上電子商務平台該百貨公司有數千種商品出售不過目前僅打算先在網上銷售數十種方便運輸的商品當然以後可能會陸續在該電子商務平台上增加新的商品出售現在開始進行該平台數據庫的商品信息表的設計每種出售的商品都
From:http://tw.wingwit.com/Article/program/Oracle/201311/17002.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.