亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > SQL Server > 正文

淺談數據庫設計技巧(上)

2019-11-03 08:36:56
字體:
來源:轉載
供稿:網友

  說到數據庫,我認為不能不先談數據結構。1996年,在我初入大學學習計算機編程時,當時的老師就告訴我們說:計算機程序=數據結構+算法。盡管現在的程序開發已由面向過程為主逐步過渡到面向對象為主,但我還是深深贊同8年前老師的告訴我們的公式:計算機程序=數據結構+算法。面向對象的程序開發,要做的第一件事就是,先分析整個程序中需處理的數據,從中提取出抽象模板,以這個抽象模板設計類,再在其中逐步添加處理其數據的函數(即算法),最后,再給類中的數據成員和函數劃分訪問權限,從而實現封裝。

  數據庫的最初雛形據說源自美國一個奶牛場的記賬薄(紙質的,由此可見,數據庫并不一定是存儲在電腦里的數據^_^),里面記錄的是該奶牛場的收支賬目,程序員在將其整理、錄入到電腦中時從中受到啟發。當按照規定好的數據結構所采集到的數據量大到一定程度后,出于程序執行效率的考慮,程序員將其中的檢索、更新維護等功能分離出來,做成單獨調用的模塊,這個模塊后來就慢慢發展、演變成現在我們所接觸到的數據庫管理系統(DBMS)——程序開發中的一個重要分支。

  下面進入正題,首先按我個人所接觸過的程序給數據庫設計人員的功底分一下類:
  1、沒有系統學習過數據結構的程序員。這類程序員的作品往往只是他們的即興玩具,他們往往習慣只設計有限的幾個表,實現某類功能的數據全部塞在一個表中,各表之間幾乎毫無關聯。網上不少的免費管理軟件都是這樣的東西,當程序功能有限,數據量不多的時候,其程序運行起來沒有什么問題,但是如果用其管理比較重要的數據,風險性非常大。
 ?。?、系統學習過數據結構,但是還沒有開發過對程序效率要求比較高的管理軟件的程序員。這類人多半剛從學校畢業不久,他們在設計數據庫表結構時,嚴格按照教科書上的規定,死扣E-R圖和3NF(別灰心,所有的數據庫設計高手都是從這一步開始的)。他們的作品,對于一般的access型輕量級的管理軟件,已經夠用。但是一旦該系統需要添加新功能,原有的數據庫表差不多得進行大換血。
 ?。场⒌诙惓绦騿T,在經歷過數次程序效率的提升,以及功能升級的折騰后,終于升級成為數據庫設計的老鳥,第一類程序員眼中的高人。這類程序員可以勝任二十個表以上的中型商業數據管理系統的開發工作。他們知道該在什么樣的情況下保留一定的冗余數據來提高程序效率,而且其設計的數據庫可拓展性較好,當用戶需要添加新功能時,原有數據庫表只需做少量修改即可。
  4、在經歷過上十個類似數據庫管理軟件的重復設計后,第三類程序員中堅持下來沒有轉行,而是希望從中找出“偷懶”竅門的有心人會慢慢覺悟,從而完成量變到質變的轉換。他們所設計的數據庫表結構有一定的遠見,能夠預測到未來功能升級所需要的數據,從而預先留下伏筆。這類程序員目前大多晉級成數據挖掘方面的高級軟件開發人員。
 ?。怠⒌谌惓绦騿T或第四類程序員,在對現有的各家數據庫管理系統的原理和開發都有一定的鉆研后,要么在其基礎上進行二次開發,要么自行開發一套有自主版權的通用數據庫管理系統。

  我個人正處于第三類的末期,所以下面所列出的一些設計技巧只適合第二類和部分第三類數據庫設計人員。同時,由于我很少碰到有興趣在這方面深鉆下去的同行,所以文中難免出現錯誤和遺漏,在此先行聲明,歡迎大家指正,不要藏私哦8)

  一、樹型關系的數據表
  不少程序員在進行數據庫設計的時候都遇到過樹型關系的數據,例如常見的類別表,即一個大類,下面有若干個子類,某些子類又有子類這樣的情況。當類別不確定,用戶希望可以在任意類別下添加新的子類,或者刪除某個類別和其下的所有子類,而且預計以后其數量會逐步增長,此時我們就會考慮用一個數據表來保存這些數據。按照教科書上的教導,第二類程序員大概會設計出類似這樣的數據表結構:

