如何实现系统记录变更的记录功能

在程序操作中,我们需要把记录变更操作记录下来,通用权限管理系统正好有这个表,下面参照这个表创建自己的修改记录表,表结构如下

用代码生成器的截图如下

实体类

  1 //-----------------------------------------------------------------------
  2 // <copyright file="BASEMODIFYRECORDEntity.cs" company="ZTO">
  3 //     Copyright (c) 2014 , All rights reserved.
  4 // </copyright>
  5 //-----------------------------------------------------------------------
  6
  7 using System;
  8 using System.Collections.Generic;
  9 using System.Linq;
 10 using System.Data;
 11
 12 namespace DotNet.Business
 13 {
 14     using DotNet.Utilities;
 15
 16     /// <summary>
 17     /// BASEMODIFYRECORDEntity
 18     ///
 19     ///
 20     /// 修改纪录
 21     ///
 22     /// 2014-11-04 版本:1.0 SongBiao 创建文件。
 23     ///
 24     /// <author>
 25     ///     <name>SongBiao</name>
 26     ///     <date>2014-11-04</date>
 27     /// </author>
 28     /// </summary>
 29     public partial class BASEMODIFYRECORDEntity : BaseEntity
 30     {
 31         private string nEWKEY = string.Empty;
 32         /// <summary>
 33         /// NEWKEY
 34         /// </summary>
 35         public string NEWKEY
 36         {
 37             get
 38             {
 39                 return nEWKEY;
 40             }
 41             set
 42             {
 43                 nEWKEY = value;
 44             }
 45         }
 46
 47         private string nEWVALUE = string.Empty;
 48         /// <summary>
 49         /// NEWVALUE
 50         /// </summary>
 51         public string NEWVALUE
 52         {
 53             get
 54             {
 55                 return nEWVALUE;
 56             }
 57             set
 58             {
 59                 nEWVALUE = value;
 60             }
 61         }
 62
 63         private string cOLUMNDESCRIPTION = string.Empty;
 64         /// <summary>
 65         /// COLUMNDESCRIPTION
 66         /// </summary>
 67         public string COLUMNDESCRIPTION
 68         {
 69             get
 70             {
 71                 return cOLUMNDESCRIPTION;
 72             }
 73             set
 74             {
 75                 cOLUMNDESCRIPTION = value;
 76             }
 77         }
 78
 79         private string createBy = string.Empty;
 80         /// <summary>
 81         /// CREATEBY
 82         /// </summary>
 83         public string CreateBy
 84         {
 85             get
 86             {
 87                 return createBy;
 88             }
 89             set
 90             {
 91                 createBy = value;
 92             }
 93         }
 94
 95         private string oLDKEY = string.Empty;
 96         /// <summary>
 97         /// OLDKEY
 98         /// </summary>
 99         public string OLDKEY
100         {
101             get
102             {
103                 return oLDKEY;
104             }
105             set
106             {
107                 oLDKEY = value;
108             }
109         }
110
111         private DateTime? createOn = null;
112         /// <summary>
113         /// CREATEON
114         /// </summary>
115         public DateTime? CreateOn
116         {
117             get
118             {
119                 return createOn;
120             }
121             set
122             {
123                 createOn = value;
124             }
125         }
126
127         private string oLDVALUE = string.Empty;
128         /// <summary>
129         /// OLDVALUE
130         /// </summary>
131         public string OLDVALUE
132         {
133             get
134             {
135                 return oLDVALUE;
136             }
137             set
138             {
139                 oLDVALUE = value;
140             }
141         }
142
143         private string createUserId = string.Empty;
144         /// <summary>
145         /// CREATEUSERID
146         /// </summary>
147         public string CreateUserId
148         {
149             get
150             {
151                 return createUserId;
152             }
153             set
154             {
155                 createUserId = value;
156             }
157         }
158
159         private string rECORDKEY = string.Empty;
160         /// <summary>
161         /// RECORDKEY
162         /// </summary>
163         public string RECORDKEY
164         {
165             get
166             {
167                 return rECORDKEY;
168             }
169             set
170             {
171                 rECORDKEY = value;
172             }
173         }
174
175         private string cOLUMNCODE = string.Empty;
176         /// <summary>
177         /// COLUMNCODE
178         /// </summary>
179         public string COLUMNCODE
180         {
181             get
182             {
183                 return cOLUMNCODE;
184             }
185             set
186             {
187                 cOLUMNCODE = value;
188             }
189         }
190
191         private Decimal? id = null;
192         /// <summary>
193         /// ID
194         /// </summary>
195         public Decimal? Id
196         {
197             get
198             {
199                 return id;
200             }
201             set
202             {
203                 id = value;
204             }
205         }
206
207         private string tABLEDESCRIPTION = string.Empty;
208         /// <summary>
209         /// TABLEDESCRIPTION
210         /// </summary>
211         public string TABLEDESCRIPTION
212         {
213             get
214             {
215                 return tABLEDESCRIPTION;
216             }
217             set
218             {
219                 tABLEDESCRIPTION = value;
220             }
221         }
222
223         private string tABLECODE = string.Empty;
224         /// <summary>
225         /// TABLECODE
226         /// </summary>
227         public string TABLECODE
228         {
229             get
230             {
231                 return tABLECODE;
232             }
233             set
234             {
235                 tABLECODE = value;
236             }
237         }
238
239         /// <summary>
240         /// 从数据行读取
241         /// </summary>
242         /// <param name="dr">数据行</param>
243         protected override BaseEntity GetFrom(IDataRow dr)
244         {
245             GetFromExpand(dr);
246             NEWKEY = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldNEWKEY]);
247             NEWVALUE = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldNEWVALUE]);
248             COLUMNDESCRIPTION = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldCOLUMNDESCRIPTION]);
249             CreateBy = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldCreateBy]);
250             OLDKEY = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldOLDKEY]);
251             CreateOn = BaseBusinessLogic.ConvertToNullableDateTime(dr[BASEMODIFYRECORDEntity.FieldCreateOn]);
252             OLDVALUE = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldOLDVALUE]);
253             CreateUserId = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldCreateUserId]);
254             RECORDKEY = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldRECORDKEY]);
255             COLUMNCODE = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldCOLUMNCODE]);
256             Id = BaseBusinessLogic.ConvertToNullableDecimal(dr[BASEMODIFYRECORDEntity.FieldId]);
257             TABLEDESCRIPTION = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldTABLEDESCRIPTION]);
258             TABLECODE = BaseBusinessLogic.ConvertToString(dr[BASEMODIFYRECORDEntity.FieldTABLECODE]);
259             return this;
260         }
261
262         ///<summary>
263         ///
264         ///</summary>
265         public static string TableName = "BASEMODIFYRECORD";
266
267         ///<summary>
268         /// NEWKEY
269         ///</summary>
270         public static string FieldNEWKEY = "NEWKEY";
271
272         ///<summary>
273         /// NEWVALUE
274         ///</summary>
275         public static string FieldNEWVALUE = "NEWVALUE";
276
277         ///<summary>
278         /// COLUMNDESCRIPTION
279         ///</summary>
280         public static string FieldCOLUMNDESCRIPTION = "COLUMNDESCRIPTION";
281
282         ///<summary>
283         /// CREATEBY
284         ///</summary>
285         public static string FieldCreateBy = "CreateBy";
286
287         ///<summary>
288         /// OLDKEY
289         ///</summary>
290         public static string FieldOLDKEY = "OLDKEY";
291
292         ///<summary>
293         /// CREATEON
294         ///</summary>
295         public static string FieldCreateOn = "CreateOn";
296
297         ///<summary>
298         /// OLDVALUE
299         ///</summary>
300         public static string FieldOLDVALUE = "OLDVALUE";
301
302         ///<summary>
303         /// CREATEUSERID
304         ///</summary>
305         public static string FieldCreateUserId = "CreateUserId";
306
307         ///<summary>
308         /// RECORDKEY
309         ///</summary>
310         public static string FieldRECORDKEY = "RECORDKEY";
311
312         ///<summary>
313         /// COLUMNCODE
314         ///</summary>
315         public static string FieldCOLUMNCODE = "COLUMNCODE";
316
317         ///<summary>
318         /// ID
319         ///</summary>
320         public static string FieldId = "Id";
321
322         ///<summary>
323         /// TABLEDESCRIPTION
324         ///</summary>
325         public static string FieldTABLEDESCRIPTION = "TABLEDESCRIPTION";
326
327         ///<summary>
328         /// TABLECODE
329         ///</summary>
330         public static string FieldTABLECODE = "TABLECODE";
331     }
332 }

