數倉開發之ODS層

公众号-JavaEdge發表於2024-03-15

優秀可靠的數倉體系,需要良好的資料分層結構。合理的分層,能夠使資料體系更加清晰,使複雜問題得以簡化。以下是該專案的分層規劃。

1 設計要點

(1)ODS層的表結構設計依託於從業務系統同步過來的資料結構

(2)ODS層要儲存全部歷史資料,故其壓縮格式應選擇壓縮比較高的,此處選擇gzip

(3)ODS層表名的命名規範為:ods_表名_單分割槽增量全量標識(inc/full)。

2 相關表

2.1 整車日誌表(增量日誌表)

CREATE EXTERNAL TABLE ods_car_data_inc
(
  `vin`                                      STRING  COMMENT '汽車唯一ID',
  `car_status`                               INT     COMMENT '車輛狀態',
  `charge_status`                            INT     COMMENT '充電狀態',
  `execution_mode`                           INT     COMMENT '執行模式',
  `velocity`                                 INT     COMMENT '車速',
  `mileage`                                  INT     COMMENT '里程',
  `voltage`                                  INT     COMMENT '總電壓',
  `electric_current`                         INT     COMMENT '總電流',
  `soc`                                      INT     COMMENT 'SOC',
  `dc_status`                                INT     COMMENT 'DC-DC狀態',
  `gear`                                     INT     COMMENT '擋位',
  `insulation_resistance`                    INT     COMMENT '絕緣電阻',
  `motor_count`                              INT     COMMENT '驅動電機個數',
  `motor_list`                              ARRAY<STRUCT<
                                               `id`: INT,
                                               `status`: INT,
                                               `rev`: INT,
                                               `torque`: INT,
                                               `controller_temperature`: INT,
                                               `temperature`: INT,
                                               `voltage`: INT,
                                               `electric_current`: INT
                                             >>      COMMENT '驅動電機列表',
  `fuel_cell_voltage`                        INT     COMMENT '燃料電池電壓',
  `fuel_cell_current`                        INT     COMMENT '燃料電池電流',
  `fuel_cell_consume_rate`                   INT     COMMENT '燃料消耗率',
  `fuel_cell_temperature_probe_count`         INT     COMMENT '燃料電池溫度探針總數',
  `fuel_cell_temperature`                     INT     COMMENT '燃料電池溫度值',
  `fuel_cell_max_temperature`                 INT     COMMENT '氫系統中最高溫度',
  `fuel_cell_max_temperature_probe_id`        INT     COMMENT '氫系統中最高溫度探針號',
  `fuel_cell_max_hydrogen_consistency`        INT     COMMENT '氫氣最高濃度',
  `fuel_cell_max_hydrogen_consistency_probe_id`  INT COMMENT '氫氣最高濃度感測器代號',
  `fuel_cell_max_hydrogen_pressure`           INT     COMMENT '氫氣最高壓力',
  `fuel_cell_max_hydrogen_pressure_probe_id`   INT    COMMENT '氫氣最高壓力感測器代號',
  `fuel_cell_dc_status`                       INT     COMMENT '高壓DC-DC狀態',
  `engine_status`                             INT     COMMENT '發動機狀態',
  `crankshaft_speed`                          INT     COMMENT '曲軸轉速',
  `fuel_consume_rate`                         INT     COMMENT '燃料消耗率',
  `max_voltage_battery_pack_id`               INT     COMMENT '最高電壓電池子系統號',
  `max_voltage_battery_id`                    INT     COMMENT '最高電壓電池單體代號',
  `max_voltage`                              INT     COMMENT '電池單體電壓最高值',
  `min_temperature_subsystem_id`              INT     COMMENT '最低電壓電池子系統號',
  `min_voltage_battery_id`                    INT     COMMENT '最低電壓電池單體代號',
  `min_voltage`                              INT     COMMENT '電池單體電壓最低值',
  `max_temperature_subsystem_id`              INT     COMMENT '最高溫度子系統號',
  `max_temperature_probe_id`                  INT     COMMENT '最高溫度探針號',
  `max_temperature`                           INT     COMMENT '最高溫度值',
  `min_voltage_battery_pack_id`               INT     COMMENT '最低溫度子系統號',
  `min_temperature_probe_id`                  INT     COMMENT '最低溫度探針號',
  `min_temperature`                           INT     COMMENT '最低溫度值',
  `alarm_level`                              INT     COMMENT '報警級別',
  `alarm_sign`                               INT     COMMENT '通用報警標誌',
  `custom_battery_alarm_count`                INT     COMMENT '可充電儲能裝置故障總數N1',
  `custom_battery_alarm_list`                 ARRAY<INT> COMMENT '可充電儲能裝置故障程式碼列表',
  `custom_motor_alarm_count`                  INT     COMMENT '驅動電機故障總數N2',
  `custom_motor_alarm_list`                   ARRAY<INT> COMMENT '驅動電機故障程式碼列表',
  `custom_engine_alarm_count`                 INT     COMMENT '發動機故障總數N3',
  `custom_engine_alarm_list`                  ARRAY<INT> COMMENT '發動機故障程式碼列表',
  `other_alarm_count`                         INT     COMMENT '其他故障總數N4',
  `other_alarm_list`                          ARRAY<INT> COMMENT '其他故障程式碼列表',
  `battery_count`                             INT     COMMENT '單體電池總數',
  `battery_pack_count`                        INT     COMMENT '單體電池包總數',
  `battery_voltages`                          ARRAY<INT> COMMENT '單體電池電壓值列表',
  `battery_temperature_probe_count`            INT     COMMENT '單體電池溫度探針總數',
  `battery_pack_temperature_count`             INT     COMMENT '單體電池包總數',
  `battery_temperatures`                      ARRAY<INT> COMMENT '單體電池溫度值列表',
  `timestamp`                                 BIGINT  COMMENT '日誌採集時間'
)
COMMENT '整車日誌表'
PARTITIONED BY (`dt` STRING COMMENT '統計日期')
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.JsonSerDe'
LOCATION '/warehouse/car_data/ods/ods_car_data_inc';

