数据质量评估的8个维度
数据质量可以从八个维度进行衡量,分别是真实性、完整性、规范性、一致性、准确性、唯一性、关联性、及时性。
① 真实性:数据必须真实准确的反映客观的实体存在或真实的业务,是一切管理工作的基础。数据的真实性取决于数据采集过程的可控程度高,可追溯情况好,数据的真实性容易得到保障,而可控程度低或者无法追溯,数据造假后无法追溯,则真实性难以保证。
② 完整性:数据的完整性是从数据采集到的程度来衡量的,用于度量哪些数据丢失了或者哪些数据不可用
③ 规范性:规范性指的是描述数据遵循预定的语法规则的程度,是否符合其定义,比如数据的类型、格式、取值范围,存储格式等。
④ 一致性:数据的一致性可用于度量哪些数据的值在信息含以上是冲突的。例如,相同的数据有多个副本的情况下的数据不一致,便会存在数据内容冲突的问题。
⑤ 准确性:数据的准确性是指数据采集值或者观测值和真实值之间的接近程度,数据的准确性由数据的采集方法决定。
⑥ 唯一性:数据的唯一性用于识别和度量重复数据、冗余数据。重复数据是导致业务无法协同、流程无法追溯的重要因素,也是数据治理需要解决的最基本的数据问题。
⑦ 关联性:数据的关联性包括函数关系、相关系数、主外键关系、索引关系等。存在数据关联性问题,会直接影响数据分析的结果,进而影响管理决策。
⑧ 及时性:数据的及时性是指能否在需要的时候获到数据,数据的及时性与企业的数据处理速度及效率有直接的关系,是影响业务处理和管理效率的关键指标
数据质量检查
1:数据有效性
- 字段长度约束
- 字段内容约束
- 字段数值范围约束
- 枚举值集合约束
枚举值集合约束
描述检核对象的值是否按照一定的要求和规范进行数据的录入与存储。
例 1 : 依业务规则性别只有 “0:男” ,”1:女”,则性别字段只应出现0或1。
例 2 : 货币代码 (CURCODE) 只应有RMB或是USD值。
数据质量中代码值域首先要指定企业级的统一编码表,然后按照对照关系进行 etl 转换,至于出报告只需要通过 sql 查询不再范围内的数值就可以了。
长度约束
描述检核对象的长度是否满足长度约束。
例如身份证号是 18 位。
长度约束可以通过建表时指定字符长度去限制,如果业务系统最初没有做限制,只能通过 sql 判断长度的方式获取异常值再进行处理。
内容规范约束
描述检核对象的值是否按照一定的要求和规范进行数据的录入与存储。
例如:余额或者日期等一般都会按照固定类型存储,如果最初设计为字符型后续应按照对应类型调整。
首先这种情况最好一开始就建立好统一规范,按照业务含义去指定技术类型。如果最初做的不好,可以通过类型进行数据探查,对数据统一格式化。
取值范围约束
描述检核对象的取值是否在预定义的范围内。
例如:余额不能为负数,日期不能为负数等等。
如果业务初始没有做限制,只能通过 sql 去对数据过滤查询,对有问题数据集中 etl 处理。
2:数据一致性
数据一致性维度大类下可细分为以下维度小类:
等值一致性依赖约束:描述检核对象之间数据取值的约束规则。一个检核对象数据取值必须与另一个或多个检核对象在一定规则下相等。
存在一致性依赖约束:描述检核对象之间数据值存在关系的约束规则。一个检核对象的数据值必须在另一个检核对象满足某一条件时存在。
逻辑一致性依赖约束:描述检核对象之间数据值逻辑关系的约束规则。一个检核对象上的数据值必须与另一个检核对象的数据值满足某种逻辑关系(如大于、小于等)。
等值一致性依赖约束 一般指外键关联的场景。例如:保单表,理赔表的保单号存在保单主表,同一张表,两个字段之间的关联关系。
存在一致性依赖约束 主要是强调业务的关联性,一个状态发生了则某个值一定会如何。
例如:投保状态为已投保,则投保日期不应为空;
逻辑一致性依赖约束 主要强调的是字段间的互相约束关系。
例如:投保开始时间小于等于投保结束时间。
3:数据完整性
- 字段是否为空或NULL(字段缺失)
- 记录数是否丢失(记录缺失)
- 记录数环比波动 (记录数数据异常)
- 录数波动范围
- 记录数方差检验
- 实体缺失(数据同步或者加工过程中是否丢表)
- 字段是否丢失(属性缺失)
- 数据不多:一般是检查全表数据、重要枚举值,看数据有没有多余、重复或者数据主键是否唯一
- 数据不少:一般是检查全表数据、重要字段(比如主键字段、枚举值、日期等),看字段的数值是否为空、为null等
表级别完整性:
- 全表维度,通过查看全表的总行数/表大小,若出现表总行数/总大小不变或下降,说明表数据可能出现了问题
- 分区维度,通过查看当日分区表的数据行数/大小,若和之前分区相比差异太大(偏大或偏小),说明表数据可能出现了问题
字段级别完整性
- 字段为NULL或者缺失或空白
4:数据准确性
数据准确性主要是指取值的准确性,描述该检核对象是否与其对应的客观实体的特征相一致。
- 数值同比
- 数值环比
- 数值方差检验
- 表逻辑检查
5: 数据唯一性
唯一性指的是数据仓库中的数据不存在重复的情形。比如真实成交 1 万条,但数据表有 3000 条重复了,成了 1.3 万条成交记录,这种数据不符合数据唯一性。
6: 数据及时性
- 表级别质量监控指标,数据是否按时产出
- 数据是否发生了漂移
- 数据统计是否已经失效
7: 数据关联性
数据是否缺失关联条件或关联外键
上游相依赖的表是否缺失或者关联错误
8:数据规范性
数据同步中每日/月增量数据是否符合理论的经验值。
日期,年龄,地域...等字段值是否符合常规要求或标准
数据质量检查脚本样例
监控某张表一列的重复值
#!/usr/bin/env bash # -*- coding: utf-8 -*- # 监控某张表一列的重复值 # 参数解析 while getopts "t:d:c:s:x:l:" arg; do case $arg in # 要处理的表名 t) TABLE=$OPTARG ;; # 日期 d) DT=$OPTARG ;; # 要计算重复值的列名 c) COL=$OPTARG ;; # 重复值指标下限 s) MIN=$OPTARG ;; # 重复值指标上限 x) MAX=$OPTARG ;; # 告警级别 l) LEVEL=$OPTARG ;; ?) echo "unkonw argument" exit 1 ;; esac done #如果dt和level没有设置,那么默认值dt是昨天 告警级别是0 [ "$DT" ] || DT=$(date -d '-1 day' +%F) [ "$LEVEL" ] || LEVEL=0 # 数仓DB名称 HIVE_DB=gmall # 查询引擎 HIVE_ENGINE=hive # MySQL相关配置 mysql_user="root" mysql_passwd="000000" mysql_host="hadoop102" mysql_DB="data_supervisor" mysql_tbl="duplicate" # 认证为hive用户,如在非安全(Hadoop未启用Kerberos认证)环境中,则无需认证 kinit -kt /etc/security/keytab/hive.keytab hive # 重复值个数 RESULT=$($HIVE_ENGINE -e "set hive.cli.print.header=false;select count(1) from (select $COL from $HIVE_DB.$TABLE where dt='$DT' group by $COL having count($COL)>1) t1;") # 将结果插入MySQL mysql -h"$mysql_host" -u"$mysql_user" -p"$mysql_passwd" \ -e"INSERT INTO $mysql_DB.$mysql_tbl VALUES('$DT', '$TABLE', '$COL', $RESULT, $MIN, $MAX, $LEVEL) ON DUPLICATE KEY UPDATE \`value\`=$RESULT, value_min=$MIN, value_max=$MAX, notification_level=$LEVEL;"
计算一张表单日数据量环比增长值
#!/usr/bin/env bash # -*- coding: utf-8 -*- # 计算一张表单日数据量环比增长值 # 参数解析 while getopts "t:d:s:x:l:" arg; do case $arg in # 要处理的表名 t) TABLE=$OPTARG ;; # 日期 d) DT=$OPTARG ;; # 环比增长指标下限 s) MIN=$OPTARG ;; # 环比增长指标上限 x) MAX=$OPTARG ;; # 告警级别 l) LEVEL=$OPTARG ;; ?) echo "unkonw argument" exit 1 ;; esac done #如果dt和level没有设置,那么默认值dt是昨天 告警级别是0 [ "$DT" ] || DT=$(date -d '-1 day' +%F) [ "$LEVEL" ] || LEVEL=0 # 数仓DB名称 HIVE_DB=gmall # 查询引擎 HIVE_ENGINE=hive # MySQL相关配置 mysql_user="root" mysql_passwd="000000" mysql_host="hadoop102" mysql_DB="data_supervisor" mysql_tbl="day_on_day" # 认证为hive用户,如在非安全(Hadoop未启用Kerberos认证)环境中,则无需认证 kinit -kt /etc/security/keytab/hive.keytab hive # 昨日数据量 YESTERDAY=$($HIVE_ENGINE -e "set hive.cli.print.header=false; select count(1) from $HIVE_DB.$TABLE where dt=date_add('$DT',-1);") # 今日数据量 TODAY=$($HIVE_ENGINE -e "set hive.cli.print.header=false;select count(1) from $HIVE_DB.$TABLE where dt='$DT';") # 计算环比增长值 if [ "$YESTERDAY" -ne 0 ]; then RESULT=$(awk "BEGIN{print ($TODAY-$YESTERDAY)/$YESTERDAY*100}") else RESULT=10000 fi # 将结果写入MySQL表格 mysql -h"$mysql_host" -u"$mysql_user" -p"$mysql_passwd" \ -e"INSERT INTO $mysql_DB.$mysql_tbl VALUES('$DT', '$TABLE', $RESULT, $MIN, $MAX, $LEVEL) ON DUPLICATE KEY UPDATE \`value\`=$RESULT, value_min=$MIN, value_max=$MAX, notification_level=$LEVEL;"
检查id空值
#!/usr/bin/env bash # -*- coding: utf-8 -*- # 检查id空值 # 解析参数 while getopts "t:d:c:s:x:l:" arg; do case $arg in # 要处理的表名 t) TABLE=$OPTARG ;; # 日期 d) DT=$OPTARG ;; # 要计算空值的列名 c) COL=$OPTARG ;; # 空值指标下限 s) MIN=$OPTARG ;; # 空值指标上限 x) MAX=$OPTARG ;; # 告警级别 l) LEVEL=$OPTARG ;; ?) echo "unkonw argument" exit 1 ;; esac done #如果dt和level没有设置,那么默认值dt是昨天 告警级别是0 [ "$DT" ] || DT=$(date -d '-1 day' +%F) [ "$LEVEL" ] || LEVEL=0 # 数仓DB名称 HIVE_DB=gmall # 查询引擎 HIVE_ENGINE=hive # MySQL相关配置 mysql_user="root" mysql_passwd="000000" mysql_host="hadoop102" mysql_DB="data_supervisor" mysql_tbl="null_id" # 认证为hive用户,如在非安全(Hadoop未启用Kerberos认证)环境中,则无需认证 kinit -kt /etc/security/keytab/hive.keytab hive # 空值个数 RESULT=$($HIVE_ENGINE -e "set hive.cli.print.header=false;select count(1) from $HIVE_DB.$TABLE where dt='$DT' and $COL is null;") #结果插入MySQL mysql -h"$mysql_host" -u"$mysql_user" -p"$mysql_passwd" \ -e"INSERT INTO $mysql_DB.$mysql_tbl VALUES('$DT', '$TABLE', '$COL', $RESULT, $MIN, $MAX, $LEVEL) ON DUPLICATE KEY UPDATE \`value\`=$RESULT, value_min=$MIN, value_max=$MAX, notification_level=$LEVEL;"
计算某一列异常值个数
#!/usr/bin/env bash # -*- coding: utf-8 -*- # 计算某一列异常值个数 while getopts "t:d:l:c:s:x:a:b:" arg; do case $arg in # 要处理的表名 t) TABLE=$OPTARG ;; # 日替 d) DT=$OPTARG ;; # 要处理的列 c) COL=$OPTARG ;; # 不在规定值域的值的个数下限 s) MIN=$OPTARG ;; # 不在规定值域的值的个数上限 x) MAX=$OPTARG ;; # 告警级别 l) LEVEL=$OPTARG ;; # 规定值域为a-b a) RANGE_MIN=$OPTARG ;; b) RANGE_MAX=$OPTARG ;; ?) echo "unkonw argument" exit 1 ;; esac done #如果dt和level没有设置,那么默认值dt是昨天 告警级别是0 [ "$DT" ] || DT=$(date -d '-1 day' +%F) [ "$LEVEL" ] || LEVEL=0 # 数仓DB名称 HIVE_DB=gmall # 查询引擎 HIVE_ENGINE=hive # MySQL相关配置 mysql_user="root" mysql_passwd="000000" mysql_host="hadoop102" mysql_DB="data_supervisor" mysql_tbl="rng" # 认证为hive用户,如在非安全(Hadoop未启用Kerberos认证)环境中,则无需认证 kinit -kt /etc/security/keytab/hive.keytab hive # 查询不在规定值域的值的个数 RESULT=$($HIVE_ENGINE -e "set hive.cli.print.header=false;select count(1) from $HIVE_DB.$TABLE where dt='$DT' and $COL not between $RANGE_MIN and $RANGE_MAX;") # 将结果写入MySQL mysql -h"$mysql_host" -u"$mysql_user" -p"$mysql_passwd" \ -e"INSERT INTO $mysql_DB.$mysql_tbl VALUES('$DT', '$TABLE', '$COL', $RESULT, $RANGE_MIN, $RANGE_MAX, $MIN, $MAX, $LEVEL) ON DUPLICATE KEY UPDATE \`value\`=$RESULT, range_min=$RANGE_MIN, range_max=$RANGE_MAX, value_min=$MIN, value_max=$MAX, notification_level=$LEVEL;"
-
计算一张表一周数据量同比增长值
#!/usr/bin/env bash # -*- coding: utf-8 -*- # 计算一张表一周数据量同比增长值 # 参数解析 while getopts "t:d:s:x:l:" arg; do case $arg in # 要处理的表名 t) TABLE=$OPTARG ;; # 日期 d) DT=$OPTARG ;; # 同比增长指标下限 s) MIN=$OPTARG ;; # 同比增长指标上限 x) MAX=$OPTARG ;; # 告警级别 l) LEVEL=$OPTARG ;; ?) echo "unkonw argument" exit 1 ;; esac done #如果dt和level没有设置,那么默认值dt是昨天 告警级别是0 [ "$DT" ] || DT=$(date -d '-1 day' +%F) [ "$LEVEL" ] || LEVEL=0 # 数仓DB名称 HIVE_DB=gmall # 查询引擎 HIVE_ENGINE=hive # MySQL相关配置 mysql_user="root" mysql_passwd="000000" mysql_host="hadoop102" mysql_DB="data_supervisor" mysql_tbl="week_on_week" # 认证为hive用户,如在非安全(Hadoop未启用Kerberos认证)环境中,则无需认证 kinit -kt /etc/security/keytab/hive.keytab hive # 上周数据量 LASTWEEK=$($HIVE_ENGINE -e "set hive.cli.print.header=false;select count(1) from $HIVE_DB.$TABLE where dt=date_add('$DT',-7);") # 本周数据量 THISWEEK=$($HIVE_ENGINE -e "set hive.cli.print.header=false;select count(1) from $HIVE_DB.$TABLE where dt='$DT';") # 计算增长 if [ $LASTWEEK -ne 0 ]; then RESULT=$(awk "BEGIN{print ($THISWEEK-$LASTWEEK)/$LASTWEEK*100}") else RESULT=10000 fi # 将结果写入MySQL mysql -h"$mysql_host" -u"$mysql_user" -p"$mysql_passwd" \ -e"INSERT INTO $mysql_DB.$mysql_tbl VALUES('$DT', '$TABLE', $RESULT, $MIN, $MAX, $LEVEL) ON DUPLICATE KEY UPDATE \`value\`=$RESULT, value_min=$MIN, value_max=$MAX, notification_level=$LEVEL;"
-
脚本相关:
#!/usr/bin/env bash DT=$1 [ "$DT" ] || DT=$(date -d '-1 day' +%F) #检查表 dim_user_info 的重复ID #参数: -t 表名 # -d 日期 # -c 检查重复值的列 # -s 异常指标下限 # -x 异常指标上限 # -l 告警级别 bash duplicate.sh -t dim_user_info -d "$DT" -c id -s 0 -x 5 -l 0 #检查表 dim_user_info 的空ID #参数: -t 表名 # -d 日期 # -c 检查空值的列 # -s 异常指标下限 # -x 异常指标上限 # -l 告警级别 bash null_id.sh -t dim_user_info -d "$DT" -c id -s 0 -x 10 -l 0 # 检查表 dwd_order_info 重复ID #参数: -t 表名 # -d 日期 # -c 检查重复值的列 # -s 异常指标下限 # -x 异常指标上限 # -l 告警级别 bash duplicate.sh -t dwd_order_info -d "$DT" -c id -s 0 -x 5 -l 0 #检查表 dwd_order_info 的空ID #参数: -t 表名 # -d 日期 # -c 检查空值的列 # -s 异常指标下限 # -x 异常指标上限 # -l 告警级别 bash null_id.sh -t dwd_order_info -d "$DT" -c id -s 0 -x 10 -l 0 #检查表 ods_order_info 数据量日环比增长 #参数: -t 表名 # -d 日期 # -s 环比增长下限 # -x 环比增长上限 # -l 告警级别 bash day_on_day.sh -t ods_order_info -d "$DT" -s -10 -x 10 -l 1 #检查表 ods_order_info 数据量周同比增长 #参数: -t 表名 # -d 日期 # -s 同比增长下限 # -x 同比增长上限 # -l 告警级别 bash week_on_week.sh -t ods_order_info -d "$DT" -s -10 -x 50 -l 1 #检查表 ods_order_info 订单异常值 #参数: -t 表名 # -d 日期 # -s 指标下限 # -x 指标上限 # -l 告警级别 # -a 值域下限 # -b 值域上限 bash range.sh -t ods_order_info -d "$DT" -c final_amount -a 0 -b 100000 -s 0 -x 10