【问题标题】:Best way to store a versioning number (e.g. 1, 1.1, 1.11, 1.11.1) in a column?在列中存储版本号(例如 1、1.1、1.11、1.11.1)的最佳方式?
【发布时间】:2019-08-13 18:14:46
【问题描述】:

我需要将 WCAG 的成功标准树存储在我的 Rails 应用程序中:https://www.w3.org/TR/WCAG20/

到目前为止,所有成功标准都取自 WCAG 2.0。现在,在 WCAG 2.1 中添加了更多成功标准,我也需要存储这些标准,并且能够将它们与 WCAG 2.0 分开。

所以我想在表中添加一个wcag 字段,并将值2.0 添加到现有的成功标准中。然后我想添加新的成功标准,值为2.1

首先我想使用普通的浮点数,但后来我意识到版本号有不同的逻辑:

  • 对于浮点数,这是正确的:1.11 < 1.2
  • 对于版本号,相反:1.11 > 1.2

如何在数据库中存储这种特殊类型的数据?最好同时保留maxmin之类的方法,以及将它们相互比较的简单方法(<>=等)?

【问题讨论】:

  • 你用什么数据库?
  • 我用的是 MySQL 数据库。
  • 目前,由于似乎不存在简单的插入式解决方案(gem 或类似的),我决定只使用带有scale: 1 的小数字段。由于 WCAG 更新非常缓慢,我怀疑我的应用程序永远不会遇到问题(当前版本是 WCAG 2.1,它需要很多年才能转到 2.10,而且可能这永远不会发生,因为版本 3.0 会到来前一天)。我添加了一个自定义格式验证以避免遇到问题,这只是阻止用户尝试输入2.10 或类似内容。

标签: ruby-on-rails database


【解决方案1】:

版本“数字”并不是真正的数字,它们是有限的数字序列(即它们是数组)。所以1.11.6实际上是[1, 11, 6]的代表。

如果您使用的是 PostgreSQL,那么您可以访问数组列,因此您可以使用 int[] 列,分解输入字符串:

version_number.split('.').map(&:to_i)

然后在输出时将它们重新组合在一起:

version_array.join('.')

PostgreSQL 数组逐个元素进行比较,因此排序将在数据库中按需要进行:

psql> select array[1,2,3] > array[1,2];
-- True
psql> select array[1,2,3] > array[1,2,5];
-- False

如果您无权访问数组列,那么您可以左填充版本组件以将它们作为字符串存储在数据库中:

 '1.2.3'.split('.').map { |s| s.rjust(4, '0') }.join('.')
 # "0001.0002.0003" 

当你把它们拉出来时清理它们:

'0001.0002.0003'.split('.').map(&:to_i).join('.')
# "1.2.3" 

'0001.0002.0003''0001.0012' 这样的字符串将在数据库中按需要排序,同时仍然可以按原样理解。缺点是您必须决定组件的大小才能正确填充组件。


您可能希望将所有这些都包含在 ActiveRecord 关注点中,以隐藏所有丑陋和字符串争吵。

【讨论】:

    【解决方案2】:

    如果您使用 postresql,您可以使用扩展来拥有“semver”类型(版本控制在我看来就像 semver,不确定是否遵循每个版本的含义的规范)。

    https://pgxn.org/dist/semver/doc/semver.html

    【讨论】:

      【解决方案3】:

      如果您使用的是版本 8+,您也许可以使用 MYSQL json datatype

      您可以对 json 部分运行查询。

      【讨论】:

        猜你喜欢
        • 2020-04-02
        • 2010-11-11
        • 1970-01-01
        • 1970-01-01
        • 2010-09-14
        • 2011-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多