我想创建一个数据库来存储流程周期时间数据。例如:
说某个产品的特定过程,比如焊接,理论上需要大约10秒钟(过程循环时间)。由于各种问题,机器的实际循环时间会在一天内变化。我希望全天存储机器的实际循环时间,并随时间(天,周,月)进行分析。我将如何为此设计数据库?
我考虑过使用时间序列数据库,但我觉得它不合适 - 循环时间数据有一个开始时间和一个结束时间 - 基本上我是测量时间性能随着时间的推移 - 如果这样做的话感。同时,我还担心使用关系数据库来存储然后显示/分析时间相关数据是低效的。
对于良好的数据库结构的任何想法将不胜感激。如果需要更多信息,请告诉我,我很乐意编辑此问题
答案 0 :(得分:2)
您正在跟踪事件的发生。事件(焊接)在某个时间开始并在某个时间结束。像这样对事件实体进行建模可能很诱人:
StationID StartTime StopTime
每个焊接站都有一个唯一的标识符。一些示例数据可能如下所示:
17 08:00:00 09:00:00
17 09:00:00 10:00:00
为简单起见,我将时间设置为较大的值(每个1小时)并删除日期值。这告诉您#17焊接站在上午8点开始焊接,并在上午9点结束,此时第二次焊接开始于上午10点结束。
这看起来很简单。但请注意,第一个条目的StopTime与第二个条目的StartTime匹配。当然可以,一个焊接的结束表示下一个焊缝的开始。这就是系统的设计方式。
但这会设置我称之为行跨越依赖性反模式:其中一行的一个字段的值必须与另一行中另一个字段的值同步。
这可能会产生任何问题。例如,如果第二个条目的StartTime显示'09:15:00'怎么办?现在我们在第一次焊接结束和下一次焊接开始之间有15分钟的间隙。系统不允许间隙 - 每个焊缝的末端也开始下一个焊缝。应该如何解释这个差距。第一行的StopTime是错误的吗?第二行的StartTime是错误的吗?都错了吗?或者它们之间是否有另一行被删除?无法确定哪种解释正确。
如果第二个条目的StartTime显示'08:45'怎么办?这是一个重叠,其中第二个循环的开始假设在第一个循环结束之前开始。同样,我们无法知道哪一行包含错误数据。
行跨越依赖性允许间隙和重叠,数据中不允许这两者。需要大量的数据库和应用程序代码来防止这种情况发生,并且当它确实发生时(确实会这样),没有办法确定哪些数据是正确的,哪些是错误的 - 不是从数据库中,即。
一个简单的解决方案是完全取消StopTime字段:
StationID StartTime
17 08:00:00
17 09:00:00
每个条目都表示焊接的开始。焊缝的末端由下一个焊缝的开始表示。这简化了数据模型,使得不可能有间隙或重叠,并且更精确地匹配我们正在建模的系统。
但我们需要两排数据来确定焊缝的长度。
select w1.StartTime, w2.StartTime as StopTime
from Welds w1
join Welds w2
on w2.StationID = w1.StationID
and w2.StartTime =(
select Max( StartTime )
from Welds
where StationID = w2.StationID
and StartTime < w2.StartTime );
这可能看起来像一个更复杂的查询,如果开始和停止时间在同一行 - 而且,它是 - 但想想所有那些不再需要编写和执行的检查代码在每个DML操作。由于StationID和StartTime的组合将是明显的PK,因此查询将仅使用索引数据。
还有一个建议。当天的第一次焊接或休息后(如午餐)以及当天的最后一次焊接或休息前的焊接情况如何?我们必须努力不将休息时间作为循环时间。我们可以包含智能来检测查询中的这种情况,但这会进一步增加复杂性。
另一种方法是在记录中包含状态值。
StationID StartTime Status
17 08:00:00 C
17 09:00:00 C
17 10:00:00 C
17 11:00:00 C
17 12:00:00 B
17 13:00:00 C
17 14:00:00 C
17 15:00:00 C
17 16:00:00 C
17 17:00:00 B
所以前几个条目代表一个周期的开始,而中午和下午5点的条目代表一个休息的开始。现在我们只需要添加一行
where w1.Status = 'C'
到上面的查询结束。因此,'B'条目提供前一周期的结束时间,但不开始另一个周期。