个人重构版的机房收费系统正在紧锣密鼓的进行着,虽然不是很难的东西,但是有时候小毛病还是很多。程序正在代码实现中,抛下程序不谈,先来总结下数据库的设计。
1、数据完整性
约束、规则、默认值等能够较好的保证数据的完整性,为了保证系统数据的完整性,设计时使用了主键、外键、Check约束,同时使用规则和默认值来保证数据的正确性。使用主键时约束了一列,把表中的一列作为主键,创建主键约束的表中数据不能为空,且不能重复,表的索引默认的是主键约束的列;使用主键约束了同一个表中的两列,受约束后的表中的数据是按照第一个设置主键的列的排序规则进行排序的,保证了两个列中数据不能为空且不能重复,同时也符合第二范式。
主键约束不会存在太大的问题,主要是外键约束。外键约束保证了数据的完整性,在对数据库操作时它会级联触发保证数据的完整性,但是外键约束的创建要基于唯一约束、非空约束或主键约束,被约束的外键表中的列必须保证非空且唯一。
主要操作步骤不在详述,前篇博客已有总结。
2、业务规则
好的数据库能够减少程序开发者写代码的时间,而在数据库设计时巧妙的运用触发器在保证业务规则的同时也减少了编写复杂代码的时间。虽然在保证数据完整性上,触发器的效率要低于约束,但触发器在处理业务逻辑上拥有者得天独厚的便利,因为它能够自动触发,实现级联修改。触发器按大类可分为DDL、DML和登陆触发器,具体划分如下图:
在使用DML数据操作语言类数据库时,它会在触发器表中生成相应的Deleted、Inserted表,这两个表分别保存要删除行的数据、要增加行的数据,在使用触发器时也可以应用这两个表中的数据。
与SQL2000不同的是SQL2008在创建触发器时,是在相应的表下创建,当然也可直接在查询中运行创建语句来创建。如下图:
为了完善业务逻辑,系统在设计时用了Insert类型的触发器,在表中插入数据时,修改另一表中数据,主要语句如下:
use [ChargeSystem] go /*表充值记录触发器,能够触发修改Student中余额主要实现的是当为某学生充值金额时,自动将充值金额增加到学生的余额中*/ if OBJECT_ID('chargesystem.trChargeAdd','TR') is not null drop trigger chargesystem.trChargeAdd; go create trigger trChargeAdd on tblchargelog for insert as /*将增加的充值金额,增加到学生余额中*/ update S set stu_Balance=(S.stu_Balance+I.ch_Chargecash) from tblstudent as s inner join Inserted as I on S.stu_Cardid=I.ch_CardID Go /*上面语句中的Inner join查询是将on后面符合条件的Inserted表中的行加入到tblstudent表中*/
为了保证数据库的安全性,防止
SQL
注入的情况发生,我们在使用结构化查询或者操作时,应用使用参数,使用参数化查询或操作代替字段拼接,能够防止
SQL
注入的情况。