我正在设计这个数据库,该数据库必须保留员工薪资和组织内部动向的历史记录。基本上,我的设计有3个表(我的意思是,有更多的表,但对于这个问题,我会提到3,所以请耐心等待)。员工表(包含最新的薪水,职位数据等),SalaryHistory表(薪水,日期,原因等)和MovementHistory(Title,Dept.,comments)。我将使用Linq to Sql,所以我想的是每次更新员工数据时,旧值将被复制到各自的历史表中。 这是一个好方法吗?我应该使用Linq to SQL还是触发器来执行此操作?感谢您提供任何帮助,建议或想法。
答案 0 :(得分:8)
查看http://www.simple-talk.com/sql/database-administration/database-design-a-point-in-time-architecture。
基本上,文章建议您在跟踪历史记录的表格中有以下列 -
* DateCreated – the actual date on which the given row was inserted.
* DateEffective – the date on which the given row became effective.
* DateEnd – the date on which the given row ceased to be effective.
* DateReplaced – the date on which the given row was replaced by another row.
* OperatorCode – the unique identifier of the person (or system) that created the row.
DateEffective和DateEnd一起告诉您行有效的时间(或员工在某个部门的时间,或者他获得特定薪水的时间)。
答案 1 :(得分:6)
将逻辑保留在数据库内部是一个好主意:这基本上就是触发器存在的原因。然而,我谨慎地说,因为有很多理由让它保持外部。通常情况下 - 特别是使用像LINQ-to-SQL这样简单的技术 - 从外部编写代码更容易。根据我的经验,更多人可以在C#/ LINQ中编写逻辑,而不是使用触发器正确地编写逻辑。
触发器很快 - 它们被编译了!但是,它们很容易被误用,并使您的逻辑过于复杂,以至于性能可能会迅速降低。考虑到你的用例有多简单,我会选择使用触发器,但那是我个人的。
答案 2 :(得分:2)
触发器可能会更快,并且不需要“中间人”来完成工作,从而消除至少一次错误的机会。
根据您选择的数据库,您只需使用一个表并在其上启用OID,然后再添加两个列“flag”和“previous”。永远不要更新此表,只插入。添加一个触发器,以便在为员工#id添加一行时,将员工#id的所有记录设置为标记为“old”,并将新行“previous”值设置为上一行。
答案 3 :(得分:2)
我认为这属于数据库有两个原因。
首先,中间层来去,但数据库是永恒的。今年Java EJB,明年.NET,那之后的那一年。根据我的经验,数据仍然存在。
其次,如果数据库完全共享,则不必依赖于使用它的每个应用程序来了解如何维护其数据完整性。我认为这是封装数据库的一个例子。为什么要强迫每个客户了解和维护历史?
答案 4 :(得分:1)
触发器使您的前端更容易迁移到其他内容,无论数据如何插入/更新/删除,它们都将保持数据库的一致性。
除了你的情况,我会将工资直接写入工资历史 - 根据你的描述,我不会看到你应该通过员工表上的更新触发器去的方式。