Var*_*rma 43 c# sql database-design data-modeling
我正在尝试在C#中开发一个与调度程序和日历相关的事件应用程序,其关键要求是表示数据库中的重复事件.表示数据库中重复事件的最佳方法是什么?
更多细节:
在创建活动时,我也向某些用户发送邀请,并且只允许被邀请者在指定的窗口(会议持续时间)内登录会议,或者可能在被邀请者尝试登录时拒绝登录,比如5分钟前预定的会议开始.
Bob*_*Bob 38
SQL Server中的sysjobs,sysjobsschedule和sysschedules表可以很好地完成这项工作.我不会重新发明轮子,我只是复制他们的设计.
以下是一些重要的领域 sysschedules
freq_type
此计划的作业运行频率.
1 =仅一次
4 =每日
8 =每周
16 =每月
32 =每月,相对于freq_interval
64 = SQL Server代理服务启动时运行
128 =计算机空闲时运行
freq_interval的
作业执行的天数.取决于freq_type的值.默认值为0,表示freq_interval未使用.freq_type的值对freq_interval的影响
1(一次)freq_interval未使用(0)
4(每天)每个freq_interval天
8(每周)freq_interval是以下一项或多项:1 =星期日2 =星期一4 =星期二8 =星期三16 =星期四32 =星期五64 =星期六
16(每月)在该月的freq_interval日
32(每月,相对)freq_interval是以下之一:1 =星期日2 =星期一3 =星期二4 =星期三5 =星期四6 =星期五7 =星期六8 =第9天=工作日10 =周末
64(SQL Server代理服务启动时启动)freq_interval未使用(0)
128(在计算机空闲时运行)freq_interval未使用(0)
的freq_subday_type
freq_subday_interval的单位.可以是以下值之一:值描述(单位)
1在指定的时间
2秒
4分钟
8小时
freq_subday_interval
每次执行作业之间发生的freq_subday_type周期数.
freq_relative_interval
当freq_interval在每个月发生时,如果freq_interval是32(每月相对).可以是以下值之一:
0 = freq_relative_interval未使用
1 =第一
2 =第二
4 =第三
8 =第四
16 =最后
freq_recurrence_factor
计划执行作业之间的周数或月数.freq_recurrence_factor仅在freq_type为8,16或32时使用.如果此列包含0,则freq_recurrence_factor未使用.
Jon*_*eet 24
好吧,要存储重复规则本身,您可以使用RFC 5545的缩减版本(我真的建议您大幅减少).除此之外,如果您愿意,可以轻松导出到其他应用程序.
在做出决定之后,对于数据库方面,您需要确定是要存储事件的每个事件,还是只记录重复事件的一个记录,并根据需要进行扩展.显然,当您已经扩展了所有内容时,查询数据库要容易得多 - 但这使得维护变得更加棘手.
除非你想写一些非常复杂的SQL,这可能很难测试(并且你需要对各种极端情况进行大量的单元测试),我建议你让数据库本身相对"愚蠢"并写下大部分的使用Java或C#等语言的业务逻辑 - 当然,根据您的数据库,其中任何一个都可以嵌入存储过程中.
您需要问自己的另一件事是,您是否需要应对事件的例外情况 - 一系列更改时间/位置的事件等.
我有压延(我大部分时间都在去年的日历位工作的一些经验谷歌同步通过ActiveSync),我要提醒你,事情就变得复杂真的很快.任何你认为"超出范围"的东西都是一种祝福.特别是,您需要在多个时区工作吗?
哦,最后 - 当您使用日历操作进行实际算术时,要非常非常小心.如果您打算使用Java,请使用Joda Time而不是内置Calendar/ Date类.他们会帮助你很多.
小智 7
这里接受的答案太复杂了.例如,如果事件每5天发生一次,则5存储在freq_interval中,但如果它每5周发生一次,则5存储在freq_recurrence中.最大的问题是freq_interval意味着三种不同的东西,具体取决于freq_type的值(每日复发的发生次数,每月复发的日期,或每周或每月相对的星期几).此外,当不需要且不太有用时,使用1,2,4,8 ...类型序列.例如,freq_relative_interval只能是可能值中的"一个".这与一个下拉框或单选按钮类型输入对齐,而不是一个复选框类型输入,可以选择多个选项.对于编码和人类可读性,这个序列会妨碍使用1,2,3,4 ...更简单,更有效,更合适.最后,大多数日历应用程序不需要子日间隔(一天中多次发生的事件 - 每隔很多秒,几分钟或几小时).
但是,说了这些,这个答案确实帮助我改进了我对自己的看法.将其与其他文章混合并匹配后,从我在Outlook日历界面和其他一些来源中看到的内容,我想出了这个:
重复
0 =无复发
1 =每日
2 =每周
3 =每月
recurs_interval
这是重复之间的多少个句点.如果事件每5天重复一次,则会有5,并且recurs会有1.如果事件每2周重复一次,则会有2,recurs将有2.
recurs_day
如果用户选择每月类型重复,则在该月的某一天(例如:10日或14日).这个日期.如果用户未选择每月或特定日期重复,则该值为0.否则,该值为1到31.
recurs_ordinal
如果用户选择了每月类型重复,但是一个序数类型的日(例如:第一个星期一,第二个星期四,上周五).这将具有该序数.如果用户未选择此类重复,则该值为0.
1 =前
2 =后
3 =第三
4 =第四
5 =最后
每周和每月序数重复的recurs_weekdays存储重复发生的工作日.1 =星期日
2 =星期一
4 =星期二
8 =星期三
16 =星期四
32 =星期五
64 =星期六
所以,例子:
所以,周六和周日每4周一次
同样,每个月的第一个星期五每6个月一次
根据另一个领域的价值,拥有一个意味着三个完全不同的东西的领域的业务都没有.
在用户界面方面,我让用户指定日期,开始时间,结束时间.然后,他们可以指定是否需要除非之外的某种类型的重复.如果是这样,应用程序会扩展网页的相关部分,为用户提供上述内容所需的选项,看起来很像Outlook选项,除了每天都没有"每个工作日"重复出现(这是多余的)每个星期一每周复发,并且没有每年复发.如果有重复,那么我还要求用户指定一个在今天一年内的结束日期(用户希望这样,并简化我的代码) - 我不做无休止的重复或"结束后# #occurrence."
我将这些字段与用户选择存储在我的事件表中,并在具有所有事件的计划表中展开它.这有利于碰撞检测(我实际上正在进行设施预约应用)和编辑个别事件或重构未来事件.
我的用户都在CST,我感谢好主.现在这是一个有用的简化,如果将来用户群将扩展到那个以外,那么我可以弄清楚如何处理它,作为一个分离良好的任务.
更新 自从我第一次写这篇文章以来,我确实每天都会添加"每个工作日".我们的用户有一段时间的困难,他们认为您可以使用每周重复发生从周四一周到下周二周二发生的事件,并且仅在工作日发生.即使已经有另一种方式可以做到这一点,他们更直观地拥有它.