管理类

  1 //-----------------------------------------------------------------------
  2 // <copyright file="BASEMODIFYRECORDManager.Auto.cs" company="ZTO">
  3 //     Copyright (c) 2014 , All rights reserved.
  4 // </copyright>
  5 //-----------------------------------------------------------------------
  6
  7 using System;
  8 using System.Collections.Generic;
  9 using System.Linq;
 10 using System.Data;
 11
 12 namespace DotNet.Business
 13 {
 14     using DotNet.Business;
 15     using DotNet.Utilities;
 16
 17     /// <summary>
 18     /// BASEMODIFYRECORDManager
 19     ///
 20     ///
 21     /// 修改纪录
 22     ///
 23     /// 2014-11-04 版本:1.0 SongBiao 创建文件。
 24     ///
 25     /// <author>
 26     ///     <name>SongBiao</name>
 27     ///     <date>2014-11-04</date>
 28     /// </author>
 29     /// </summary>
 30     public partial class BASEMODIFYRECORDManager : BaseManager, IBaseManager
 31     {
 32         /// <summary>
 33         /// 构造函数
 34         /// </summary>
 35         public BASEMODIFYRECORDManager()
 36         {
 37             if (base.dbHelper == null)
 38             {
 39                 base.dbHelper = DbHelperFactory.GetHelper(BaseSystemInfo.UserCenterDbType, BaseSystemInfo.UserCenterDbConnection);
 40             }
 41             if (string.IsNullOrEmpty(base.CurrentTableName))
 42             {
 43                 base.CurrentTableName = BASEMODIFYRECORDEntity.TableName;
 44             }
 45             base.PrimaryKey = "Id";
 46         }
 47
 48         /// <summary>
 49         /// 构造函数
 50         /// <param name="tableName">指定表名</param>
 51         /// </summary>
 52         public BASEMODIFYRECORDManager(string tableName)
 53         {
 54             base.CurrentTableName = tableName;
 55         }
 56
 57         /// <summary>
 58         /// 构造函数
 59         /// </summary>
 60         /// <param name="dbHelper">数据库连接</param>
 61         public BASEMODIFYRECORDManager(IDbHelper dbHelper): this()
 62         {
 63             DbHelper = dbHelper;
 64         }
 65
 66         /// <summary>
 67         /// 构造函数
 68         /// </summary>
 69         /// <param name="userInfo">用户信息</param>
 70         public BASEMODIFYRECORDManager(BaseUserInfo userInfo) : this()
 71         {
 72             UserInfo = userInfo;
 73         }
 74
 75         /// <summary>
 76         /// 构造函数
 77         /// </summary>
 78         /// <param name="userInfo">用户信息</param>
 79         /// <param name="tableName">指定表名</param>
 80         public BASEMODIFYRECORDManager(BaseUserInfo userInfo, string tableName) : this(userInfo)
 81         {
 82             base.CurrentTableName = tableName;
 83         }
 84
 85         /// <summary>
 86         /// 构造函数
 87         /// </summary>
 88         /// <param name="dbHelper">数据库连接</param>
 89         /// <param name="userInfo">用户信息</param>
 90         public BASEMODIFYRECORDManager(IDbHelper dbHelper, BaseUserInfo userInfo) : this(dbHelper)
 91         {
 92             UserInfo = userInfo;
 93         }
 94
 95         /// <summary>
 96         /// 构造函数
 97         /// </summary>
 98         /// <param name="dbHelper">数据库连接</param>
 99         /// <param name="userInfo">用户信息</param>
100         /// <param name="tableName">指定表名</param>
101         public BASEMODIFYRECORDManager(IDbHelper dbHelper, BaseUserInfo userInfo, string tableName) : this(dbHelper, userInfo)
102         {
103             base.CurrentTableName = tableName;
104         }
105
106         /// <summary>
107         /// 添加, 这里可以人工干预,提高程序的性能
108         /// </summary>
109         /// <param name="entity">实体</param>
110         /// <param name="identity">自增量方式,表主键是否采用自增的策略</param>
111         /// <param name="returnId">返回主键,不返回程序允许速度会快,主要是为了主细表批量插入数据优化用的</param>
112         /// <returns>主键</returns>
113         public string Add(BASEMODIFYRECORDEntity entity, bool identity = true, bool returnId = true)
114         {
115             this.Identity = identity;
116             this.ReturnId = returnId;
117             entity.Id = int.Parse(this.AddObject(entity));
118             return entity.Id.ToString();
119         }
120
121         /// <summary>
122         /// 更新
123         /// </summary>
124         /// <param name="entity">实体</param>
125         public int Update(BASEMODIFYRECORDEntity entity)
126         {
127             return this.UpdateObject(entity);
128         }
129
130         /// <summary>
131         /// 获取实体
132         /// </summary>
133         /// <param name="id">主键</param>
134         public BASEMODIFYRECORDEntity GetObject(string id)
135         {
136             return GetObject(int.Parse(id));
137         }
138
139         public BASEMODIFYRECORDEntity GetObject(int id)
140         {
141             return BaseEntity.Create<BASEMODIFYRECORDEntity>(this.GetDataTable(new KeyValuePair<string, object>(this.PrimaryKey, id)));
142         }
143
144         /// <summary>
145         /// 添加实体
146         /// </summary>
147         /// <param name="entity">实体</param>
148         public string AddObject(BASEMODIFYRECORDEntity entity)
149         {
150             string key = string.Empty;
151             SQLBuilder sqlBuilder = new SQLBuilder(DbHelper, this.Identity, this.ReturnId);
152             sqlBuilder.BeginInsert(this.CurrentTableName, this.PrimaryKey);
153             if (!this.Identity)
154             {
155                 // 这里已经是指定了主键了,所以不需要返回主键了
156                 sqlBuilder.ReturnId = false;
157                 sqlBuilder.SetValue(this.PrimaryKey, entity.Id);
158             }
159             else
160             {
161                 if (!this.ReturnId && (DbHelper.CurrentDbType == CurrentDbType.Oracle || DbHelper.CurrentDbType == CurrentDbType.DB2))
162                 {
163                     if (DbHelper.CurrentDbType == CurrentDbType.Oracle)
164                     {
165                         sqlBuilder.SetFormula(this.PrimaryKey, "SEQ_" + this.CurrentTableName.ToUpper() + ".NEXTVAL ");
166                     }
167                     if (DbHelper.CurrentDbType == CurrentDbType.DB2)
168                     {
169                         sqlBuilder.SetFormula(this.PrimaryKey, "NEXT VALUE FOR SEQ_" + this.CurrentTableName.ToUpper());
170                     }
171                 }
172                 else
173                 {
174                     if (this.Identity && (DbHelper.CurrentDbType == CurrentDbType.Oracle || DbHelper.CurrentDbType == CurrentDbType.DB2))
175                     {
176                         BaseSequenceManager sequenceManager = new BaseSequenceManager(DbHelper);
177                         entity.Id = int.Parse(sequenceManager.Increment(this.CurrentTableName));
178                         sqlBuilder.SetValue(this.PrimaryKey, entity.Id);
179                     }
180                 }
181             }
182             this.SetObject(sqlBuilder, entity);
183             if (UserInfo != null)
184             {
185                 sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldCreateUserId, UserInfo.Id);
186                 sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldCreateBy, UserInfo.Realname);
187             }
188             sqlBuilder.SetDBNow(BASEMODIFYRECORDEntity.FieldCreateOn);
189             if (this.Identity && (DbHelper.CurrentDbType == CurrentDbType.SqlServer || DbHelper.CurrentDbType == CurrentDbType.Access))
190             {
191                 key = sqlBuilder.EndInsert().ToString();
192             }
193             else
194             {
195                 sqlBuilder.EndInsert();
196             }
197             if (this.Identity && (DbHelper.CurrentDbType == CurrentDbType.Oracle || DbHelper.CurrentDbType == CurrentDbType.DB2))
198             {
199                 return entity.Id.ToString();
200             }
201             return key;
202         }
203
204         /// <summary>
205         /// 更新实体
206         /// </summary>
207         /// <param name="entity">实体</param>
208         public int UpdateObject(BASEMODIFYRECORDEntity entity)
209         {
210             SQLBuilder sqlBuilder = new SQLBuilder(DbHelper);
211             sqlBuilder.BeginUpdate(this.CurrentTableName);
212             this.SetObject(sqlBuilder, entity);
213             sqlBuilder.SetWhere(this.PrimaryKey, entity.Id);
214             return sqlBuilder.EndUpdate();
215         }
216
217         // 这个是声明扩展方法
218         partial void SetObjectExpand(SQLBuilder sqlBuilder, BASEMODIFYRECORDEntity entity);
219
220         /// <summary>
221         /// 设置实体
222         /// </summary>
223         /// <param name="entity">实体</param>
224         private void SetObject(SQLBuilder sqlBuilder, BASEMODIFYRECORDEntity entity)
225         {
226             SetObjectExpand(sqlBuilder, entity);
227             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldNEWKEY, entity.NEWKEY);
228             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldNEWVALUE, entity.NEWVALUE);
229             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldCOLUMNDESCRIPTION, entity.COLUMNDESCRIPTION);
230             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldOLDKEY, entity.OLDKEY);
231             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldOLDVALUE, entity.OLDVALUE);
232             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldRECORDKEY, entity.RECORDKEY);
233             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldCOLUMNCODE, entity.COLUMNCODE);
234             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldTABLEDESCRIPTION, entity.TABLEDESCRIPTION);
235             sqlBuilder.SetValue(BASEMODIFYRECORDEntity.FieldTABLECODE, entity.TABLECODE);
236         }
237
238         /// <summary>
239         /// 删除实体
240         /// </summary>
241         /// <param name="id">主键</param>
242         /// <returns>影响行数</returns>
243         public int Delete(int id)
244         {
245             return this.Delete(new KeyValuePair<string, object>(this.PrimaryKey, id));
246         }
247     }
248 }

