从数据库管理系统的开放层面来讲,数据库设计的key point就是妥协。一个设计的比较好的数据库都是在业务逻辑、设计规约和便于开发这三者之前来回考量,从而获得3-win的结果。下面主要是在思考和总结的点。

如何设计出高灵活性的数据库

  可以说在项目交付前,需求不断在变,如何在需求改变的同时尽可能减少对表结构的修改是我现在考虑的问题。对于一般情况而言,在设计的时候我们可以适当添加一些预留的字段,需求改变的时候可以用上,或者说是添加不足的字段。

  但是也会出现一些比较麻烦的情况——旧表不足以进行修改维护,需要局部重新设计,这就会给开发带来比较多的麻烦,因为大多现在我们都会使用ORM。

eg1:

  在贷款的业务流程中,每一笔借款申请需要进行审核。起初,参与的审核角色只有2名,所以我选择了,直接添加字段到贷款申请表中。

  之后,参与审核的角色数变多,并且审核产生的业务参数变多(例如各类附件、意见等),直接添加字段到贷款表中显得不那么合理,同时不利于审核流程的体现。因此,这一部分需要单独重新设计,根据业务流的需要,将审核的事件单独拉出来一张表,通过外键关联到申请表中。(流程复复杂可参考工作流引擎的设计思路)

  这个案例里,最初的设计,觉得既然审核人数少,直接把审核信息添加到申请表中即可,不需要单独建表,也方便了开发,但是后来的需求改变就有单措手不及了。

  这里就感觉很矛盾,同时也发现数据库的设计居然也和软件工程那一套理论惊人的相似。在软件工程里面,我们经常会听到一句话“低耦合、高内聚”,一般是提醒我们,尽可能保证模块与模块之间相互独立,减少不必要的依赖关系。

  这也就是最令人困扰的地方,如果一开始设计就考虑单一职责,分成两张表,未免显得有些复杂化了,也不利于开发(需要维护1-n的关系)。毕竟代码一定程度上是可以重构的。

数据库原理在实际设计中的应用

  我们在《数据库原理与设计》中学过很多的概念,由于实验环境的限制(数据量小、课设的业务偏简单etc.),导致很多概念在那时真的就变成了一个死记硬背的概念。这点或许随着开发经验的增长会豁然开朗吧。下面介绍几个,替他们刷一下存在感,内容都很浅,但也希望对在学习数据库的有一点帮助吧。

范式(NF)

1NF的定义为:符合1NF的关系中的每个属性都不可再分
2NF在1NF的基础之上,消除了非主属性对于码的部分函数依赖。
3NF在2NF的基础之上,消除了非主属性对于码的传递函数依赖。

范式的概念大家肯定背的很熟,面试也经常会考这个。这一点其实大家在按设计数据库的时候都已经用上了。明确实体间的关系,画E-R图,其实就是对范式的运用。

索引(Index)

Index,面试的时候也经常会问到,但是呢学他的时候基本上感觉不到他的存在,毕竟测试的数据集太小了。底层的原理牵扯到数据结构,这里就不展开了。但是需要知道的是:

  • 需要做表连接的字段,需要添加index。

  • 经常需要查询的字段,需要添加index。

  • 很多字段需要联查的时候,需要添加组合查询。

下面是一个实际项目中的例子,可以感受下:

  有一个地方需要数据展示,需要多表联查。下面就是建索引和不建索引的区别了。

事务(Transaction)

  数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。

  事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

  这个写过管理系统的应该都明白。大概就是下面这个模型。JDBC中就有,在ssh或ssm中可以配合注解或配置文件来实现。

BeginTransaction{// to-do
    commit
}catch{rollback
}

  一般在多表操作时必须使用事务!例如级联删除,多表修改。如果不使用,一旦出现异常,会导致数据不一致!

锁(lock)

  锁根据不同的法,可以分为乐观锁悲观锁。也可以分为共享锁排它锁。一般在出现并发问题的时候会用到锁,解决小规模并发下单问题。

冗余字段的应用

