热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

数据库设计StepbyStep(6)提取业务规则

引言:数据库设计StepbyStep(5)中我们通过多种方法来理解客户的需求并撰写了需求文档。本文我们将回答三个问题。1.为什么业务规则非常重要。2.怎样识别业务规则。3.如何修改关系模型并隔离出业务规则。什么是业务规则业务规则描述了业务过程中重要

引言:数据库设计 Step by Step (5)中我们通过多种方法来理解客户的需求并撰写了需求文档。本文我们将回答三个问题。1. 为什么业务规则非常重要。2. 怎样识别业务规则。3. 如何修改关系模型并隔离出业务规则。 什么是业务规则 业务规则描述了业务过程中重要

引言:数据库设计 Step by Step (5)中我们通过多种方法来理解客户的需求并撰写了需求文档。本文我们将回答三个问题。1. 为什么业务规则非常重要。2. 怎样识别业务规则。3. 如何修改关系模型并隔离出业务规则。

什么是业务规则

业务规则描述了业务过程中重要的且值得记录的对象、关系和活动。其中包括业务操作中的流程、规范与策略。业务规则保证了业务能满足其目标和义务。

生活中的一些业务规则可能是:

本系列我们关注数据库相关的业务规则,一些例子如下:

从数据库的视角来看,业务规则是一种约束。简单的约束如:

所有订单必须有一个联系电话。

上述这类简单的规则可以很容易的映射到关系数据库定义中,为字段确定数据类型或设定某字段为必填(不能为NULL)。某些业务规则表达的约束会复杂些,如:

学生每天的上课时间加上项目时间必须在1至14小时之间。

我们可以通过check约束或外键约束来实现这类业务规则。对于一些非常复杂的业务规则,如:

一名教员每周不能少于30小时工作量,其中分为办公时间、实验时间和上课时间。每1小时的课需要0.5小时办公时间进行备课。每1小时实验需1小时办公准备。每周指导学生论文时间不少于2小时。

类似上述的业务规则需要从多个表中收集数据,故在程序代码中实现最为合适。

识别关键业务规则

记录所有的业务规则并对这些规则进行分类能帮助我们更好的在系统中实现业务逻辑。

如何实现业务规则不仅与当前的业务逻辑有关,而且与该业务逻辑将来如何变化有关。当一个规则在将来很可能变化时,我们需要使用更复杂但更灵活的方式构建该规则。

举例来说,假设公司只能向当地设有仓库的城市发货,这些城市包括:南京、长沙、西安、广州。业务规则要求订单中的发货城市字段必须为NJ、CS、XA、GZ之一。

我们可以把该规则简单的实现为check约束。但将来公司若在上海有了一个新仓库,就必须从后台数据库端修改该check约束。若公司随后设立更多新仓库或业务规则变化为可以向没有仓库的城市发货,每次我们都需要修改该约束。

考虑另一种实现该业务规则的方法——使用外键。我们创建一张ShippingCities表,其中存放值:NJ、CS、XA、GZ,并让订单表中的发货城市字段外键引用ShippingCities表中的主键。这样订单的发货城市列只能接受ShippingCities中存在的城市。当支持的发货城市增加或减少时,只需要在ShippingCities中插入或删除记录。

两种方式的实现难度差异不大,但前一种方式每次都需要修改数据库结构,后一种只需要修改数据。修改数据不仅更省力而且技术要求也更低。

上述业务规则实现为check约束可能如下:

ShippingCity = ‘NJ’ or ShippingCity = ‘CS’ or ShippingCity = ‘XA’ or ShippingCity = ‘GZ’

上述代码并不复杂,但只有熟悉数据库的程序员从后台才能修改。ShippingCitis表中的数据相对更易于理解,我们可以提供一个界面来让用户自己维护其中的城市。

要识别关键业务规则,我们可以问自己两个问题。

第一、修改规则会有多困难。越是复杂的规则,香港服务器租用,修改起来越困难且更容易出错。

第二、规则变化的可能性有多大。变化频繁的规则需要额外的设计来更好的应对将来的变化。

需要特别注意的规则(关键业务规则):

一些直接可以在数据库中实现的业务规则:

作为软件从业人员不要拒绝或回避变化。世界上唯一不变的就是变化。在收集业务规则时多去了解该规则的业务背景与历史变化历程,而不是逼迫客户保证规则不会变化。尽可能发现所有的业务规则并记录下来。对这些业务规则按变化的可能性和修改难度进行分类,精心设计那些将来可能变化且修改困难的规则。

提取关键业务规则

识别并分类业务规则之后,我们需要在数据库中或数据库外来实现关键业务规则。我们可以参考如下方法:

1. 若规则为检验一组有效值时,香港虚拟主机,把该规则转化为外键约束。先前举例中的有效发货城市就是一个很好的例子。创建ShippingCities表,填入允许的发货城市。然后把Orders表的ShippingCity列设为外键,引用ShippingCities表的主键。

2. 若规则为参数可能变化的计算式时,把这些参数提取到一张表中。例如:一个月内卖出总价超过100万元汽车的销售员能获得500元奖金。把参数100万元和500元提取到一张表中,如果需要甚至可以把一个月的时间段也作为参数提取出来。

我还见过一些软件系统在数据库中有一张通用的参数表。该通用参数表中存放系统需要的各种参数,一些是用于计算、一些是作为检验、另一些决定系统的行为。每一条记录有两个字段:Name和Value。例如需要确定一名销售员能获得多少奖金,我们先要查找Name字段为BonusSales的记录,检查该销售员的销售额是否达到了Value字段的金额,若答案是肯定的再查找Name字段为BonusAward的记录来确定奖金数额。这种设计另有一好处,在程序启动时可以把通用参数表读入内存的某集合中,此后使用参数值时就无需再次连接数据库。

3. 若逻辑或计算规则很复杂时,则提取到代码中进行实现。这里说的代码可以是应用程序端代码,还可以是数据库端存储过程。把规则放到代码中实现的意义在于业务规则与数据库表结构分离了,规则的变化不会影响到数据库表结构。通过结构化编程或面向对象编程来实现复杂的规则更易于维护。

举一个综合性的例子:

一本关于数据库设计的书籍卖出前5000本的版税为5%,5000本至10000本之间的版税为7%,超过10000本后的版税为10%,不同类型书籍的版税可能不同。

上述规则比较复杂且包含多个可能变化的参数,故使用第1、2条方法。我们可以通过存储过程来实现该规则,并把参数隔离到一张参数表中进行维护。创建的参数表为RoyaltyRates,并通过BookId与Books关联(如图1所示)。这样为不同书籍创建新的版税规则就非常容易了。

image

图1 参数表RoyaltyRates与Books表的关系
推荐阅读
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • 本文是一位90后程序员分享的职业发展经验,从年薪3w到30w的薪资增长过程。文章回顾了自己的青春时光,包括与朋友一起玩DOTA的回忆,并附上了一段纪念DOTA青春的视频链接。作者还提到了一些与程序员相关的名词和团队,如Pis、蛛丝马迹、B神、LGD、EHOME等。通过分享自己的经验,作者希望能够给其他程序员提供一些职业发展的思路和启示。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
author-avatar
一个不起眼的小人物
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有