参照上面,在操作时调用对应方法,即可将记录变更的数据记录下来。这样数据出现问题就可以及时找到。

用通用权限管理的代码系统生成器生成代码确实非常棒,与其权限功能配合很好用,我们只需考虑业务功能即可,大大节省了开发时间。

时间: 2024-10-25 14:57:21

如何实现系统记录变更的记录功能的相关文章

iOS开发:一个高仿美团的团购ipad客户端的设计和实现(功能:根据拼音进行检索并展示数据,离线缓存团购数据,浏览记录与收藏记录的批量删除等)

大致花了一个月时间,利用各种空闲时间,将这个客户端实现了,在这里主要是想记录下,设计的大体思路以及实现过程中遇到的坑...... 这个项目的github地址:https://github.com/wzpziyi1/GroupPurchase 主要实现的功能,用UICollectionViewController展示团购数据,根据拼音进行检索并展示数据,离线缓存团购数据,浏览记录与收藏记录的批量删除,友盟分享的集成,利用UIView+AutoLayout写布局,实现地图定位.自定义大头针等 整个项

项目记录3:基础功能

本文内容来自:<传智播客-OA项目> 1,设计 BaseDao 与 BaseDaoImpl    1,设计接口 BaseDao        1,每个实体都应有一个对应的Dao接口,封装了对这个实体的数据库操作.例            实体            Dao接口                实现类            ========================================================            User        

