【问题标题】:Weekly Schedules - How can you store this in a database?每周计划 - 您如何将其存储在数据库中?
【发布时间】:2008-12-23 16:28:08
【问题描述】:

目前,我正在开展一个项目,以管理服务器等数据库上的维护窗口。基本上,我只需要精确到小时,但允许将它们设置为允许或禁止,一周中的每一天。

我对如何做到这一点有一些想法,但由于我自己工作,我不想在没有反馈的情况下承诺任何事情。

为了形象化,它类似于流动的“图表”

    | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
    -------------------------------------------
5AM |allow|allow|allow|deny |deny |allow|allow|
    -------------------------------------------
6AM |allow|deny |deny |deny |deny |deny |allow|
    -------------------------------------------
7AM |allow|deny |deny |deny |deny |deny |allow|
    -------------------------------------------
8AM |allow|deny |deny |deny |deny |deny |allow|
    -------------------------------------------
9AM |allow|deny |deny |deny |deny |deny |allow|
    -------------------------------------------
... etc... 

有没有标准的方法或资源可以给我一些想法......

  1. 制作可以轻松保存和恢复的格式
  2. 使其可在数据库中搜索(例如,无需反序列化即可搜索时间)

[更新]

值得一提的是,即使不太可能,也可以将一天设置为“允许、拒绝、允许、拒绝……等等……”。不保证跨度是一整天的唯一跨度。

这也不是唯一的时间表,数百台设备每个都有自己的时间表,所以会很麻烦...哈哈??

Rob 询问是否需要每周跟踪 - 不需要。这是适用于全年的通用时间表(定期维护)

【问题讨论】:

  • 您需要跟踪一年中的每一周,还是这只是一个通用一周的配置表?
  • 在我看来,您需要旋转该表,因为如果您想获取某一天的所有小时数,则需要返回 24 行,而没有简单的方法可以将数据放在 WHERE 位置。在我看来,7 行 24 列更有意义,1 行可以为您提供给定一天的所有时间。

标签: database datetime data-structures timespan


【解决方案1】:

对于 (1),我会考虑使用包含开始时间和结束时间的格式,以及一周中某一天的整数字段。我知道您说过这些块将始终为一小时,但这可以通过您的代码强制执行。此外,如果有一天您的需求发生了变化,那么在第 (2) 步中您不必担心的问题要比您的 DB 语句都编写为假设 1 小时块的情况要少得多。

