mysql 临时表实现临时编辑功能 作者:七棵菜 日期:2022-11-30 栏目:计算机分类:1 人气:298 #### 需求 产品模型有很多配件,这些配件是递归树的结构,实现产品的新增和编辑功能。 #### 分析 功能难点在于树的编辑,存储递归树结构最简单的办法是使用如下表保存树结点: ``` DROP TABLE IF EXISTS `jx_parts_library`; CREATE TABLE `jx_parts_library` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号', `parts_id` int(10) unsigned NOT NULL COMMENT '组件编号', `parent_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '父级组件库编号', PRIMARY KEY (`id`), KEY (`parts_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='组件库'; ``` 新增产品比较简单,但是在编辑产品的时候,用户更改了组件树,但是临时取消了,并没有保存更改;那么如果是使用数据库保存树结构的话就有问题了,因为编辑树是即时更新到数据表中的,即使用户没有保存产品,但是产品的配件数也已经更新了。 #### 解决方案 ##### 不使用数据库 在编辑产品的时候,使用缓存保存数据库。但是在组件数结构比较庞大的时候,维护产品缓存树可能成本较高。 ##### 使用数据库临时表 解决思路如下: - 新建一张临时表用于临时存储配件数结构 - 在编辑产品时,将树结构同步到临时表中 - 树结构的编辑在临时表中完成 - 产品保存时将临时表中的树结构同步到主表中 技术实现细节: - 主表和临时表的数据结构必须一致,即字段必须相同。 - 主表和临时表的主键必须保持一致。在编辑临时表的时候,主表中可能有新的记录插入进来(新增其他产品),因此插入操作只能在主表中进行,通过触发器将新增的记录同步到附表中,临时表的插入操作在主表中通过状态字段加以标识。 ``` DROP TRIGGER IF EXISTS t_afterinsert_on_parts_library; CREATE TRIGGER t_afterinsert_on_parts_library AFTER INSERT ON jx_parts_library FOR EACH ROW REPLACE INTO jx_parts_library_tmp SELECT * FROM jx_parts_library WHERE id = new.id; ``` - 主表主键必须设置为自增,临时表主键不能设置自增,但是临时表的插入操作必须使用`replace into`。因为在将临时表的数据同步到主表中时,会通过触发器再次将数据插入到临时表,如果使用`insert into`会有主键冲突。 - 新增产品时组件树的删除操作必须在主表中进行,编辑时的删除操作必须在临时表中进行。删除操作不能同步,否则在取消保存时,影响主表中的数据。 - 同步的步骤如下 - 临时表树结构数据同步到主表,首先删除主表中的树结构,然后将临时表中的树结构插入进来(insert into),不能直接使用(replace into),因为删除操作没有同步触发器,并不能保证两个表中数据完全一致。 - 主表树结构数据同步到临时表,首先删除临时表中的树结构,然后将主表中的树结构插入进来(replace into),此时不能使用(insert into),因为如果此前用户有编辑树结构但是没有保存产品,则临时表中的数据结构已经发生变化,如果使用`insert into`,可能会产生主键冲突。 > 由于删除操作不同步,还可以增加一个备份表,用于记录主表的删除操作。此步骤可选,不影响功能实现。 ``` DROP TRIGGER IF EXISTS `t_parts_library_transh`; CREATE TRIGGER `t_parts_library_transh` BEFORE DELETE ON `jx_parts_library` FOR EACH ROW REPLACE INTO jx_parts_library_transh SELECT * FROM jx_parts_library WHERE id = old.id; ``` 最后附上表结构: ``` -- -------------------- -- 组件主表 -- -------------------- DROP TABLE IF EXISTS `jx_parts_library`; CREATE TABLE `jx_parts_library` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号', `parts_id` int(10) unsigned NOT NULL COMMENT '组件编号', `parent_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '父级组件库编号', `time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `status` TINYINT(1) DEFAULT 1 COMMENT '状态.1=>确认,0=>未确认', PRIMARY KEY (`id`), KEY (`parts_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='组件库'; -- -------------------- -- 组件临时表 -- -------------------- DROP TABLE IF EXISTS `jx_parts_library_tmp`; CREATE TABLE `jx_parts_library_tmp` ( `id` INT (10) UNSIGNED NOT NULL COMMENT '编号', `parts_id` INT (10) UNSIGNED NOT NULL COMMENT '组件编号', `parent_id` INT (10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '父级组件库编号', `time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `status` TINYINT(1) DEFAULT 1 COMMENT '状态.1=>确认,0=>未确认', PRIMARY KEY (`id`), KEY (`parts_id`) ) ENGINE = MyISAM DEFAULT CHARSET = utf8 COMMENT = '组件库回收站'; -- -------------------- -- 组件备份表 -- -------------------- DROP TABLE IF EXISTS `jx_parts_library_transh`; CREATE TABLE `jx_parts_library_transh` ( `id` INT (10) UNSIGNED NOT NULL COMMENT '编号', `parts_id` INT (10) UNSIGNED NOT NULL COMMENT '组件编号', `parent_id` INT (10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '父级组件库编号', `time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `status` TINYINT(1) DEFAULT 1 COMMENT '状态.1=>确认,0=>未确认', PRIMARY KEY (`id`), KEY (`parts_id`) ) ENGINE = MyISAM DEFAULT CHARSET = utf8 COMMENT = '组件库回收站'; ``` 标签: mysql 临时表 树结构 临时编辑 上一篇:如何使用mvn命令导入依赖 下一篇:Bootstrap 栅格系统 随便看看 2024-02-19 PHP7 运算符“??” 和“?:”的区别 2022-11-30 Linux 后台运行命令 2022-11-25 关于我们 2022-11-30 centos一键系统安装lnmp集成环境 2022-11-30 linux 生成 ssh 公钥 留言