云星空的“主键外键”原创
金蝶云社区-山抹微云
山抹微云
31人赞赏了该文章 2,602次浏览 未经作者许可,禁止转载编辑于2019年12月19日 16:10:53
summary-icon摘要由AI智能服务提供

本文介绍了企业管理系统中关系型数据库的应用,特别是云星空如何利用MSSQL和ORACLE数据库。关系型数据库通过主键和外键约束实现数据之间的关联,云星空则在服务层上实现外键规则和业务逻辑,以解决性能瓶颈和代码耦合度问题。文章还讨论了将业务逻辑放在数据库或服务层的优缺点,并指出云星空通过将业务逻辑放在服务器插件中,实现了更高效的开发和数据管理。


      企业管理系统很强调数据的准确性,关系型数据库可以满足其需求。那云星空后台数据,库也是关系型数据库(即MSSQL跟ORACLE),云星空是如何利用这些数据库的呢。

      关系型数据库,有主关键字(主键)的概念。主关键字 (primary key)是表中的一个或多个字段,它的值用于唯一标识表中的某一条记录。可以把身份证作为个人信息中的主键,能唯一标识到具体的记录具体的人,可以把公司的工号作为是职工信息表的主键,可以唯一标识到具体的记录具体的人。一个或多个属性组成了对象,多个对象组成了对象组,能够在对象组中唯一标识到具体对象的一个或多个属性就是主键了。

      在关系数据库中,关系之间的联系是通过相容或相同的属性或属性组来表示的。如果两个关系中具有相容或相同的属性或属性组,那么这个属性或属性组呗称为两个关系的公共关键字。公共关键字是用来论述两个表的关系,即如果属性或属性组c是表A的主键组其中一部分或全部,属性或属性组c也是表B的主键组其中一部分或全部,那我们说属性或属性组c是表A与表B的公共关键字。

      如果公共关键字在一个关系中是主关键字,那个这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的联系,以另一个关系的外键作主关键字的表被称为主表,具有外键的表被称为主表的从表。外键也被称为外关键字。这个解释有点文绉绉。通俗地说,属性或属性组c是表A的主键,然后c是表B主键的一部分,那就是一行表A对应表B的多行(因为表B主键还有其他属性)。往深想一点,是不是与云星空的单据头、单据体类似。单据头跟单据体分别是两张表,一条单据头记录可以对应多条单据体的记录,似乎有异曲同工之妙。单据头可以由单据编号作为关键字,单据体可以由单据编号跟序号作为关键字(公共关键字是单据编号),那单据头是主表,单锯体时细表。这主从表关系,也被称为主从表与主细表,或者主表与细表,在台湾也称为“主细档”。

       关系型数据库的主细表可以提供外键约束,即必须先修改或删除细表中的所有关联数据,才能修改和删除主表。举例来说,发票没有抬头就不会有发票明细(即不允许存在没有发票抬头的发票明细)。那数据库要保证这点,只要在删除(或修改)发票明细后才能删除发票头。关系型数据库是原生支持外键约束的,也是关系型数据的核心竞争力之一。

       外键约束是关系型数据库上的概念,也是一种规则。在本文中,我推广外键约束的概念,称为外键规则。即不通过数据库的设置,而使得软件具有类似于外键约束的特性,称为软件满足外键规则。外键规则也是现实要求的业务逻辑之一,那云星空是在哪里存放业务逻辑呢??----在服务层上。那我们的外键规则是在服务层上实现的,而不是数据库上实现的。这话的意思的,用户通过前端操作是可以满足外键规则的,如果直接操作数据库是没有外键约束的。有时候同样的SQL查询语句,用客户端导出来的EXCEL合计数值,与用SQL在后台查的合计数值不一致,后台查的合计数值会更加多,这就有可能是因为存在着没有对应主表记录的细表,我曾经入过这种坑,删除该部分的细表语句是一个方法,完善好SQL语句也是一个方法(要求细表的单据编号存在于主表的单据编号。)

       我为何兜兜转转说那么多,为何?在这个问题上,外键规则甚至整个业务逻辑的设置,有一种解决方案是设置在数据库,另一种是设置在逻辑层。我想分享下两者的区别之处。

       把业务逻辑设置在数据库,优点,一是在数据库层保证业务逻辑的完成比较可靠,二是直接操作数据库开发效率高。缺点,一是直接操作数据库不方便测试,二是数据库作为软件有一定的性能瓶颈,特别是客户端数量的快速增加(客户规模做大了),设备的投入解决不了性能瓶颈,满足不了高并发。三是代码直接操作数据库,代码耦合度底,容易代码冗余,且开发团队不容易分工合作。把业务逻辑设置在服务器,优点,一是可以通过增加服务器数量较好解决性能问题(如客户端数量快速增加),数据库只是辅助数据读存。二是使用面向对象编程,有益于开发团队分工合作,可以人为提高代码耦合度。三是,方便测试。其缺点,一是开发代码量较大。二是开发人员直接操控数据库风险大,有可能破坏数据之间的业务逻辑。

       云星空的数据库,每张表的主键基本是一个字段是FID,这个不提供给前端用户,所以称为内码。在单据头中,其主键是字段FID,用户看到的单据编号(大部分字段名为FBillNo)不是数据库的主键,是业务逻辑上的主键。单锯体数据库也是主键FEntryID的,单据编号(大部分为FBillNo)与序号FSEQ不是数据库主键,而是业务逻辑上的主键。

      数据库设置了外键约束,必然要求细表有两个主键字,而主关键字不能为空。所以程序会在用户进行细表编辑之前保存主表以获得主表的主键,这样细表的外键才不会为空。如果用户在编辑细表时候想要放弃整单单据,那必须是通过删除按钮删除单据,这样就增加了不必要的主表关键字跳号的情景了。逻辑层设置了外键规则,能避免前述的情况,如云星空,细表主键只是一个字段,可以采用自增列,不依赖于主表的主键,可以在用户点击保存按钮是一起写入主表细表的数据,用户放弃单据时候只需要退出该模块即可。

     我之前的ERP虽然也是三层架构,是C/S,但是业务逻辑放在后台数据库了。重新学习了云星空,让我感受到世界的不一样。我发现云星空更加先进,仅用关系型数据库做数据的读存,业务逻辑是放在服务器的插件里,所以写了上述的心得与大家分享。

    感谢经常解答我问题的师傅、黄老板、肖老师以及这个充满活力的团队,谢谢。


赞 31