sqlite 跟踪每一次财产变动

8cdiaqws  于 2023-05-07  发布在  SQLite
关注(0)|答案(1)|浏览(117)

我是一名来自德国的计算机科学专业的学生,我在一家小型IT初创公司工作。我被分配了一个具有挑战性要求的项目。客户需要一个人力资源管理工具,其中包括工作计划器、假期计划器、工资管理器等。挑战在于客户希望跟踪整个系统中的每个属性更改,并且每个属性都需要一个“validFrom”属性。此外,某些属性还需要“validUntil”属性。
最终目标是能够查看给定时间点的系统状态,并且还能够补充更改或添加将来的更改。这意味着我们需要实现一个跟踪每个属性更改的系统,并允许我们在任何给定的时间点访问系统状态。
该项目是一个winforms应用程序与c#和一个sqlite数据库与可选的实体框架层。
一个基本的例子:系统中有用户:

class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Password { get; set; }
    public ICollection<Permission> Permissions { get; set; }
}

为了能够跟踪“名称”,“密码”和“权限”的更改,我们为每个人都有一个单独的数据库表:

class UserNameRecord
{
    public int Id { get; set; }
    public int UserId { get; set; } 
    public string Name { get; set; }
    public DateTime ValidFrom { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime DeletedAt { get; set; }
}

对于收藏,比如:

class UserPermissionsRecord
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public CollectionAction Action { get; set; } // added or removed
    public Permission Permission { get; set; }
    public DateTime ValidFrom { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime DeletedAt { get; set; }
}

问题是我们有200多张table,而且数量还在不断增加。获取视图的数据非常复杂,并且需要大量的时间。此外,验证约束是一场噩梦。
我想解决这个问题,因为它给我带来了严重的减速,我需要一些关于如何做得更好的建议。

8e2ybdfx

8e2ybdfx1#

你需要问这个问题,如果你需要能够在数据库级别上完成所有这些。
如果您遵循规范化所有数据的方法,那么您最终将得到一堆令人费解的表格。
如果不对某些内容进行规范化,最终将得到更少表,但会增加数据冗余。当然,这不是你想要的,但它通常是你可以忍受的。
因此,就用户对象而言,您可以持久化整个实体(在一个表中包含名称和密码),并将其视为某个时间点的快照。为了审计跟踪的目的,以某种序列化的格式为每个这样的实体添加一列,记录与该记录的先前版本相比发生了什么变化。这样您就可以相当快地提取整个更改历史
就项目管理三角形而言,这一个又便宜又快。但是它缺乏在不影响其余属性的情况下精确更改一个属性的能力,一旦您有一个历史记录并希望将另一个更改插入到现有历史记录中,这将成为一个缺陷
就项目管理三角而言,前面的建议牺牲了“好”……如果我们想保持这一点,我们要么牺牲“快”,要么牺牲“便宜”
如果你不能接受这样的方法,另一个建议是通过标记需要在单独的表中维护的属性,基于更高级别的对象生成实体类。
TLDR --〉使用自动代码生成,例如T4
把你的业务对象放到一个单独的程序集中。
创建一些属性来标记这些属性的属性(同一程序集中的属性类)
查看属性,您会注意到可以提取所有这些额外属性表的共同点。不是所有的看起来都一样,但是你可以把它们分成不同的(或者不那么不同的)组,分享相同的“治疗”...因为找不到更好的词
(if你最终得到的不是那么明显的群体,比如每个属性可能有多个治疗方法,那么它不是关于属性得到哪种治疗方法,而是哪种组合)
在这种情况下,您需要创建的属性需要获取此类属性的所有信息,以便将其放入处理类(具有ValidFrom、CreatedAt、DeletedAt;有validUntil;等)
将所有这些放在单独的程序集中的原因是,您可以独立地构建该程序集,并在主项目的构建时使用它来分析这些类。
根据需要创建T4模板,以便在构建时根据属性自动生成实体类
通过这种方式,您可以实现每个“处理”类(在存储方面如何处理某些属性)
找到并实施每一种“治疗”并将其推广是这里的关键
一旦你有了实体,用T4生成create table语句是一样的,但语法不同。
同样,将这些实体重新组合为业务对象或将业务对象拆分为这些实体是一个可推广的过程,T4可以帮助您创建特定于域的代码,以相同的方式完成此操作。
如果你沿着这条路走下去,你就在“处理”类级别上解决问题,一旦你需要一个新的属性或业务对象类,一旦你编写了业务对象类并将属性放入,T4就会生成相应的实体和表。所以这一个解决了问题,在中期或长期的抽象处理的性质
对关系的分析和相应的财产“处理”是这里的大未知数。这可能是一个手满,你做了...要么就是一个接一个的特殊情况

相关问题