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

Max*_*Max 1 java sql database-design google-cloud-datastore

每个人。我想弄清楚 Google Datastore 是否是我的最佳选择。

我需要存储员工的日程安排,例如:

id
name
schedule 
Run Code Online (Sandbox Code Playgroud)

时间表如下:

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

如果员工现在工作与否,API 之一将返回

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

.. WHERE current_time>start_time AND current_time<close_time

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

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

  1. 有什么方法可以将数据存储用于我的任务吗?还是最好去sql?
  2. 如何设计我的数据库以在 datasore/sql 中存储计划?

提前致谢!

Dan*_*ath 5

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

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

0. 你的实体模型

我将使用以下稻草人实体

实体种类:员工
- id:自动 id
- 名称:字符串
- 时间表:重复整数,索引

2. 将一天分成 30 分钟

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

  • 0 = 12:00 AM 到 12:30 AM
  • 30 = 中午 12:30 至凌晨 1:00
  • 60 = 凌晨 1:00 至凌晨 1:30
  • ...
  • 1380 = 晚上 11:00 至晚上 11:30
  • 1440 = 晚上 11:30 至凌晨 12:00

这个整数很容易从您当前的时间推导出来。使用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
Run Code Online (Sandbox Code Playgroud)

我在 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;
Run Code Online (Sandbox Code Playgroud)

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

4. 存储时间表

现在,不是将您的日程表存储为每天的开始和停止时间,而是使用上述相同的想法来存储 Employee 计划的每 30 分钟时间段。在您的示例中,您有:

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

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

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
Run Code Online (Sandbox Code Playgroud)

5.查询时间!

查询现在非常容易,只是一个等式。这将为您现在工作的每个 Employee 实体提供 O(1) 的性能,或者更一般地说 O(n),其中n是现在工作的员工数量(与员工总数相反)。

... WHERE schedule=day_period
Run Code Online (Sandbox Code Playgroud)