資料庫設計技巧 下

2021-04-16 19:54:11 字數 4983 閱讀 1378

三、多使用者及其許可權管理的設計

開發資料庫

管理類的軟體,不可能不考慮多使用者和使用者許可權設定的問題。儘管目前市面上的大、中型的後台資料庫系統軟體都提供了多使用者,以及細至某個資料庫內某張表的許可權設定的功能,我個人建議:一套成熟的資料庫管理軟體,還是應該自行設計使用者管理這塊功能,原因有二:

1.那些大、中型後台資料庫系統軟體所提供的多使用者及其許可權設定都是針對資料庫的共有屬性,並不一定能完全滿足某些特例的需求;

2.不要過多的依賴後台資料庫系統軟體的某些特殊功能,多種大、中型後台資料庫系統軟體之間並不完全相容。否則一旦日後需要轉換資料庫平台或後台資料庫系統軟體版本公升級,之前的架構設計很可能無法重用。

下面看看如何自行設計一套比較靈活的多使用者管理模組,即該資料庫管理軟體的系統管理員可以自行新增新使用者,修改已有使用者的許可權,刪除已有使用者。首先,分析使用者需求,列出該資料庫管理軟體所有需要實現的功能;然後,根據一定的聯絡對這些功能進行分類,即把某類使用者需使用的功能歸為一類;最後開始建表:

功能表(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)   不允許為空    使用者組許可權表,內容為功能表f_id的集合

使用者表(user_table)

名稱     型別    約束條件   說明

user_id       int         無重複        使用者標識,主鍵

user_name     char(20)    無重複        使用者名稱

user_pwd      char(20)    不允許為空    使用者密碼

user_type     int         不允許為空    所屬使用者組標識,和user_group.group_id關聯

採用這種使用者組的架構設計,當需要新增新使用者時,只需指定新使用者所屬的使用者組;當以後系統需要新增新功能或對舊有功能許可權進行修改時,只用操作功能表和使用者組表的記錄,原有使用者的功能即可相應隨之變化。當然,這種架構設計把資料庫管理軟體的功能判定移到了前台,使得前台開發相對複雜一些。但是,當使用者數較大(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關聯

b_id          int         不允許為空    書籍標識,和book_table.book_id關聯

rent_date     datetime    不允許為空    借閱時間

……為了實現按批查詢借閱記錄,我們可以再建乙個表來儲存批量借閱的資訊,例如:

批量借閱表(batch_rent)

名稱     型別    約束條件   說明

batch_id      int         無重複        批量借閱標識,主鍵

batch_no      int         不允許為空    批量借閱編號,同一批借閱的batch_no相同

rent_id       int         不允許為空    借閱記錄標識,和rent_log.rent_id關聯

batch_date    datetime    不允許為空    批量借閱時間

這樣的設計好嗎?我們來看看為了列出某個使用者某次借閱的所有書籍,需要如何查詢?首先檢索批量借閱表(batch_rent),把符合條件的的所有記錄的rent_id欄位的資料儲存起來,再用這些資料作為查詢條件帶入到借閱記錄表(rent_log)中去查詢。那麼,有沒有什麼辦法改進呢?下面給出一種簡潔的批量設計方案,不需新增新錶,只需修改一下借閱記錄表(rent_log)即可。修改後的記錄表(rent_log)如下:

借閱記錄表(rent_log)

名稱     型別    約束條件   說明

rent_id       int         無重複        借閱記錄標識,主鍵

r_id          int         不允許為空    使用者標識,和renter_table.renter_id關聯

b_id          int         不允許為空    書籍標識,和book_table.book_id關聯

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設計比起來,哪一種更好呢?答案就不用我說了吧。

五、冗餘資料的取捨

上篇的「樹型關係的資料表」中保留了乙個冗餘字段,這裡的例子更進一步——新增了乙個冗餘表。先看看例子:我原先所在的公司為了解決員工的工作餐,和附近的一家小餐館聯絡,每天吃飯記賬,費用按人數平攤,月底由公司現金結算,每個人每個月的工作餐費從工資中扣除。當然,每天吃飯的人員和人數都不是固定的,而且,由於每頓工作餐的所點的菜色不同,每頓的花費也不相同。例如,星期一中餐5人花費40元,晚餐2人花費20,星期二中餐6人花費36元,晚餐3人花費18元。為了方便計算每個人每個月的工作餐費,我寫了乙個簡陋的就餐記賬管理程式,資料庫裡有3個表:

員工表(clerk_table)

名稱     型別    約束條件   說明

clerk_id      int         無重複        員工標識,主鍵

clerk_name    char(10)    不允許為空    員工姓名

每餐總表(eatdata1)

名稱     型別    約束條件   說明

totle_id      int         無重複        每餐總表標識,主鍵

persons       char(100)   不允許為空    就餐員工的員工標識集合

eat_date      datetime    不允許為空    就餐日期

eat_type      char(1)     不允許為空    就餐型別,用來區分中、晚餐

totle_price   money       不允許為空    每餐總花費

persons_num   int         不允許為空    就餐人數

就餐計費細表(eatdata2)

名稱     型別    約束條件   說明

id            int         無重複        就餐計費細表標識,主鍵

t_id          int         不允許為空    每餐總表標識,和eatdata1.totle_id關聯

c_id          int         不允許為空    員工標識標識,和clerk_table.clerk_id關聯

price         money       不允許為空    每人每餐花費

其中,就餐計費細表(eatdata2)的記錄就是把每餐總表(eatdata1)的一條記錄按就餐員工平攤拆開,是個不折不扣的冗餘表。當然,也可以把每餐總表(eatdata1)的部分字段合併到就餐計費細表(eatdata2)中,這樣每餐總表(eatdata1)就成了冗餘表,不過這樣所設計出來的就餐計費細表重複資料更多,相比來說還是上面的方案好些。但是,就是就餐計費細表(eatdata2)這個冗餘表,在做每月每人餐費統計的時候,大大簡化了程式設計的複雜度,只用類似這麼一條查詢語句即可統計出每人每月的寄餐次數和餐費總帳:

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想象一下,如果不用這個冗餘表,每次統計每人每月的餐費總帳時會多麻煩,程式效率也夠嗆。那麼,到底什麼時候可以增加一定的冗餘資料呢?我認為有2個原則:

資料庫設計技巧

1.設計資料庫之前 需求分析階段 1 理解客戶需求,詢問使用者如何看待未來需求變化。讓客戶解釋其需求,而且隨著開發的繼續,還要經常詢問客戶保證其需求仍然在開發的目的之中。2 了解企業業務可以在以後的開發階段節約大量的時間。3 重視輸入輸出。在定義資料庫表和字段需求 輸入 時,首先應檢查現有的或者已經...

資料庫設計技巧

1.設計資料庫之前 需求分析階段 1 理解客戶需求,詢問使用者如何看待未來需求變化。讓客戶解釋其需求,而且隨著開發的繼續,還要經常詢問客戶保證其需求仍然在開發的目的之中。2 了解企業業務可以在以後的開發階段節約大量的時間。3 重視輸入輸出。在定義資料庫表和字段需求 輸入 時,首先應檢查現有的或者已經...

資料庫設計技巧

下述14則資料庫設計技巧,是許多人在大量的資料庫分析與設計實踐中,逐步總結出來的。對於這些資料庫設計經驗的運用,靈活掌握,並逐步做到 在應用中發展,在發展中應用。資料庫設計技巧14則 1.原始單據與實體之間的關係 可以是一對 一 一對多 多對多的關係。在一般情況下,它們是一對一的關係 即一張原始單據...