我正在制作一项需要保存按年月组合分组和计算的数据的服务。我知道如何计算数据并将其放在新表上。但是我很困惑应该使用哪种数据类型来存储月 - 年值。这是我考虑过的。
- 两个整数列,一个是一年,另一个是一个月(易于理解且易于操作(使用此表的任何人都可以轻松使用范围和顺序),但我认为这将比其他解决方案占用更多空间。
- 使用日期字段,并始终为整个月存储一个日期。(很难向用户解释它是如何工作的以及如何创建 WHERE 子句)
- 一个 varchar(7) 列并在那里放置 2012-02,2013-01 之类的刺痛。对我来说,这很容易理解,但很难操作。
我应该选哪个?还是有其他解决方案。有人可以根据性能建议哪种方式是好的解决方案,因为大多数查询将使用解决方案中的数据范围,而我的新表将有大约 2-5 百万条记录。
我会使用带有一个月第一天的日期字段和一个 CHECK 约束来确保它保持在第一天。
这使其保持本机日期/时间格式(这是您对选项 3 的观察)
选项 1 需要更少的存储空间,但比较复杂。500 万行并不多:您使用更少的存储空间,但增加了代码和查询的复杂性
我认为您应该根据需要检索数据的方式选择一个(或多个)选项。
对于 500 万条记录,空间真的不应该是您最关心的问题。对于您的每个选项,以下是检索的优缺点:
(1) 两个整数列: 如果您需要比较不同年份的月份,这是一种很好的方法。如果单独索引年和月,按月提取和按年排序会快得多。如果这是使用数据的重要或频繁模式,则选项 1 是最好的。另一方面,这种模式在提取年份和月份以外的范围时很糟糕。例如,它不适用于跨年的范围。当日期范围跨越日历年边界时,WHERE 子句可能会变得比您希望的更复杂。(想想从 2011 年 11 月到 2012 年 2 月。)
(2) 日期字段: 您和 gbn 都发现了这种格式的优点。它也适用于按时间顺序排序和提取月份范围。它恰好是最紧凑的表示(只有 3 个字节)。比较不同年份的月份并不好,也不适合在屏幕和报告中显示。
(3) char(7) YYYY-MM 字段: 请注意,如果您真的关心空间(并且您不应该在您的情况下),那么您可以使用
char
而不是,varchar
因为每个项目的长度都是已知的。使用 YYYY-MM 有利于排序和过滤范围。它不如 (2) 的空间好,但它更适合 WHERE 子句的显示和简单性 - 除非您需要跨年提取几个月。您可能已经注意到 (1) 和 (2)/(3) 在您需要进行的提取的性质方面存在差异。如果您需要同时进行月/年和月范围提取,那么这些选项都不是完美的。如果是这种情况,我建议您考虑使用 (1) 和 (2) 或 (3) 的组合 - 我自己选择 (3),因为我更看重显示/使用的易用性而不是存储空间。如果您确实使用了组合,请将其中一个或另一个作为计算列并将其编入索引以进行有效检索。
考虑建模为具有两个日期值的时期——开始日期和结束日期——使用封闭-开放表示(“开放”表示结束日期实际上并未出现在该时期中)。
例如,当前月份(2012 年 3 月)将使用行建模
如果您在表中也有完整日期并且仅将缩减日期用于聚合,则创建一个函数,从该日期创建一个标准化的、理想的合理分布值(例如“自 1970 年 1 月以来的月份”),并创建一个索引该函数的结果以加快聚合过程。