同一列的不同类型

时间:2012-05-04 20:34:13

标签: mysql relational-database

我的数据库存储版本号;但是,它们有两种格式: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|
+---+---+-----+-----+-----+-----+--------+

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

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

6 个答案:

答案 0 :(得分:1)

你的情况是你有不同类型的版本化对象,其中一种版本控制使用日期,另一种版本控制使用版本号,或者你的情况是引用相同类型的对象的版本使用日期和使用版本号?

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

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我认为这里没有银弹。如果你坚持拥有一个单独的列,你可以天真地将它们都打到CHAR(10)中,尽管这有其自身的问题(例如,无效的日期或格式错误的构建数字符串等)。

我认为关键问题是你想要运行什么类型的查询,以及你期望有多少行?

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

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

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

相关问题