国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

淺談數(shù)據(jù)庫設(shè)計技巧(下)

2024-07-21 02:31:15
字體:
供稿:網(wǎng)友

  三、多用戶及其權(quán)限管理的設(shè)計
  開發(fā)數(shù)據(jù)庫管理類的軟件,不可能不考慮多用戶和用戶權(quán)限設(shè)置的問題。盡管目前市面上的大、中型的后臺數(shù)據(jù)庫系統(tǒng)軟件都提供了多用戶,以及細至某個數(shù)據(jù)庫內(nèi)某張表的權(quán)限設(shè)置的功能,我個人建議:一套成熟的數(shù)據(jù)庫管理軟件,還是應(yīng)該自行設(shè)計用戶管理這塊功能,原因有二:
  1.那些大、中型后臺數(shù)據(jù)庫系統(tǒng)軟件所提供的多用戶及其權(quán)限設(shè)置都是針對數(shù)據(jù)庫的共有屬性,并不一定能完全滿足某些特例的需求;
  2.不要過多的依賴后臺數(shù)據(jù)庫系統(tǒng)軟件的某些特殊功能,多種大、中型后臺數(shù)據(jù)庫系統(tǒng)軟件之間并不完全兼容。否則一旦日后需要轉(zhuǎn)換數(shù)據(jù)庫平臺或后臺數(shù)據(jù)庫系統(tǒng)軟件版本升級,之前的架構(gòu)設(shè)計很可能無法重用。

  下面看看如何自行設(shè)計一套比較靈活的多用戶管理模塊,即該數(shù)據(jù)庫管理軟件的系統(tǒng)管理員可以自行添加新用戶,修改已有用戶的權(quán)限,刪除已有用戶。首先,分析用戶需求,列出該數(shù)據(jù)庫管理軟件所有需要實現(xiàn)的功能;然后,根據(jù)一定的聯(lián)系對這些功能進行分類,即把某類用戶需使用的功能歸為一類;最后開始建表:
  
功能表(Function_table)
名稱     類型    約束條件   說明
f_id          int        無重復(fù)     功能標識,主鍵
f_name        char(20)    不允許為空   功能名稱,不允許重復(fù)
f_desc        char(50)    允許為空     功能描述

用戶組表(User_group)
名稱     類型    約束條件   說明
group_id      int         無重復(fù)        用戶組標識,主鍵
group_name    char(20)    不允許為空    用戶組名稱
group_power   char(100)   不允許為空    用戶組權(quán)限表,內(nèi)容為功能表f_id的集合

用戶表(User_table)
名稱     類型    約束條件   說明
user_id       int         無重復(fù)        用戶標識,主鍵
user_name     char(20)    無重復(fù)        用戶名
user_pwd      char(20)    不允許為空    用戶密碼
user_type     int         不允許為空    所屬用戶組標識,和User_group.group_id關(guān)聯(lián)

  采用這種用戶組的架構(gòu)設(shè)計,當需要添加新用戶時,只需指定新用戶所屬的用戶組;當以后系統(tǒng)需要添加新功能或?qū)εf有功能權(quán)限進行修改時,只用操作功能表和用戶組表的記錄,原有用戶的功能即可相應(yīng)隨之變化。當然,這種架構(gòu)設(shè)計把數(shù)據(jù)庫管理軟件的功能判定移到了前臺,使得前臺開發(fā)相對復(fù)雜一些。但是,當用戶數(shù)較大(10人以上),或日后軟件升級的概率較大時,這個代價是值得的。


  四、簡潔的批量m:n設(shè)計
  碰到m:n的關(guān)系,一般都是建立3個表,m一個,n一個,m:n一個。但是,m:n有時會遇到批量處理的情況,例如到圖書館借書,一般都是允許用戶同時借閱n本書,如果要求按批查詢借閱記錄,即列出某個用戶某次借閱的所有書籍,該如何設(shè)計呢?讓我們建好必須的3個表先:

書籍表(Book_table)
名稱     類型    約束條件   說明
book_id       int         無重復(fù)        書籍標識,主鍵
book_no       char(20)    無重復(fù)        書籍編號
book_name     char(100)   不允許為空    書籍名稱
……

借閱用戶表(Renter_table)
名稱     類型    約束條件   說明
renter_id     int         無重復(fù)        用戶標識,主鍵
renter_name   char(20)    不允許為空    用戶姓名
……

借閱記錄表(Rent_log)
名稱     類型    約束條件   說明
rent_id       int         無重復(fù)        借閱記錄標識,主鍵
r_id          int         不允許為空    用戶標識,和Renter_table.renter_id關(guān)聯(lián)
b_id          int         不允許為空    書籍標識,和Book_table.book_id關(guān)聯(lián)
rent_date     datetime    不允許為空    借閱時間
……

  為了實現(xiàn)按批查詢借閱記錄,我們可以再建一個表來保存批量借閱的信息,例如:

批量借閱表(Batch_rent)
名稱     類型    約束條件   說明
batch_id      int         無重復(fù)        批量借閱標識,主鍵
batch_no      int         不允許為空    批量借閱編號,同一批借閱的batch_no相同
rent_id       int         不允許為空    借閱記錄標識,和Rent_log.rent_id關(guān)聯(lián)
batch_date    datetime    不允許為空    批量借閱時間

  這樣的設(shè)計好嗎?我們來看看為了列出某個用戶某次借閱的所有書籍,需要如何查詢?首先檢索批量借閱表(Batch_rent),把符合條件的的所有記錄的rent_id字段的數(shù)據(jù)保存起來,再用這些數(shù)據(jù)作為查詢條件帶入到借閱記錄表(Rent_log)中去查詢。那么,有沒有什么辦法改進呢?下面給出一種簡潔的批量設(shè)計方案,不需添加新表,只需修改一下借閱記錄表(Rent_log)即可。修改后的記錄表(Rent_log)如下:

