停车场的数据仓库设计——日期和时间维度
Data warehouse design for parking lot - date and time dimensions
我遇到了一道数据仓库练习题。我试图想出各种方法来设计这个,但我不确定最佳实践是什么。问题涉及为停车场设计数据仓库并编写 SQL 查询以获取停车费。
约束条件如下:
工作日每小时费率
双轮车 - 1$
四轮车 - 2$
周末时薪
双轮车 - 2$
四轮车 - 3$
一辆车从周五早上 9 点停到周六上午 10 点。设计一个数据仓库来存储这些数据,并写一个SQL来获取车辆的停车费。
我只能想到以下两种表示方式,
- 方法一
具有 date_id、time_id 和类型。在这里查询停车费可能很困难,因为我们没有一小时的数据。停车费计算困难但耗流量少
fact_parking_lot_data
fact_key
vehicle_id
date_id
time_id
type
1
1
20220506
9
in
2
1
20220507
22
out
- 方法二
一天中的每个小时都有 date_id、time_id。这将为车辆创建多个事实 table 条目,如果车辆停放 2 天,那么它将有 48 条记录。停车费计算简单但占用大量存储空间
fact_parking_lot_data
fact_key
vehicle_id
date_id
time_id
1
1
20220506
9
2
1
20220506
10
3
1
20220506
11
4
1
20220506
12
.
.
.
.
.
.
.
.
.
.
.
.
26
1
20220507
10
如有任何想法或建议,我们将不胜感激。谢谢!
您的模型是累积快照的明确示例 table:维度的外键为 vehicle_id、date_in_id、date_out_id、time_in_id 和 time_out_id。并作为衡量停车时间的标准。
当汽车进来时,date_in_id 和 time_in_id 会出现,但 date_out_id、time_out_id 和持续时间不会出现。当汽车离开时,date_out_id、time_out_id 和持续时间将被填充。
这为您提供了一个自然的指标来计算:一天或几天的总持续时间。
累积快照的缺点是它需要查找事实 table 并更新“out”事件,但我猜你的事实 table 不会太大(您的模型中没有 location_id,所以我假设我们每天谈论的是几百辆汽车,可能多达几千辆)。
如果您对累积的快照不满意,那么我在您建议的两个模型之间的偏好是第二个,其中每小时在汽车停放时填充。
现在,几点说明:
- 你的模型只考虑了时间。您可能希望时间键包括分钟和秒。即使您现在不使用它,如果将来需要分秒必争的分辨率,它也会为您提供成长空间(当然,在这种情况下,您的第二个模型会变得有点太大,因此累积快照成为显而易见的解决方案)
- 注意夏令时和任何其他可能的未来时区变化。如果汽车可以在周末停放过夜,您可能会有一个从周六晚上 8 点开始到周日早上 8 点结束的停车事件,实际上在 DST 转换期间持续 11 或 13 个小时。选择一个时区并坚持下去。
- 加一个location_id。当然,也许现在您所有的停车事件都发生在一个地点,但将来可能会有其他地点。现在包含一个维度而不使用它比以后必须添加它更好
- 添加车辆 class 维度。该维度应该是 SCD Type II,具有轮子数量和单价等属性。价格变化时,插入新的单价,版本控制确保历史记录得以保留。
累积快照与您的第二个模型(每个时间段 1 行)相比的缺点:没有简单的方法来计算在给定时间停放了多少辆汽车。您必须计算整个事实的行数 table where
(date_in_id < X or (date_in_id = X and time_in_id <= Y))
and
(date_out_id > X or (date_out_id = X and time_out_id > Y))
而您的模型允许您通过计算所有具有
的车辆来快速计算在任何给定时刻停放的汽车数量
date_id = X and time_id = Y
我遇到了一道数据仓库练习题。我试图想出各种方法来设计这个,但我不确定最佳实践是什么。问题涉及为停车场设计数据仓库并编写 SQL 查询以获取停车费。
约束条件如下:
工作日每小时费率
双轮车 - 1$
四轮车 - 2$
周末时薪
双轮车 - 2$
四轮车 - 3$
一辆车从周五早上 9 点停到周六上午 10 点。设计一个数据仓库来存储这些数据,并写一个SQL来获取车辆的停车费。
我只能想到以下两种表示方式,
- 方法一
具有 date_id、time_id 和类型。在这里查询停车费可能很困难,因为我们没有一小时的数据。停车费计算困难但耗流量少
fact_parking_lot_data
fact_key | vehicle_id | date_id | time_id | type |
---|---|---|---|---|
1 | 1 | 20220506 | 9 | in |
2 | 1 | 20220507 | 22 | out |
- 方法二
一天中的每个小时都有 date_id、time_id。这将为车辆创建多个事实 table 条目,如果车辆停放 2 天,那么它将有 48 条记录。停车费计算简单但占用大量存储空间
fact_parking_lot_data
fact_key | vehicle_id | date_id | time_id |
---|---|---|---|
1 | 1 | 20220506 | 9 |
2 | 1 | 20220506 | 10 |
3 | 1 | 20220506 | 11 |
4 | 1 | 20220506 | 12 |
. | . | . | . |
. | . | . | . |
. | . | . | . |
26 | 1 | 20220507 | 10 |
如有任何想法或建议,我们将不胜感激。谢谢!
您的模型是累积快照的明确示例 table:维度的外键为 vehicle_id、date_in_id、date_out_id、time_in_id 和 time_out_id。并作为衡量停车时间的标准。
当汽车进来时,date_in_id 和 time_in_id 会出现,但 date_out_id、time_out_id 和持续时间不会出现。当汽车离开时,date_out_id、time_out_id 和持续时间将被填充。
这为您提供了一个自然的指标来计算:一天或几天的总持续时间。
累积快照的缺点是它需要查找事实 table 并更新“out”事件,但我猜你的事实 table 不会太大(您的模型中没有 location_id,所以我假设我们每天谈论的是几百辆汽车,可能多达几千辆)。
如果您对累积的快照不满意,那么我在您建议的两个模型之间的偏好是第二个,其中每小时在汽车停放时填充。
现在,几点说明:
- 你的模型只考虑了时间。您可能希望时间键包括分钟和秒。即使您现在不使用它,如果将来需要分秒必争的分辨率,它也会为您提供成长空间(当然,在这种情况下,您的第二个模型会变得有点太大,因此累积快照成为显而易见的解决方案)
- 注意夏令时和任何其他可能的未来时区变化。如果汽车可以在周末停放过夜,您可能会有一个从周六晚上 8 点开始到周日早上 8 点结束的停车事件,实际上在 DST 转换期间持续 11 或 13 个小时。选择一个时区并坚持下去。
- 加一个location_id。当然,也许现在您所有的停车事件都发生在一个地点,但将来可能会有其他地点。现在包含一个维度而不使用它比以后必须添加它更好
- 添加车辆 class 维度。该维度应该是 SCD Type II,具有轮子数量和单价等属性。价格变化时,插入新的单价,版本控制确保历史记录得以保留。
累积快照与您的第二个模型(每个时间段 1 行)相比的缺点:没有简单的方法来计算在给定时间停放了多少辆汽车。您必须计算整个事实的行数 table where
(date_in_id < X or (date_in_id = X and time_in_id <= Y))
and
(date_out_id > X or (date_out_id = X and time_out_id > Y))
而您的模型允许您通过计算所有具有
的车辆来快速计算在任何给定时刻停放的汽车数量date_id = X and time_id = Y