2.2 汽車資訊表(全量表)

drop table if exists ods_car_info_full;
CREATE EXTERNAL TABLE IF NOT EXISTS ods_car_info_full (
  `id` string COMMENT '車輛唯一編碼',
  `type_id` string COMMENT '車型ID',
  `type` string COMMENT '車型',
  `sale_type` string COMMENT '銷售車型',
  `trademark` string COMMENT '品牌',
  `company` string COMMENT '廠商',
  `seating_capacity` int COMMENT '準載人數',
  `power_type` string COMMENT '車輛動力型別',
  `charge_type` string COMMENT '車輛支援充電型別',
  `category` string COMMENT '車輛分類',
  `weight_kg` int COMMENT '總質量(kg)',
  `warranty` string COMMENT '整車質保期(年/萬公里)'
)
COMMENT '整車資訊表'
PARTITIONED BY (dt string COMMENT '統計日期')
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
LOCATION '/warehouse/car_data/ods/ods_car_info_full';

3 資料裝載

#!/bin/bash

APP='car_data'

# 判斷第二個引數是否填寫 如果填寫使用作為日期 如果沒有填寫 預設使用昨天作為日期
if [ -n "$2" ]; then
	# statements
	do_date=$2
else
	do_date=`date -d '-1 day' +%F`
fi

case "$1" in
  "ods_car_data_inc")
    hive -e "LOAD DATA INPATH '/origin_data/car_data_ful1/$do_date' INTO TABLE $APP.ods_car_data_inc PARTITION (dt='$do_date');"
    ;;
  "ods_car_info_full")
    hive -e "LOAD DATA INPATH '/origin_data/car_info_full/$do_date' INTO TABLE $APP.ods_car_info_full PARTITION (dt='$do_date');"
    ;;
  "all")
    hive -e "LOAD DATA INPATH '/origin_data/car_data_ful1/$do_date' INTO TABLE $APP.ods_car_data_inc PARTITION (dt='$do_date');"
    hive -e "LOAD DATA INPATH '/origin_data/car_info_full/$do_date' INTO TABLE $APP.ods_car_info_full PARTITION (dt='$do_date');"
    ;;
  *)
    echo "Usage: $0 {ods_car_data_inc|ods_car_info_full|all}"
    ;;
esac

確保在Hive載入資料之前,資料檔案已經存在於對應的HDFS路徑中,且表的分割槽欄位名是正確的。在執行指令碼之前,授予其執行許可權,使用以下命令。然後根據你的需求執行指令碼:

./your_script_name.sh ods_car_data_inc
./your_script_name.sh ods_car_info_full

./your_script_name.sh all 2024-03-11

寫好指令碼,以後放入 dophinschedule 排程器每天跑就行。實現將 HDFS 資料載入 ods表 中。

關注我,緊跟本系列專欄文章,咱們下篇再續!

作者簡介:魔都技術專家兼架構,多家大廠後端一線研發經驗,各大技術社群頭部專家博主。具有豐富的引領團隊經驗,深厚業務架構和解決方案的積累。

負責:

  • 中央/分銷預訂系統效能最佳化
  • 活動&優惠券等營銷中臺建設
  • 交易平臺及資料中臺等架構和開發設計

目前主攻降低軟體複雜性設計、構建高可用系統方向。

參考:

  • 程式設計嚴選網

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章