借閱記錄表(Rent_log)
名稱     類型    約束條件   說明
rent_id       int         無重復(fù)        借閱記錄標識,主鍵
r_id          int         不允許為空    用戶標識,和Renter_table.renter_id關(guān)聯(lián)
b_id          int         不允許為空    書籍標識,和Book_table.book_id關(guān)聯(lián)
batch_no      int         不允許為空    批量借閱編號,同一批借閱的batch_no相同
rent_date     datetime    不允許為空    借閱時間
……

  其中,同一次借閱的batch_no和該批第一條入庫的rent_id相同。舉例:假設(shè)當前最大rent_id是64,接著某用戶一次借閱了3本書,則批量插入的3條借閱記錄的batch_no都是65。之后另外一個用戶租了一套碟,再插入出租記錄的rent_id是68。采用這種設(shè)計,查詢批量借閱的信息時,只需使用一條標準T_SQL的嵌套查詢即可。當然,這種設(shè)計不符合3NF,但是和上面標準的3NF設(shè)計比起來,哪一種更好呢?答案就不用我說了吧。


  五、冗余數(shù)據(jù)的取舍
  上篇的“樹型關(guān)系的數(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         無重復(fù)        員工標識,主鍵
clerk_name    char(10)    不允許為空    員工姓名

每餐總表(Eatdata1)
名稱     類型    約束條件   說明
totle_id      int         無重復(fù)        每餐總表標識,主鍵
persons       char(100)   不允許為空    就餐員工的員工標識集合
eat_date      datetime    不允許為空    就餐日期
eat_type      char(1)     不允許為空    就餐類型,用來區(qū)分中、晚餐
totle_PRice   money       不允許為空    每餐總花費
persons_num   int         不允許為空    就餐人數(shù)

就餐計費細表(Eatdata2)
名稱     類型    約束條件   說明
id            int         無重復(fù)        就餐計費細表標識,主鍵
t_id          int         不允許為空    每餐總表標識,和Eatdata1.totle_id關(guān)聯(lián)
c_id          int         不允許為空    員工標識標識,和Clerk_table.clerk_id關(guān)聯(lián)
price         money       不允許為空    每人每餐花費

  其中,就餐計費細表(Eatdata2)的記錄就是把每餐總表(Eatdata1)的一條記錄按就餐員工平攤拆開,是個不折不扣的冗余表。當然,也可以把每餐總表(Eatdata1)的部分字段合并到就餐計費細表(Eatdata2)中,這樣每餐總表(Eatdata1)就成了冗余表,不過這樣所設(shè)計出來的就餐計費細表重復(fù)數(shù)據(jù)更多,相比來說還是上面的方案好些。但是,就是就餐計費細表(Eatdata2)這個冗余表,在做每月每人餐費統(tǒng)計的時候,大大簡化了編程的復(fù)雜度,只用類似這么一條查詢語句即可統(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、用戶的整體需求。當用戶更多的關(guān)注于,對數(shù)據(jù)庫的規(guī)范記錄按一定的算法進行處理后,再列出的數(shù)據(jù)。如果該算法可以直接利用后臺數(shù)據(jù)庫系統(tǒng)的內(nèi)嵌函數(shù)來完成,此時可以適當?shù)脑黾尤哂嘧侄?,甚至冗余表來保存這些經(jīng)過算法處理后的數(shù)據(jù)。要知道,對于大批量數(shù)據(jù)的查詢,修改或刪除,后臺數(shù)據(jù)庫系統(tǒng)的效率遠遠高于我們自己編寫的代碼。
  2、簡化開發(fā)的復(fù)雜度。現(xiàn)代軟件開發(fā),實現(xiàn)同樣的功能,方法有很多。盡管不必要求程序員精通絕大部分的開發(fā)工具和平臺,但是還是需要了解哪種方法搭配哪種開發(fā)工具的程序更簡潔,效率更高一些。冗余數(shù)據(jù)的本質(zhì)就是用空間換時間,尤其是目前硬件的發(fā)展遠遠高于軟件,所以適當?shù)娜哂嗍强梢越邮艿?。不過我還是在最后再強調(diào)一下:不要過多的依賴平臺和開發(fā)工具的特性來簡化開發(fā),這個度要是沒把握好的話,后期維護升級會栽大跟頭的。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 海林市| 钟山县| 株洲市| 获嘉县| 西峡县| 岱山县| 榆林市| 泊头市| 阳春市| 宁化县| 莒南县| 班玛县| 珲春市| 黔江区| 临沭县| 家居| 孝昌县| 五河县| 合阳县| 崇左市| 三明市| 潮州市| 板桥市| 新巴尔虎右旗| 盐边县| 濮阳县| 泰顺县| 吉木萨尔县| 榆林市| 泾川县| 新龙县| 兰州市| 仙桃市| 东兴市| 龙陵县| 竹溪县| 宜宾市| 长治县| 济源市| 新田县| 德格县|