類別表_1(Type_table_1)
名稱     類型    約束條件   說明
type_id      int        無重復     類別標識,主鍵
type_name   char(50)    不允許為空   類型名稱,不允許重復
type_father   int         不允許為空   該類別的父類別標識,如果是頂節點的話設定為某個唯一值

  這樣的設計短小精悍,完全滿足3NF,而且可以滿足用戶的所有要求。是不是這樣就行呢?答案是NO!Why?

  我們來估計一下用戶希望如何羅列出這個表的數據的。對用戶而言,他當然期望按他所設定的層次關系一次羅列出所有的類別,例如這樣:
總類別
  類別1
    類別1.1
      類別1.1.1
    類別1.2
  類別2
    類別2.1
  類別3
    類別3.1
    類別3.2
  ……

  看看為了實現這樣的列表顯示(樹的先序遍歷),要對上面的表進行多少次檢索?注意,盡管類別1.1.1可能是在類別3.2之后添加的記錄,答案仍然是N次。這樣的效率對于少量的數據沒什么影響,但是日后類型擴充到數十條甚至上百條記錄后,單單列一次類型就要檢索數十次該表,整個程序的運行效率就不敢恭維了。或許第二類程序員會說,那我再建一個臨時數組或臨時表,專門保存類型表的先序遍歷結果,這樣只在第一次運行時檢索數十次,再次羅列所有的類型關系時就直接讀那個臨時數組或臨時表就行了。其實,用不著再去分配一塊新的內存來保存這些數據,只要對數據表進行一定的擴充,再對添加類型的數量進行一下約束就行了,要完成上面的列表只需一次檢索就行了。下面是擴充后的數據表結構:

類別表_2(Type_table_2)
名稱     類型    約束條件                       說明
type_id      int        無重復                     類別標識,主鍵
type_name   char(50)    不允許為空                   類型名稱,不允許重復
type_father   int         不允許為空                   該類別的父類別標識,如果是頂節點的話設定為某個唯一值
type_layer    char(6)     限定3層,初始值為000000       類別的先序遍歷,主要為減少檢索數據庫的次數

  按照這樣的表結構,我們來看看上面例子記錄在表中的數據是怎樣的:

type_id      type_name          type_father          type_layer
1             總類別               0                 000000
2             類別1                1                 010000
3             類別1.1              2                 010100
4             類別1.2              2                 010200
5             類別2                1                 020000
6             類別2.1              5                 020100
7             類別3                1                 030000
8             類別3.1              7                 030100
9             類別3.2              7                 030200
10            類別1.1.1            3                 010101
……

  現在按type_layer的大小來檢索一下:SELECT * FROM Type_table_2 ORDER BY type_layer

列出記錄集如下:

