Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
将扁平JSON数据转换为MySQL分层结构教程_创想鸟

将扁平JSON数据转换为MySQL分层结构教程

将扁平JSON数据转换为MySQL分层结构教程

本教程详细介绍了如何将包含分层信息的扁平json字符串(例如“clothes – pants – jeans”)导入mysql数据库,并构建出具有父子关系的层级结构。通过php脚本解析json、拆分字符串并巧妙管理父级id,确保数据正确地存储为可查询的树状结构,解决在创建层级关系时常见的父级id关联错误。

从扁平JSON构建MySQL分层结构

在数据处理和存储中,我们经常会遇到需要将某种格式的扁平数据转换为具有层级关系的结构。本教程将指导您如何使用PHP将包含以特定分隔符表示的层级信息的JSON数据导入MySQL数据库,并构建一个可查询的树状结构。

1. 问题背景与数据结构

假设我们有一个JSON文件,其中包含产品类别信息,但这些信息是以扁平的、通过分隔符连接的字符串形式存在的:

[  {"productCategory":"Clothes - Pants - Jeans"},  {"productCategory":"Clothes - Pants - Chinos"},  {"productCategory":"Electronics - Laptops - Gaming"}]

我们的目标是将这些类别导入到MySQL数据库中,并形成一个具有父子关系的层级结构。期望的数据库表结构如下:

taxonomy_id taxonomy_name taxonomy_parent taxonomy_type

1Clothes0Category2Pants1Category3Jeans2Category4Chinos2Category5Electronics0Category6Laptops5Category7Gaming6Category

其中,taxonomy_id 是主键,taxonomy_name 是类别名称,taxonomy_parent 指向其父类别的 taxonomy_id(根类别为0),taxonomy_type 标识类别类型。

2. 核心思路与挑战

处理这种数据转换的核心思路是:

解析JSON: 读取JSON文件并将其解码为PHP数组。拆分层级字符串: 使用分隔符(例如 ‘-‘)将每个 productCategory 字符串拆分成独立的层级名称数组。迭代处理层级: 遍历拆分后的层级名称数组,为每个层级名称在数据库中创建或查找对应的条目。管理父级ID: 这是最关键的一步。在处理每个子层级时,需要知道其直接父级的 taxonomy_id。

最初的尝试可能遇到的问题是,在处理子层级时,父级ID的跟踪逻辑可能出现偏差,导致某些子类别的 taxonomy_parent 字段未能正确关联到其父级。

3. PHP实现:逐步构建层级

我们将使用PHP来完成这一任务。为了简化数据库操作,我们假设存在一个 Insert_Taxonomy 类,它封装了与数据库交互的方法:

Exists_Taxonomy_Name($name): 检查给定名称的类别是否已存在。Get_Taxonomy_Id($name): 根据类别名称获取其 taxonomy_id。如果名称为0,则返回0(表示根类别)。create_taxonomy($args): 创建新的类别记录,$args 数组包含名称、父ID和类型。

