考虑以下情况:
有一个Action
表,其中包含字段-id
,start_time
,end_time
和group_id
。
有一个ActionGroup
表,该表具有一组多个操作的字段-id
,start_time
和end_time
(请注意,操作顺序发生)。 / p>
ActionGroup
与Action
具有一对多关系。
例如:
如果有四个Action
记录,
相关的ActionGroup
记录如下
Action
表似乎已经包含ActionGroup
表所需的数据,而ActionGroup
实际上是在重复它。
是否可以通过简单而高效的方式查询ActionGroup
的开始时间和结束时间,而不必分别记录start_time
内的end_time
和ActionGroup
字段?
此外,在设计表模式时,像上面那样复制数据是否被认为是不好的做法?
答案 0 :(得分:1)
首先要回答的最后一个问题:数据重复不好,因为它会带来不一致的风险,例如如果您的ActionGroup
1已向end_time
注册(例如)8,而Action
与end_time
13已注册。如果数据不一致,则您将无法信任任何数据查询结果,因为不一致的逻辑系统根本无法产生任何结果。
在您的示例中,可以使用聚合查询(关系代数伪代码)从ActionGroup
派生Action
:
Action group by { group_id } add {
Min(start_time) start_time,
Max(end_time) end_time
}
rename { group_id id }
–因此,您不需要Action
relvar(表)中的那些属性。这很简单;是否足够快取决于您的要求。
但是请注意,如果您确实在start_time
中保留了冗余end_time
和ActionGroup
属性,则需要控制冗余(最好使用约束,或者使用触发操作,或者使用最坏的情况是应用程序代码),以避免不一致。这也会影响性能,但它们将适用于写入而不是读取。
答案 1 :(得分:1)
我认为您不需要示例中的
ActionGroup
表
在您的示例Action
表中,已经具有操作组的所有信息(group_id,start_time,end_time)
您可以只使用Action
表来获取start_time和end_time的最小值,最大值,但是如果您需要ActionGroup
上的更多字段并获取该组的Actions的start_time和end_time,请尝试类似这个。
SELECT *
FROM `ActionGroup` as action_group
INNER JOIN (
SELECT group_id, min(start_time), max(end_time)
FROM ACTION
GROUP BY group_id) as action
ON action_group.id = action.group_id
答案 2 :(得分:0)
看来
Action
表已经包含了ActionGroup
表需要,而ActionGroup
实际上在重复它。
我认为您是对的,您只是根据您的示例在重复一遍。如果仅使用ActionGroup
来存储最低(0)的start_time和最高(13)的end_time,因为Action
已经具有group_id,则可以使用
Select start_time in Action where group_id = '1' order by start_time;
然后ActionGroup
根本没有目标,但是如果您想实现更多目标,那么我认为创建ActionGroup
是个好主意。
例如:
有一个ActionGroup表,其中包含字段-id,start_time和 一组多个动作的结束时间(请注意,动作会发生 顺序)。
如果您有一个开始时间为4、8、2、2、10的动作,那么我们知道2将存储在ActionGroup
中,但是Action
是什么呢?然后,您可以执行类似start_time_id而不是start_time的操作。
以下是一些用于创建表格的阅读材料,可以帮助您: