为了账号安全,请及时绑定邮箱和手机立即绑定

别把数据质量搞复杂了

三个零成本解决方案,只需几个小时而不是几个月

这是一条经过高质量数据认证的数据管道。来源:unsplash.com

在我的职业经历中,数据质量项目通常意味着重大的变化。从治理流程到昂贵的工具,再到dbt的实现——数据质量项目似乎总是规模庞大。

更重要的是,这样处理数据质量问题往往会带来新的问题,比如更多的复杂性、更高的成本以及更慢的数据项目上线……

作者使用Google Sheets创建

但不必如此。

最有效的方法中,解决数据问题的方法也最容易做到。

在这篇文章里,我们将分享三种快速提高数据质量的技巧,这样做可以简化复杂性并确保不增加新成本。开始吧!

简短摘要
  • 利用传统数据库技巧,如 ENUM 数据类型等和列约束条件。
  • 为特定的数据质量难题创建一个自定义仪表板。
  • 用一个简单的 Python 脚本生成数据溯源。
利用一些传统的数据库技巧

在过去的10到15年里,数据行业发生了巨大的变化,特别是大数据、并行处理、云计算、数据仓库等,以及层出不穷的新工具。

所以,我们不得不放弃一些旧的东西来给这些新东西腾地方。一些是好的(比如微软的Access),但也有一些值得商榷的,比如传统的数据设计原则以及数据在输入时的质量和验证。后面的部分就是我们要讨论的内容。

首先来说,我所说的“数据录入验证”是什么意思?简单讲,就是指在数据进入表格前进行检查。想想夜店门口的保安,他们把进入夜店的人检查一遍。

它被替换为“构建后测试”(即先将新数据放入表中,然后再稍后检查)。许多现代数据质量工具,例如最流行的dbt,都使用这种方法。

Dbt 首先运行整个数据转换管道,只有在所有新数据到位后,它才会检查数据是否良好。当然,在很多情况下,这种方法可能是最优解。例如,如果业务方愿意牺牲质量来换取速度,或者在生产表前有一个 QA 表(Netflix 称为Write-Audit-Publish)。然而,仅依赖这种方法来保证数据质量的数据工程师可能错失了组织可以从中获益的大好机会。

对生成表格前后的测试,作者使用draw.io制作的,用于测试生成表格前后的差异。

与先构建后测试相比,测试后再构建主要有以下两个优势。

首先,它确保下游表中的数据在任何时刻都符合预期的数据质量标准。这使得数据对于下游用户来说更加可靠,因为这种信任常常是下游用户所缺乏的。这也能让负责这条数据管道的数据工程师们感到更安心。

我记得我以前在一个公司工作时,我拥有一个关键的财务管道。不幸的是,这个管道经常出现问题的数据质量,而当时解决这个问题的方法是使用一个构建后再测试的系统。因此我每天早上都需要早起查看昨晚运行的结果,确保在任何下游用户开始查看数据之前一切都正常。如果发现问题,我会尽快修复,或者发送一条羞辱性的Slack消息,通知大家数据有问题,请大家耐心等待我解决这个问题。

当然,测完再建并不能完全解决这种焦虑问题。故事会从需要赶紧修复问题以避免给下游用户带来差的数据,变为需要赶紧修复问题以避免给下游用户带来老旧数据。毕竟,工程学说到底就是权衡不同解决方案的利弊。在这种情况下,我知道使用旧数据可能是对业务和我个人而言最佳的两害相权取其轻的选择。

测试后再构建的第二个好处是,它可能实施起来更简单,尤其是与设置一个完整的质量保证区域相比,后者是用大炮打蚊子的方式来解决大多数数据质量问题,显得过于复杂。你只需要在创建表时加入数据质量标准即可。请参阅下面的PostgreSQL查询:

    CREATE TYPE currency_code_type AS ENUM (  
        'USD', -- 美金  
        'EUR', -- 欧元  
        'GBP', -- 英镑  
        'JPY', -- 日元  
        'CAD', -- 加元  
        'AUD', -- 澳元  
        'CNY', -- 人民币  
        'INR', -- 印度卢比  
        'BRL', -- 巴西雷亚尔  
        'MXN'  -- 墨西哥比索  
    );  

    CREATE TYPE payment_status AS ENUM (  
        'pending',  
        'completed',  
        'failed',  
        'refunded',  
        'partially_refunded',  
        'disputed',  
        'canceled'  
    );  

    CREATE TABLE daily_revenue (  
        id INTEGER PRIMARY KEY,  
        date DATE NOT NULL,  
        revenue_source revenue_source_type NOT NULL,  
        gross_amount NUMERIC(15,2) NOT NULL CHECK (gross_amount >= 0),  
        net_amount NUMERIC(15,2) NOT NULL CHECK (net_amount >= 0),  
        currency currency_code_type,  
        transaction_count INTEGER NOT NULL CHECK (transaction_count >= 0),  
        notes TEXT,  

        CHECK (net_amount <= gross_amount),  
        CHECK (gross_amount >= processing_fees + tax_amount),  
        CHECK (date <= CURRENT_DATE),  
        CONSTRAINT unique_daily_source UNIQUE (date, revenue_source)  
    );  