清除Centos系统用户登录记录和命令记录

echo > /var/log/wtmp #清除用户登录记录和命令记录 echo > /var/log/btmp echo > /var/log/secure #如果没有这个文件,重启syslog进程service syslog restart echo > .bash_history history -c #清除命令记录

Ecmall系统自带的分页功能

在Ecmall的二次开发中,分页是必不可少的.这个系统已经自带了分页功能,下面来看看如何使用这个分页. 下面是一个自定义的类,用于查看订单的详细情况.关键在于get_order_data()这个方法,分页的使用也在这个方法的内部了.应该有的注释都有了,应该会比较容易懂,我不就多说了. <?php define('NUM_PER_PAGE', 15); // 每页显示数量 class NowaMagicApp extends MallbaseApp { public function index(

A记录和CNAME记录的区别

1.什么是域名解析? 域名解析就是国际域名或者国内域名以及中文域名等域名申请后做的到IP地址的转换过程.IP地址是网路上标识您站点的数字地址,为了简单好记,采用域名来代替ip地址标识站点地址.域名的解析工作由DNS服务器完成. 2.什么是A记录? A (Address) 记录是用来指定主机名(或域名)对应的IP地址记录.用户可以将该域名下的网站服务器指向到自己的web server上.同时也可以设置您域名的二级域名. 3.什么是CNAME记录? 即:别名记录.这种记录允许您将多个名字映射到另外一

