5

我的数据库存储版本号;但是,它们有两种格式:major.minor.build(例如 8.2.0、12.0.1)和日期(例如 YY-MM-DD)。我想到了两种解决方案:

+---+---+-----+-----------+ +-----+-----+-----+-----+ +-----+--------+
|...|...|id   |versionType| |id   |major|minor|build| |id   |date    |
|---+---+-----+-----------| |-----+-----+-----+-----| |-----+--------|
|...|...|12345|0          | |12345|0    |1    |2    | |21432|12-04-05|
|---+---+-----+-----------| +-----+-----+-----+-----+ +-----+--------+
|...|...|21432|1          |
+---+---+-----+-----------+

或者

+---+---+-----+-----+-----+-----+--------+
|...|...|id   |major|minor|build|date    |
|---+---+-----+-----+-----+-----+--------|
|...|...|12345|0    |1    |2    |null    |
|---+---+-----+-----+-----+-----+--------+
|...|...|21432|null |null |null |12-04-05|
+---+---+-----+-----+-----+-----+--------+

这两个看起来都不是特别有效:第一个需要连接两个表才能获得版本号,而第二个每个版本条目浪费的空间是第一个的两倍。或者,我可以将值存储在列中的一些位中,然后在客户端解释它,但我希望有一些我忽略的这种情况的标准做法。

是否有适当的方法在关系数据库中为同一“列”存储两种不同类型的数据?

4

6 回答 6

1

您的情况是您有不同类型的版本化对象,一种版本控制使用日期,另一种版本控制使用版本号,还是您的情况是同时使用日期引用相同类型的对象版本并使用版本号?

在第一种情况下,不要费心创建这样一个没有任何用处的人造表。只有当它们解决了真正存在的业务问题时才需要创建表,并且从版本日期到版本号或反之亦然的转换在这种情况下不存在。即使它后来出现,那么你仍然可以......

在第二种情况下,定义一个类似于第二个选项中的表,但是:

没有所有那些愚蠢的无意义的ID。只需留下四列 maj/min/bld/date。不要让它们中的任何一个为空。定义两个键:maj/min/bld 和 date。为每个新构建注册一行,记录构建的创建(/activation/whatever ...)日期。使用 maj/min/bld 构造作为描述您正在管理的版本化对象的任何表中的版本指示符,并且每当收到使用日期完成版本引用的请求时,通过查询将其解析为版本号你的 4 列表。

于 2012-05-05T21:57:55.657 回答
0

第一个更好。如果您觉得每次进行联接都让您头疼,那么您可以创建一个视图(使用联接)并使用该视图,而不是直接使用表(或每次都进行联接)。

于 2012-05-04T20:38:01.973 回答
0

我不认为这里有灵丹妙药。如果您坚持使用单个列,则可以天真地将它们都放入 CHAR(10) 中,尽管这有其自身的问题(例如,无效的日期或格式错误的内部版本号字符串等)。

我认为关键问题实际上是您设想运行什么样的查询,以及您希望有多少行?

我会让预期的查询需要驱动数据库设计。

于 2012-05-04T20:41:47.607 回答
0

您可能可以将数据存储在一个 int/bigint 字段中。但在这种情况下,您将必须转换所有值: Date - 将其转换为从某个日期开始的天数,或者您可以使用 unixtimestamp 版本 - 限制内置值(让它最大 1000),次要(1000 )。= 主要*1000*1000 + 次要*1000 + 构建

于 2012-05-04T20:50:35.770 回答
0

我会选择第二个选项,因为表格的粒度是一个版本,不管它是如何出现的。将它存储在 3 个数字列和 1 个日期列中应该只有每行 16 个字节(每个数字和日期列 4 个字节) 在像 Oracle 这样的数据库上。如果您的数据库处理虚拟(计算)列,您可以添加一个类似于 nvl(to_char(date),major||'.'||minor||'.'||build) 的列,并始终从其中选择数据格式化为 varchar 或者您可以对其进行查看。

于 2012-05-04T21:01:11.880 回答
0

这实际上取决于您希望如何在查询中使用此版本号。如果将版本号视为标签就足够了,那么您应该考虑将其存储在 varchar 列中。

如果这还不够,并且您希望能够按版本号排序,事情会变得更加复杂,因为将版本号存储在保留自然排序顺序的数据类型中会更方便。我可能会选择您的解决方案2。有理由担心效率吗?你期待数百万行吗?如果没有,那么你可能不应该太担心。

如果空间、速度和体积是明确的考虑因素,您可以考虑将实际版本号存储为文本标签,并派生一个替代版本号(单个整数),将其存储在用于排序目的的单独列中。

另一方面,如果事实证明某些对象具有版本日期,某些版本号,有时两者都有,我仍然会考虑您的第二个解决方案。如果你真的想要一个 uber-normalized 模型,你可以考虑创建单独的 version_date 和 version_number 表,它们与对象表具有 1:1 的关系。你仍然需要这些连接。不过再一次 - 没有理由担心这一点:数据库擅长连接,这就是它们做得好的地方。

于 2012-05-04T21:12:46.257 回答