Mysql 构建管理审批系统的最佳实践
应该有一个管理面板的子系统,不同的用户可以管理他们的产品,但是每次更改都应该在影响主产品表之前得到管理员的批准。 有三个主表:Mysql 构建管理审批系统的最佳实践,mysql,database-design,admin,change-management,Mysql,Database Design,Admin,Change Management,应该有一个管理面板的子系统,不同的用户可以管理他们的产品,但是每次更改都应该在影响主产品表之前得到管理员的批准。 有三个主表: 产品:存储最终批准并在整个系统中使用的产品 Changes_versions:一个与产品表有一对多关系的表,表示每个更改版本由谁提交、何时提交、是否被管理员批准/拒绝或仍处于挂起状态。表结构如下: CREATE TABLE `changes_versions` ( `xid` int(11) unsigned NOT NULL AUTO_INCREMENT, `
CREATE TABLE `changes_versions` (
`xid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`xcreated_date` datetime DEFAULT NULL,
`xupdated_date` timestamp NULL DEFAULT NULL,
`xversion` int(11) DEFAULT NULL,
`xobject_id` int(11) DEFAULT NULL,
`xobject_type` varchar(255) DEFAULT NULL,
`xstate` enum('PENDING','ACCEPTED','REJECTED') DEFAULT 'PENDING',
PRIMARY KEY (`xid`)
) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8
CREATE TABLE `changes` (
`xid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`xcreated_date` datetime DEFAULT NULL,
`xcreated_by` varchar(255) DEFAULT NULL,
`xupdated_date` timestamp NULL DEFAULT NULL,
`xupdated_by` varchar(255) DEFAULT NULL,
`xversion_id` int(11) DEFAULT NULL,
`xcolumn_name` varchar(255) DEFAULT NULL,
`xcolumn_value` varchar(255) DEFAULT NULL,
`xstate` enum('PENDING','ACCEPTED','REJECTED') DEFAULT 'PENDING',
`xadmin_review` text,
PRIMARY KEY (`xid`)
) ENGINE=InnoDB AUTO_INCREMENT=764 DEFAULT CHARSET=utf8
CREATE TABLE `changes_versions` (
`xid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`xcreated_date` datetime DEFAULT NULL,
`xupdated_date` timestamp NULL DEFAULT NULL,
`xversion` int(11) DEFAULT NULL,
`xobject_id` int(11) DEFAULT NULL,
`xobject_type` varchar(255) DEFAULT NULL,
`xstate` enum('PENDING','ACCEPTED','REJECTED') DEFAULT 'PENDING',
PRIMARY KEY (`xid`)
) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8
CREATE TABLE `changes` (
`xid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`xcreated_date` datetime DEFAULT NULL,
`xcreated_by` varchar(255) DEFAULT NULL,
`xupdated_date` timestamp NULL DEFAULT NULL,
`xupdated_by` varchar(255) DEFAULT NULL,
`xversion_id` int(11) DEFAULT NULL,
`xcolumn_name` varchar(255) DEFAULT NULL,
`xcolumn_value` varchar(255) DEFAULT NULL,
`xstate` enum('PENDING','ACCEPTED','REJECTED') DEFAULT 'PENDING',
`xadmin_review` text,
PRIMARY KEY (`xid`)
) ENGINE=InnoDB AUTO_INCREMENT=764 DEFAULT CHARSET=utf8
我还应该注意到,对于这个问题,这个表结构的某些内容可能看起来很复杂。这个结构很复杂,因为更改和更改表保存并显示了许多具有不同结构的表的历史和管理审批流程。我认为SQL View在这里很方便,更改表名并添加一个标记字段,该字段标记临时行,然后创建一个名为Product的视图,并在视图中排除该字段和该字段标记的行,这样您的原始表(现在已转换为视图)将保持不变(如果我错了,请纠正我) 系统中有不同的项目(如产品),每个项目类型有一个(InnoDB)表。 每个项目表都有一个自动增量列(如
id
)。
您有一个项目版本表(changes\u versions
)来存储特定项目的不同版本。
该项由列标识
- 引用表的类型(如“产品”)
这是一个引用上表主键的“多态外键”xobject\u id
xobject\u id
列中
一种可能的解决方案是:通过在事务中插入和删除一行来“保留”ID
例如:
start transaction;
insert into products(column_1, column_2) values ('value_1', 'value_2');
delete from products where id = last_insert_id();
select last_insert_id();
commit;
您将得到:
- 插入的行对于其他用户将永远不可见,因为它在同一事务中被删除
仍将从删除的行返回自动生成的idlast\u insert\u id()
- 该ID将被“烧掉”,因此引擎将不再生成该ID
- 当管理员接受该项目时,您仍然可以手动插入该ID
- 不需要更改数据库模式
演示:解决方案是按说明创建所有表,当用户将产品创建到
changes\u version
表中时,应该有一个mysql事件,定期检查product
表中的每个记录,并将其与changes\u version
表匹配。如果在其中发现任何更改或新插入已更改\u版本
表,应相应插入/更新产品
表
修订后的解决方案:
您可以在用户登录时将用户记录从changes\u version
插入产品表,并在注销时将其删除。这适用于尚未移动到product
表中的产品,您可以通过查询进行检查
如果您有前端源代码,那么您可以仅向用户显示
更改\u version
记录,并在其获得批准时通过触发器将其移动到产品
表中。如果版本表中包含来自产品的所有列以及授权列,是否会更简单更改是通过将主字段从版本表复制到产品来完成的。对于新记录,Version.productID将为空,但可以在创建产品记录后填写。@NigelRen我也应该解释一下,版本控制系统的用法不仅仅适用于产品表。它还适用于具有不同t结构和列,因此您的方式不适用于我的情况。是否可以更改一个新项目(产品),该项目(产品)不在原始表(products
)中,因为它从未被接受过?@PaulSpiegel我不完全理解您的问题。在我的系统中,我希望该用户创建一行(假设管理员尚未批准)可以编辑该行too@ArefAnafgeh我的问题回答得很好。我问了它,因为如果不是这样的话,您可以将NULL
写入xobject\u id
并在