冗余字段的利用,其实仅仅是为了开发方便的一个tip。

  具体可以看上面一个小例子。一笔借款需要经过很多人的审核才能通过。因此存在借款表和审核流程表,两者一对多。通过借款单号可以去审核表中查询其所有的审核情况。

  那么此时,我选择在借款表中存审核流程表id(外键)的同时,存下当前这一笔借款的审核信息。这么做的好处就是,我不需要去做表连接,直接可以查询到借款的当前进行到哪一流程,或者说申请失败,失败在哪一流程。从开发的角度,如果有一个页面需要显示出借款的当前流程,那就可以轻松查询到了。

  毕竟,处理表连接操作是相对麻烦的,同时效率并不高。因此在存储条件允许的情况下,可以通过适当冗余来减少开发中的麻烦。这里就体现了数据库设计的一种妥协,现在存在冗余是违反了2-NF的,所以有的时候就需要凭经验来进行调整。对于不是频繁需要修改的字段,是可以适当冗余存取的,反之,经常需要修改的字段,如果冗余存取,一不小心很容易造成数据的不一致,就不建议了。

视图与冗余表

在谈冗余表前,先来看几个在Java OO中的概念,抛砖引玉一下。

VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。
DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。
DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。
PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。

  首先,这些对象其实是和数据库中数据表存在一些关系的。我想说的是,在数据展示或数据传输时,可能会涉及多张表,这个时候我们会做的就是创建一个新的Object,然后讲多张表对应的持久化对象放进去,或者直接从多个表的持久化对象中抽取需要的字段。这个对象也就是上面提到的VO和DTO了。

  这种做法同时也可以在数据库进行实现,那就是冗余表。其实也就是把很多张表的数据统一到一张表中去,为的也是查询和更新的方便。

之前遇到以下这个业务:

  存在订单、订单明细之前一对多,订单又需要和卡绑定,一对多。现在我需要将数据一起显示出来看,同时粒度要最细,以订单明细和卡号的形式显示出来,t同时可更新。

eg:有订单记录A ,订单明细B1、B2,绑定了两张卡C1、C2,那么显示效果如下

C1 A B1
C1 A B2
C2 A B1
C2 A B2

  这个时候考虑到如果创建一个DTO来保存这些数据的话,在查询组装上需要花很多的时间,于是就直接创建了一张冗余表,用于维护这层关系。那么通过这层冗余表查询出来的结果就是可以直接用于显示的,更新的时候也只需要直接找到外键进行更新就可以了。

  我觉得使用DTO还是冗余表,完全就是取决于开发上的的便利以及是否需要对数据进行持久化了。

  同样的,之前的例子提到是需要对数据进行更新或删除的,如果仅仅是为了数据的展示,例如一些统计数据的展示。那么就不需要冗余表了。数据库里面有个专有的概念——视图。比如说查询每天每年每季度的销售情况等等,直接用sql创建视图,查询以天为单位的结果,展示的时候直接从view中取数据即可,将复杂的sql语句就留在数据库那边了。

  当然创建视图若使用大量表连接时,记得创建index进行优化,否则查询效率会很低。

数据字典与代码表

  数据字典与代码表其实存储的就是一些常量了。

  数据字典一般两张表,一张存类别,一张存键值对。数据字典一般用于存取一些不太会变的数据,例如性别、订单状态etc。而且这些数据量比较小,可以统一存储。

  代码表,一般都是各管各存储的。例如文章分类表、标签表、省市区代码、商品分类etc。这些本来数据就大,并且有一定的业务性,有些会随着业务的扩大而变动,因此单独存表会比较好。

总结

本篇文章主要写了一些数据库中的一些概念在实际应用上的体现。表达了最近一段时间对数据库设计上面的一些思考和见解。人是会思想的芦苇,实践是检验真理的唯一标准,共勉。

    

原文参考【https://www.javazhiyin.com/20295.html】

转载于:https://www.cnblogs.com/Kevin-ZhangCG/p/10270996.html

