跳转到主要内容
该数据集由纽约公共图书馆创建,包含酒店、餐馆和咖啡馆菜单的历史数据,以及其中菜品及其价格。 来源:http://menus.nypl.org/data 这些数据属于公有领域。 这些数据来自图书馆档案,因此可能并不完整,也不太适合用于统计分析。尽管如此,它也“很美味”。 数据规模仅为 130 万条菜单菜品记录——对于 ClickHouse 来说,这只是非常小的数据量,但仍然是一个很好的示例。

下载数据集

运行以下命令:
如有需要,请将该链接替换为 http://menus.nypl.org/data 中的最新链接。 下载大小约为 35 MB。

解压数据集

未压缩大小约为 150 MB。 这些数据经过归一化后,由四个表组成:
  • Menu — 菜单相关信息:餐厅名称、菜单被记录到的日期等。
  • Dish — 菜品相关信息:菜名以及一些特征。
  • MenuPage — 菜单页面相关信息,因为每个页面都属于某个菜单。
  • MenuItem — 菜单中的一个条目,即某个菜单页面上的一道菜及其价格:关联到菜品和菜单页面。

创建表

我们使用 Decimal 数据类型来存储价格。

导入数据

将数据导入 ClickHouse,运行:
我们使用 CSVWithNames 格式,因为数据是以带请求头的 CSV 形式表示的。 我们禁用 format_csv_allow_single_quotes,因为数据字段只使用双引号,而单引号可以出现在值中,不应让 CSV parser 产生误判。 我们禁用 input_format_null_as_default,因为我们的数据中没有 NULL。否则 ClickHouse 会尝试解析 \N 序列,从而可能与数据中的 \ 混淆。 设置 date_time_input_format best_effort 允许以多种格式解析 DateTime 字段。例如,不带秒的 ISO-8601 格式 (如 ‘2000-01-01 01:02’) 也能被识别。如果不启用此设置,则只允许固定的 DateTime 格式。

对数据进行反规范化

数据以多个表的规范化结果形式呈现。这意味着,如果你想查询例如菜单项对应的菜名,就必须执行 JOIN。 对于典型的分析任务,直接处理预先 JOIN 好的数据效率要高得多,可以避免每次都执行 JOIN。这类数据称为“反规范化的”数据。 我们将创建一个表 menu_item_denorm,其中包含通过 JOIN 合并在一起的所有数据:

验证数据

Query
Response

执行一些查询

菜品历史价格的平均值

Query
Response
仅供参考。

汉堡价格

Query
Response

伏特加

Query
Response
要查 vodka,我们得写 ILIKE '%vodka%',这写法绝对很有态度。

鱼子酱

让我们输出鱼子酱的价格,再输出一道含有鱼子酱的菜名。
Query
Response
至少他们还有鱼子酱配伏特加。真不错。

在线体验环境

数据已上传至 ClickHouse Playground,示例
最后修改于 2026年7月1日