nodejs如何做到区分字段的日志记录存入数据库?
发布于 8 年前 作者 SuperZee 4789 次浏览 来自 问答

感谢你来到这个问题页面,可以请你花1分钟阅读一下嘛… 需求: 日志需要记录(mysql): 操作用户ID | 操作类型 | 操作时间 | 操作表 | 操作字段 | 新值 | 旧值 有几个疑问如下:

  1. 前4个值都比较好得到,主要是后3个值,(操作字段,新值,旧值)不太好判断,以用户修改信息为例,修改信息页面有 email, phone_number, address, gender,… 等多个字段,用户可能修改了其中,一个或者多个,甚至没修改点击了保存。 这是时候需要进行修改前后值的对比,再插入数据库,是一件繁琐(逻辑多)的事情。有没有好的思考方案?
  2. 这个日志的扩展性不高,如果我要添加操作用户类型(普通用户,管理员),那么以前的日志记录都失效了…
3 回复

对比?不是都要存新值和旧值吗?用户点了修改按钮就把此时的表单信息赋给旧值,点了保存按钮就把此时的表单信息赋给新值 管理员和普通用户修改的东西不一样吧?能不能根据只有管理可以做的某个操作来判断以前有过这个操作的记录是属于管理员的记录

第一 . 现在一些流行的库其实都内建各种hook,实现了AOP机制,意味着比如应用层代码取出来一个数据对象比如User,user= User::byID(123),就可以对该对象进行事件侦听,如 user.onChange("*",function (field, oldValue, newValue) { … }),当你做user->email = ‘xxxx’ 就触发change事件,如果在使用这样的库,在它的文档里查一下有没有onchange这样的东西。

如果不用这样的库,在有效的修改操作的进程里触发事件,也不难自己实现,基本原理并不复杂

function updateUserInfo() { if (changed) { emitChangeEvent(field, oldValue, newValue); } }

但需要控制好数据操作的粒度,不要取值,而要取出整个数据库对象。

第二. 这是为什么通常用RDBMS作日志存储不好的地方,扩展性不好,其实常用的实践是不用RDBMS,而是用NoSQL,CouchDB,MongoDB都可以是不错的选择,因为数据字段可随时扩展。但需要注意的是,用NoSQL并不解决你的这种情况,因为你已经预设了日志字段,所以即使NoSQL数据库允许你后面随时扩展,但之前的日志记录仍然不会有用户这列。这是一个设计问题,日志尽量用NoSQL来存,而日志的内容尽量详实,不管以后用不用得到,只要不产生重大性能问题,就不必太小器,把相关字段记下来,或者至少把主键和外键值记下来。这是需要设计的,不是通过存储系统来解决的。

@flamingtop 谢谢你,我目前使用的ORM库是 [node-orm2 ](Object Relational Mapping http://dresende.github.io/node-orm2) ,有相应的 Hook,但是粒度都是对象级别的,没有详细到 某个值或者列…
如果存储新值和旧值以数据库对象来操作的话,那么就有很多冗余, 一行有多列,用户只修改了其中一列,其余相同的列也会在保存在新值和旧值中。 也看了看 sequelize 的API , 同样的如果不以Instance为单位,那么用户修改10列就要向数据库中插入10列…

/**
 * A hook that is run after updating a single instance
 * @param {String}   name
 * @param {Function} fn   A callback function that is called with instance, options
 * @name afterUpdate
 */

不太清楚参数name指的是Table Name还是Column Name?

回到顶部