当前位置: 首页 > 面试题库 >

储存工作时间并有效查询的最佳方法

曹华荣
2023-03-14
问题内容

我打算存储商店的工作时间。我想知道在工作时间字段中最好的建模方法是什么,这样我就可以以非常有效的方式获得当前时刻开/关商店的列表。


问题答案:

要存储正常的工作时间,您需要存储一些记录,其中包含:

  • 商店-INTEGER
  • DayOfWeek-整数(0-6)
  • 营业时间-TIME
  • 关闭时间-TIME

例如,我假设每个商店在国定假日减少工作时间或关闭工厂,因此您还需要存储一些替代记录:

  • 商店-INTEGER
  • OverrideStartDate-DATE
  • OverrideEndDate-DATE
  • DayOfWeek-整数(0-6)
  • AltOpenTime-时间
  • AltCloseTime-TIME
  • 已关闭-INTEGER(0,1)

要找到开放式商店并不容易,但是您还需要检查是否有超车时间:

SELECT Shop
FROM OverrideHours
WHERE OverrideStartDate <= NOW()
AND OverrideEndDate >= NOW()
AND DayOfWeek = WEEKDAY(NOW())

如果返回任何记录,则这些商店将有其他时间或关闭。

您可以在此处执行一些不错的SQL-fu,但这为您提供了基础知识。

编辑

我还没有测试过,但这应该可以使您接近:

SELECT Normal.Shop
FROM Normal
LEFT JOIN Override
ON Normal.Shop = Override.Shop
AND Normal.DayOfWeek = Override.DayOfWeek
AND NOW() BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate
WHERE Normal.DayOfWeek = WEEKDAY(NOW())
AND ((Override.Shop IS NULL AND TIME(NOW()) BETWEEN Normal.OpenTime AND Normal.CloseTime)
 OR  (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(NOW()) BETWEEN Override.AltOpenTime AND Override.AltCloseTime))

编辑

至于效率,从某种意义上讲,它是高效的,您只需要对MySQL进行一次调用,而如果它是跨网络的,则通常是瓶颈。您必须进行测试,看看它是否符合您的规格。如果没有,您可能会玩一些索引。

编辑

测试。没有完成测试,但是有些。

mysql> select * from Normal;
+------+-----------+----------+-----------+
| Shop | DayOfWeek | OpenTime | CloseTime |
+------+-----------+----------+-----------+
|    1 |         1 | 09:00:00 | 17:00:00  | 
|    1 |         5 | 09:00:00 | 16:00:00  | 
|    2 |         1 | 09:00:00 | 17:00:00  | 
|    2 |         5 | 09:00:00 | 17:00:00  | 
+------+-----------+----------+-----------+
4 rows in set (0.01 sec)

mysql> select * from Override;
+------+-------------------+-----------------+-----------+-------------+--------------+--------+
| Shop | OverrideStartDate | OverrideEndDate | DayOfWeek | AltOpenTime | AltCloseTime | Closed |
+------+-------------------+-----------------+-----------+-------------+--------------+--------+
|    2 | 2010-12-01        | 2010-12-31      |         1 | 09:00:00    | 18:00:00     |      0 | 
|    2 | 2010-12-01        | 2010-12-31      |         5 | 09:00:00    | 18:00:00     |      0 | 
|    1 | 2010-12-01        | 2010-12-31      |         1 | 09:00:00    | 17:00:00     |      1 | 
+------+-------------------+-----------------+-----------+-------------+--------------+--------+
3 rows in set (0.00 sec)

mysql> SET @whenever = TIMESTAMP('2010-11-23 16:05');
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT WEEKDAY(@whenever);
+--------------------+
| WEEKDAY(@whenever) |
+--------------------+
|                  1 | 
+--------------------+
1 row in set (0.00 sec)

mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime)  OR  (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime));
+------+
| Shop |
+------+
|    1 | 
|    2 | 
+------+
2 rows in set (0.00 sec)

mysql> SET @whenever = TIMESTAMP('2010-11-23 17:05');
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime)  OR  (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime));
Empty set (0.01 sec)

mysql> SET @whenever = TIMESTAMP('2010-12-25 16:05');
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime)  OR  (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime));
+------+
| Shop |
+------+
|    2 | 
+------+
1 row in set (0.00 sec)

mysql> SET @whenever = TIMESTAMP('2010-11-23 17:05');
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT WEEKDAY(@whenever);
+--------------------+
| WEEKDAY(@whenever) |
+--------------------+
|                  1 | 
+--------------------+
1 row in set (0.00 sec)

mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime)  OR  (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime));
Empty set (0.00 sec)


 类似资料:
  • 我正在使用java servlet编写一个简单的服务器。为了从数据库中获取数据,我编写了一个特殊的Dao层类,我想知道我应该在哪里存储SQL查询? 我需要创建一个特殊的类,将查询存储为最终字符串,还是有更有效的方法来实现?

  • 我想要的桌子: 更新 谢了!我做了一些关于writetime的实验,因为我无论如何都要写值,所以我只写时间。 这给了我: 简单的基准测试在存储或从更大的表中读取时没有显著的性能差异。

  • 问题内容: 我在想这样的UTC时间字符串可能是可以的,因为如果在视图键中使用它们,则可以正确排序,但是存储时区(例如)会使文档更具可读性。从可读性的角度来看,将日期转换为纪元整数似乎没有什么吸引力,但对于性能而言可能是最好的选择(或者是否有所作为?)。这里推荐的做法是什么? 问题答案: 时间是一维的东西。时间戳加上时区是二维的,描述了时间点和位置。Couch视图是一维的(但不是GeoCouch插件

  • 问题内容: 我正在使用Hibernate检索特定查询的行数。假设我有一个名为“ Person”的表,其中包含各种列。这些列之一是“名称”。 如果我想获得带有“安德鲁”名字的人数,以下哪种方法最有效?假设某些/全部之间存在性能差异。使用Hibernate / SQL是否有更好的方法? (1)选择所有列 (2)仅选择名称列 (3)在查询中使用Count (4)在查询中的名称列中使用Count 编辑:对

  • 问题内容: 我正在使用Redis来存储一些信息并检测该信息随时间的变化(例如,考虑用户和位置)。使用更长或更短的键名的值是什么?使用更长的键会更清楚,但是使用更长的键名是否会在内存或性能上付出很多成本? 以下是示例: 要么 问题答案: 这完全取决于您将如何使用它。如果每个字节都很重要,例如,当您必须为传输到云服务的每个kB支付费用时,您可以计算成本。数学很简单;一个字节是“在线”上的一个字节。在r

  • 我想弄清楚我看到的一个问题。我注意到,当我通过添加一个新字段来更改实体对象定义时,有时我不再能够从数据存储中已经存在的先前记录中获得结果。例如,在下面的示例中,我可以看到数据存储中的实体,但我得到了以下异常: