mysql apache google Ubuntu wordpress 程序员 centos nginx linux 微软 开源 Android java Firefox 编程 Python 云计算 php Windows shell

走近復雜數據庫計算型軟件的設計與制作(5)—存儲過程的設計

摘要:接著昨天的數據庫的函數的設計,今天敘述存儲過程的設計。
存儲過程是整個軟件中最核心的部分,實現了幾乎全部的商業業務規則。這裏所說的業務規則不是指數據庫中的rule那樣的業務規則,而是公司規定的獎金計劃等商業規則。在本軟件設計中,涉及了大量的業務規則,每個業務規則都對應一種獎金類型,大約有35種獎金類型。在此只講解一個存儲過程,當中涉及了5種業務規則。
業務規則中有一項規則是一個節點之下,每產生3個節點即為一組,每一組中的前兩個節點產生的時候獎勵2000元,產生第三個節點的時候獎金4000元,如果下面有3個節點,則為A級代理,如果3個節點下面有13個節點,則當前節點為B級代理,如果3個節點下面有50個節點,則為C級代理,當前節點在每一組中的級別是不一樣的。每一種代理都有不同的優惠政策,為了簡化描述,其他相關的規則就不再一一敘述了。
根據業務規則定義相應的表如下:
create table shop(
m_ID                                         D_M_ID, --當前節點ID
rm_ID                                        D_M_ID, --上一級節點ID
turns                                          D_INT,
groupId                               D_INT,--當前節點所屬的上一級節點的組編號
next_groupId         int default 1, -----當前節點的下級節點的下一個組編號
allCommends                D_INT,---所有的推薦人數
enabled                                D_bit,
regDate                        D_REGDATE,
deal_flag                       D_BIT,
constraint pk_shop primary key(m_id)
)
Go
數據庫中設計的字段在上面已經註釋,下面詳細講述整個存儲過程,首先找到沒有被處過的Shop實體,取得m_id和@rm_id
set @m_id=(select top 1 m_id from shop where enabled=1 and turns=@turns and deal_flag=0 order by regdate asc)
                     set @rm_id=(select rm_id from shop where m_id=@m_id)
                     set @bm_id=@m_id
獲得並設置當前節點在父節點中的組號
update sh1
                     set sh1.groupId=sh2.next_groupId
                     from shop sh1,shop sh2
                     where sh1.m_id=@m_id and sh2.m_id=@rm_id
更新父節點的推薦人數,當前的更新一直跟蹤到樹的根部,
       update shop
                            set allCommends=allCommends+1
                            where m_id=@rm_id
如果當前節點為第一層的節點@level=1並且在當前組中為第一個或者第二個,則獎勵2000元,設置獎金類型,這個在數據表的設計中有說明。
set @award_type=70
                           
                            if @level=1 and exists(select 1 from shop  where  rm_id=@rm_id and groupId=@groupId and enabled=1  having count(1) between 1 and 2)                            
                            begin
                                                                     
                                                 insert into award_level(m_id,rm_id,turns,c_times,level,award_type,amount,money,enabled)
                                                 select sh.m_id,@m_id,@turns,@c_times, @groupId,@award_type,1,1*a.award_num,sh.enabled
                                                 from award_about a,shop sh
                                         where a.award_type=@award_type
                                                       and sh.m_id=@rm_id
                            end
如果當前節點第一層為第三個,則獎勵4千元,並且更新父節點的下一個組號,重要的是條件語句,請註意,
set @award_type=71
                            if @level=1 and exists(select 1 from shop  where  rm_id=@rm_id and groupId=@groupId and enabled=1  having count(1)=3)                            
                            begin
                                                                     
                                                 insert into award_level(m_id,rm_id,turns,c_times, level,award_type,amount,money,enabled)
                                                 select sh.m_id,@m_id,@turns,@c_times, @groupId,@award_type,1,1*a.award_num,sh.enabled
                                                 from award_about a,shop sh
                                         where a.award_type=@award_type
                                                       and sh.m_id=@rm_id
                                        
                                         update shop
                                                 set next_groupId=next_groupId+1
                                                 where m_id=@rm_id
                            end
如果為B級代理,則進行相應的獎勵,註意條件語句中的sum()與count()函數的應用。
set @award_type=72
                      if exists(select 1 from shop where rm_id=@rm_id and groupId=@groupId and enabled=1 having sum(allCommends)>=13 and count(1)=3)
                             and not exists (select 1 from award_level where m_id=@rm_id and award_type=@award_type and level=@groupId)
                             and @groupId>0
                             begin
                                          insert into award_level(m_id,rm_id,turns,c_times,level,award_type,amount,money,enabled)
                                                 select sh.m_id,@m_id,@turns,@c_times,@groupId,@award_type,1,1*a.award_num,sh.enabled
                                                 from award_about a,shop sh
                                         where a.award_type=@award_type
                                                       and sh.m_id=@rm_id
                             end
這個存儲過程中的大部分內容已經講述完畢,每一個步驟都涉及數據庫的操作,如果把這些操作放在程序中之行,則會出現頻繁打開數據庫操作,導致性能下降,放入數據庫中並且使用事務則相對提高效率。因此筆者認為,使用存儲過程是實現商業規則的良好方案。
整個系列就講完了,也許有空的話我把數據庫的測試程序也講解一下。如果你能學到一些東西或者指出筆者的一些不足之處,筆者會十分高興。

延伸阅读

评论