在数据库中,如果只需要年份和月份,您会使用日期字段还是年份和月份字段?
Posted
技术标签:
【中文标题】在数据库中,如果只需要年份和月份,您会使用日期字段还是年份和月份字段?【英文标题】:In a database, would you use a date field or year and month fields if you only need year and month? 【发布时间】:2009-03-11 02:24:31 【问题描述】:我正在设置一个需要年份和月份的表格。在 mysql 中,我相信我有 2 个选项:(1) 2 个字段:1 个表示年份,1 个表示月份或 (2) 一个日期字段(日期始终为 1)。
这两个字段的优点是速度更快(我认为),因为 MySQL 不必将值从日期转换为整数,尽管这可能可以忽略不计。日期字段具有“自动”验证的优势:有人无法将月份为 13 或年份为 1 的数据输入数据库。使用日期字段,您还可以更轻松地进行日期计算(即,月份之间)。
你会用哪个?或者还有其他你会用的吗?
【问题讨论】:
对于任何回到这里的人,我推荐EXTRACT(YEAR_MONTH FROM mydate)
用于比较和DATE_FORMAT(mydate, '%Y-%M')
用于显示,请参阅date functions
【参考方案1】:
使用日期字段。由于 sql 原生支持日期字段,因此可以使用 WHERE 子句轻松过滤特定日期。
这 2 个字段的优点是速度更快 [...]
您的 SELECT 查询不是您的瓶颈,因此您不必担心这一点。可读性和实用程序比“感知瓶颈”更重要。
【讨论】:
我同意大多数,但是如果列命名为 year 和 month ,可读性问题在哪里? SELECT [...] WHERE date between '02-01-2009' AND '04-31-2010' vs SELECT [...] WHERE Year BETWEEN AND 2010 AND Month BETWEEN 2 AND 4 .. 不要回答这个问题。我想这是主观的。 这些选择语句不相同。第二个仅获取 2009 年和 2010 年的第 2、3 和 4 个月;这与获取 14 个月的数据相差甚远…… 当我第一次阅读您的答案时,我不同意,但您无意中证明了您的观点,通过展示当您使用单独的月份和年份列时搞砸 SQL 是多么容易。 :)【参考方案2】:即使您只需要年份和月份,我也会使用日期字段,因为收集所有数据不会丢失任何内容。作为标准做法,我总是尽可能收集所有数据。
【讨论】:
【参考方案3】:我会使用单独的列,主要是因为这样可以更好地使用索引。例如,如果您只关心给定月份(而不是年份)的数据,我认为日期时间列上的索引不会有帮助。
【讨论】:
除非 mysql 有什么“特别”之处。或者我应该说它“可以”。【参考方案4】:尽管您不会立即使用,但 IBM Informix Dynamic Server 支持以下类型:
DATETIME YEAR TO MONTH
这会准确存储您想要的内容 - 年份和月份。它有它的用途。 DATETIME 类型系列包括许多其他类型,它们偶尔会使用 - 以及一些具有边际效用的类型,典型示例是 DATETIME MONTH TO MINUTE。 (该类型的缺点是操作它需要冗长的符号,但是可以对任何或所有 DATETIME 类型执行许多操作。)
在许多 DBMS 中,您可以在列上放置约束,因此如果您采用两列方法,您将在列上放置 CHECK(month_column BETWEEN 1 AND 12)
约束,以确保用户没有在表中放置无效值.您甚至可以对年份列应用约束。
此外,一些 DBMS 允许您创建用户定义的类型,并且年月类型非常简单。当然,细节取决于 DBMS。
【讨论】:
【参考方案5】:除非单独存储年份和月份有特定的性能优势,否则我会坚持使用日期。关于索引,如果有两列,则需要在列组合上创建索引,而不是为日期列创建索引。日期将在内部转换为长值,因此所需的存储空间不是问题。
此外,请考虑两个字段可能存在的维护问题。您将有两个数据库字段,可能是一个对象上的两个字段,或者需要从数据库构建/解析月份和年份。使用日期保持简单,让数据库跟踪您的数据完整性。
我使用您所描述的数据 - 到期日期,其中日期始终是本月的最后一天,因此我们只需要月份和年份。我们将这些存储为日期。
【讨论】:
【参考方案6】:我会保留一个日期时间列和两个带有月份和年份的计算列(当然是索引)。吃我的蛋糕,也吃:)
【讨论】:
【参考方案7】:如果您预计查询形式为“在 7 月提供所有行,无论年份如何”,使用单独的月份和年份列编写它们会更容易一些。月份列的单独索引应该让它变得活泼。
否则,我会选择单个日期列:简单、易于理解、内置验证和日期数学函数都可以工作。您唯一担心的是,刚接触设计的人会想知道为什么所有事情总是发生在月初。
我遇到过使用单独的月份和年份列的另一个原因:当月份未知时。我已经将它用于允许即将发生的事件“在 2009 年的某个时候”的应用程序。在这种情况下,在月份列中使用 NULL 可以很好地解决问题。使用日期类型的列没有简单的方法来做到这一点,除非您想出一些可怕的技巧,比如 1 月 2 日意味着月份是未知的。
【讨论】:
【参考方案8】:这样想:有一天会有人来找你,要求你增强应用程序,不仅可以保存年月,还可以保存一天。 然后,您会在一天中添加一个额外的列吗? 然后,接下来,他们可能希望您也节省时间。
如果您有单独的年/月/日列,那么增强功能有多容易?如果您只有一个日期列?
仅出于这个原因,我会选择日期列。
【讨论】:
【参考方案9】:如果您要在日期字段上运行大量操作,那么我会将其拆分为单独的列,并在表约束或 DAL 中处理数据验证。
例如,当拆分字段时,按日、月、年构建销售报告的效率要高得多。原因是您不必使用日期时间函数来拆分日期以进行分组。
如果是生日之类的东西,我可能会偶尔查询一次,那我就不用担心了,只需将其留在日期字段中即可。
【讨论】:
【参考方案10】:可能不是因为 SQL Server (Microsoft) 中最小的日期时间数据类型是 smalldatetime
,它有 4 个字节长。如果只需要月份和年份,那么月份需要 1 个字节,年份需要 2 个字节。
【讨论】:
应该不会吧?我是要么:P以上是关于在数据库中,如果只需要年份和月份,您会使用日期字段还是年份和月份字段?的主要内容,如果未能解决你的问题,请参考以下文章