浅析实际项目中对数据库设计的一些思考相关推荐

  1. 谈谈实际项目中对 数据库设计 的一些思考

    注:本人开发经验尚浅,下文主要谈的是自己的一些想法,不足之处请指出. 最近半年时间都花在管理系统的开放上面,对数据库的设计有一些自己的想法,在我看来数据库设计的key point就是妥协.一个设计的比 ...

  2. 项目小结之数据库设计

    最近做了一个小项目完整的数据库设计,想总结一些设计上的所得,希望大家多多指教. 有时一个项目,普通程序员一般不会去接触数据库设计,一般都有专业的DBA或是老程序员去设计,下面是我推测的几点可能原因: ...

  3. 项目开发周期与数据库设计对比

    项目开发周期与数据库设计对比 项目开发周期 数据库设计 需求分析 分析客户的业务和数据处理需求. 1.         收集信息(不怕多,但怕漏): 2.         标识对象: 3.       ...

  4. 团队作业第五次—项目系统设计与数据库设计

    作业描述 所属课程 软件工程1916|W(福州大学) 作业要求 团队作业第五次-项目系统设计与数据库设计 团队名称 待就业六人组 作业目标 宏观的对系统的整体结构设计,并在此基础上,进行数据库设计 系 ...

  5. XamarinSQLite教程在Xamarin.Android项目中提取数据库文件

    XamarinSQLite教程在Xamarin.Android项目中提取数据库文件 由于不能直接打开该文件,开发者需要先将数据库文件从Android系统中提取出来.操作步骤如下. (5)选择MyDoc ...

  6. XamarinSQLite教程在Xamarin.Android项目中定位数据库文件

    XamarinSQLite教程在Xamarin.Android项目中定位数据库文件 实际开发中,经常需要验证数据库操作的正确性.这个时候,需要打开数据库文件,进行确认.下面是如何找到MyDocumen ...

  7. XamarinSQLite教程在Xamarin.Android项目中使用数据库

    XamarinSQLite教程在Xamarin.Android项目中使用数据库 在Xamarin.Android项目中使用预设数据库的具体操作步骤如下: (1)创建一个Xamarin.Android项 ...

  8. XamarinSQLite教程Xamarin.iOS项目中打开数据库文件

    XamarinSQLite教程Xamarin.iOS项目中打开数据库文件 以下是打开MyDocuments.db数据库的具体操作步骤: (1)将Mac电脑上的MyDocuments.db数据库移动到W ...

  9. XamarinSQLite教程在Xamarin.iOS项目中定位数据库文件

    XamarinSQLite教程在Xamarin.iOS项目中定位数据库文件 开发者可以在指定的路径中找到复制的数据库文件,具体的操作步骤如下: (1)单击Mac电脑中Finder菜单中的"前 ...

最新文章

  1. 各大厂分布式链路跟踪系统架构对比
  2. 用价值锚定革掉股市的命!
  3. matlab选择激发波长,【求助】怎么确定一个物质的激发波长和发射波长?
  4. 输出超限怎么解决 oj_三菱PLC输出指示灯输出模块不亮怎么解决
  5. mysql find()方法_Mysql find_in_set()函数使用方法
  6. 手机端html表格,jQuery Mobile 表格
  7. Oracle E-Business Suite 12.1.1 Rapid Clone
  8. leetcode 838. Push Dominoes | 838. 推多米诺(分析每个状态)
  9. OpenShift 4 - 查看Node上的日志
  10. 串口类QextSerialPort
  11. 5G对于数据中心的影响有哪些
  12. My前端bootstrap(一)
  13. NET 连接池救生员
  14. gms认证流程_Android P(9.0)GMS认证新要求
  15. python股票量化交易系统源码_经典的股票量化交易策略(含源码)
  16. 易经读书笔记16 雷地豫
  17. 手机网页版JS压缩上传图片--base64位 兼容IOS和安卓
  18. Pikachu靶场全关详细教学(一)
  19. unity Inspector
  20. MySQL远程连接报错:ERROR 2002 (HY000): Can‘t connect to server on ‘192.168.172.130‘ (115)

热门文章

  1. crc16的c语言函数 计算ccitt_CCITT CRC-16计算原理与实现
  2. js轮播图案例(个人总结向-参考黑马pink老师教程
  3. web测试工程师的工作职责(合集)
  4. 5个设计类宝藏网站分享
  5. 写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B....5152Z
  6. CentOS下安装docker
  7. 概览与建造者builder(创建型 一)
  8. 根据模板导出word,复合格式表格生成、可变列表格生成
  9. (二十二)岁月无声 - 8
  10. android系统设置无障碍,RK3326 Android 8.1 为自己的APK的服务默认开启无障碍权限,避免使用时还是有一个小跳转:设置的无障碍选项...