【问题标题】:Handling Version number - versioning处理版本号 - 版本控制
【发布时间】:2014-12-09 00:20:38
【问题描述】:

我正在处理我的程序与一些记录的数据文件之间的接口。我的程序将加载数据文件并将其存储到数据库中。在记录的数据文件中,它的格式结构包含其他程序(生成该文件)的不同版本号

处理版本号的最佳方法是什么?

Major_Minor_Build_Revision

12.03.04.142

我将在我的程序中使用稍后加载指定版本(例如 2.03.04.142)的所有数据

编程

在 Delphi 中,我们可以创建一条记录并处理版本号:

TVersion = Record
   Major : integer;
   Minor : integer;
   Build : integer;
   Revision : integer;
end;

或者将它转换为整数并存储它会更好吗?如果这是进行转换的最佳方法是什么?

数据库

在 SQL 数据库中也是一样,我们可以将 [Major]、[Minor]、[Build]、[Revision] 的每一列创建为整数来存储它。

或者如果我们使用版本转换,我们可以在 SQL [Version] 中只使用一列。

哪一种是最好的使用方法?或者有没有更好的处理方法?

提前致谢。

【问题讨论】:

  • 你问的是什么版本号? IDE 已经为您的项目处理了您的版本号,并且 Windows 知道 GetVersionInfo 中内置的主要/次要/构建/修订版本。大多数现代软件项目使用相同的版本号定义。为什么你需要一个 Delphi 记录来存储 IDE 已经存储在你的可执行文件中并且 WinAPI 已经检索的内容?如何将它存储在您的数据库中显然是只有您可以决定的事情,因为您是更新和检索它的人。你打算如何使用它?
  • @sMah 。 . .存储数据的最佳方式取决于数据的使用方式。您能否通过一些有关如何使用版本号的示例来编辑您的问题?
  • 你用的是什么数据库?
  • Microsoft SQL Server - 关系型数据库
  • 从您的使用场景来看,您仍然不清楚您希望我们替代哪个来倡导:-) 您是否打算确定 eq. 之间的关系? 1.22.1?然后将版本打包为数字类型,例如 pastebin.com/z3Jmk35M 。顺便说一句,签名版本的组件让我很高兴。

标签: sql sql-server delphi versioning


【解决方案1】:

SQL Server 对解析字符串的内置支持很糟糕。因此,我不鼓励您将版本 only 存储为句点分隔的字符串。如果这样做,您可能会广泛使用PARSENAME() 函数。然后,有一天,如果你的版本有第五个或第六个元素,那就什么都行不通了。

所以,这里有一些替代方案:

  • 为版本创建参考表。这将具有与 Delphi 版本控制相同的结构,以及关于它应该在输出和身份主键上的外观的附加字段。其他表中的版本将引用此表中的值。

  • 将版本的四个部分分别存储在自己的列中,并使用用户定义的函数或计算列来操作版本。

  • 为版本创建您自己的用户定义类型。

我倾向于选择前两个选项之一。

【讨论】:

    【解决方案2】:

    我个人会使用转换将此版本号存储在单个整数中。

    我会按照您的建议使用记录。但是我不会将每个版本字段存储在整数本身中,而是使用字节。

    TVersion = Record
       Major : Byte;
       Minor : Byte;
       Build : Byte;
       Revision : Byte;
    end;
    

    为什么使用字节字段而不是整数?因为这为您提供了一种生成单个 Integer 来存储整个版本号的绝佳方式。现在,由于一个 Byte 等于 8 位,您可以轻松地将四个 Byte 字段存储在一个 32 位整数中,其中第一个字段表示前 8 位,第二个字段表示第二个 8 位,依此类推。

    现在这确实在某种程度上限制了您,因此每个版本字段只能包含 0 到 255 之间的数字,但我认为这已经绰绰有余了。如果不是,您可以将这些 Byte 字段(8 位整数)替换为 SmallInt 字段(16 位整数)并生成一个 64 位整数来存储版本信息,而不是我最初建议的 32 位整数。

    现在将版本号存储在单个整数中,它还可以更容易地确定哪个版本是特定版本。

    例如,假设您有一个使用版本为 1.52.45.75 的程序生成的文件,并且使用该程序生成的版本从 1.02.05.45 到 2.84.62.42 的所有文件都是以特定方式构建的(包含特定的字段等),并且您想使用特定的方法从中读取数据。

    如果您将版本号存储在四个单独的字段中,您可能会尝试使用类似于此的代码对这四个字段中的每一个进行范围检查:

    if (MayorVersion => 1) and (MayorVersion =< 2) then
      if (MinorVersion => 2) and (MinorVersion =< 84) then
        if (Build => 5) and (Build =< 62) then
          if (Revision => 45) and (Revision =< 42) then //This looks wrong doesn't it
          begin
            //Process the file in certain way
          end;
    

    现在,如果您仔细查看上面的代码,您会发现其中存在问题。那是什么问题?将以某种方式处理文件的最新程序的版本信息的修订部分小于将以某种方式处理文件的最旧程序的修订部分。

    现在,如果整个版本信息按照上面的建议存储在单个 Integer 中,您将不会遇到此问题,因为您现在将比较整个版本信息,而不是逐个比较单个版本信息字段。

    编辑:就将版本信息存储到数据库中而言。我还认为存储从多个版本字段生成的单个 Integer 更好,因为这样您可以通过一个简单的调用来检索整个版本信息。但它确实会阻止您按特定版本字段对数据库条目进行排序。因此,如果需要,那么使用单独的字段可能更合适。

    【讨论】:

    • 希望没有人拥有 > 255 的内部版本号。您无法在此处选择类型。它是由系统定义的。在 Windows 的情况下,这四个值是无符号的 16 位值。您还需要了解的是,这是一个关于数据库存储而不是代码的问题。代码具有无限延展性。数据库并非如此。
    • @DavidHeffernan 如果我正确理解,OP 不是在谈论存储在系统定义的可执行文件中的版本信息,而是通过某些程序存储在它们创建的文件中的版本信息。并且这个版本信息可能与存储在可执行文件中的版本信息不同,所以它的类型可以由程序自己定义。我专注于问题的代码方面的原因是因为问题的数据库方面对我来说似乎非常清楚。那就是最好将一个转换后的值存储在单个字段中。 ...
    • ... 问问自己这个问题:在三个字段(日、月、年)或一个日期字段中将日期存储到数据库中的更好方法是什么。版本信息与日期类型或时间类型没有太大区别。其中每一个都由多个字段组成,但可以转换为单个数字。
    • 如果我们在谈论要存储在数据库中的内容,为什么您的答案只考虑 Delphi 代码。
    • 我想我假设如果我的回答说服 OP 在代码端使用 sugested 方法,他会在数据库端做同样的事情。不管怎样,我已经编辑了我的答案以涵盖数据库方面。
    最近更新 更多