C# 版本控制算法
我有一个存储对象的数据库。我有下面的简化模式C# 版本控制算法,c#,sql,algorithm,C#,Sql,Algorithm,我有一个存储对象的数据库。我有下面的简化模式 CREATE TABLE MyObjects ( UniqueIdentifier Id; BigInt GenerationId; BigInt Value; Bit DeleteAction; ) 每个对象都有一个唯一的标识符Id和一组属性值。每次更改对象的属性值时,我都会使用新的GenerationId GenerationId在该表中输入一个新行,该id是单调
CREATE TABLE MyObjects
(
UniqueIdentifier Id;
BigInt GenerationId;
BigInt Value;
Bit DeleteAction;
)
每个对象都有一个唯一的标识符Id和一组属性值。每次更改对象的属性值时,我都会使用新的GenerationId GenerationId在该表中输入一个新行,该id是单调递增的。如果删除了一个对象,那么我通过将DeleteAction位设置为true来记录这一事实
在生成的任何时间点,我都希望检索所有活动对象的状态
下面是一个例子:
Id GenerationId Value DeleteAction
1 1 99 false
2 1 88 false
1 2 77 false
2 3 88 true
世代中的对象包括:
1: 1 {99}, 2 {88}
2: 1 {77}, 2 {88}
3: 1 {77}
关键是:我如何找出每个唯一对象的行,谁的生成id最接近但不超过给定的生成id?然后,我可以执行后期筛选步骤,删除DeleteAction字段为true的所有行。不确定这是否是标准SQL,但在Postgres中,可以使用LIMIT标志:
select GenerationId,Value,DeleteAction from MyObjects
where Id=1 and GenerationId < 3
order by GenerationId
limit 1;
这适用于MS SQL
SELECT id,value
FROM Myobjects
INNER JOIN (
SELECT id, max(GenerationID) as LastGen
FROM MyObjects
WHERE GenerationID <= @Wantedgeneration
Group by ID)
On GenerationID = LastGen
WHERE DelectedAction = false
我的版本使用表MyObject的关节与 自身的子集,由子查询创建,仅包含最后一个 为每个对象生成:
SELECT O.id,generation,value FROM
MyObjects O,
(SELECT id,max(generation) AS max_generation FROM MyObjects
WHERE generation <= $GENERATION_ID GROUP BY id) AS TheMax WHERE
TheMax.max_generation = generation AND O.deleted is False
ORDER BY generation DESC;
我得到:
> SELECT * FROM generation_objects(1) ORDER by generation DESC;
id | generation | value | deleted
----+------------+-------+---------
1 | 1 | 99 | f
> SELECT * FROM generation_objects(2) ORDER by generation DESC;
id | generation | value | deleted
----+------------+-------+---------
2 | 2 | 88 | f
1 | 1 | 99 | f
> SELECT * FROM generation_objects(3) ORDER by generation DESC;
id | generation | value | deleted
----+------------+-------+---------
1 | 3 | 77 | f
2 | 2 | 88 | f
然后,在下一代中,删除对象2:
> SELECT * FROM generation_objects(4) ORDER by generation DESC;
id | generation | value | deleted
----+------------+-------+---------
1 | 3 | 77 | f
以下是工作版本:
SELECT MyObjects.Id,Value
FROM Myobjects
INNER JOIN
(
SELECT Id, max(GenerationId) as LastGen
FROM MyObjects
WHERE GenerationId <= @TargetGeneration
Group by Id
) T1
ON MyObjects.Id = T1.Id AND MyObjects.GenerationId = LastGen
WHERE DeleteAction = 'False'
我不会在示例中关注您的对象。你能澄清一下吗?在这个例子中有一个输入错误,似乎GenerationID1被使用了两次。不,重点是要表明对象1和2都是在同一个Generation1中添加的。源代码管理的一个例子是在一个变更集中添加2个文件,其中生成是变更集编号。问题的关键不是必须指定Id=1,而是返回所有符合生成要求的Id。是的,应该这样做。至少这是一个很好的起点+1.
> SELECT * FROM generation_objects(4) ORDER by generation DESC;
id | generation | value | deleted
----+------------+-------+---------
1 | 3 | 77 | f
SELECT MyObjects.Id,Value
FROM Myobjects
INNER JOIN
(
SELECT Id, max(GenerationId) as LastGen
FROM MyObjects
WHERE GenerationId <= @TargetGeneration
Group by Id
) T1
ON MyObjects.Id = T1.Id AND MyObjects.GenerationId = LastGen
WHERE DeleteAction = 'False'