說到數(shù)據(jù)庫,我認為不能不先談數(shù)據(jù)結(jié)構(gòu)。在我初入大學學習計算機編程時,當時的老師就告訴我們說:計算機程序=數(shù)據(jù)結(jié)構(gòu)+算法。盡管現(xiàn)在的程序開發(fā)已由面向過程為主逐步過渡到面向?qū)ο鬄橹鳎疫€是深深贊同8年前老師的告訴我們的公式:計算機程序=數(shù)據(jù)結(jié)構(gòu)+算法。面向?qū)ο蟮某绦蜷_發(fā),要做的第一件事就是,先分析整個程序中需處理的數(shù)據(jù),從中提取出抽象模板,以這個抽象模板設計類,再在其中逐步添加處理其數(shù)據(jù)的函數(shù)(即算法),最后,再給類中的數(shù)據(jù)成員和函數(shù)劃分訪問權(quán)限,從而實現(xiàn)封裝。
數(shù)據(jù)庫的最初雛形據(jù)說源自美國一個奶牛場的記賬薄(紙質(zhì)的,由此可見,數(shù)據(jù)庫并不一定是存儲在電腦里的數(shù)據(jù)^_^),里面記錄的是該奶牛場的收支賬目,程序員在將其整理、錄入到電腦中時從中受到啟發(fā)。當按照規(guī)定好的數(shù)據(jù)結(jié)構(gòu)所采集到的數(shù)據(jù)量大到一定程度后,出于程序執(zhí)行效率的考慮,程序員將其中的檢索、更新維護等功能分離出來,做成單獨調(diào)用的模塊,這個模塊后來就慢慢發(fā)展、演變成現(xiàn)在我們所接觸到的數(shù)據(jù)庫管理系統(tǒng)(DBMS)——程序開發(fā)中的一個重要分支。
一、樹型關系的數(shù)據(jù)表
不少程序員在進行數(shù)據(jù)庫設計的時候都遇到過樹型關系的數(shù)據(jù),例如常見的類別表,即一個大類,下面有若干個子類,某些子類又有子類這樣的情況。當類別不確定,用戶希望可以在任意類別下添加新的子類,或者刪除某個類別和其下的所有子類,而且預計以后其數(shù)量會逐步增長,此時我們就會考慮用一個數(shù)據(jù)表來保存這些數(shù)據(jù)。按照教科書上的教導,第二類程序員大概會設計出類似這樣的數(shù)據(jù)表結(jié)構(gòu):
類別表_1(Type_table_1)
名稱 類型 約束條件 說明
type_id?? ? int??? ?? 無重復 ?? 類別標識,主鍵
type_name char(50)??? 不允許為空?? 類型名稱,不允許重復
type_father?? int???????? 不允許為空?? 該類別的父類別標識,如果是頂節(jié)點的話設定為某個唯一值
這樣的設計短小精悍,完全滿足3NF,而且可以滿足用戶的所有要求。是不是這樣就行呢?答案是NO!Why?
我們來估計一下用戶希望如何羅列出這個表的數(shù)據(jù)的。對用戶而言,他當然期望按他所設定的層次關系一次羅列出所有的類別,例如這樣:
總類別
類別1
類別1.1
類別1.1.1
類別1.2
類別2
類別2.1
類別3
類別3.1
類別3.2
……
看看為了實現(xiàn)這樣的列表顯示(樹的先序遍歷),要對上面的表進行多少次檢索?注意,盡管類別1.1.1可能是在類別3.2之后添加的記錄,答案仍然是N次。這樣的效率對于少量的數(shù)據(jù)沒什么影響,但是日后類型擴充到數(shù)十條甚至上百條記錄后,單單列一次類型就要檢索數(shù)十次該表,整個程序的運行效率就不敢恭維了。或許第二類程序員會說,那我再建一個臨時數(shù)組或臨時表,專門保存類型表的先序遍歷結(jié)果,這樣只在第一次運行時檢索數(shù)十次,再次羅列所有的類型關系時就直接讀那個臨時數(shù)組或臨時表就行了。其實,用不著再去分配一塊新的內(nèi)存來保存這些數(shù)據(jù),只要對數(shù)據(jù)表進行一定的擴充,再對添加類型的數(shù)量進行一下約束就行了,要完成上面的列表只需一次檢索就行了。下面是擴充后的數(shù)據(jù)表結(jié)構(gòu):
類別表_2(Type_table_2)
名稱 類型 約束條件 ??????????????????? 說明
type_id?? ? int???? ? 無重復 ?????????????????? 類別標識,主鍵
type_name char(50)??? 不允許為空?????????????????? 類型名稱,不允許重復
type_father?? int???????? 不允許為空?????????????????? 該類別的父類別標識,如果是頂節(jié)點的話設定為某個唯一值
type_layer??? char(6)???? 限定3層,初始值為000000?????? 類別的先序遍歷,主要為減少檢索數(shù)據(jù)庫的次數(shù)
按照這樣的表結(jié)構(gòu),我們來看看上面例子記錄在表中的數(shù)據(jù)是怎樣的:
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
……
現(xiàn)在按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
……
現(xiàn)在列出的記錄順序正好是先序遍歷的結(jié)果。在控制顯示類別的層次時,只要對type_layer字段中的數(shù)值進行判斷,每2位一組,如大于0則向右移2個空格。當然,我這個例子中設定的限制條件是最多3層,每層最多可設99個子類別,只要按用戶的需求情況修改一下type_layer的長度和位數(shù),即可更改限制層數(shù)和子類別數(shù)。其實,上面的設計不單單只在類別表中用到,網(wǎng)上某些可按樹型列表顯示的論壇程序大多采用類似的設計。
或許有人認為,Type_table_2中的type_father字段是冗余數(shù)據(jù),可以除去。如果這樣,在插入、刪除某個類別的時候,就得對 type_layer 的內(nèi)容進行比較繁瑣的判定,所以我并沒有消去type_father字段,這也正符合數(shù)據(jù)庫設計中適當保留冗余數(shù)據(jù)的來降低程序復雜度的原則,后面我會舉一個故意增加數(shù)據(jù)冗余的案例。
二、商品信息表的設計
假設你是一家百貨公司電腦部的開發(fā)人員,某天老板要求你為公司開發(fā)一套網(wǎng)上電子商務平臺,該百貨公司有數(shù)千種商品出售,不過目前僅打算先在網(wǎng)上銷售數(shù)十種方便運輸?shù)纳唐罚斎唬院罂赡軙懤m(xù)在該電子商務平臺上增加新的商品出售。現(xiàn)在開始進行該平臺數(shù)據(jù)庫的商品信息表的設計。每種出售的商品都會有相同的屬性,如商品編號,商品名稱,商品所屬類別,相關信息,供貨廠商,內(nèi)含件數(shù),庫存,進貨價,銷售價,優(yōu)惠價。你很快就設計出4個表:商品類型表(Wares_type),供貨廠商表(Wares_provider),商品信息表 (Wares_info):
商品類型表(Wares_type)
名稱 類型 約束條件 ??????????????????? 說明
type_id?? ? int??? ??????? 無重復 ?????????????????? 類別標識,主鍵
type_name? char(50)??? 不允許為空?????????????????? 類型名稱,不允許重復
type_father?? int?????????? 不允許為空?????????????????? 該類別的父類別標識,如果是頂節(jié)點的話設定為某個唯一值
type_layer??? char(6)???? 限定3層,初始值為000000?????? 類別的先序遍歷,主要為減少檢索數(shù)據(jù)庫的次數(shù)
供貨廠商表(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關聯(lián)
wares_info??? char(200)? 允許為空????????????????????? 相關信息
provider??????? int??????? 不允許為空???????????????????????? 供貨廠商標識,和Wares_provider.provider_id關聯(lián)
setnum???????? int??????? 初始值為1????????????????????????? 內(nèi)含件數(shù),默認為1
stock???????????? int??????? 初始值為0????????????????????????? 庫存,默認為0
buy_price????? money????? 不允許為空???????????????????? 進貨價
sell_price????? money????? 不允許為空???????????????????? 銷售價
discount??????? money????? 不允許為空???????????????????? 優(yōu)惠價
你拿著這3個表給老板檢查,老板希望能夠再添加一個商品圖片的字段,不過只有一部分商品有圖片。OK,你在商品信息表(Wares_info)中增加了一個haspic的BOOL型字段,然后再建了一個新表——商品圖片表(Wares_pic):
商品圖片表(Wares_pic)
名稱 ? 類型 約束條件 ??????????????????? 說明
pic_id?????????? int??? ????? 無重復 ???????????????????? 商品圖片標識,主鍵
wares_id????? int??????????? 不允許為空???????????????????? 所屬商品標識,和Wares_info.wares_id關聯(lián)
pic_address char(200)?? 不允許為空 圖片存放路徑
程序開發(fā)完成后,完全滿足老板目前的要求,于是正式啟用。一段時間后,老板打算在這套平臺上推出新的商品銷售,其中,某類商品全部都需添加“長度”的屬性。第一輪折騰來了……當然,你按照添加商品圖片表的老方法,在商品信息表(Wares_info)中增加了一個haslength的BOOL型字段,又建了一個新表——商品長度表(Wares_length):
商品長度表(Wares_length)
名稱 ? 類型 約束條件 ??????????????????? 說明
length_id???? int??? ?? 無重復 ???????????????????? 商品圖片標識,主鍵
wares_id????? int???????? 不允許為空???????????????????? 所屬商品標識,和Wares_info.wares_id關聯(lián)
length ????? char(20)??? 不允許為空 商品長度說明
剛剛改完沒多久,老板又打算上一批新的商品,這次某類商品全部需要添加“寬度”的屬性。你咬了咬牙,又照方抓藥,添加了商品寬度表 (Wares_width)。又過了一段時間,老板新上的商品中有一些需要添加“高度”的屬性,你是不是開始覺得你所設計的數(shù)據(jù)庫按照這種方式增長下去,很快就能變成一個迷宮呢?那么,有沒有什么辦法遏制這種不可預見性,但卻類似重復的數(shù)據(jù)庫膨脹呢?我在閱讀《敏捷軟件開發(fā):原則、模式與實踐》中發(fā)現(xiàn)作者舉過類似的例子:7.3 “Copy”程序。其中,我非常贊同敏捷軟件開發(fā)這個觀點:在最初幾乎不進行預先設計,但是一旦需求發(fā)生變化,此時作為一名追求卓越的程序員,應該從頭審查整個架構(gòu)設計,在此次修改中設計出能夠滿足日后類似修改的系統(tǒng)架構(gòu)。下面是我在需要添加“長度”的屬性時所提供的修改方案:
去掉商品信息表(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關聯(lián)
property_id int???????? 不允許為空 商品額外屬性標識,和Wares_ex_property.ex_pid關聯(lián)
property_value? char(200)?? 不允許為空???????????????????? 商品額外屬性值
在商品額外屬性表(Wares_ex_property)中添加2條記錄:
ex_pid??????????? p_name
1??????????????? 商品圖片
2??????????????? 商品長度
再在整個電子商務平臺的后臺管理功能中追加一項商品額外屬性管理的功能,以后添加新的商品時出現(xiàn)新的屬性,只需利用該功能往商品額外屬性表 (Wares_ex_property)中添加一條記錄即可。不要害怕變化,被第一顆子彈擊中并不是壞事,壞的是被相同軌道飛來的第二顆、第三顆子彈擊中。第一顆子彈來得越早,所受的傷越重,之后的抵抗力也越強8)
三、多用戶及其權(quán)限管理的設計
開發(fā)數(shù)據(jù)庫管理類的軟件,不可能不考慮多用戶和用戶權(quán)限設置的問題。盡管目前市面上的大、中型的后臺數(shù)據(jù)庫系統(tǒng)軟件都提供了多用戶,以及細至某個數(shù)據(jù)庫內(nèi)某張表的權(quán)限設置的功能,我個人建議:一套成熟的數(shù)據(jù)庫管理軟件,還是應該自行設計用戶管理這塊功能,原因有二:
1.那些大、中型后臺數(shù)據(jù)庫系統(tǒng)軟件所提供的多用戶及其權(quán)限設置都是針對數(shù)據(jù)庫的共有屬性,并不一定能完全滿足某些特例的需求;
2.不要過多的依賴后臺數(shù)據(jù)庫系統(tǒng)軟件的某些特殊功能,多種大、中型后臺數(shù)據(jù)庫系統(tǒng)軟件之間并不完全兼容。否則一旦日后需要轉(zhuǎn)換數(shù)據(jù)庫平臺或后臺數(shù)據(jù)庫系統(tǒng)軟件版本升級,之前的架構(gòu)設計很可能無法重用。
下面看看如何自行設計一套比較靈活的多用戶管理模塊,即該數(shù)據(jù)庫管理軟件的系統(tǒng)管理員可以自行添加新用戶,修改已有用戶的權(quán)限,刪除已有用戶。首先,分析用戶需求,列出該數(shù)據(jù)庫管理軟件所有需要實現(xiàn)的功能;然后,根據(jù)一定的聯(lián)系對這些功能進行分類,即把某類用戶需使用的功能歸為一類;最后開始建表:
功能表(Function_table)
名稱 類型 約束條件 說明
f_id?????????????? int??? ?? 無重復 ?? 功能標識,主鍵
f_name??????? char(20)??? 不允許為空?? 功能名稱,不允許重復
f_desc????????? char(50)??? 允許為空???? 功能描述
用戶組表(User_group)
名稱 類型 約束條件 說明
group_id????? int???????? 無重復??????? 用戶組標識,主鍵
group_name??? char(20)??? 不允許為空??? 用戶組名稱
group_power?? char(100)?? 不允許為空??? 用戶組權(quán)限表,內(nèi)容為功能表f_id的集合
用戶表(User_table)
名稱 類型 約束條件 說明
user_id?????? int???????? 無重復??????? 用戶標識,主鍵
user_name???? char(20)??? 無重復??????? 用戶名
user_pwd????? char(20)??? 不允許為空??? 用戶密碼
user_type???? int???????? 不允許為空??? 所屬用戶組標識,和User_group.group_id關聯(lián)
采用這種用戶組的架構(gòu)設計,當需要添加新用戶時,只需指定新用戶所屬的用戶組;當以后系統(tǒng)需要添加新功能或?qū)εf有功能權(quán)限進行修改時,只用操作功能表和用戶組表的記錄,原有用戶的功能即可相應隨之變化。當然,這種架構(gòu)設計把數(shù)據(jù)庫管理軟件的功能判定移到了前臺,使得前臺開發(fā)相對復雜一些。但是,當用戶數(shù)較大(10人以上),或日后軟件升級的概率較大時,這個代價是值得的。
四、簡潔的批量m:n設計
碰到m:n的關系,一般都是建立3個表,m一個,n一個,m:n一個。但是,m:n有時會遇到批量處理的情況,例如到圖書館借書,一般都是允許用戶同時借閱n本書,如果要求按批查詢借閱記錄,即列出某個用戶某次借閱的所有書籍,該如何設計呢?讓我們建好必須的3個表先:
書籍表(Book_table)
名稱 類型 約束條件 說明
book_id?????? int???????? 無重復??????? 書籍標識,主鍵
book_no?????? char(20)??? 無重復??????? 書籍編號
book_name???? char(100)?? 不允許為空??? 書籍名稱
……
借閱用戶表(Renter_table)
名稱 類型 約束條件 說明
renter_id???? int???????? 無重復??????? 用戶標識,主鍵
renter_name?? char(20)??? 不允許為空??? 用戶姓名
……
借閱記錄表(Rent_log)
名稱 類型 約束條件 說明
rent_id?????? int???????? 無重復??????? 借閱記錄標識,主鍵
r_id????????? int???????? 不允許為空??? 用戶標識,和Renter_table.renter_id關聯(lián)
b_id????????? int???????? 不允許為空??? 書籍標識,和Book_table.book_id關聯(lián)
rent_date???? datetime??? 不允許為空??? 借閱時間
……
為了實現(xiàn)按批查詢借閱記錄,我們可以再建一個表來保存批量借閱的信息,例如:
批量借閱表(Batch_rent)
名稱 類型 約束條件 說明
batch_id????? int???????? 無重復??????? 批量借閱標識,主鍵
batch_no????? int???????? 不允許為空??? 批量借閱編號,同一批借閱的batch_no相同
rent_id?????? int???????? 不允許為空??? 借閱記錄標識,和Rent_log.rent_id關聯(lián)
batch_date??? datetime??? 不允許為空??? 批量借閱時間
這樣的設計好嗎?我們來看看為了列出某個用戶某次借閱的所有書籍,需要如何查詢?首先檢索批量借閱表(Batch_rent),把符合條件的的所有記錄的rent_id字段的數(shù)據(jù)保存起來,再用這些數(shù)據(jù)作為查詢條件帶入到借閱記錄表(Rent_log)中去查詢。那么,有沒有什么辦法改進呢?下面給出一種簡潔的批量設計方案,不需添加新表,只需修改一下借閱記錄表(Rent_log)即可。修改后的記錄表(Rent_log)如下:
借閱記錄表(Rent_log)
名稱 類型 約束條件 說明
rent_id?????? int???????? 無重復??????? 借閱記錄標識,主鍵
r_id????????? int???????? 不允許為空??? 用戶標識,和Renter_table.renter_id關聯(lián)
b_id????????? int???????? 不允許為空??? 書籍標識,和Book_table.book_id關聯(lián)
batch_no????? int???????? 不允許為空??? 批量借閱編號,同一批借閱的batch_no相同
rent_date???? datetime??? 不允許為空??? 借閱時間
……
其中,同一次借閱的batch_no和該批第一條入庫的rent_id相同。舉例:假設當前最大rent_id是64,接著某用戶一次借閱了3 本書,則批量插入的3條借閱記錄的batch_no都是65。之后另外一個用戶租了一套碟,再插入出租記錄的rent_id是68。采用這種設計,查詢批量借閱的信息時,只需使用一條標準T_SQL的嵌套查詢即可。當然,這種設計不符合3NF,但是和上面標準的3NF設計比起來,哪一種更好呢?答案就不用我說了吧。
五、冗余數(shù)據(jù)的取舍
上篇的“樹型關系的數(shù)據(jù)表”中保留了一個冗余字段,這里的例子更進一步——添加了一個冗余表。先看看例子:我原先所在的公司為了解決員工的工作餐,和附近的一家小餐館聯(lián)系,每天吃飯記賬,費用按人數(shù)平攤,月底由公司現(xiàn)金結(jié)算,每個人每個月的工作餐費從工資中扣除。當然,每天吃飯的人員和人數(shù)都不是固定的,而且,由于每頓工作餐的所點的菜色不同,每頓的花費也不相同。例如,星期一中餐5人花費40元,晚餐2 人花費20,星期二中餐6人花費36元,晚餐3人花費18元。為了方便計算每個人每個月的工作餐費,我寫了一個簡陋的就餐記賬管理程序,數(shù)據(jù)庫里有3個表:
員工表(Clerk_table)
名稱 類型 約束條件 說明
clerk_id????? int???????? 無重復??????? 員工標識,主鍵
clerk_name??? char(10)??? 不允許為空??? 員工姓名
每餐總表(Eatdata1)
名稱 類型 約束條件 說明
totle_id????? int???????? 無重復??????? 每餐總表標識,主鍵
persons?????? char(100)?? 不允許為空??? 就餐員工的員工標識集合
eat_date????? datetime??? 不允許為空??? 就餐日期
eat_type????? char(1)???? 不允許為空??? 就餐類型,用來區(qū)分中、晚餐
totle_price?? money?????? 不允許為空??? 每餐總花費
persons_num?? int???????? 不允許為空??? 就餐人數(shù)
就餐計費細表(Eatdata2)
名稱 類型 約束條件 說明
id??????????? int???????? 無重復??????? 就餐計費細表標識,主鍵
t_id????????? int???????? 不允許為空??? 每餐總表標識,和Eatdata1.totle_id關聯(lián)
c_id????????? int???????? 不允許為空??? 員工標識標識,和Clerk_table.clerk_id關聯(lián)
price???????? money?????? 不允許為空??? 每人每餐花費
其中,就餐計費細表(Eatdata2)的記錄就是把每餐總表(Eatdata1)的一條記錄按就餐員工平攤拆開,是個不折不扣的冗余表。當然,也可以把每餐總表(Eatdata1)的部分字段合并到就餐計費細表(Eatdata2)中,這樣每餐總表(Eatdata1)就成了冗余表,不過這樣所設計出來的就餐計費細表重復數(shù)據(jù)更多,相比來說還是上面的方案好些。但是,就是就餐計費細表(Eatdata2)這個冗余表,在做每月每人餐費統(tǒng)計的時候,大大簡化了編程的復雜度,只用類似這么一條查詢語句即可統(tǒng)計出每人每月的寄餐次數(shù)和餐費總帳:
SELECT clerk_name AS personname,COUNT(c_id) as eattimes,SUM(price) AS ptprice FROM Eatdata2 JOIN Clerk_tabsle ON (c_id=clerk_id) JOIN eatdata1 ON (totleid=tid) WHERE eat_date>=CONVERT(datetime,'"&the_date&"') AND eat_date<DATEADD(month,1,CONVERT(datetime,'"&the_date&"')) GROUP BY c_id
想象一下,如果不用這個冗余表,每次統(tǒng)計每人每月的餐費總帳時會多麻煩,程序效率也夠嗆。那么,到底什么時候可以增加一定的冗余數(shù)據(jù)呢?我認為有2個原則:
1、用戶的整體需求。當用戶更多的關注于,對數(shù)據(jù)庫的規(guī)范記錄按一定的算法進行處理后,再列出的數(shù)據(jù)。如果該算法可以直接利用后臺數(shù)據(jù)庫系統(tǒng)的內(nèi)嵌函數(shù)來完成,此時可以適當?shù)脑黾尤哂嘧侄危踔寥哂啾韥肀4孢@些經(jīng)過算法處理后的數(shù)據(jù)。要知道,對于大批量數(shù)據(jù)的查詢,修改或刪除,后臺數(shù)據(jù)庫系統(tǒng)的效率遠遠高于我們自己編寫的代碼。
2、簡化開發(fā)的復雜度。現(xiàn)代軟件開發(fā),實現(xiàn)同樣的功能,方法有很多。盡管不必要求程序員精通絕大部分的開發(fā)工具和平臺,但是還是需要了解哪種方法搭配哪種開發(fā)工具的程序更簡潔,效率更高一些。冗余數(shù)據(jù)的本質(zhì)就是用空間換時間,尤其是目前硬件的發(fā)展遠遠高于軟件,所以適當?shù)娜哂嗍强梢越邮艿摹2贿^我還是在最后再強調(diào)一下:不要過多的依賴平臺和開發(fā)工具的特性來簡化開發(fā),這個度要是沒把握好的話,后期維護升級會栽大跟頭的。
?
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
