尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

大部分管理信息系统(MIS)都少不了员工

大部分管理信息系统(MIS)都少不了员工
📅 发布时间:2026/7/6 2:56:05

当为员工创建帐号并分配相应的权限后,该帐号即可登录系统并进行相应的操作。当员工与系统进行交互操作时,系统会把员工Id、操作时间、操作IP、操作内容等信息记录到操作日志中,以便随时审计。
这样,从Domain的角度讲,操作日志对象与员工对象之间存在many-to-one的引用关系;从Database的角度讲,操作日志表的员工Id列是外键,其引用员工表的主键Id列。如果遵照数据库设计第二范式(2NF),那么操作日志表包含员工Id列(外键),但不包含员工姓名、员工帐号等冗余字段。这样,当查询操作日志获取操作信息的同时,要想获取员工姓名、员工帐号等数据,需要对操作日志表与员工表在员工Id列上进行一个连接(inner join或outer join)操作。这是一个大家比较熟悉的应用连接操作的场景,但在实际项目中可能会变得稍微复杂一点,比如对员工数据的删除。
大家都知道,如果操作日志与员工之间建立了关联(外键引用)关系,那么在未删除该员工所有的操作日志数据之前,删除该员工数据会发生外键冲突 (foreign key violate),因为在删除员工数据时,数据库会自动检测并确保外键引用的完整性(referential integrity)。解决方法有四个:
(1)在物理删除员工数据之前先删除该员工的所有操作日志数据,然后再删除该员工数据;或者在数据库中设置级联删除,在物理删除员工数据时级联删除该员工的所有操作日志数据。尽管这样可以避免外键冲突,但是这个方法显然是不可行的,因为删除操作日志数据也就意味着破坏了审计功能。
(2)不物理删除员工数据,而是进行“软删除”(soft-delete),也就是说,为员工数据增加一个“是否删除”的标记列,当“删除”员工时设置此标记值。由于没有真正删除员工数据,也就避免了外键冲突问题。这可能是最常见的做法,但是soft-delete也不是没有问题,尤其是使用NHibernate进行面向DDD(Domain Model Development)的开发。大家可以看看这几篇文章:Avoid Soft Deletes(文章后面的评论也精彩)、Soft Deletes aren’t Append Only model、Don’t Delete – Just Don’t、Soft-deletes are bad, m'kay?。
(3) 操作日志与员工之间不建立关联(外键引用)关系,在数据库中仍可通过对操作日志表和员工表在员工Id列上进行连接,在一条查询语句中获取两张表的数据。由于没有建立关联(外键引用)关系,所以员工数据的物理删除不会 引起外键冲突问题。但是这个方法会引发别的问题:当员工数据被物理删除后,该员工的操作日志数据与该员工进行连接查询时,如果进行的是inner join,那么连接查询结果就为空;如果进行的是left outer join,那么在连接查询结果数据行中,关于该员工的字段信息(员工姓名、员工帐号)都为null(具体可参见outer join的相关资料)。
(4) 操作日志与员工之间不建立关联(外键引用)关系,并且在操作日志表中除包含员工Id字段外,还包含员工姓名、员工帐号等冗余字段,这样直接查询操作日志表即可获得员工姓名、员工帐号等信息,无需再与员工表进行任何连接操作(因此还可提高查询性能),同时员工数据的删除也不影响操作日志表,但是此方法违反了数据库设计的2NF。在实际开发中为了性能的提高、为了实现的简单性,有时出现类似这样的反模式是可以接受的,应该不是问题,问题是有冗余就一定会存在数据一致性问题:比如,当修改员工姓名后,操作日志表中该员工的操作日志数据的员工姓名冗余字段是否也需要同步更新呢?在这种情况下,对操作日志等历史数据进行同步更新往往没有必要,因为修改员工姓名这类操作不会经常发生,而且不同步更新正好还可以保留操作员工当时时刻的姓名。
由上面的分析可见,为实现员工操作的审计功能、确保员工数据的“删除”不引发外键冲突,方法(2)与方法(4)应该是较为可行的方案。当然有的朋友会认为员工数据不该“删除”,而应该通过设立一个表示"禁用"、"启用"的状态字段来解决,当然这与方法(2)在本质上是类似的。
说了这么多关于数据库设计的内容,不少朋友会怀疑本文是否偏离了该说的主题NHibernate,接下来就进入主题,我们选择方法(3)做为本文说明的实例。方法(3)的关键是:在操作日志与员工之间不建立关联(外键引用)关系,然后在员工Id列上进行连接操作。那么在NHibernate中如何对没有建立关联关系的实体进行连接操作呢?答案是使用theta-style join。本文首先介绍theta-style join与常见join的区别,然后通过此实例具体阐述在NHibernate中对无关联实体进行theta-style join的实现。

