数据表健康查看与数据质量核验(完整性、准确性、一致性、唯一性、规范性、及时性)要点总结

数据表健康状况主要从空间占用、碎片率、统计信息和索引有效性四方面评估。


空间膨胀需重建表释放冗余;碎片率超20%需OPTIMIZE或重建;

统计信息需在数据量变化超10%时更新;

冗余索引需定期清理。

健康口诀:"空间不虚、碎片不多、统计不旧、索引不废"。


数据质量核验包含完整性(行数对账)、准确性(金额比对)、一致性(跨表校验)、唯一性(主键去重)、规范性(格式检查)和及时性(分区就绪)六个维度。


自动化校验应在数据稳定写入后、下游使用前执行,通过对比历史值、阈值或源系统判断异常。


特别强调:Hive等数仓工具不强制主键约束,需通过ETL代码保证数据唯一性,避免因任务重跑导致重复。

(字数:149)

事务表的表健康要看哪些方面


事务表的"表健康"主要看四个方面,简短一点就是:

空间、碎片、统计信息、索引。

拆开说(面试够用):

  1. 空间是否膨胀

    • 实际数据量 vs 表占用空间(尤其是变长字段VARCHAR频繁更新,会导致空间只增不减)
  2. 碎片是否严重

    • 大量UPDATE / DELETE后,数据页存在空穴

    • 表现:扫描成本高,但数据量不大

  3. 统计信息是否准确

    • 行数、分布信息过旧 → 执行计划选错(不走索引、选错Join顺序)
  4. 索引是否合理/健康

    • 未使用、重复、或者高度碎片化的索引

一句话记忆

"表健不健康,看空间不虚、碎片不多、统计不旧、索引不废。"

1. 空间膨胀(表实际占用远大于数据量)

解决

  • 直接收紧:ALTER TABLE ... ENGINE=InnoDB;(MySQL)

  • 或导出再导入:mysqldump → 删表 → 重新导入

  • Hive里不存在这个问题(不原地更新)

面试说:"定期重建表,释放已用空间。"


2. 碎片严重(数据页不连续、有空洞)