[转]A记录和CNAME记录的区别

1.什么是域名解析? 域名解析就是国际域名或者国内域名以及中文域名等域名申请后做的到IP地址的转换过程.IP地址是网路上标识您站点的数字地址,为了简单好记,采用域名来代替ip地址标识站点地址.域名的解析工作由DNS服务器完成. 2.什么是A记录? A (Address) 记录是用来指定主机名(或域名)对应的IP地址记录.用户可以将该域名下的网站服务器指向到自己的web server上.同时也可以设置您域名的二级域名. 3.什么是CNAME记录? 即:别名记录.这种记录允许您将多个名字映射到另外一

DNS中A记录和CNAME记录的区别(转)

A记录是域名到ip的映射,即为ip起别名:CNAME是域名别名到域名的映射,即为域名起别名. 还有一个常用的记录是MX记录,它是与邮件相关的,MX记录记录了发送电子邮件时域名对应的服务器地址. 原文:http://blog.xieyc.com/differences-between-a-record-and-cname-record/ 1.什么是域名解析? 域名解析就是国际域名或者国内域名以及中文域名等域名申请后做的到IP地址的转换过程.IP地址是网路上标识您站点的数字地址,为了简单好记,采用域

DNS解析中的A记录、AAAA记录、CNAME记录、MX记录、NS记录、TXT记录、SRV记录、URL转发等

AA记录: 将域名指向一个IPv4地址(例如:100.100.100.100),需要增加A记录 NSNS记录: 域名解析服务器记录,如果要将子域名指定某个域名服务器来解析,需要设置NS记录 SOASOA记录: SOA叫做起始授权机构记录,NS用于标识多台域名解析服务器,SOA记录用于在众多NS记录中标记哪一台是主服务器 MXMX记录: 建立电子邮箱服务,将指向邮件服务器地址,需要设置MX记录.建立邮箱时,一般会根据邮箱服务商提供的MX记录填写此记录 TXTTXT记录: 可任意填写,可为空.一般做

关于如何记录数据更改记录的两种建表方式

title: 关于如何记录数据更改记录的两种建表方式 date: 2018-08-08 22:07:44 tags: 数据库 --- 当时要做的一个项目要包含一个权限管理功能,以为该系统中的所有人分配权限.而且这个权限管理的需求是可以把权限接近无限的下发(我感觉现实中是不会无限下发的(.???)ノ),这些都先不讲.因为有权限管理就涉及到用户分组的变动,权限的使用等,但是这些操作都是应该要记录下来的.于是有了两种方案. 1.通过一张单独的事件记录表来记录事件: id uid eventid eti