数据库课程设计银⾏管理系统(SQLServer)
哪吒头由于各种原因,可能存在诸多不⾜,欢迎斧正!
1需求分析
⽣活在21世纪,我们每个⼈的⽇常⽣活免不了跟银⾏打交道。安全、规范、操作简单、功能齐全的银⾏管理系统能使业务得以顺利流畅的办理,使⼈们获得极好的⽤户体验。基于这样的背景,我的选题是银⾏管理系统。
⽇常⽣活中的银⾏管理系统很复杂,对安全性和完整性要求都很⾼。在此我运⽤数据库课上所学知识,结合⾃⼰平时的银⾏业务体验,认为⼀个合格的银⾏管理系统⾄少应该具备以下⼏点要素:
1.安全性,不会泄露相关信息,造成损失;
2.功能齐全,各种业务可以⾼效办理;
3.操作简单,可以快速上⼿。
为了兼备以上的要素,我认为银⾏管理系统⾄少需要4类⽤户的参与,他们依权限可以分为银⾏注册师、银⾏营业员(以下简称营业员)、存款⽤户、贷款⽤户。
银⾏注册师负责登记银⾏信息,主要包括银⾏名、所在城市、总资产等。
营业员负责开户、销户,即处理客户信息,包括⽤户名、所在城市、所住街道,并根据客户需求是存款还是贷款分配密码和授予权限;此外,银⾏员⼯可能因为⼯作需要要完成各类查询、删除等⼯作。银⾏员⼯是整个数据库中权限较⼤的⽤户,他能看到整个银⾏系统客户信息以及相关的交易记录。
贷款⽤户属于整个数据库的底层⽤户,他只能在开户后根据权限登录到相应的窗⼝界⾯完成查询与贷款。在查询⼯程中,为了整个数据库的安全性,他只能看到⾃⼰的信息。
存款⽤户也属于整个数据库的底层⽤户,它只能在开户后根据权限登录到相应的窗⼝界⾯完成查询与存款。在查询⼯程中,为了整个数据库的安全性,他也只能看到⾃⼰的信息。
2数据库(DB)设计
为了完成整个数据库银⾏管理系统的开发,⾸先要设计数据库:按⽤户的观点对数据和信息建模,从现实世界中抽象出概念模型。整个银⾏管理系统可以⾸先预定义⼏个⽤户,如银⾏注册师、营业员,因为我的整个系统主要是服务⼴⼤的客户,包括存款⽤户与贷款⽤户。整个数据库有5个在现实世界中区别于其他对象的“事物”或“物体”,称之为实体(Entity)。5个实体分别为银⾏(Branch)、客户(Customer)、贷款(Loan)、存款(Account)、⽤户(Ur),他们共同构成了整个银⾏管理系
统的实体集(Entity Set)。以下是各种实体所包含的所有信息,它们描述了实体集中所有成员的特征,我们称之为实体的属性(Attribute):
Branch(Branch_Name、Branch_City、Asts);
Customer(Customer_Name,Customer_City,Customer_Street);
Ur(Ur_Name,Ur_Pswd,Ur_Type);
Loan(Loan_Number,Branch_Name,Amount);
Account(Account_Number,Branch_Name,Balance);
上⾯的实体彼此之间并不是孤⽴的,他们之间有⼀定的约束关系,称之为联系(Relationship)。整个数据库中的联系很多,他们中有的是⼀⼀对应的关系如⼀个客户只能开⼀个户,⽽开过户的登陆⼝令和密码只能被⼀个客户持有,即⼀个Ur对应⼀个Customer;有的是⼀对多,如⼀个客户可以办理多笔代贷款,即⼀个Customer对应多个Loan;有的是多对⼀,如多个贷款号同时被⼀个银⾏拥有,即多个Loan_Number对应⼀个Branch;还有的是多对多的关系,如⼀个客户办理多笔存款,⼀笔存款被多个客户拥有。上⾯四种联系是在银⾏管理系统中经常⽤到的,他们共同构成了整个银⾏管理系统的联系集(Relationship Set)。
有了实体集和联系集,就可以将整个现实世界中的银⾏管理系统进⾏2级抽象,得到机器世界即DBMS⽀持的数据模型(Data Model),⽤于数据库银⾏管理系统的实现。
我的整个数据库的设计是基于实体-联系模型(Entity-Relation Model)的,处理该类问题的关键是设计正确全⾯的E-R图。
五行八卦算命
说明:为了防⽌过于混乱,上述E-R省去了部分⼀⼀对应关系。
在整个数据库中,完整性是很重要的。数据库的完整性是指数据的正确性和相容性。主码的各个属性不能为空和主码值唯⼀;当更新、删除、插⼊⼀个表中的数据时,通过参照引⽤相互关联的另⼀个表中的数据,来检查对表的数据操作是否正确。完整性包括3个部分:实体完整性、参照完整性、⽤户定义完整性。以上有的表中属性是两外⼀个表的主码,我们称为外码参照(Reference relation)。正确的外码参照关系是整个数据库系统正确性、安全性的保证。我的银⾏管理系统有着规范、正确的外码参照关系。以下是我的银⾏系统模式图。
3.数据库实现
有了E-R图,剩下的⼯作就是将对应的E-R图正确的翻译为表,从⽽被计算机中数据库管理系统处理。上述E-R图中我已将可以合在另⼀张表中的联系集合并了,剩下不能合并的都是多对多关系,这类联系集是不能被合并到任何⼀张表中的。E-R图中⼀个实体集或联系集对应数据库中的⼀张表,实体集或联系集上的属性对应表中的列。
有了表的⼤致框架,我们要做的就是在计算机中存储信息。要存储,就要涉及数据结构,即每张表中每个属性分配什么样的存储单元。既要毫⽆遗漏的存储所有信息,⼜要做到尽可能的节约存储空间。在我们平时开发的应⽤程序中,就是要考虑要⼀些较为⾼级的数据结构,如字典树、线段树、哈希表等等。但由于存储过程是交由数据库管理系统(DBMS)来实现的,即我在开发银⾏管理系统时不⽤关⼼具体物理存储甚⾄是逻辑存储过程。表中的数据类型都是在实际需求与节省存储空间⼆者之间权衡的折中⽅案。
我们只需编写正确⾼效的应⽤程序,来适应不同类型⽤户的查询与办理相关业务的需求。
恋爱大过天歌词说明:在数据库中,我的整个银⾏管理系统的各种约束关系、⼀致性原则等都是通过⾃⼰编程来实现的。这个在下⾯的具体设计会详细解释。
1.银⾏注册师
怎么做披萨
这个⽤户是事先存在Ur表中的,他的权限是注册银⾏相关的⼯作。包括添加、删除、修改、查询。其中添加、查询只涉及⼀张表,即Branch表;但修改、删除就涉及多张表了,⽽且要保证修改、删除的银⾏信息元祖是客观存在的,即级联删除、级联修改。要保证修改或删除的元祖是存在的,可以在修改删除⼀直查询⼀下该元素是否存在。若不存在,输出相应的提⽰信息,并撤销相应的操作;如果存在,则根据外码参照关系来处理。在本系统中,所有的修改操作都能修改主码,这符合时下的⼀些数据库设计潮流。
电教工作计划2.营业员
对于营业员,他的⼯作就是开户、销户,修改客户个⼈信息以及按类型查询相应的信息,包括⽤户信息和银⾏信息。开户时⾸先得查询该⽤户是否开过户,若没开过就给他开户,否则输出相应的提⽰信息。销户由于设计的表⽐较多,我精⼼设计了⼀下。撤销⼀个⽤户,⾸先查询他是否存在,在这样的⽤户客观存在的情况下然后执⾏删除相应表中该客户的信息。由于涉及多张表(Customer表,Ur表,Loan表,Account表、Depositor表、Borrower表,共6张),且它们中存在⼀对多关系,如Customer—Depositor,Customer—Borrower;同时存在多对多关系,如Customer—Account,Customer—Loan。要删除⼀个客户,就得删除他的存款与贷款⽅⾯的信息。修改时也存在相应的完整性约束。
这本来在SQL Serve中注意⼀下删除顺序,做⼏个笛卡尔积就可以的。但由于⽤VC编程,⼀张表关联⼀个类,给编程带来⼀定的困难。对于多张表的笛卡尔积,我有4种想法。
解决⽅案1:
直接在数据库中表与应⽤程序中类⼀⼀对应的基本上,寻找有效的可⾏⽅案。即直接写带笛卡尔积的查询语句,然后单张表查询。事实证明该⽅案是不可⾏的。虽说⼀下打开了整个数据(m_databa.Open(_T("BANKDB"))),但是⼀张表有且只关联⼀个类,返回值为该类型。例如Customer表中关
联CCustomerSet类,不能试图通过它直接获取其他任何表中的信息。该⽅案是不可⾏的。
解决⽅案2:
在知道⼀张表有且只关联⼀个类的基础上,结合C++中类的继承关系,我试图⾃定义⼀个类,继承要做笛卡尔积的所有表。如我要求⼀个⽤户的所有贷款信息,涉及3张表,Loan表、Borrower表、Customer表,其中Customer表提供⽤户名Customer_Name,然后就是剩下的Loan表、Borrower表做笛卡尔积,可以尝试⾃定义⼀个BorrowerLoan类,如下:
Class BorrowerLoanSet
{
LoanSet m_LoanSet;
BorrowerSet m_BorrowerSet;
};
这样做就得具体看看Open(CRecordt::snapshot,Cstring strSQL),由于对VC底层和数据库打交道的具体机制不熟,导致产⽣⾃定义⼀个涉及多张表的类,事实证明这个⽅案也是不可取的。
解决⽅案3:
要处理多张表,可以先尝试把其中⼀张标的作为另⼀张表的主键的信息存起来,开个数组或调⽤C++中容器。然后再根据第⼀张表中得到的并存储起来的信息在第⼆张表中查询…知道处理完所有的表为⽌。这个⽅案是完全可⾏的。
还是解决⽅案2中的问题,Loan表、Borrower表做笛卡尔积,可以理解为先对Borrower表进⾏查询,记录中间过程结果,然后根据中间结果查询Loan表。对应伪代码为:
For(Borrower表中的所有记录)
{
If(该记录的Customer_Name就是我们所需的)
存到容器Vector中;
}
For(Loan表中的所有记录)
{
If(该记录的Loan_Number在Vector容器中)
该记录就是我们所需的;
}
上述判断Loan表中的Loan_Number是否在Vector中可以⽤哈希表的思想,将Loan_Number映射到⼀个map中,实现时间复杂度O(1)判断每条Loan表中的记录是否在Vector容器中。此⽅案是可⾏的。
解决⽅案4:
这个⽅案的基本思想就是多重循环。要做笛卡尔积,不能直接在VC中写SQL语句但可以通过编程模拟笛卡尔积的过程。猜想在数据库内部笛卡尔积就是通过⾼效的多重循环来实现的。Loan表、Borrower表做笛卡尔积,选取Borrower表中Loan_Number和Loan表中Loan_Number相等的,组合起来的信息就是我们要查的。模拟笛卡尔积的过程如下:
For(Borrower表中的每个元祖)
{
If(元祖b的Customer_Name是要查的)
{
For(Loan表中的每个元祖)
{
If(Loan中的元祖l,使得l.Loan_Number=b.Loan_Number)
{
Borrower表和Loan表中对应元祖的组合信息就是我们所要的
}
}
}
}
我实现Loan表和Borrower表做笛卡尔积(在两者Loan_Number相等的情况下)的代码见附件1
3.存款者
对于存款者,他可以选择办理存款业务,办理成功给出“业务办理成功”提⽰。若选择办理业务的银⾏不存在,则给出提⽰,防⽌在底层数据库中出错。具体的实现是先查询⼀次看看办理业务的银⾏是否存在,若不存在则给出提⽰。提前给出提⽰⽐在数据库中违反外码参照关系导致错误要健壮、鲁棒得多。同时根据现实需求,该客户是可以查询⾃⼰的交易记录的,处于安全性考虑,他仅能看到⾃⼰的交易记录,别⼈的交易记录他是没有权限访问的。同时,他也可以查询银⾏信息,做到对⽐分析,得到对⾃⼰最有利的存款⽅案。其中涉及多张表的处理⽤的⽅案同上⾯解决⽅案4,在此不再不说。
4.贷款者华是多音字吗
对于贷款者,他的权限很⼤程度上和存款者⼀样。他可以办理贷款业务。查询⾃⼰的交易记录和银⾏相关信息。功能与具体编程实现同上⾯的存款者,区别在于存款者操作的是Account表和Depositor表,⽽贷款者操作的是Loan表和Borrower表。当然⼆者的界⾯是不⼀样的。为了避免重复,在此就不再赘⾔了。
为了尽可能的符合现实⽣活中的银⾏管理系统,我的程序写得⽐较⼤。下⾯是⼀些具体数据:
为了⽅便开发,我的变量、函数、类、资源等都⽤相应的英⽂表⽰,做到了见名知意。
以下是我程序中的类视图:向南林
怎么剪福字窗花