在日历中保存年月日有用吗Table
Is it useful to save Year, Month and Date in the Calendar Table
我正在使用日历 table 来保存日期信息。 table 我的初步目的是确定工作日和休假日(包括周末和节假日)。 table 中的字段是
- 日期(主键)
- 年
- 月份
- 天(第 1、2、3 等没有后缀)
- 类型(工作日、周六、周日等)
使用年、月和日字段起初似乎很有用,尤其是设置假期,但事后看来我想我可以只使用 DATEPART(yyyy, [Date])
来获取年以及类似的月和日。这些字段还有任何其他用途吗?
如果性能是一个因素,那么影响有多大?日历 table 只有 100 年的数据,即 ~36,500 条记录,一些叶子可以为所有 100 年预置,一些每年落在不同日期(~5 条记录)的叶子可以每年设置一次.考虑性能差异是否值得?
总结
使用单独的字段来保存年月日信息有什么用吗?性能差异是否大到足以被打扰?
编辑 1
从执行计划来看,我什至没有看到任何性能差异,所以主要是这些字段还有其他用途吗?
编辑 2
有些人似乎误解了这个问题。我的问题不是如何创建日历 table 或对日历中字段的看法 table。我的问题是,是否 ANY 使用了 [Year]
、[Month]
和 [Day]
字段。
我已经经历了这种过程的几个不同的迭代,这就是我过去实现它的方式。
这是一个起点。在每场比赛中,停止处理进一步的规则。
- 如果是星期六,就是周末。
- 如果是星期天,就是周末。
- 如果是 1 月 1 日,则为假期(元旦)。
- 如果是 1 月 2 日并且是星期一,则为假期(庆祝元旦)。
- 如果是一月的第三个星期一,则为假期(MLK Day)。
- 如果是二月的第三个星期一,则为假期(总统日)。
- 如果是五月的最后一个星期一,则为假期(阵亡将士纪念日)。
- 如果 7 月 3 日是星期五,则为假期(庆祝独立日)。
- 如果是 7 月 4 日,则为假期(独立日)。
- 如果 7 月 5 日是星期一,则为假期(独立日)。
- 如果是 9 月的第一个星期一,则为假期(劳动节)。
- 如果是10月的第2个星期一,则为节假日(哥伦布纪念日)。
- 如果 11 月 10 日是星期五,则为假期(纪念退伍军人节)。
- 如果是 11 月 11 日,则为假期(退伍军人节)。
- 如果 11 月 12 日是星期一,则为假期(庆祝退伍军人节)。
- 如果是11月的第四个星期四,则为假期(感恩节)。
- 如果是 11 月的第 4 个星期五并且不是 11 月 22 日,则为假期(黑色星期五)。
- 如果 11 月 29 日是星期五,则为假期(黑色星期五)。
- 如果 12 月 24 日是星期五,则为假期(平安夜)。
- 如果是 12 月 25 日,则为假期(圣诞节)。
- 如果 12 月 26 日是星期一,则为假期(节礼日)。
- 如果是 12 月 31 日,并且是星期五,则为假期(除夕夜)。
- 如果满足上述条件中的none,则为工作日。
通过这种方式,您可以遍历规则并识别工作日、周末和节假日。您可以使用这些字段存储这些规则:
- 月份
- 一个月中的第几天
- 星期几
- 周数
- 年份
算法的工作原理如下。
- 如果
[Year] > 0
,则此规则只影响当年的日期;否则,无论年份如何,此规则均有效。
- 如果
[Month] > 0
,则此规则只影响该月的日期;否则,无论月份如何,此规则均有效。
- 如果
[Day Of Month] > 0 AND [Day of Week] == 0
,则此规则会影响当月那天的日期。
- 如果
[Day of Month] == 0 AND [Day of Week] > 0
,则此规则会影响一周中那一天的日期。
- 如果
[Day of Month] == 0 AND [Day of Week] > 0 AND [Week Number] > 0 AND [Week Number] < 6
,此规则会影响 [Day of Week]
的 [Week Number]
基数实例。例如,如果 [Day of Week] = @Monday
和 [Week Number] = 1
,则此规则会影响该月的第一个星期一。
- 如果
[Day of Month] > 0 AND [Day of Week] > 0 AND [Week Number] > 0 AND [Week Number] < 6
,则此规则影响 [Day of Week]
落在 [Day of Month]
或之后的 [Week Number]
个基数实例;如果 [Day of Week]
的 [Week Number]
个基数实例落在 [Day of Month]
之前,则此规则会影响 [Day of Week]
的 [Week Number] + 1
个基数实例。我把这个介绍给了黑色星期五的算法。
- 如果
[Day of Month] == 0
AND [Day of Week] > 0
AND [Week Number] == 6
,则此规则会影响一个月内 [Day of Week]
的最后一个实例。
使用此算法和这 22 条规则,您不必为所有内容都存储一个条目。这将涵盖您的所有 U.S。一个世纪的联邦假期。您可以添加带有确切日期的请假条目 ([Year]
、[Month]
、[Day of Month]
)。
日历表很小。正如您所指出的,即使您明确存储年份和月份,您所谈论的存储容量也可以覆盖 100 年。行宽不是问题。
如果您保留它们,请将它们设为计算列以强制与 [date]
保持一致。如果您希望它们也物理存在,请将它们设为持久计算列。
CREATE TABLE Calendar (
[date] date NOT NULL PRIMARY KEY
,[year] AS ISNULL(DATEPART(year,[date]),0)
,[month] AS ISNULL(DATEPART(month,[date]),0)
,[day] AS ISNULL(DATEPART(day,[date]),0)
,[type] int NOT NULL DEFAULT 0
)
DECLARE @date_from date = '2000-01-01'
DECLARE @date_to date = '2099-12-31'
INSERT Calendar ([date])
SELECT TOP(1+DATEDIFF(day,@date_from, @date_to))
DATEADD(day,ROW_NUMBER() OVER(ORDER BY (SELECT 1))-1,@date_from)
FROM master.dbo.spt_values a, master.dbo.spt_values b
我正在使用日历 table 来保存日期信息。 table 我的初步目的是确定工作日和休假日(包括周末和节假日)。 table 中的字段是
- 日期(主键)
- 年
- 月份
- 天(第 1、2、3 等没有后缀)
- 类型(工作日、周六、周日等)
使用年、月和日字段起初似乎很有用,尤其是设置假期,但事后看来我想我可以只使用 DATEPART(yyyy, [Date])
来获取年以及类似的月和日。这些字段还有任何其他用途吗?
如果性能是一个因素,那么影响有多大?日历 table 只有 100 年的数据,即 ~36,500 条记录,一些叶子可以为所有 100 年预置,一些每年落在不同日期(~5 条记录)的叶子可以每年设置一次.考虑性能差异是否值得?
总结
使用单独的字段来保存年月日信息有什么用吗?性能差异是否大到足以被打扰?
编辑 1
从执行计划来看,我什至没有看到任何性能差异,所以主要是这些字段还有其他用途吗?
编辑 2
有些人似乎误解了这个问题。我的问题不是如何创建日历 table 或对日历中字段的看法 table。我的问题是,是否 ANY 使用了 [Year]
、[Month]
和 [Day]
字段。
我已经经历了这种过程的几个不同的迭代,这就是我过去实现它的方式。
这是一个起点。在每场比赛中,停止处理进一步的规则。
- 如果是星期六,就是周末。
- 如果是星期天,就是周末。
- 如果是 1 月 1 日,则为假期(元旦)。
- 如果是 1 月 2 日并且是星期一,则为假期(庆祝元旦)。
- 如果是一月的第三个星期一,则为假期(MLK Day)。
- 如果是二月的第三个星期一,则为假期(总统日)。
- 如果是五月的最后一个星期一,则为假期(阵亡将士纪念日)。
- 如果 7 月 3 日是星期五,则为假期(庆祝独立日)。
- 如果是 7 月 4 日,则为假期(独立日)。
- 如果 7 月 5 日是星期一,则为假期(独立日)。
- 如果是 9 月的第一个星期一,则为假期(劳动节)。
- 如果是10月的第2个星期一,则为节假日(哥伦布纪念日)。
- 如果 11 月 10 日是星期五,则为假期(纪念退伍军人节)。
- 如果是 11 月 11 日,则为假期(退伍军人节)。
- 如果 11 月 12 日是星期一,则为假期(庆祝退伍军人节)。
- 如果是11月的第四个星期四,则为假期(感恩节)。
- 如果是 11 月的第 4 个星期五并且不是 11 月 22 日,则为假期(黑色星期五)。
- 如果 11 月 29 日是星期五,则为假期(黑色星期五)。
- 如果 12 月 24 日是星期五,则为假期(平安夜)。
- 如果是 12 月 25 日,则为假期(圣诞节)。
- 如果 12 月 26 日是星期一,则为假期(节礼日)。
- 如果是 12 月 31 日,并且是星期五,则为假期(除夕夜)。
- 如果满足上述条件中的none,则为工作日。
通过这种方式,您可以遍历规则并识别工作日、周末和节假日。您可以使用这些字段存储这些规则:
- 月份
- 一个月中的第几天
- 星期几
- 周数
- 年份
算法的工作原理如下。
- 如果
[Year] > 0
,则此规则只影响当年的日期;否则,无论年份如何,此规则均有效。 - 如果
[Month] > 0
,则此规则只影响该月的日期;否则,无论月份如何,此规则均有效。 - 如果
[Day Of Month] > 0 AND [Day of Week] == 0
,则此规则会影响当月那天的日期。 - 如果
[Day of Month] == 0 AND [Day of Week] > 0
,则此规则会影响一周中那一天的日期。 - 如果
[Day of Month] == 0 AND [Day of Week] > 0 AND [Week Number] > 0 AND [Week Number] < 6
,此规则会影响[Day of Week]
的[Week Number]
基数实例。例如,如果[Day of Week] = @Monday
和[Week Number] = 1
,则此规则会影响该月的第一个星期一。 - 如果
[Day of Month] > 0 AND [Day of Week] > 0 AND [Week Number] > 0 AND [Week Number] < 6
,则此规则影响[Day of Week]
落在[Day of Month]
或之后的[Week Number]
个基数实例;如果[Day of Week]
的[Week Number]
个基数实例落在[Day of Month]
之前,则此规则会影响[Day of Week]
的[Week Number] + 1
个基数实例。我把这个介绍给了黑色星期五的算法。 - 如果
[Day of Month] == 0
AND[Day of Week] > 0
AND[Week Number] == 6
,则此规则会影响一个月内[Day of Week]
的最后一个实例。
使用此算法和这 22 条规则,您不必为所有内容都存储一个条目。这将涵盖您的所有 U.S。一个世纪的联邦假期。您可以添加带有确切日期的请假条目 ([Year]
、[Month]
、[Day of Month]
)。
日历表很小。正如您所指出的,即使您明确存储年份和月份,您所谈论的存储容量也可以覆盖 100 年。行宽不是问题。
如果您保留它们,请将它们设为计算列以强制与 [date]
保持一致。如果您希望它们也物理存在,请将它们设为持久计算列。
CREATE TABLE Calendar (
[date] date NOT NULL PRIMARY KEY
,[year] AS ISNULL(DATEPART(year,[date]),0)
,[month] AS ISNULL(DATEPART(month,[date]),0)
,[day] AS ISNULL(DATEPART(day,[date]),0)
,[type] int NOT NULL DEFAULT 0
)
DECLARE @date_from date = '2000-01-01'
DECLARE @date_to date = '2099-12-31'
INSERT Calendar ([date])
SELECT TOP(1+DATEDIFF(day,@date_from, @date_to))
DATEADD(day,ROW_NUMBER() OVER(ORDER BY (SELECT 1))-1,@date_from)
FROM master.dbo.spt_values a, master.dbo.spt_values b