这14行代码将确保daily_revenue表满足以下标准:

id

  • 主键约束确保每条记录的唯一性

日期

  • 不能是未来的日期(通过 CHECK 约束)。
  • 与 revenue_source 一起构成唯一约束。

收入渠道

  • 不可为 NULL。
  • 与 date 一起构成唯一键约束。
  • 必须是 revenue_source_type 枚举中的一个有效值。

总额即总收入或总金额,包括了所有收入。

  • 不能为空值。
  • 必须大于等于0。
  • 必须大于等于处理费和税额之和。
  • 必须大于等于净额。
  • 需要精确处理小数位。

净金额

  • 不可为 NULL。
  • 必须大于或等于 0。
  • 必须小于或等于毛额。
  • 要处理好小数位精度。

数字货币

  • 必须是有效的 currency_code_type 值。

交易笔数

  • 不能为 NULL,
  • 必须是非负数。

很简单,很可靠。你能相信吗,这一切自 PostgreSQL 6.5 在 1999 年发布以来……就这样一直可用,对吧?

当然世界上没有免费的午餐。这样做确实会带来一些缺点。例如,这让表的灵活性降低,并且在更新表时性能会有所下降。正如通常所说,在使用任何工具、技术和方法前,你应该像一个工程师一样思考。

创建个性化仪表板

我有个要坦白的事情。我一直以为真正厉害的数据工程师不会用仪表板工具解决问题。我认为真正的工程师会看日志、难以理解的代码等等让人看起来很厉害的东西,如果有人随便瞄一眼他们的电脑屏幕。

我当时真傻啊。

事实证明,如果有效地执行且目的明确,它们可以变得非常有价值。此外,大多数商业智能工具使得创建仪表板变得极其简单快捷,几乎不用花太多时间去学习工具。

回到我的个人工作流程经验。我曾管理一个每日汇总所有业务收入来源的表格。每个来源都来自不同的系统来源,因此来自不同的系统。有的通过API调用,有的通过邮件接收,还有些通过共享S3桶。就像每个工程师预料的一样,这些来源偶尔会出故障,而且因为它们来自第三方,我无法直接解决问题(只能请求对方来修,但成功的几率很小)。

原来,我只使用故障日志来确定哪里需要修复。问题在于优先级。有些故障需要立即解决,而其他一些问题则不够严重,不足以打断手头的工作(我们有一些收入来源每天实际收入只有几美分)。结果,小的数据质量问题慢慢累积,难以跟踪。

打开 Tableau。

我做了一个非常基础的数据仪表板,突出显示了最近14天内按收入来源和日期的元数据信息。只需要三个指标就够了。

  1. 绿色或红色的标记,表示数据是否有。
  2. 数据中的行数。
  3. 数据的总收入。

简洁而有效的数据仪表板。作者使用Tableau创建。

这让管道的数据质量管理变得更加容易。而且问题所在更容易查看,而且也足够用户友好,方便其他人查看,从而实现了共同的责任分担。

实施了仪表板之后,业务相关的管道bug报告几乎降至零,我的中风风险也几乎消失了。

一个数据谱系图来映射你的数据

简单的数据可观测性解决方案不仅仅局限于仪表板,而是更进一步。

数据血统可以快速识别哪些表受到上游不良数据的影响。

然而,实施起来可能非常困难。

在我看来,罪魁祸首是dbt。这个开源工具的一个重要卖点是其数据血统追踪能力。但为了实现这一点,你必须遵循dbt的框架。包括但不限于以下内容:

  • 在所有 SQL 文件中使用 Jinja3
  • 为每一个数据模型创建一个 YAML 文件。
  • 通过 YAML 文件添加源数据的配置信息。
  • 设置开发和测试流程,比如开发环境,版本控制和 CI/CD。
  • 基础设施搭建,例如托管自己的服务器或购买托管服务 (dbtCloud)。

是啊,这真的很多。

但这并不是必须的。最终,你所需要的只是动态数据血缘,这只需一个能扫描你SQL文件的程序,以及一个能生成用户友好的血缘图的工具。得益于Python,这可以通过一个仅包含100行代码的脚本实现。

如果你对Python和LLM提示技术有所了解,你应该能够在一小时内破解这段代码。或者,你可以试试这个轻量级的开源Python工具叫做SQL-WatchPup,已经包含了这段代码。

只要你手头上的所有SQL文件齐全,你应该能够在15分钟内生成类似这样的动态数据血缘图:如下。

示例数据血缘图的输出。由作者使用SQL-WatchPup制作。

就这样。没有服务器托管费用。不用学别的编程语言。也不用整理你的文件。只需要运行一个简单的本地 Python 脚本。

结论

说实话,我们都爱新潮的工具,但有时最好的解决方法其实是很旧、不酷或不受欢迎的。

下次当你遇到数据质量问题时,先别急着动手。可以先退一步思考:一个简单的数据库限制条件、一个基本的仪表盘,或者一个轻量级的Python脚本能否搞定?

你的理智会感激你。公司的预算也会因此而受益。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消