数据存储区是否适合存储小时班次?

时间:2016-09-26 05:57:29

标签: java sql database-design google-cloud-datastore

大家。 我想弄清楚Google Datastore是否是我个案中的最佳选择..

我需要按照以下时间表存储员工:

id
name
schedule 

时间表如下:

Mon   10am-10pm                 (simple)
Tue   10am-5pm, 5.30pm-8pm      (multiple, not even hours) 
..
Sun  6pm-4am                  (start/end are in different days)

如果员工现在正在工作,其中一个API会返回

我尝试使用数据存储但GQL查询似乎非常有限,例如您无法在一个查询中比较两个不同的属性(例如

.. WHERE current_time>start_time AND current_time<close_time

  

您不能使用不等于运算符(小于,等于)   同一查询中的不同属性名称。

这意味着我需要将大量实体加载到我的后台并解析它们,浪费时间和资源......而不是直接从数据库中获取结果

  1. 有没有办法为我的任务使用数据存储?或者更好的去sql?
  2. 如何设计我的数据库以在datasore / sql中存储日程安排?
  3. 提前感谢!

2 个答案:

答案 0 :(得分:4)

根据您的示例,我将假设工作班次以30分钟为增量。如果不是这种情况,您可以轻松调整以下内容,但您可能需要考虑一些优化。

以下解决方案将为员工提供持续的时间查看,无论他们工作多少班次。它还可以无缝地处理从一天到下一天的轮班。

0。您的实体模型

我将使用以下稻草人实体

实体种类:员工
   - id:自动识别
   - 名称:字符串
   - schedule:重复整数,索引

2。休息日为30分钟

24小时为您提供48个30分钟的周期,所以让我们将整数映射到时间段:

  • 0 = 12:00 AM至12:30 AM
  • 30 = 12:30 AM至凌晨1:00
  • 60 =凌晨1:00至凌晨1:30
  • ...
  • 1380 = 11:00 PM至11:30 PM
  • 1440 = 11:30 PM至12:00 AM

此整数很容易从您当前的时间推导出来。使用java.util.Calendarjava.util.Date

Date date = new Date(); // Initializes to now.
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTime(date);
int hour = calendar.get(Calendar.HOUR_OF_DAY); // Hour in 24h format
int minute = calendar.get(Calendar.MINUTE); // Minute of the hour

int period = hour*60 + minute/30*30; // Integer division rounds down to nearest 30

我在compilejava.net上测试了这个,测试代码在这里:https://gist.github.com/55a98bbdb9b5eb3eeaee5f8984f11687

3。星期几帐户

现在我们有30分钟的时段,我们应该在星期几合并(星期日= 0,星期六= 6)。由于最长30分钟的周期值是1440,因此可以方便地将一周中的几天乘以10000,这样我们就可以将它们加在一起而不会发生冲突:

int day = calendar.get(Calendar.DAY_OF_WEEK);
int day_period = day*10000 + period;

此处扩展了测试代码:https://gist.github.com/217221e03b3eb143b4be45bf3f641d25

4。存储时间表

现在,不要将您的日程安排存储为每天的开始和停止时间,而是使用上面相同的想法来存储员工安排的每30分钟的时间段。在你的例子中,你有:

Mon   10am-10pm                 (simple)
Tue   10am-5pm, 5.30pm-8pm      (multiple, not even hours) 
..
Sun  6pm-4am                  (start/end are in different days)

在计划字段(重复整数)中,这看起来像:

10600,10630,10660,10690,10720,10750,10780,10810,10840,10870,10900,10930,10960,10990,11020,
11050,11080,11110,11140,11170,11200,11230,11260,11290,20600,20630,20660,20690,20720,20750,
20780,20810,20840,20870,20900,20930,20960,20990,21050,21080,21110,21140,21170,1080,1110,
1140,1170,1200,1230,1260,1290,1320,1350,1380,1410,0,30,60,90,120,150,180,210

5。查询时间!

现在查询非常简单,只是平等。这将为每个现在正在工作的员工实体提供O(1)性能,或者更一般地为O(n),其中n是现在正在工作的员工数(而不是总员工数)。

... WHERE schedule=day_period

答案 1 :(得分:1)

您可以存储开始时间和结束时间的长表示。 1小时= 3600000毫秒。因此,如果00-00是参考点,则02-00将由2 x 3600000表示。
另一种选择是存储java.util.Date(一个用于开始时间,一个用于结束时间)