CREATE TABLE maintWindow (
   maintWindowId  int primary key auto_increment not null,
   startTime      Time,
   endTime        Time,
   dayOfWeek      int,
   ...

对于 (2),如果每条记录都有与之关联的开始和结束时间,那么很容易检查任何给定时间的窗口:

SELECT maintWindowId
FROM maintWindow
WHERE $time >= TIME(startTime) AND $time <= TIME(endTime) AND DAYOFWEEK($time) = dayOfWeek

(其中$time 表示您要检查的日期和时间)。

一周中每一天的允许或禁止将由单独的记录处理。恕我直言,这比一周中的每一天的硬编码更灵活,因为您将使用某种 case 语句或 if-else 开关来检查您感兴趣的那一天的正确 DB 列。

注意:确保您知道您的数据库在一周中的整数天使用哪种标准,并尝试使您的代码独立于它(始终询问数据库)。对于一周开始(周日或周一)和起始索引(0 或 1)的不同标准,我们玩得很开心。

【讨论】:

  • 这绝对是我会使用的方法。
【解决方案2】:

如果每周都不一样,那就这样摆桌子;

TABLE:
    StartTime DATETIME    PrimaryKey

如果设置了特定日期/小时的开始时间,则假定它是允许的,否则拒绝。

如果是通用一周的通用配置不变,试试这个;

TABLE:
    Hour  INT,
    Day   INT,
    Allow BIT

然后为每个小时/天组合添加行。

【讨论】:

    【解决方案3】:

    我之前实际上使用过这种设计,基本上是为您想要定期安排的时间跨度除以您想要的周期数创建一个位图。因此,在您的示例中,您需要一个以小时为单位的周计划,因此您将拥有一个只有 21 个字节长的 168 位位图。几个日期时间加在一起是 16 个字节,您需要其中的多行来表示给定一周的可能时间表,所以如果您完全关心大小,我认为您无法击败它。

    我承认与之前的建议相比,处理起来有点棘手,而且灵活性较低。考虑一下,如果您突然想要使用 1/2 小时的时间段,则需要将所有现有数据转码为新的 336 位图并将值分发出去。

    如果您使用 SQL,您可以将其存储为二进制博客并进行位旋转以比较您自己的位是打开还是关闭,或者您可以将每个位存储为一列。 MS SQL Server 支持高达 1024 的标准表或 30k 的宽表,因此您可以轻松地将粒度降至 10 分钟,或者对于 30k 表更精细。

    我希望这会增加一些关于如何完成它的不同视角。仅当您担心空间/大小或者您可能有 10 或 100 数百万个时才需要这样做。

    【讨论】:

      【解决方案4】:

      您可以轻松地在表格中记录“允许”时间。这样,如果它不存在,则不允许。如果您需要更多可变的“时间表”,您可以轻松添加年份和月份字段。

       TABLE DBMaintSched
            ID int PK
            ServerID varchar(30) (indexed)
            Day int
            Month char(3)
            DayOfWeek char(3)
            Year int
            StartDT DateTime
            EndDT DateTime
      

      2008 年 12 月:

       SELECT * FROM DBMaintSched WHERE ServerID = 'SQLSERVER01' AND Month = 'DEC' AND Year = 2008 ORDER BY DAY ASC
      

      您在 2008 年 12 月的所有日子里都可以进行维护。随心所欲地显示。

      【讨论】:

        【解决方案5】:

        每一个提议的解决方案对我都有好处,无论如何,如果您遇到性能和/或表大小问题,我会考虑这个。由于您可能会在时间和您的实体(即服务器)之间建立关系,因此大小将增加 entity_number * entity_times。如果每个时间跨度都有一行,这可能会很痛苦。

        这个方案在表结构方面略显丑陋,但在磁盘空间和表扫描速度方面效率更高。

        TABLE times
            entityFK int -- your entity foreign key
            day INT      -- 0-7 day identifier
            bit time0    -- ON if the time 00:00 - 00:59 is being covered
            bit time1 
            bit time2
            -- more columns
            bit time23
        

        考虑您希望在周日和周一为服务器分配 16:00 - 20:00 正常运行时间的示例,您将只有两行类似

        entityFK | day | time16 | time17 | time18 | time19 | -- other bits are set to 0
        server1    0     1        1        1        1
        server1    1     1        1        1        1
        

        你会假设每一个缺失的行都意味着服务器已经关闭。

        如果您需要这个,您可以考虑使用日期列的 DATE 格式来设置特定日期(即正常运行时间仅为 2013/10/02 16:00 到 20:00 之间)。

        希望对你有帮助

        【讨论】:

          【解决方案6】:

          也许像

          TABLE:
             StartTime DATETIME      PrimaryKey,
             EndTime   DATETIME      PrimaryKey,  /*if you are positive it will be in one hour incerments then you might want to omit this one*/
             Monday    BIT,
             TuesDay   BIT,
             Wednesday BIT,
             Thursday  BIT,
             Friday    BIT,
             Saturday  BIT,
             Sunday    BIT
          

          【讨论】:

            【解决方案7】:

            用 Python 编写,这样的模块可能会起作用-https://github.com/AndrewPashkin/pytempo

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-01-22
              • 1970-01-01
              • 1970-01-01
              • 2019-11-05
              • 2020-12-05
              • 1970-01-01
              • 2010-12-20
              相关资源
              最近更新 更多