解决

  • MySQL / Oracle:OPTIMIZE TABLE

  • 或者:重建表(ALTER TABLE ... ENGINE=InnoDB

  • 不要对频繁更新的小表频繁优化,反而浪费

面试说:"碎片率超过20%时,用OPTIMIZE TABLE或重建表。"


3. 统计信息过旧(执行计划选错)

解决

  • MySQL:ANALYZE TABLE

  • Hive:ANALYZE TABLE COMPUTE STATISTICS

  • 不是天天跑,大表在数据量明显变化时跑一次

面试说:"大表在数据量变化超过10%后,手动更新统计信息,避免走错索引。"


4. 索引不健康(冗余、没用、碎片高)

解决

  • 删冗余索引(pt-duplicate-key-checker 或人工分析)

  • 删未使用索引(MySQL 用 performance_schema 查)

  • 重建索引(ALTER TABLE ... ENGINE=InnoDB

面试说:"定期清理冗余索引,监控未使用索引,关键表定期重建索引。"

面试一句话总结(直接背)

"空间膨胀就重建表;碎片严重就 OPTIMIZE;统计过旧就 ANALYZE;索引不健康就删冗余、重建索引。"

表健康 文件合并,黑名单

你提到的这几个点------表健康、文件合并、黑名单------在大数据/数据库里各自含义非常不同。我帮你拆成三个"面试一句话"版本,既简短又不会说错。


1. 表健康(Table Health)

一句话

指表在存储、统计信息、数据质量、访问性能方面没有明显问题。

面试怎么说

"我看表健康主要看:

  • 小文件是否过多(Hive/HDFS)

  • 统计信息是否过旧(影响执行计划)

  • 是否有大量删除/更新后的碎片(数据库)

  • 关键字段是否有异常空值或数据倾斜。"


2. 文件合并(小文件合并 / File Merge)

一句话

把多个小文件读出来、写成一个或几个大文件,然后删除小文件,解决元数据压力和查询性能问题。

面试怎么说

"离线数仓里小文件多了,NameNode会撑爆、查询会变慢。我会用INSERT OVERWRITE重写全量数据,或者开Hive的自动合并参数:

hive.merge.mapredfiles = true。"
注意 :合并不是直接删除小文件,而是**"合并后删除"**,否则丢数据。


3. 黑名单(Blacklist)

在大数据和银行业务里,黑名单至少有三种不同意思 ,面试最容易混淆。我按面试正确用法整理:

黑名单类型 含义 你的场景
业务黑名单 风险客户、欺诈手机号、失信人等 1104 / 风控 / 信贷
实时风控黑名单 Redis里的缓存黑名单,Flink实时匹配 反欺诈、交易拦截
技术黑名单 Hive/Spark 慢查询、非法SQL、UDF黑名单 很少主动提

面试怎么说(选一句)

"在银行项目里,我遇到的业务黑名单主要是风险客户、企业、地域。我们会在ETL里做两件事:

  1. DWD层打标:关联黑名单表标记风险等级

  2. 实时风控里放Redis:交易发生时毫秒级命中黑名单。"


总结一句(如果面试官把这几个词混在一起问)

"表健康看小文件、统计信息、数据质量;

文件合并就是解决小文件问题的;

黑名单在银行里主要分业务黑名单技术黑名单,我接触多的是业务风控那个方向。"

表 元数据变更 涉及哪些方面 怎么变更

这个问题问得挺细,元数据变更是数据开发和运维里经常碰的事。我直接给你一个清晰、简短、面试够用的回答。


一、涉及哪些方面

变更类型 具体内容 示例
表结构 增加/删除/修改字段 ADD COLUMNCHANGE COLUMNDROP COLUMN
分区 增加/删除分区 ADD PARTITIONDROP PARTITION
表属性 修改存储格式、压缩、位置 SET TBLPROPERTIES('format'='parquet')
统计信息 更新行数、列分布 ANALYZE TABLE COMPUTE STATISTICS
权限 授权/回收 GRANT SELECT ON table TO user
重命名 表名/字段名 RENAME TOALTER TABLE ... RENAME COLUMN

二、怎么变更(Hive + 通用)

场景 命令
增加字段 ALTER TABLE t ADD COLUMNS (age INT)
修改字段 ALTER TABLE t CHANGE COLUMN old_name new_name STRING
删字段 很多系统不支持直接删(Hive 可以 REPLACE COLUMNS,但会丢数据,一般不直接做)
增加分区 ALTER TABLE t ADD PARTITION (dt='2024-01-01')
删分区 ALTER TABLE t DROP PARTITION (dt='2024-01-01')
修改表属性 ALTER TABLE t SET TBLPROPERTIES ('comment'='新备注')
重命名表 ALTER TABLE old_name RENAME TO new_name

三、面试时怎么说(话术)

"元数据变更我主要遇到过加字段、加分区、改表属性这三种。

  • 加字段用ALTER TABLE ADD COLUMNS,注意位置一般加在最后

  • 加分区用ALTER TABLE ADD PARTITION,Hive里是MSCK REPAIR TABLE可以自动识别已有分区

  • 改表属性比如改存储格式、改压缩,用SET TBLPROPERTIES

变更时注意两点:

  1. 分区表加字段不影响老分区,老分区只有新增数据才有新字段

  2. 删字段要小心,很多系统不支持直接删,或者删了会丢数据"


四、一个金句收尾

"元数据变更的核心原则:能加不加、能不改就不改、实在要改先确认下游依赖。"

数据质量核对,都做什么

数据质量核对在银行项目里不是可选项,是必选项。面试官问这个,就是想知道你有没有"质量意识"。

下面我给你一个完整、简短、面试直接能说的回答。


一、一句话总结

"数据质量核对就是验证数据对不对、全不全、格式规不规范、关系平不平。"


二、具体做哪几件事(面试时按这个顺序说)

核对项 做什么 怎么判断
1. 完整性 数据有没有丢 行数对账:源表count vs 目标表count
2. 准确性 数值对不对 金额求和、关键指标对比(新旧系统比对)
3. 一致性 不同表/系统间对得上 勾稽校验:G01资产=负债+权益
4. 唯一性 有没有重复 主键去重检查:COUNT(DISTINCT pk) = COUNT(1)
5. 规范性 格式对不对 日期格式、枚举值、空值率、长度检查
6. 及时性 数据出没出来 监控调度任务完成时间、分区是否就绪

三、举个例子

"我每天早上会跑一套Python自动校验脚本,顺序是:

  1. 先检查ODS层行数和源库对不对得上(完整性)

  2. 再检查核心金额字段求和跟昨日波动是否正常(准确性)

  3. 然后跑G01/G21勾稽校验(一致性)

  4. 最后扫一遍空值率、日期格式(规范性)

有问题就发钉钉告警,我去定位修复。没问题才通知下游报表系统可以取数。"


四、面试官追问:发现问题怎么定位?

问题类型 定位方法
行数对不上 按ID分段count,找缺失区间
金额对不上 按机构/产品拆解,定位到具体科目
勾稽不平 先确认是不是口径问题,再逐级往下钻
空值率突增 查上游源表是不是字段变更了

五、一个金句收尾

"数据质量核对不是为了找问题而找问题,是为了让业务方敢用你的数据。我对账过了,他才敢签字。"

主键去重检查:COUNT(DISTINCT pk) = COUNT(1),这里怎么理解,主键不是没有重复吗

你这个问题问得非常到位,说明你在认真思考,而不是死记硬背。

结论先行 :你说得对,主键在源系统里应该是没有重复的 。但到了数仓的ODS层,因为数据抽取、重跑、增量合并等操作,主键可能被人为弄出重复 。所以这个检查不是为了验证源系统的设计,而是验证ETL过程有没有产生脏数据


一、为什么ODS层的主键会有重复?

场景 说明
增量重跑 某天增量任务重跑,没做好去重,同一条主键被插了两次
全量+增量混用 全量跑了一次,增量又追加了一次,重叠的部分就重复了
Sqoop抽数分界问题 时间戳边界没控制好,同一条数据被两个批次都抽到
手动补数据 临时补数时没检查,插入了已存在的记录

一句话:源表的主键在ODS层不一定还是主键,因为ODS不是关系数据库,没有主键约束。


二、这个检查在验证什么?

sql

复制代码
COUNT(DISTINCT pk) = COUNT(1)
结果 含义
相等 没有重复行,ETL正常
不相等 存在重复,COUNT(1) > COUNT(DISTINCT pk),说明同一条pk出现了多次

三、举个例子

源表有一条数据:loan_id = 10001

正常ODS:只有一行 10001

出问题的ODS:

loan_id amount
10001 10000
10001 10000

重跑增量时没去重,插了两遍。

COUNT(1) = 2,COUNT(DISTINCT loan_id) = 1 → 不相等 → 告警


四、面试时怎么说

"源系统里主键确实没有重复,但数据进了ODS层之后,因为重跑任务、增量边界没控制好、或者手动补数,可能会产生重复记录。这个检查就是用来发现ETL过程中有没有意外引入重复数据,保证下游不会因为重复而算错指标。"


五、一个金句

"源表的主键是业务保证的,ODS的主键是ETL保证的。这个检查验的就是ETL有没有守住底线。"

ODS不是关系数据库,没有主键约束是什么意思,ODS是Oracle表,还是Hive表?

这个问题问得很好,刚好澄清一个核心概念。ODS在银行项目里可以是Oracle表,也可以是Hive表,看项目阶段和架构

下面我把两套逻辑分开说,你就清楚了。


一、ODS是什么(先定调)

ODS是"贴源层",数据结构和源系统基本一样,只是把多个业务系统的数据集中存到一起。

它可以是关系型数据库的表(如Oracle),也可以是Hive的表。有没有主键约束,取决于它存在什么数据库里,而不是它叫ODS


二、两种情况对比

项目阶段 ODS存在哪 有没有主键约束 为什么
老架构(迁移前) Oracle ✅ 可以有 Oracle是关系库,支持主键
新架构(迁移后) Hive ❌ 没有 Hive是数仓,不强制约束

三、项目(迁移)的ODS

迁移前,ODS在Oracle里,是可以有主键的。

迁移后,数据底座换成Hive ,ODS变成了Hive表。Hive在建表时不会写PRIMARY KEY,也不检查唯一性。就算你往Hive表里插两条主键一样的数据,它也不会报错。

所以"没有主键约束"这句话,针对的是迁移后的Hive ODS。


四、面试时怎么说(话术)

"ODS不是关系数据库,没有主键约束,这句话的背景是数据迁到Hive之后。Hive是数仓,不是关系型数据库,它不会自动帮你检查主键唯一性。所以ETL过程中如果出了重复,Hive不会报错,只能靠我们自己写的对账脚本去发现。"


五、一个金句收尾

"Oracle里的ODS有主键约束,Hive里的ODS没有。这是两种不同数据库的特性,不是ODS本身变了。"

分区是否就绪 是什么意思

这个问题问得很实际,分区是否就绪是数仓日常运维里每天都要看的事。


一、一句话解释

检查今天要用的分区有没有生成好,数据有没有写进去。

比如今天是2026-06-14,凌晨跑批应该产出dt='2026-06-13'的分区。

"分区是否就绪"就是问:这个分区存在吗?里面有数据吗?数据完整吗?


二、具体检查什么

检查项 怎么做 什么算"就绪"
分区存在 SHOW PARTITIONS table_name 能看到dt=2026-06-13
有数据 SELECT COUNT(1) FROM table_name WHERE dt='2026-06-13' 行数 > 0
数据完整 行数在预期范围内(比如跟昨天比波动不大) 不突然少一半或多一倍
下游可用 下游依赖这个分区的任务已经跑完 没有阻塞告警

三、举个例子

每天早上我到公司,先看Azkaban调度。昨天凌晨的任务应该产出dt='2026-06-13'的分区。

我会跑一句:

sql

复制代码
SELECT COUNT(1) FROM dwd_loan_detail WHERE dt='2026-06-13';

如果返回1亿行左右(跟平时差不多),分区就绪。

如果是0,说明任务失败或没跑;如果是5000万,说明数据少了,可能增量抽漏了。


四、面试时怎么说

"分区是否就绪,就是确认今天要用的分区有没有生成、数据量对不对。我每天早上会跑行数校验脚本,自动检查昨天分区的行数是否在正常范围内。如果行数异常或分区不存在,就发告警,我去定位问题。"


五、一个金句收尾

"分区就绪不是'分区存在',而是'数据完整、下游可用'。"

Python自动校验脚本,或者说是自动化校验脚本,一般是什么时候执行数据质量核对

这个问题很实际。自动化校验脚本不是什么时候都能跑的,时机不对,校验结果就是错的。

下面我给你一个清晰、简短、面试直接能说的回答。


一、核心原则

在数据稳定写入之后、被下游使用之前执行。

太早:数据还没写完,校验会误报

太晚:下游已经用了脏数据,来不及了


二、具体执行时机(按场景分)

场景 执行时机 说明
离线T+1(核心) 每日ETL跑完之后、下游报表取数之前 比如凌晨4点ETL跑完,4点半跑校验,5点没问题了再通知下游
增量同步 每次增量任务完成后 比如每2小时抽一次,抽完立刻校验本轮数据
数据迁移 全量迁移后、增量追平后 迁完一张表就校验一张表,不用等所有表迁完
口径变更后 新口径SQL上线前(测试环境) 先在测试环境跑校验,确认没问题再上线生产

三、项目的实际时间线

我们离线数仓的跑批窗口是凌晨2点到6点

  • 2:00 - 5:30:各层ETL任务按依赖跑

  • 5:30:Azkaban触发校验脚本(Python)

  • 5:30 - 5:45:跑行数对账、金额对账、勾稽校验

  • 5:45:出校验报告

    • 没问题 → 自动发消息"今日数据就绪"

    • 有问题 → 钉钉告警,我爬起来处理

  • 6:00:下游报表系统开始取数

关键:校验在下游取数之前跑完,但不要求所有ETL一结束就立刻跑------留一点缓冲时间,避免ETL刚结束元数据还没刷新。


四、面试官追问:如果校验失败怎么办?

"校验失败分情况:

  • 行数对不上:先看是不是重跑任务导致的,如果不是,定位差异区间,修复后重跑

  • 金额/指标对不上:逐层下钻定位问题,修完后重跑

  • 如果是阻塞性问题一时修不好:邮件通知下游今天的数先不要用,同时报给项目负责人


五、一个金句收尾

"自动化校验不是跑得越早越好,而是在'数据写完了、下游还没用'这个窗口里跑。早了不准,晚了没用。"

再检查核心金额字段求和跟昨日波动是否正常(准确性),好像不是和昨天对比吧?

你说得对,我那个表述确实不严谨,容易引起误解。感谢你指出来。

下面我把这个问题彻底讲清楚。


一、核心金额字段对比,到底和谁比?

不是固定和昨天比,而是和"一个可信的基准"比。

场景 对比对象 说明
增量数据 和昨天比(波动检测) 比如今天的贷款发放金额,和昨天对比,波动超过阈值就告警
全量数据(如余额) 和上个月末比,或和老系统比 余额是累计值,今天和昨天比变化很小,波动检测没意义
迁移过程 和老系统(Oracle)比 新旧系统对账,不是和时间比
日常监控 和历史均值/阈值比 比如贷款总额平时在100亿左右,突然掉到80亿,就告警

二、我之前错在哪

我说"核心金额字段求和跟昨日波动是否正常",这句话只适用于增量类字段(如当日交易额),不适用于余额类累计字段。

正确的说法应该是:

"增量字段(如当日发放金额)和昨日对比看波动;余额类字段(如贷款余额)和历史均值或上月同期对比,或者做新旧系统对账。"


三、三种对比方式(面试时这样说)

对比方式 适用场景 例子
环比(vs 昨日/上周) 增量指标、流水类 今日交易额 vs 昨日交易额
同比(vs 去年同期) 有季节性的指标 本月不良率 vs 去年同月
基线对比(vs 老系统) 迁移、口径变更 Hive贷款余额 vs Oracle贷款余额

四、项目的实际做法

"我们分两类监控:

  1. 余额类字段(贷款余额、存款余额):每天记录,画趋势图。如果某天突然掉了一个亿,自动告警,人工排查是数据问题还是业务原因(比如大额还款)。

  2. 增量类字段(当日发放金额):和昨天对比,波动超过30%就告警。"


五、一个金句收尾

"金额对比,比的不是固定的'昨天',比的是'应该和谁一样'。迁移时和老系统比,日常时和历史趋势比,增量时和昨日比。"

源表的主键是业务保证的,ODS的主键是ETL保证的。是什么意思,不是说Hive没有主键吗

你抓到了我表述里一个容易造成误解的地方,谢谢指出来。我重新说清楚。


一、先说清楚:Hive确实没有主键约束

你说得完全对。Hive没有主键、没有唯一约束、没有索引。你在Hive里可以往一张表里插任意多条相同ID的数据,它不会报错。

所以"ODS的主键"这句话里的"主键",不是指数据库约束意义上的PRIMARY KEY ,而是指业务逻辑上的唯一标识字段


二、那我说的"ODS的主键是ETL保证的"到底是什么意思?

意思是:ETL要保证ODS表里,每一条业务数据只出现一次,没有重复。

换句话说:

角色 责任
源系统 保证业务主键不重复(这是它的本职工作)
ETL 保证在抽取、写入ODS的过程中,不把同一条数据搞出两个副本

"保证"的方式:不是靠数据库约束,而是靠ETL脚本里写去重逻辑、设好增量边界、任务做好幂等设计。


三、举个例子

源表(Oracle)里,loan_id = 10001这条数据只应该出现一次

ODS表(Hive)里,正常情况下也应该是一次

但如果增量任务重跑、Sqoop边界没卡好、或者全量和增量重叠了,ODS里可能出现两条loan_id = 10001。Oracle不会让它发生,但Hive不会拦你

这时候就需要ETL来兜底:

  • 要么在写入前做去重(比如ROW_NUMBER()取最新一条)

  • 要么在写入后监控告警(比如COUNT(DISTINCT loan_id) = COUNT(1)

这就是**"ETL保证"** 的意思:数据库不拦的坑,ETL来填。


四、面试时怎么说(修正版)

"Hive本身没有主键约束,所以ODS表的唯一性要靠ETL来保证。我会在关键表上做重复校验,或者在ETL里显式去重,确保不会因为任务重跑、边界问题导致ODS出现重复数据。"


五、一个金句收尾

"源表的主键是表结构保证的;ODS的唯一性是ETL写代码保证的。Hive不拦你,但你要自己兜底。"

相关推荐
千桐科技1 个月前
qData 数据中台社区开源版 v1.4.0 发布:元数据管理核心模块正式上线
开源·数据治理·数据集成·数据开发·数据中台·元数据管理·qdata
千桐科技3 个月前
qData 数据中台开源版 v1.2.0 正式发布:重构数据建模体系,重塑开发体验!
开源软件·数据治理·数据建模·数据集成·数据开发·数据中台·qdata
ha_lydms6 个月前
2、Spark 函数_a/b/c
大数据·c语言·hive·spark·时序数据库·dataworks·数据开发
涤生大数据6 个月前
放弃Canal后,我们用Flink CDC实现了99.99%的数据一致性
大数据·数据仓库·flink·大数据开发·flink cdc·数据开发·实时数据
大数据CLUB9 个月前
基于spark的澳洲光伏发电站选址预测
大数据·hadoop·分布式·数据分析·spark·数据开发
linweidong10 个月前
深入剖析 Spark Shuffle 机制:从原理到实战优化
大数据·分布式·spark·spark sql·数据开发·shuffle·数据倾斜
涤生大数据1 年前
Apache Spark 4.0:将大数据分析提升到新的水平
数据分析·spark·apache·数据开发
袋鼠云数栈1 年前
3节点开启大数据时代:EasyMR助力中小企业轻装上阵、国产转型
大数据·数据库·数据仓库·sql·数据开发·数据中台·袋鼠云
涤生大数据1 年前
数据质量问题中,数据及时性怎么保证?如何有深度体系化回答!
数据仓库·数据治理·数仓·数据开发·及时性