什么是模式?数据结构、契约与变更

什么是模式?

Scrapeless Web Unlocker 获取网页内容,你的应用可以将其转换为受显式数据模式约束的记录。

什么是模式?

模式是对数据如何组织以及其结构必须满足哪些规则的描述。它可以定义字段名称、数据类型、必填值、关系以及约束。这个词有几个相关含义:数据库模式可以描述表和键,API 模式可以描述交换的消息,而具名 SQL 模式可以为数据库对象提供命名空间。

关键问题是模式建立了哪一种契约。一个商品观测记录可能需要来源标识符和观测时间,允许价格缺失,但只要有金额就必须有货币单位。该契约为生产方和消费方提供了对记录的共同解释。没有这些含义的字段列表只是部分规格说明。

摘要

  • 模式描述结构和约束。 其精确范围取决于数据系统。
  • 缺失、null 和空值是不同的状态。 在规范化源数据之前先定义它们的含义。
  • 一条结构上合法的记录仍然可能在事实层面是错误的。 结构检查不能证明来源的准确性。
  • 模式变更需要进行消费者兼容性检查。 看似只是增加字段的变更也可能破坏严格的读取方。

你应区分哪些“模式”的含义?

模式可以指概念数据模型、逻辑记录契约、物理数据库结构或对象命名空间。概念模型说明一个产品可以有多个报价。逻辑模式定义用于表示这些报价的字段和关系。物理设计则选择实际的表、类型和索引。

SQL 命名空间是一个更窄的含义。 PostgreSQL 对具名模式的说明 解释了模式如何在一个数据库内组织数据库对象。创建这样一个命名空间本身并不会定义其中每张表的业务含义。

API 消息模式描述调用方发送和接收的内容。JSON Schema 是用于指定 JSON 结构和约束的一种语言。API 契约可能还需要身份验证要求、分页行为、错误含义以及兼容性规则。这些关注点超出了单条消息结构本身的范畴。

搜索结构化数据是该术语的另一种不同用法。用词汇来描述页面并不能取代应用数据库的模式。只要设计文档中只写了“the schema”,就要明确其受众和校验边界。

一个有用的记录契约应定义什么?

一个有用的记录契约会定义标识、类型、存在规则、单位、关系以及预期含义。从记录粒度开始。一行可以表示一个产品、一个报价,或某一时刻的产品观测。这些粒度需要不同的键,即使它们共享诸如标题和价格这样的字段。

类型应遵从领域而不是表面形式。由数字组成的产品标识符可能需要保持为字符串,因为前导零是有意义的,而且对它进行算术运算没有意义。金额需要精度策略和货币上下文。时间戳需要定义解释方式和时区策略。

存在规则同样重要。 JSON Schema 关于对象属性的规则 区分由模式描述的属性与被要求必须出现的属性。声明属性类型并不会自动使该属性成为必填。

说明是否接受额外字段。严格的读取方可能会拒绝未知属性。宽松的读取方可能会保留或忽略它们。不能仅因为负载使用 JSON 就推断其行为。将这些决策记录在契约中,并用具有代表性的输入进行验证。

契约决策需要解决的问题常见失败
标识一条记录标识的是什么?报价和产品共享了一个含义不清的键
存在性该属性必须存在吗?被忽略的值会被悄悄虚构出来
可空性该属性可以是 null 吗?null 与缺失被视为相同
单位该数值衡量的是什么?比较了使用不同货币单位的金额
演进读取方可以接受哪些变更?生产方在不改变类型的情况下改变了含义

缺失、null 和空值有何不同?

缺失属性在记录中不存在,null 属性存在但其值为 null,而空字符串则是存在但不包含任何字符的字符串。它们的业务含义取决于约定。对于源描述而言,缺失可能表示抽取器未找到该字段;null 可能表示源明确报告没有值;空字符串则可能是不被允许的。

The JSON 数据交换规范 将 null、字符串、数字、对象和数组定义为彼此不同的 JSON 值。它并不会为缺失的价格或空标题赋予你应用程序的业务含义。这样的解释应当写在记录契约中。

不要仅仅为了满足数值列而将未知数字替换为零。零本身是一个取值,会影响汇总、筛选和告警。应保留“明确缺失”的状态,并在有用的情况下给出原因,例如来源遗漏或抽取不确定性。

