关于存储具有许多不同列的不同类型的数据文件(历史和实时)的数据库模式



我有一些数据(最初在数据文件中)想要存储在数据库中。

数据文件可能具有不同的跟踪策略,因此具有不同的列。

跟踪数据A:

NodeID
Date
max_X@9am-10am 
min_X@9am-10am
max_Y@9am-10am 
min_Y@9am-10am
max_speed@9am-10am
min_speed@9am-10am
max_X@10am-11am 
min_X@10am-11am
max_Y@10am-11am 
min_Y@10am-11am
max_speed@10am-11am
min_speed@10am-11am
...

跟踪数据B:

NodeID
Date
avg_X@9am-9:30am 
avg_Y@9am-9:30am 
avg_speed@9am-9:30am
avg_X@10am-10:30am 
avg_Y@10am-10:30am 
avg_speed@10am-10:30am
...

跟踪数据C:

NodeId
Date
avg_X@the.whole.day
avg_Y@the.whole.day
min_X@the.whole.day
max_X@the.whole.day
min_Y@the.whole.day
max_Y@the.whole.day
sum_MovingDistance@the.whole.day
avg_Speed@the.whole.day

简而言之,一个数据文件以不同的时间间隔存储某个节点在给定日期的位置范围、速度。在数据文件之外有区域层次结构,例如国家:美国。

然后,每一个跟踪数据都有两个版本,一个是历史版本,另一个是实时版本。历史包含汇总数据,它们不会更改。实时数据是在时间的推进过程中生成的。当时间未达到时间间隔时,没有值(NA)。当时间在一个时间间隔内时,每次生成实时数据文件时,值都会发生变化。

所以我有一些选择

一:将不同类型的数据文件存储在不同的表中,数据库表的列可以与数据文件中的列相匹配。这会导致许多失误,这通常是一件应该避免的坏事吗?

二:在一个表中遍历数据文件。有点像

Area, NodeID, TrackingStratygy, VarName,             Value    DataType    recordTime  
US    KKEA1   A                 max_X@9am-10am        ??      real-time   09:55@20111203
US    KKEA1   B                 avg_X@9am-9:30am      ??      real-time   09:55@20111203
US    KKEA1   C                 avg_Y@the.whole.day   ??      daily       00:00@20111202

这方面的问题是区域、nodeID、跟踪stratyg和varname的大规模复制。

欢迎任何评论和意见。

谢谢。

您需要做的第一件事就是计算出您想要的最终结果。大概是某种报告?

最终结果是否需要以相同的格式显示所有内容(历史/新内容)?

历史数据是否要归档?

新数据是以不同的格式生成的吗?这是数据库必须反映的业务需求吗?

我相信还有其他问题。。。

如果新数据是以不同的格式生成的;如果您需要报告这些格式,那么最简单(不一定是最好的)的选择就是使用多个表(如果不是多个db实例的话)。

如果您正在对报告进行标准化,那么您将需要了解以每种格式复制哪些字段,以及哪些字段可以从源数据创建,而这些字段不是精确的副本。然后,它就变成了一个标准化任务,为不匹配的数据提供了单独的表。

您的示例"二:将数据文件存储在一个表中"非常可怕。如果你正沿着这条路走下去,那么你可以将任何东西正常化,例如Area、NodeID等。

最终,就我而言,这是一个商业逻辑问题,而不是数据库问题。找出需求并对数据库进行建模,使最终用户尽可能简单地检索数据,而不影响您可能拥有的任何安全/存储/业务规则。

选项一将是"官方"方法;只要您可以通过组合表中的条目来重新构造行,就很好(尽管连接表确实需要时间/精力)。

选项二看起来更适合拥有一组动态字段。对于你所描述的,我认为它的方式太灵活了;你需要的开销太大。

另一种选择是有一个表,包含所有可能的字段,其中一些字段对于某些记录是空的。这在空间方面有些低效,但避免了必须连接记录的开销。如果这些字段不多,并且包含这些字段的记录也不多,那么开销可能值得只使用一个表,并避免联接。

如果你能改变它,把你的传入数据改成这种格式可能是最好的:

Tracking_Data
====================
nodeId  -- along with locationTrackedInstant, the unique PK
locationTrackedInstant -- timestamp, in terms of UTC
xPosition  -- whatever your RDBMS uses for location info, and dependent on scale
yPosition
areaId -- Only use if x/y aren't GPS coordinates, as I suspect they may be.

这将允许你提取你想要的任何信息,比你当前的数据要好得多(例如,09:30到10:30之间的平均速度是多少?)。在所有选项中,它可能需要最少的空间来存储,尽管您会损失一些聚合函数的处理时间(但如果您的RDBMS已经物化了视图,您可以将其交换回来)。

您可以几乎将其重组为如下所示的单个表:

Tracking_Data          -- why, oh why, are these at different resolutions?
                       -- and seperated?  They measure the same things...
======================
nodeId
aggregatePeriodStart  -- timestamp
periodDurationInSeconds  -- only due to aggregates.  Alternate units possible.
min_X
max_X
avg_X
min_Y
max_Y
avg_Y
max_Speed
min_Speed
avg_Speed
distance_travelled

然而,你有不同分辨率的数据——至关重要的是,最大/最小值的分辨率比平均值高(反之亦然)。不幸的是,您无法推断"丢失"的数据,因为它实际上并不正确。所以,你被一些看起来相似的表格卡住了:

Tracking_Data_A
====================
nodeId
aggregatePeriodStart  -- timestamp
perdiodDurationInHours
min_X
max_X
min_Y
max_Y
min_Speed
max_Speed
Tracking_Data_B
===================
nodeId
aggregatePeriodStart  -- timestamp
periodDurationInMinutes
avg_X
avg_Y
avg_Speed
Tracking_Data_C
===================
nodeId
aggregateDate  -- date, not timestamp
min_X
max_X
avg_X
min_X
max_X
avg_Y
avg_Speed
distanceTravelled

与所包含的实际数据的开销相比,每个单独的表的开销是最小的。尽管EAV表具有可感知的"灵活性",但您最终会使用怪物语句来重构任何内容;它们也不能正确地索引或排序
哦,别忘了对你的单位进行资格认证——特别是速度和距离(英里与公里)。

最新更新