type_id      type_name          type_father          type_layer
1             總類別               0                 000000
2             類別1                1                 010000
3             類別1.1              2                 010100
10            類別1.1.1            3                 010101
4             類別1.2              2                 010200
5             類別2                1                 020000
6             類別2.1              5                 020100
7             類別3                1                 030000
8             類別3.1              7                 030100
9             類別3.2              7                 030200
……

  現在列出的記錄順序正好是先序遍歷的結果。在控制顯示類別的層次時,只要對type_layer字段中的數值進行判斷,每2位一組,如大于0則向右移2個空格。當然,我這個例子中設定的限制條件是最多3層,每層最多可設99個子類別,只要按用戶的需求情況修改一下type_layer的長度和位數,即可更改限制層數和子類別數。其實,上面的設計不單單只在類別表中用到,網上某些可按樹型列表顯示的論壇程序大多采用類似的設計。

  或許有人認為,Type_table_2中的type_father字段是冗余數據,可以除去。如果這樣,在插入、刪除某個類別的時候,就得對type_layer 的內容進行比較繁瑣的判定,所以我并沒有消去type_father字段,這也正符合數據庫設計中適當保留冗余數據的來降低程序復雜度的原則,后面我會舉一個故意增加數據冗余的案例。

  
  二、商品信息表的設計
  假設你是一家百貨公司電腦部的開發人員,某天老板要求你為公司開發一套網上電子商務平臺,該百貨公司有數千種商品出售,不過目前僅打算先在網上銷售數十種方便運輸的商品,當然,以后可能會陸續在該電子商務平臺上增加新的商品出售?,F在開始進行該平臺數據庫的商品信息表的設計。每種出售的商品都會有相同的屬性,如商品編號,商品名稱,商品所屬類別,相關信息,供貨廠商,內含件數,庫存,進貨價,銷售價,優惠價。你很快就設計出4個表:商品類型表(Wares_type),供貨廠商表(Wares_PRovider),商品信息表(Wares_info):

商品類型表(Wares_type)
名稱     類型    約束條件                       說明
type_id      int        無重復                     類別標識,主鍵
type_name   char(50)    不允許為空                   類型名稱,不允許重復
type_father   int         不允許為空                   該類別的父類別標識,如果是頂節點的話設定為某個唯一值
type_layer    char(6)     限定3層,初始值為000000       類別的先序遍歷,主要為減少檢索數據庫的次數

供貨廠商表(Wares_provider)
名稱     類型    約束條件                       說明
provider_id   int        無重復                     供貨商標識,主鍵
provider_name char(100)   不允許為空                   供貨商名稱

商品信息表(Wares_info)
名稱      類型    約束條件                       說明
wares_id       int       無重復                       商品標識,主鍵
wares_name     char(100)  不允許為空                     商品名稱
wares_type   int        不允許為空           商品類型標識,和Wares_type.type_id關聯
wares_info     char(200)  允許為空                       相關信息
provider       int        不允許為空                     供貨廠商標識,和Wares_provider.provider_id關聯
setnum         int        初始值為1                      內含件數,默認為1
stock          int        初始值為0                      庫存,默認為0
buy_price      money      不允許為空                     進貨價
sell_price     money      不允許為空                     銷售價
discount       money      不允許為空                     優惠價

  你拿著這3個表給老板檢查,老板希望能夠再添加一個商品圖片的字段,不過只有一部分商品有圖片。OK,你在商品信息表(Wares_info)中增加了一個haspic的BOOL型字段,然后再建了一個新表——商品圖片表(Wares_pic):

商品圖片表(Wares_pic)
名稱      類型    約束條件                       說明
pic_id        int        無重復                       商品圖片標識,主鍵
wares_id      int         不允許為空                     所屬商品標識,和Wares_info.wares_id關聯
pic_address  char(200)   不允許為空           圖片存放路徑

  程序開發完成后,完全滿足老板目前的要求,于是正式啟用。一段時間后,老板打算在這套平臺上推出新的商品銷售,其中,某類商品全部都需添加“長度”的屬性。第一輪折騰來了……當然,你按照添加商品圖片表的老方法,在商品信息表(Wares_info)中增加了一個haslength的BOOL型字段,又建了一個新表——商品長度表(Wares_length):

