|
| 1 | +# 数仓开发之ODS层 |
| 2 | + |
| 3 | +优秀可靠的数仓体系,需要良好的数据分层结构。合理的分层,能够使数据体系更加清晰,使复杂问题得以简化。以下是该项目的分层规划。 |
| 4 | + |
| 5 | +## 1 设计要点 |
| 6 | + |
| 7 | +(1)ODS层的表结构设计依托于从业务系统同步过来的数据结构 |
| 8 | + |
| 9 | +(2)ODS层要保存全部历史数据,故其压缩格式应选择压缩比较高的,此处选择gzip |
| 10 | + |
| 11 | +(3)ODS层表名的命名规范为:ods_表名_单分区增量全量标识(inc/full)。 |
| 12 | + |
| 13 | +## 2 相关表 |
| 14 | + |
| 15 | +### 2.1 整车日志表(增量日志表) |
| 16 | + |
| 17 | +```sql |
| 18 | + |
| 19 | +create external table ods_car_data_inc |
| 20 | + |
| 21 | +( |
| 22 | + |
| 23 | + `vin` string comment '汽车唯一ID', |
| 24 | + |
| 25 | + `car_status` int comment '车辆状态', |
| 26 | + |
| 27 | + `charge_status` int comment '充电状态', |
| 28 | + |
| 29 | + `execution_mode` int comment '运行模式', |
| 30 | + |
| 31 | + `velocity` int comment '车速', |
| 32 | + |
| 33 | + `mileage` int comment '里程', |
| 34 | + |
| 35 | + `voltage` int comment '总电压', |
| 36 | + |
| 37 | + `electric_current` int comment '总电流', |
| 38 | + |
| 39 | + `soc` int comment 'SOC', |
| 40 | + |
| 41 | + `dc_status` int comment 'DC-DC状态', |
| 42 | + |
| 43 | + `gear` int comment '挡位', |
| 44 | + |
| 45 | + `insulation_resistance` int comment '绝缘电阻', |
| 46 | + |
| 47 | + `motor_count` int comment '驱动电机个数', |
| 48 | + |
| 49 | + `motor_list` array<struct<`id` :int, `status` :int, `rev` :int, `torque` :int, |
| 50 | + |
| 51 | + `controller_temperature` :int, `temperature` :int, |
| 52 | + |
| 53 | + `voltage` |
| 54 | + |
| 55 | + :int, `electric_current` :int>> comment '驱动电机列表', |
| 56 | + |
| 57 | + `fuel_cell_voltage` int comment '燃料电池电压', |
| 58 | + |
| 59 | + `fuel_cell_current` int comment '燃料电池电流', |
| 60 | + |
| 61 | + `fuel_cell_consume_rate` int comment '燃料消耗率', |
| 62 | + |
| 63 | + `fuel_cell_temperature_probe_count` int comment '燃料电池温度探针总数', |
| 64 | + |
| 65 | + `fuel_cell_temperature` int comment '燃料电池温度值', |
| 66 | + |
| 67 | + `fuel_cell_max_temperature` int comment '氢系统中最高温度', |
| 68 | + |
| 69 | + `fuel_cell_max_temperature_probe_id` int comment '氢系统中最高温度探针号', |
| 70 | + |
| 71 | + `fuel_cell_max_hydrogen_consistency` int comment '氢气最高浓度', |
| 72 | + |
| 73 | + `fuel_cell_max_hydrogen_consistency_probe_id` int comment '氢气最高浓度传感器代号', |
| 74 | + |
| 75 | + `fuel_cell_max_hydrogen_pressure` int comment '氢气最高压力', |
| 76 | + |
| 77 | + `fuel_cell_max_hydrogen_pressure_probe_id` int comment '氢气最高压力传感器代号', |
| 78 | + |
| 79 | + `fuel_cell_dc_status` int comment '高压DC-DC状态', |
| 80 | + |
| 81 | + `engine_status` int comment '发动机状态', |
| 82 | + |
| 83 | + `crankshaft_speed` int comment '曲轴转速', |
| 84 | + |
| 85 | + `fuel_consume_rate` int comment '燃料消耗率', |
| 86 | + |
| 87 | + `max_voltage_battery_pack_id` int comment '最高电压电池子系统号', |
| 88 | + |
| 89 | + `max_voltage_battery_id` int comment '最高电压电池单体代号', |
| 90 | + |
| 91 | + `max_voltage` int comment '电池单体电压最高值', |
| 92 | + |
| 93 | + `min_temperature_subsystem_id` int comment '最低电压电池子系统号', |
| 94 | + |
| 95 | + `min_voltage_battery_id` int comment '最低电压电池单体代号', |
| 96 | + |
| 97 | + `min_voltage` int comment '电池单体电压最低值', |
| 98 | + |
| 99 | + `max_temperature_subsystem_id` int comment '最高温度子系统号', |
| 100 | + |
| 101 | + `max_temperature_probe_id` int comment '最高温度探针号', |
| 102 | + |
| 103 | + `max_temperature` int comment '最高温度值', |
| 104 | + |
| 105 | + `min_voltage_battery_pack_id` int comment '最低温度子系统号', |
| 106 | + |
| 107 | + `min_temperature_probe_id` int comment '最低温度探针号', |
| 108 | + |
| 109 | + `min_temperature` int comment '最低温度值', |
| 110 | + |
| 111 | + `alarm_level` int comment '报警级别', |
| 112 | + |
| 113 | + `alarm_sign` int comment '通用报警标志', |
| 114 | + |
| 115 | + `custom_battery_alarm_count` int comment '可充电储能装置故障总数N1', |
| 116 | + |
| 117 | + `custom_battery_alarm_list` array<int> comment '可充电储能装置故障代码列表', |
| 118 | + |
| 119 | + `custom_motor_alarm_count` int comment '驱动电机故障总数N2', |
| 120 | + |
| 121 | + `custom_motor_alarm_list` array<int> comment '驱动电机故障代码列表', |
| 122 | + |
| 123 | + `custom_engine_alarm_count` int comment '发动机故障总数N3', |
| 124 | + |
| 125 | + `custom_engine_alarm_list` array<int> comment '发动机故障代码列表', |
| 126 | + |
| 127 | + `other_alarm_count` int comment '其他故障总数N4', |
| 128 | + |
| 129 | + `other_alarm_list` array<int> comment '其他故障代码列表', |
| 130 | + |
| 131 | + `battery_count` int comment '单体电池总数', |
| 132 | + |
| 133 | + `battery_pack_count` int comment '单体电池包总数', |
| 134 | + |
| 135 | + `battery_voltages` array<int> comment '单体电池电压值列表', |
| 136 | + |
| 137 | + `battery_temperature_probe_count` int comment '单体电池温度探针总数', |
| 138 | + |
| 139 | + `battery_pack_temperature_count` int comment '单体电池包总数', |
| 140 | + |
| 141 | + `battery_temperatures` array<int> comment '单体电池温度值列表', |
| 142 | + |
| 143 | + \`timestamp\` bigint comment '日志采集时间' |
| 144 | +
|
| 145 | +) |
| 146 | +
|
| 147 | + comment '整车日志表' |
| 148 | +
|
| 149 | + partitioned by (`dt` string comment '统计日期') |
| 150 | +
|
| 151 | + ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.JsonSerDe' |
| 152 | +
|
| 153 | + location '/warehouse/car_data/ods/ods_car_data_inc'; |
| 154 | +``` |
| 155 | + |
| 156 | +### 2.2 汽车信息表(全量表) |
| 157 | + |
| 158 | +```sql |
| 159 | +drop table if exists ods_car_info_full; |
| 160 | +CREATE EXTERNAL TABLE IF NOT EXISTS ods_car_info_full ( |
| 161 | + `id` string COMMENT '车辆唯一编码', |
| 162 | + `type_id` string COMMENT '车型ID', |
| 163 | + `type` string COMMENT '车型', |
| 164 | + `sale_type` string COMMENT '销售车型', |
| 165 | + `trademark` string COMMENT '品牌', |
| 166 | + `company` string COMMENT '厂商', |
| 167 | + `seating_capacity` int COMMENT '准载人数', |
| 168 | + `power_type` string COMMENT '车辆动力类型', |
| 169 | + `charge_type` string COMMENT '车辆支持充电类型', |
| 170 | + `category` string COMMENT '车辆分类', |
| 171 | + `weight_kg` int COMMENT '总质量(kg)', |
| 172 | + `warranty` string COMMENT '整车质保期(年/万公里)' |
| 173 | +) |
| 174 | +COMMENT '整车信息表' |
| 175 | +PARTITIONED BY (dt string COMMENT '统计日期') |
| 176 | +ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' |
| 177 | +LOCATION '/warehouse/car_data/ods/ods_car_info_full'; |
| 178 | +``` |
| 179 | + |
| 180 | +## 3 数据装载 |
| 181 | + |
| 182 | +```shell |
| 183 | +#!/bin/bash |
| 184 | +
|
| 185 | +APP='car_data' |
| 186 | +
|
| 187 | +# 判断第二个参数是否填写 如果填写使用作为日期 如果没有填写 默认使用昨天作为日期 |
| 188 | +if [ -n "$2" ]; then |
| 189 | + # statements |
| 190 | + do_date=$2 |
| 191 | +else |
| 192 | + do_date=`date -d '-1 day' +%F` |
| 193 | +fi |
| 194 | +
|
| 195 | +case "$1" in |
| 196 | + "ods_car_data_inc") |
| 197 | + hive -e "LOAD DATA INPATH '/origin_data/car_data_ful1/$do_date' INTO TABLE $APP.ods_car_data_inc PARTITION (dt='$do_date');" |
| 198 | + ;; |
| 199 | + "ods_car_info_full") |
| 200 | + hive -e "LOAD DATA INPATH '/origin_data/car_info_full/$do_date' INTO TABLE $APP.ods_car_info_full PARTITION (dt='$do_date');" |
| 201 | + ;; |
| 202 | + "all") |
| 203 | + hive -e "LOAD DATA INPATH '/origin_data/car_data_ful1/$do_date' INTO TABLE $APP.ods_car_data_inc PARTITION (dt='$do_date');" |
| 204 | + hive -e "LOAD DATA INPATH '/origin_data/car_info_full/$do_date' INTO TABLE $APP.ods_car_info_full PARTITION (dt='$do_date');" |
| 205 | + ;; |
| 206 | + *) |
| 207 | + echo "Usage: $0 {ods_car_data_inc|ods_car_info_full|all}" |
| 208 | + ;; |
| 209 | +esac |
| 210 | +``` |
| 211 | + |
| 212 | +确保在Hive加载数据之前,数据文件已经存在于对应的HDFS路径中,且表的分区字段名是正确的。在运行脚本之前,授予其执行权限,使用以下命令。然后根据你的需求执行脚本: |
| 213 | + |
| 214 | +```bash |
| 215 | +./your_script_name.sh ods_car_data_inc |
| 216 | +./your_script_name.sh ods_car_info_full |
| 217 | +
|
| 218 | +./your_script_name.sh all 2024-03-11 |
| 219 | +``` |
| 220 | + |
| 221 | +写好脚本,以后放入 dophinschedule 调度器每天跑就行。实现将 HDFS 数据载入 ods表 中。 |
0 commit comments