使用源感知规则对空格和本地化格式进行规范化。一个可见数值可能包含货币符号或特定地区的小数分隔符。在规范化时,保留足够的、允许的证据来解释其解释方式。

如何将架构应用于抓取的数据?

在识别源记录之后并在向消费者发布规范化输出之前应用模式。在一个示例性的目录工作流中,收集已审批页面,确认其包含预期的目录,提取候选列表,并将每个字段映射到商定的观测契约。然后验证会对该规范化的候选项进行评估。

无痕网页解锁器 可以提供页面内容。 Web Unlocker 集合请求 是与你的输出模式分离的单独契约。格式良好的集合响应并不能保证你提取的产品记录包含正确的数量或标识。

将解析错误与来源缺失区分开来。如果产品页面上有价格,但你的选择器无法定位到它,将金额标记为来源为 null 会错误陈述证据。候选项可以保持未解决状态,而不必进入已接受的数据集。这样的区分使得之后解析器被修正时更容易理解。

The 从抓取的记录转换为分析表 展示了为什么在存储边界上使用类型化输出很重要。模式还应描述数组、重复提供项以及嵌套变体如何转换为关系型行,而不是让每个使用方各自独立地对它们进行扁平化处理。

写时模式或读时模式是什么意思?

写入时模式在数据被接收并存入存储之前或过程中就施加结构化解释,而读取时模式则在读取数据时才施加解释。两者的区别在于规则何时被强制执行。这并不意味着一个系统具有含义而另一个系统没有结构。

早期验证会在下游查询处理之前捕获不兼容的记录。它还可以拒绝新的源字段,直到合同被更新。后期解释则保留了灵活性,但将责任转移给读取方,如果他们采用不同的解析规则,可能会产生分歧。

许多工作流会结合这两种方法。着陆层可以保留带有最少元数据的已批准原始表示,而整理过的表则强制执行稳定的业务模式。原始数据留存需要独立的访问和删除控制;灵活性并不是永远保留所有源响应的理由。

模式如何安全演进?

模式演进只有在相对于必须保持兼容的读者和写入者时才是安全的。添加一个可选字段对于一个宽松的读取器来说可能可行,但对于一个拒绝未知属性的读取器则可能失败。将数字改为字符串,即使显示的值看起来没有变化,也可能会破坏计算。

语义变化尤其容易被忽视。一个名为 price 的字段最初可能表示主要报价金额,后来却表示最低分期付款额。类型依然是数值型,但使用方的理解却被打破。一旦含义发生变化,就应当重命名或进行版本化处理该概念,并发布迁移路径。

同时测试生产者和消费者的期望。保留具有代表性的已接受记录、缺失情况和被拒绝情况。针对承诺向后兼容的场景,用旧读取器评估新的输出。定义旧的契约何时可以退休,以及由谁负责迁移。

对于表格交换, W3C 表格数据与元数据模型 描述了列注解、键和值概念。这些有助于在各类工具之间记录契约,但并不能消除就业务定义达成一致的必要性。

结论

写下一个记录的含义,然后定义其结构和缺失状态。在发布边界进行验证,并将含义的变化视为契约变更。在规划收集部分时,使用 无抓取定价 以及您自身的验证和存储成本。

将集合层付诸实践

选择与您的数据源相匹配的 Scrapeless 集合能力,然后根据上述说明执行验证和操作决策。

今天注册即可获得 $5 免费额度 — 无需信用卡.

领取您的 $5 额度 →

常见问题

模式和数据是同一个东西吗?

不对。模式描述的是允许的结构和约束;数据则是根据这些规则进行评估的实例。即使尚未收集到任何记录,模式也可以先行存在。

JSON 会自动强制执行模式(schema)吗?

不对。JSON 定义的是一种数据格式。模式验证需要一个约定好的模式,以及一个实际对记录进行评估的验证器或等效的应用逻辑。

添加字段总是向后兼容的吗?

不可以。兼容性取决于消费者行为。对于会拒绝未知字段的读取方来说,即使属性是可选的,当生产者添加一个属性时也可能导致失败。

架构能证明抓取到的价格是正确的吗?

不可以。架构可以要求提供金额和货币,但这些值是否描述了预期的报价取决于来源匹配和解释。还要使用具备来源感知能力的质量检查。

参考资料