商品長度表(Wares_length)
名稱      類型    約束條件                       說明
length_id     int        無重復                       商品圖片標識,主鍵
wares_id      int         不允許為空                     所屬商品標識,和Wares_info.wares_id關聯
length       char(20)    不允許為空           商品長度說明

  剛剛改完沒多久,老板又打算上一批新的商品,這次某類商品全部需要添加“寬度”的屬性。你咬了咬牙,又照方抓藥,添加了商品寬度表(Wares_width)。又過了一段時間,老板新上的商品中有一些需要添加“高度”的屬性,你是不是開始覺得你所設計的數據庫按照這種方式增長下去,很快就能變成一個迷宮呢?那么,有沒有什么辦法遏制這種不可預見性,但卻類似重復的數據庫膨脹呢?我在閱讀《敏捷軟件開發:原則、模式與實踐》中發現作者舉過類似的例子:7.3 “Copy”程序。其中,我非常贊同敏捷軟件開發這個觀點:在最初幾乎不進行預先設計,但是一旦需求發生變化,此時作為一名追求卓越的程序員,應該從頭審查整個架構設計,在此次修改中設計出能夠滿足日后類似修改的系統架構。下面是我在需要添加“長度”的屬性時所提供的修改方案:

  去掉商品信息表(Wares_info)中的haspic字段,添加商品額外屬性表(Wares_ex_property)和商品額外信息表(Wares_ex_info)2個表來完成添加新屬性的功能。

商品額外屬性表(Wares_ex_property)
名稱      類型    約束條件                       說明
ex_pid        int        無重復                       商品額外屬性標識,主鍵
p_name        char(20)    不允許為空                     額外屬性名稱

商品額外信息表(Wares_ex_info)
名稱        類型    約束條件                       說明
ex_iid          int        無重復                       商品額外信息標識,主鍵
wares_id        int         不允許為空                     所屬商品標識,和Wares_info.wares_id關聯
property_id    int         不允許為空           商品額外屬性標識,和Wares_ex_property.ex_pid關聯
property_value  char(200)   不允許為空                     商品額外屬性值

  在商品額外屬性表(Wares_ex_property)中添加2條記錄:
