单车租赁系统
项目简介
这个单车租赁系统全部是由本人设计开发,主要是关于MySQL数据库的项目设计,虽然学校教的是SQL server,但是我在这个项目中使用的是MySQL。这个系统项目包括了CSS和HTML实现的前端,结合MySQL数据库和PHP实现数据库的操作与后端的管理。通过这个项目实现对MySQL和网页设计的实践操作,以提高自己的相应项目经验和实践能力。
数据库需求分析简介
在整个单车租赁系统中应该包括三个基本的角色,包括管理员、车主和用户。管理员用来管理整个系统包括其中的用户和管理员,而用户主要用来租借单车,车主关心的重点是自己的单车情况。本系统还应该具有相应的安全性,要在单车被租借后使其显示为不可借状态,而且要对不守信的用户进行惩罚,还要保证车主单车的安全性和用户使用的方便性。
数据流图的设计
下图是本系统功能结构的简单描述,因为项目主要是关于数据库的实践,所以系统的功能结构采用了最简单最基本最常见的形式,虽然系统的功能结构简单但是涉及了数据库的大部分操作所以暂且用了如下简单的形式。
数据库的数据字典
下面是该系统涉及到的表信息
对于管理员可以用编号、姓名、年龄、电话、居住地址、密码等信息字段来表示,编号是主键
对于用户可以用编号、姓名、负责人编号、性别、电话、专业、信誉度、密码等信息字段来表示,用户编号是主键,负责人编号是外键,并设置级联更新
对于车主可以用车主编号、姓名、性别、电话、专业、密码等信息字段来表示,车主编号是主键
对于类被表class可以用类别编号、类别名称、该类别单车价格、该类别单车座位数量等信息字段来表示,类别编号是主键,并且设置类别名称的字段为非空字段
对于停放单车地址表address_可以用地址编号、地点名称、具体的停放地点等信息字段来表示,地点编号是主键,并且设置该停放地址的具体地点的字段为非空字段
对于单车表car_可以用单车编号、类别编号、车主编号、标志是否可借的标志位、停放地编号等信息字段来表示,单车编号是主键,类别编号为外键并且设置为级联更新和级联删除;车主编号为外键,并且设置为级联删除和级联更新,并且设置该字段为非空字段;停放点编号也为外键,并且设置为级联更新,保持和停放地点表保持一致。
对于多对多的关系需要用一个单独的表进行表示,对于租借表可以用用户编号、单车编号、租借时间、租借时长、归还时间、是否预期等信息字段来表示,用户编号、单车编号和租借时间共同组成主键,用户编号是外键,和用户表的用户编号保持一致,并设置为级联更新;单车编号也是外键,和单车表的单车编号保持一致,并设置为级联更新级联删除。是否预期的字段为int类型的数据,用来判断该租借记录是否超过了期限,如果是超过了时间,就会设置为1,根据用户逾期的次数来给用户评断信誉度。
使用power designer画出E-R图
第一范式(1NF):属性不可再分,保证属性的原子性
第二范式(2NF):属性完全依赖于主键,消除了非主属性对于码的部分函数依赖
第三范式:(3NF)属性不依赖于其它非主属性,消除了非主属性对于码的传递函数依赖
该系统数据库满足第三范式
数据库约束的实现
用car表的外键约束作为示范,在rent、user_等多个表上都添加了外键约束并添加了级联更新或者级联删除,还在car、class等多个表添加了非空、唯一约束,虽然在mysql中添加check约束但是不会起作用,这是mysql的不足之处,相比之下SQL server可以实现check约束
数据库中的视图
创建一个视图,用来查找某一用户所有的租借信息,这个视图使用了with check option 在使用视图进行改数据的时候会进行检查。这个视图会查看用户租借信息,包括用户编号、姓名、信誉度、单车编号、租借时间、租借时长、归还时间的字段
创建一个视图,用来查询所有未归还的单车的具体信息,这个视图连接了别的表,这个视图会查看未归还的单车的具体信息,包括单车编号、租借单车的用户名称、该用户的信誉度、该单车租借的时间、租借该单车的租借时长、该单车的归还时间的字段信息,根据归还时间是否为空来判断该条的租借信息,如果是空则代表未归还。
数据库中的触发器
创建一个触发器,实现当有一个用户租借到某一个单车后,就将该单车的可借标志位设置位0,如果归还了该单车就将其标志位设置位1,这个触发器通过归还时间是否为空来判断,为空的表示该单车未归还,如果该单车的单车编号在归还时间为空的所有记录中,就将其设置未1。
创建一个触发器,实现对用户租借信息中的违约标志的修改,当一个用户对一次租借单车进行归还的时候,系统会自动通过触发器进行判断该用户是否逾期,用归还时间减去租借时间,取其所使用的小时数,当该得数大于租借时间的时候,则可以判断该用户的该条租借记录是否逾期,如果逾期将标志位miss_time设置为1,否则为0。
创建一个触发器,用来通过用户不守信誉的次数来动态的修改其信誉度,通过统计每个用户的租借记录,然后统计该用户逾期的次数,通过逾期标志位miss_time来进行判断,如果该字段为1标志该租借记录是逾期的租借记录,统计每个用户逾期的次数来改变用户信誉度,如果逾期超过1次将其信誉度修改为B,如果逾期超过3次,将其信誉度修改为C,如果逾期超过4次,将其信誉度修改为D。
数据库中的存储过程
创建一个存储过程,查询属于某一个车主的单车信息,这个存储过程连接了多个表,在调用这个存储过程的时候可以传入一个车主的编号进去,然后就会根据这个车主编号查找出属于该车主的单车的具体信息,包括单车的编号、车主的姓名、该单车的类别名称、该单车停放的地点名称、该单车类别的小时租借价格、该单车类别的座位数量等信息。
创建一个存储过程,查看租借指定车主的单车的用户的信息,这个存储过程连接了多个表,在调用这个存储过程的时候可以传入一个车主的编号进去,然后就会根据这个车主编号查找出租借指定车主的单车的用户的信息,包括用户的姓名、该用户的负责人的姓名、该用户的专业、该用户的电话、该用户租借的单车的编号、该用户租借的时间等信息。
使用explain查看数据库执行的效率
explian命令可以用来解释这句sql语句,select_type查询的类型,simple代表简单的select查询;type是访问类型,all是全表扫描,eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数(可根据这个值来判断搜索用到了多少行),extra是补充信息,出现using where表明索引被用来执行索引键值的查找,extra中出现了using temporary和using filesort,说明MySQL会对数据使用一个外部的索引排序而且使用了临时表保存中间结果,所以出现说明sql语句执行效率很差
在这个select语句中,仅仅是改变了group by后面的u_id来自来个表就产生了不同的查询效率,在使用user_表的u_id时,对rent查询的type是all也就是全表查询,当使用rent表的u_id后会使rent表的查询type变成index索引查询,而且extra出现了using index:表明相应的select 操作中使用了覆盖索引,避免访问了表的数据行。
MySQL的锁机制
MySQL也是支持多并发的机制的并且是支持事务的功能的,所以会出现一下三种问题
脏读:指一个线程中的事务读取到了另外一个线程中未提交的数据。
不可重复读(虚读):指一个线程中的事务读取到了另外一个线程中提交的update的数据,就是一个连接在更新前读的内容不一致。
幻读:指一个线程中的事务读取到了另外一个线程中提交的insert的数据。
前端效果展示
这里使用公共的界面进行登陆,用户在登陆之后,系统会做出正确性检测并且识别不同的身份,然后根据不同的身份进入不同的功能选项界面
这是管理进行之后的功能界面,这里包括对单车、用户和车主进行管理的功能选择
这里是查询单车的界面,管理员可以查看到全部的单车信息,而用户只能查看到可借的单车信息,车主可以查看属于自己的单车的信息。这里使用的是Ajax动态请求,根据输入不然的条件,第一个是一个下拉列表,可以选择根据单车的哪个属性进行选择,后面是一个输入框,根据这些信息可以动态的查询到符合要求的单车信息并将其显示。
这是删除单车的功能界面,在这里可以根据条件查找到单车之后点击后面的delete按钮即可删除对应的单车。
这是车主查看自己租借单车的情况,因为租借表的主键是用户编号、单车编号和租借时间,所以一个用户可以在不同的时间内租借同一个单车。
总结
此单车租赁系统具备了基本的功能,可以满足某些小型校园单车租赁的需要。但是,其中也存在某些不足之处,如操作界面不美观,而且使用到的MySQL数据库本身就有许多限制,但是对其有很多不支持的功能,比如是对触发器或者是约束的实现不完全,如果在最初使用SQL sever会使系统的容差能力更强。
通过这个项目的独立实现,我认识到一个项目的完成前期的分析很重要,比如一开始的系统功能设计以及实体的组成以及实体间的联系,所以前期的需求分析以及数据流图很重要。同时巩固了对MySQL以及PHP知识的学习,在遇到一些问题通过在网上搜索一些建议大部分能够解决,一些零碎的知识记不得没关系,可以通过查找文档或者是找一些网站寻找解决方法,所以我明白了要利用资源的重要性以及资源整合的必要性。
致谢
本人才疏学浅,一个字一个字的完成的上述博客,如果以上的内容有什么问题,欢迎大家批评指教,前端的源码和MySQL的代码我会放到我的GitHub上,感谢大家提出宝贵的意见。