完整解决方案代码:

 $current_category_name ) {        // 1. 检查当前类别名称是否已存在于数据库中        $exists_tax_name = $taxonomy->Exists_Taxonomy_Name($current_category_name);        // 2. 获取当前类别的父级ID        // $previous_value 存储的是父级“名称”(或0),需要通过 Get_Taxonomy_Id 转换为实际的ID        $parent_id = $taxonomy->Get_Taxonomy_Id($previous_value);        // 3. 如果当前类别不存在,则插入新记录        if ( empty( $exists_tax_name ) ) {            $args = array($current_category_name, $parent_id, 'category');            $taxonomy->create_taxonomy($args);        }        // 4. 更新 previous_value 为当前类别名称,以便在下一次循环中作为子类别的父级        // 这一步至关重要,确保了正确的父子关系链        $previous_value = $current_category_name;    }}?>

4. 代码解析与关键点

文件读取与解码:

$string = file_get_contents("category.json");$json_decode = json_decode($string, true);

这部分负责读取JSON文件并将其转换为PHP数组,true 参数确保解码为关联数组。

实例化数据库操作类:

$taxonomy = new Insert_Taxonomy();

在循环外部实例化 Insert_Taxonomy 对象,避免在每次迭代中重复创建,提高效率。

拆分与清理:

$split_categories = explode( '-', $category_full_path );$trimmed_categories = array_map('trim', $split_categories);

explode 函数将字符串按 ‘-‘ 分隔符拆分为数组。array_map(‘trim’, …) 用于移除每个子字符串两端的空白,确保数据干净。

父级ID跟踪 ($previous_value):

$previous_value = 0; // 初始化为0,表示根类别的父级// ...$parent_id = $taxonomy->Get_Taxonomy_Id($previous_value);// ...$previous_value = $current_category_name; // 更新为当前类别名称

这是解决层级关系的关键。$previous_value 变量在每次内部循环中存储 前一个 已经处理过的类别名称(或0),这个名称随后被用来通过 Get_Taxonomy_Id 方法获取其对应的 taxonomy_id,作为当前类别的 taxonomy_parent。

操作顺序的重要性:

$exists_tax_name = $taxonomy->Exists_Taxonomy_Name($current_category_name); // 1. 检查是否存在$parent_id = $taxonomy->Get_Taxonomy_Id($previous_value); // 2. 获取父IDif ( empty( $exists_tax_name ) ) { // 3. 如果不存在则插入    $args = array($current_category_name, $parent_id, 'category');    $taxonomy->create_taxonomy($args);}$previous_value = $current_category_name; // 4. 更新previous_value

正确的执行顺序是:

首先,检查当前类别是否已存在。然后,根据 previous_value 获取当前类别的父级ID。这一步必须在检查类别是否存在之前,因为即使类别已存在,我们也需要 previous_value 来更新它,或者在后续循环中作为下一个子类别的父级。如果类别不存在,则使用获取到的 parent_id 插入新记录。最后,将 current_category_name 赋值给 previous_value,为下一个层级的处理做好准备。这个顺序确保了无论是插入新类别还是仅仅更新 previous_value 以供后续使用,parent_id 都能正确地被计算。

5. Insert_Taxonomy 类(示例)

为了使上述代码能够运行,Insert_Taxonomy 类可能看起来像这样(仅为示例,实际实现需根据您的数据库连接和ORM库进行调整):

pdo = new PDO("mysql:host=localhost;dbname=your_db", "user", "pass");        // 为简化示例,我们假设连接已存在或通过其他方式获取        // 这里只是一个占位符,实际需要您自己的数据库连接代码        $this->pdo = null; // 实际应为有效的PDO对象        error_log("Insert_Taxonomy class initialized. (Database connection assumed)");    }    /**     * 检查分类名称是否存在     * @param string $name 分类名称     * @return bool 如果存在则返回true,否则返回false     */    public function Exists_Taxonomy_Name($name) {        if ($name === 0) return true; // 根节点始终被认为“存在”        // 实际查询数据库        // $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM taxonomy_table WHERE taxonomy_name = ?");        // $stmt->execute([$name]);        // return $stmt->fetchColumn() > 0;        error_log("Checking if taxonomy name '{$name}' exists.");        // 模拟返回        return false; // 假设默认不存在,以便创建    }    /**     * 根据分类名称获取ID     * @param string|int $name 分类名称或0(表示根)     * @return int 分类ID,如果不存在或为0则返回0     */    public function Get_Taxonomy_Id($name) {        if ($name === 0) {            return 0; // 根分类的ID为0        }        // 实际查询数据库        // $stmt = $this->pdo->prepare("SELECT taxonomy_id FROM taxonomy_table WHERE taxonomy_name = ?");        // $stmt->execute([$name]);        // $result = $stmt->fetch(PDO::FETCH_ASSOC);        // return $result ? $result['taxonomy_id'] : 0;        error_log("Getting taxonomy ID for name '{$name}'.");        // 模拟返回一个ID,实际应从数据库获取        // 在实际运行中,如果名称不存在,这里应返回0或抛出错误        return crc32($name); // 简单模拟一个ID    }    /**     * 创建新的分类记录     * @param array $args 包含 [name, parent_id, type]     * @return bool 插入成功返回true,否则返回false     */    public function create_taxonomy($args) {        list($name, $parent_id, $type) = $args;        // 实际插入数据库        // $stmt = $this->pdo->prepare("INSERT INTO taxonomy_table (taxonomy_name, taxonomy_parent, taxonomy_type) VALUES (?, ?, ?)");        // return $stmt->execute([$name, $parent_id, $type]);        error_log("Creating taxonomy: Name='{$name}', ParentID='{$parent_id}', Type='{$type}'.");        return true; // 模拟成功    }}?>

6. 注意事项与最佳实践

幂等性: 确保您的脚本可以重复运行而不会创建重复的数据。本教程中的 Exists_Taxonomy_Name 方法正是为了实现这一点。错误处理: 在实际生产环境中,您应该为文件操作(file_get_contents)、JSON解码(json_decode)以及所有数据库操作添加适当的错误处理机制。数据库事务: 对于批量数据插入,考虑使用数据库事务。如果中间发生错误,可以回滚所有已执行的操作,保持数据一致性。性能优化: 对于非常大的JSON文件和大量类别,可以考虑批量插入或优化数据库查询,例如一次性获取所有现有类别的名称和ID,而不是在每次循环中都进行查询。灵活性: 如果分隔符可能变化,可以将其定义为配置项。

7. 总结

通过本教程,您应该已经掌握了如何将扁平的、分隔符连接的JSON数据转换为MySQL数据库中的分层结构。关键在于正确解析数据,并巧妙地管理父级ID的跟踪逻辑,确保每个子类别都能准确地关联到其直接父级。这种方法不仅适用于产品类别,也适用于任何需要构建树状或层级关系的数据导入场景。

以上就是将扁平JSON数据转换为MySQL分层结构教程的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1328478.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
生成友好的阿拉伯语URL:PHP中的字符替换技巧
上一篇 2025年12月12日 14:45:56
理解PHP中的八进制字面量:025与算术运算
下一篇 2025年12月12日 14:46:11

相关推荐

  • X旗下Grok上线即时语音搜索,挑战Google引领搜索新方向

    近日,x平台旗下的ai助手grok正式推出了“即时语音搜索”功能。用户现在可以通过语音直接提问,触发实时网页检索,并迅速获得整合后的精准答案。此举意在优化信息获取流程,推动人机交互向更自然、高效的方向演进。 该语音搜索模式实现了“即说即搜即答”的流畅体验。例如,当用户提出“星舰发射的具体时间是什么?…

    2026年9月21日
    100
  • 如何备份VSCode的全部设置和扩展?

    备份VSCode全部设置和扩展需保存配置文件与扩展目录;2. 配置文件位于各系统指定路径的User文件夹内,包含settings.json和keybindings.json;3. 通过code –list-extensions导出扩展列表并用xargs批量重装可恢复扩展;4. 推荐直接复…

    2026年9月21日
    000
  • mysql数据库和表的关系是怎样

    数据库是表的集合,一个MySQL数据库可包含多个表,表依赖数据库存在,需先创建数据库才能建表,如CREATE DATABASE school;USE school;CREATE TABLE students;数据库实现数据隔离与管理,不同项目使用不同数据库,便于组织与权限控制。 MySQL数据库和表…

    2026年9月21日
    000
  • Laravel 8 登录后重定向到仪表盘的全面指南

    本文深入探讨了 Laravel 8 中用户登录后重定向到仪表盘的多种策略。我们将详细解析默认的重定向机制,包括 LoginController 和 RedirectIfAuthenticated 中间件,并重点介绍如何通过自定义登录逻辑实现精确的重定向控制,同时提供示例代码和常见问题排查建议,确保用…

    2026年9月21日
    000
  • Guava Multimap:高效获取并打印指定键的所有关联值

    guava multimap是处理一键多值映射关系的强大工具。要获取特定键的所有关联值,应直接使用其提供的`multimap#get(k)`方法。该方法会返回一个包含所有匹配值的`collection`,即使键不存在,也会返回一个空集合而非`null`,从而简化了值检索和空值处理逻辑,是比手动迭代键…

    2026年9月21日
    000
  • 你也是”钥匙卡”?Xbox新大作《天外世界2》PS5盘仅1.32GB

    备受期待的Obsidian新作《天外世界2》(The Outer Worlds 2)即将于10月29日正式登陆PS5平台,不过打算入手实体版本的玩家需要留意一个特殊情况。 根据DoesItPlay发布的消息,该游戏的完整容量大约为77GB,但PS5实体光盘内实际仅包含1.32GB的数据。 DoesI…

    2026年9月21日
    000
  • mysql如何调整字符集和排序规则

    答案是调整MySQL字符集和排序规则需分层级操作:先修改数据库默认设置,再转换表和字段,最后配置服务器参数。具体步骤为:使用ALTER DATABASE更改数据库默认字符集;用ALTER TABLE CONVERT TO转换表中所有字符型字段;通过MODIFY修改特定字段的字符集;在my.cnf中设…

    2026年9月21日
    000
  • 怎样配置VSCode与Jest、Cypress等测试框架进行集成测试?

    首先安装Jest和Cypress插件及依赖,配置jest.config.js和.vscode/settings.json实现Jest自动运行,再通过launch.json添加Cypress调试配置,最后在package.json中定义统一脚本命令,使两者在VSCode中高效协同工作。 要在 VSCo…

    2026年9月21日
    000
  • mysql安装后如何优化配置文件

    答案:优化MySQL配置需先定位配置文件,再根据硬件和业务调整内存、InnoDB、连接等核心参数。具体包括设置innodb_buffer_pool_size为物理内存50%~70%,合理配置日志参数与连接数,启用慢查询日志,并使用工具辅助调优,避免过度配置,确保稳定高效。 MySQL 安装后,优化配…

    2026年9月21日
    000
  • 育碧3A大作《阿凡达:潘多拉边境》第三人称更新宣传片公开

    育碧3A大作《阿凡达:潘多拉边境》第三人称更新宣传片公开育碧3A大作《阿凡达:潘多拉边境》第三人称更新宣传片公开育碧3A大作《阿凡达:潘多拉边境》第三人称更新宣传片公开育碧3A大作《阿凡达:潘多拉边境》第三人称更新宣传片公开

    《阿凡达:潘多拉边境》作为育碧旗下《阿凡达》系列的最新力作,于2023年正式发布,游戏基于詹姆斯·卡梅隆执导的《阿凡达》电影宇宙打造,现已登陆pc、ps5及xsx平台。 近日,育碧官方发布了关于游戏更新补丁的宣传视频,重点介绍了即将上线的第三人称视角功能,并通过一段实机演示展示了该模式下的部分 ga…

    2026年9月21日 用户投稿
    100
  • VSCode的括号匹配功能如何自定义?

    可通过 settings.json 自定义括号高亮的边框和背景色;2. 用 editor.matchBrackets 控制是否启用高亮;3. 启用 bracketPairColorization 可为嵌套括号着色;4. 使用 Ctrl/Cmd + Shift + 快速跳转配对括号。 VSCode 的…

    2026年9月21日
    000
  • mysql如何设计数据归档表

    归档目标是解决主表数据量过大问题,需明确归档范围如时间维度冷数据,设计与原表一致或简化的归档表结构,保留必要索引并可添加archive_time字段和分区,通过分批迁移、限流休眠、事务安全和断点记录策略执行归档,避免影响线上服务,同时建立查询视图、定期备份、监控任务及生命周期管理,确保数据可用与系统…

    2026年9月21日
    000
  • JSF应用中Markdown文档动态链接处理指南

    本教程旨在解决jsf web应用程序中集成markdown文档时,如何动态处理内部链接以实现页面局部更新的问题。通过结合服务器端markdown渲染和客户端javascript事件监听,我们可以拦截markdown生成的html链接点击事件,利用ajax异步加载并渲染目标markdown文件,从而在…

    2026年9月21日
    500
  • 如何基于Swoole开发自定义框架?

    基于swoole开发自定义框架可以通过以下步骤实现:1. 创建核心app类,初始化swoole服务器并定义回调函数;2. 实现路由功能,使用router类处理请求分发;3. 添加中间件支持,使用middleware类处理请求;4. 集成异步数据库操作,使用swoole的mysql协程客户端;5. 实…

    2026年9月21日
    100
  • mysql如何理解数据压缩

    MySQL数据压缩通过减少存储空间提升I/O效率,主要在InnoDB引擎中实现页级压缩,使用zlib算法对BLOB、TEXT等大字段表压缩效果显著,需设置ROW_FORMAT=COMPRESSED和KEY_BLOCK_SIZE;压缩可降低磁盘使用并加速全表扫描,但增加CPU开销,频繁更新可能导致页分…

    2026年9月21日
    000
  • 小可AI小程序入口链接_小可AI小程序官方地址

    小可AI小程序官方入口为https://xcx.xiaokeai.com.cn,用户可在社交平台搜索使用;平台支持多轮对话、文本生成、图像理解及语音转文字功能,界面简洁、响应迅速,具备历史记录查看与持续优化的智能算法。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepS…

    2026年9月21日
    000
  • Bing搜索主页官方地址_Bing搜索官方网站登录网址

    Bing搜索主页官方地址是https://www.bing.com/,页面布局简洁,顶部为搜索框,下方展示个性化信息模块,并每日更新全球高清背景图片。 Bing搜索主页官方地址在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来Bing搜索官方网站登录网址,感兴趣的网友一起随小编来瞧瞧吧! h…

    2026年9月21日
    000
  • mysql如何使用savepoint

    SAVEPOINT用于在事务中设置回滚点,支持部分回滚。开启事务后可用SAVEPOINT命名保存点,通过ROLLBACK TO回滚至指定点,RELEASE SAVEPOINT可释放保存点。例如转账时先扣款并设保存点,若后续操作失败可回滚到该点,保留前置操作。保存点仅在当前事务有效,提交或回滚后自动清…

    2026年9月21日
    100
  • Bing搜索最新官方网址入口 Bing搜索在线使用官网主页直达

    Bing搜索最新官方网址入口是https://www.bing.com,该网站提供每日更新的高清背景图片、简洁的页面布局、深色模式切换及个性化主页定制等视觉体验功能。 Bing搜索最新官方网址入口在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来Bing搜索在线使用官网主页直达,感兴趣的网友…

    2026年9月21日
    100
  • mysqlmysql如何优化in条件大列表查询

    使用EXPLAIN和慢查询日志判断IN性能问题,type为ALL且possible_keys为空或rows过大说明需优化;JOIN在有索引时通常优于IN,尤其当列表值来自另一表时;大IN列表可拆分为多个小IN结合UNION ALL,或存入临时表后用JOIN提升效率。 优化 MySQL 中 IN 条件…

    2026年9月21日
    000

发表回复

登录后才能评论
关注微信