ex_pid            p_name
1                商品圖片
2                商品長度

  再在整個電子商務平臺的后臺管理功能中追加一項商品額外屬性管理的功能,以后添加新的商品時出現新的屬性,只需利用該功能往商品額外屬性表(Wares_ex_property)中添加一條記錄即可。不要害怕變化,被第一顆子彈擊中并不是壞事,壞的是被相同軌道飛來的第二顆、第三顆子彈擊中。第一顆子彈來得越早,所受的傷越重,之后的抵抗力也越強8)(待續)


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91成品人片a无限观看| 欧美疯狂xxxx大交乱88av| 亚洲人成网在线播放| 岛国av一区二区| 日韩精品在线免费观看视频| 亚洲国产精品中文| 亚洲一区美女视频在线观看免费| 成人免费视频在线观看超级碰| 日本电影亚洲天堂| 国产欧美在线观看| 中文.日本.精品| 亚洲一区二区三区久久| 韩国福利视频一区| 欧美日韩国产一区二区| 欧美壮男野外gaytube| 国产精品电影网| 欧美老妇交乱视频| 亚洲奶大毛多的老太婆| 精品国产福利在线| 亚洲人成网在线播放| 亚洲在线免费看| 欧美激情精品久久久久久| 日韩电影免费在线观看中文字幕| 秋霞成人午夜鲁丝一区二区三区| 欧美日韩国产在线看| 亚洲欧美精品一区| 视频在线观看一区二区| 懂色av一区二区三区| 欧美国产高跟鞋裸体秀xxxhd| 成人国产精品免费视频| 国产精品三级久久久久久电影| 精品成人国产在线观看男人呻吟| 一区二区三区国产在线观看| 性亚洲最疯狂xxxx高清| 国产精品免费一区二区三区都可以| 久久亚洲精品成人| 国产欧美一区二区三区在线| 精品久久中文字幕| 免费97视频在线精品国自产拍| 91老司机在线| 国产精品88a∨| 亚洲电影免费观看高清完整版在线| 91精品国产91久久久久久不卡| 色先锋久久影院av| 日韩一区二区久久久| 久久最新资源网| 国产成人综合精品在线| 国产一区二区在线免费视频| 精品国产一区二区三区久久久| 国产精品爱久久久久久久| 欧美视频第一页| 亚洲人午夜精品免费| 欧美精品在线观看| 国产精品视频网| 91免费在线视频网站| 亚洲视频网站在线观看| 国产精品伦子伦免费视频| 欧美激情精品久久久久久| 精品久久久久久久中文字幕| 国产99视频在线观看| 国产网站欧美日韩免费精品在线观看| 亚洲xxxx做受欧美| 日本免费在线精品| 日韩在线观看你懂的| 精品久久久久久亚洲国产300| 尤物精品国产第一福利三区| 亚洲男人天天操| 欧美国产日韩中文字幕在线| 亚洲欧美福利视频| 久久九九国产精品怡红院| 不卡毛片在线看| 中文字幕不卡av| 亚洲男人的天堂网站| 国产免费一区视频观看免费| 黑人巨大精品欧美一区二区免费| 亚洲精品久久久久国产| 一本色道久久88综合亚洲精品ⅰ| 欧美亚洲在线视频| 亚洲综合在线做性| 精品久久久香蕉免费精品视频| 成人h片在线播放免费网站| 大胆人体色综合| 精品福利在线观看| 在线成人激情黄色| 色妞在线综合亚洲欧美| 日韩在线中文视频| 亚洲性夜色噜噜噜7777| 日韩高清有码在线| 亚洲色图综合网| 日韩精品黄色网| 国产精品久久激情| 亚洲三级av在线| 国产精品欧美在线| 日韩有码在线播放| 美女国内精品自产拍在线播放| 国产精品私拍pans大尺度在线| 亚洲精品自拍视频| 黄网站色欧美视频| 亚洲国产精品yw在线观看| 欧美成人精品在线视频| 亚洲福利在线看| 亚洲精品美女久久久| 国产欧美最新羞羞视频在线观看| 伊人激情综合网| 欧美日韩中文字幕在线视频| 成人激情在线播放| 九九精品在线视频| 欧美日韩免费在线观看| 美女性感视频久久久| 欧美日本黄视频| 在线看日韩欧美| 一区二区三区美女xx视频| 日韩精品久久久久久久玫瑰园| 欧美日韩国产中文字幕| 91美女片黄在线观看游戏| 97欧美精品一区二区三区| 中文字幕在线日韩| 一本色道久久88亚洲综合88| 美女999久久久精品视频| 17婷婷久久www| 国产精品亚洲第一区| 日韩在线播放av| 欧美性xxxxxx| 国产精品视频资源| 日韩中文字幕精品| 国产婷婷色综合av蜜臀av| 97视频在线免费观看| 国产精品激情av电影在线观看| 日韩中文字幕在线| 亚洲成人三级在线| 97成人精品视频在线观看| 国产成人涩涩涩视频在线观看| 上原亚衣av一区二区三区| 亚洲日韩欧美视频一区| 国产丝袜一区二区三区| 亚洲国产精品久久久| 奇门遁甲1982国语版免费观看高清| 亚洲新声在线观看| 麻豆成人在线看| 欧美激情一级二级| 日韩精品视频在线观看网址| 91精品国产自产在线老师啪| 国产suv精品一区二区| 久久亚洲影音av资源网| 国产美女久久精品| 欧美大片在线看| 不用播放器成人网| 8090成年在线看片午夜| 亚洲成人三级在线| 国内精品小视频| 中文字幕亚洲欧美一区二区三区| 国产精品久久激情| 成人伊人精品色xxxx视频| 欧美色欧美亚洲高清在线视频| 国产精品美女主播在线观看纯欲| 91久久嫩草影院一区二区| 91在线观看免费观看| www.日韩不卡电影av| 久久久99免费视频| 国产成人精品综合久久久| 精品国产视频在线| 久久韩国免费视频| 日韩精品在线观看网站| 久久久免费在线观看|