二、实例场景
有员工(Employee)和操作日志(OperationLog)两张数据表,为说明问题,这两张表之间不建立外键引用关系。创建数据表的SQL如下:

Code

接着往数据表中插入测试数据,如下图所示:



三、常见join与theta-style join的差别
我们对没有建立外键引用关系的Employee表和OperationLog表,分别进行常见join和theta-style join的连接操作,两者SQL写法的区别如下:
(1)常见join的SQL写法(在inner join中指定要连接的表,在on中指定连接条件。SQL92标准):

select OperationLog.Id, OperationLog.OperationDateTime, Employee.Name
from OperationLog inner join Employee
on OperationLog.EmployeeId=Employee.Id

(2)theta-style join的SQL写法(在from中指定要连接的表,在where中指定连接条件。SQL89标准):

select OperationLog.Id, OperationLog.OperationDateTime, Employee.Name
from OperationLog, Employee
where OperationLog.EmployeeId=Employee.Id

在关系数据库中,尽管没有为Employee表和OperationLog表建立外键引用关系,但是仍然可以用SQL在任意列(只要类型兼容)上进行常见join或theta-style join的操作(当然,是否在外键列上进行连接操作会影响到数据库查询优化器对连接操作算法的选择,从而影响连接查询的性能),而且对于上面这个例子,这两个连接操作逻辑上是等价的,查询结果是相同的,连接查询结果如下图所示:


但在NHibernate中,对无关联实体进行连接操作,只能使用theta-style join而无法使用常见join,而且仅HQL支持theta-style join,Criteria并不支持theta-style join。接下去通过实例进行验证:

四、使用HQL的theta-style join实现无关联实体的连接
先分别建立Employee与OperationLog实体类(注意:两个实体类没有建立关联关系):
Employee.cs:

namespace NHibernatePractice3.Domain
{
public class Employee
{
public virtual int Id { get; set; }
public virtual String Name { get; set; }
}
}

OperationLog.cs:

Code


接着创建mapping文件(注意:在mapping文件中不建立关联关系):
Employee.hbm.xml:

Code

OperationLog.hbm.xml:

Code


接下去写测试方法,测试theta-style join的实现:

相关新闻

  • Agent Memory最新综述:长上下文和RAG之后,还缺什么?
  • 昆仑芯的“第三条路”
  • Week7:卷积神经网络、深度网络原理与循环神经网络专题

最新新闻

  • 【学习记录】Week14(二):沙箱机制深度剖析与进阶 ORW 绕过体系
  • 湿地生态好不好,不能只看绿不绿
  • 从零学习Kafka:调优
  • Node.js-Phase 1 学习总结:CLI 文件管理系统
  • 3分钟极速指南:用Python工具一键获取国家中小学智慧教育平台电子课本
  • Educator头歌答案分享:数据预处理与特征工程在线实验闯关

日新闻

  • AI智能体安全防护框架AgentGuard:从原理到实战部署指南
  • KMX63与PIC18F26K40硬件组合及低功耗设计实践
  • 基于YOLO13改进的门体检测模型:C3k2模块与PoolingFormer技术解析

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号