2008-12-23 70 views
6

目前,我正在开发一个项目来管理服务器数据库上的维护窗口等。基本上,我只需要准确到小时,但允许它们被设置为允许或不允许一周中的每一天。每周计划 - 如何将其存储在数据库中?

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

为直观起见,它像流动的“图”

| 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询问是否需要跟踪每个星期 - 事实并非如此。这是一个通用的时间表,将适用于整个年度(定期维护)

+0

你需要每周跟踪的一年,或者这只是一个配置表中一般一周? – 2008-12-23 16:38:58

+0

对于我来说,您需要旋转此表,因为如果您想要在特定的一天中获得所有的小时数,那么您将需要返回24行,并且不会轻松访问WHERE数据。在我看来,有7行24列更有意义,1行给你一整天的时间。 – TravisO 2008-12-23 16:41:24

回答

0

也许像

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 
8

我会考虑(1)使用包括开始时间和结束时间的格式,并且星期几的整数字段。我知道你说的块总是一个小时,但这可以通过你的代码来实施。另外,如果你的需求有一天会改变,那么在步骤(2)中你会少得多担心如果你的数据库语句全部写入假设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代表日期和时间你想检查)。

允许或不允许每周的每一天将由单独的记录处理。恕我直言,这比一周中的每一天的硬编码更灵活,因为您将使用某种情况下的陈述或if-else开关检查您感兴趣的日期的正确的数据库列。

注意:请确保您知道您的数据库在一周中的整数日期使用哪种标准,并尝试使代码独立于此(始终询问数据库)。我们在本周开始时(周日或周一)和起始指数(0或1)有很多不同的标准。

1

如果每周都会有所不同,那么就像这样设置表格;

TABLE: 
    StartTime DATETIME PrimaryKey 

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

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

TABLE: 
    Hour INT, 
    Day INT, 
    Allow BIT 

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

1

其实我已经使用过这样的设计,基本上创建要定期安排由你想要的周期数除以时间跨度的位图。因此,在您的示例中,您需要每周安排一个小时的时间表,因此您将拥有一个只有21个字节长的168位位图。几个日期时间是16个字节,你需要多行这些来表示给定星期的可能时间表,所以如果你关心所有的大小,我不认为你能打败它。

我承认这是一个有点棘手,处理,比以前的建议不够灵活。考虑如果您突然想要使用1/2小时时间段,则需要将所有现有数据转码为新的336位位图并分配值。

如果你使用SQL,你可以将此作为存储二进制博客,做位操作,比较了一下是否是开启还是关闭自己或你可以每一位存储为一列。 MS SQL Server最高可支持1024个标准或30个宽表,因此您可以轻松地将精细度降至10分钟,而对于30k表可以更加精细。

我希望这会增加一点点不同的观点,看它如何完成。如果你担心空间/大小,或者如果你有几十万或几百万的数量,那真的只有这样。

1

您可以很容易地在表中记录“允许”时间。那样,如果它不在那里,那是不允许的。如果您需要更多变量的“时间表”,您可以轻松添加年份和月份字段。

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月所有天可以进行维修。不过你希望显示。

1

每一个提出的解决方案是对我好,反正我会认为这是一个你应该面对性能和/或表大小的问题。由于您可能会在时间与您的实体(即服务器)之间建立关系,所以size_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 

你会认为每一个丢失的行意味着服务器关闭。

如果你需要这个,你可以考虑在day列中使用DATE格式来设置特定的日期(即只在2013年10月2日16:00到20:00之间的正常运行时间)。

希望它可以帮助

相关问题