假设我有一个关系数据库应用程序,一个“用户”对象和一个“消息”对象。现在,我想向该用户显示未读邮件的数量。
存档的最佳方法是什么?我是否在用户中引入一个字段并在用户收到消息时对其进行计数,并在他阅读消息时减少计数?还是我每次都执行查询以计算标记为未读的用户消息数?
我认为第一种方法更复杂且容易出错,但是会比第二种方法表现更好。
这通常是如何完成的,或者有什么更好的方法?
假设我有一个关系数据库应用程序,一个“用户”对象和一个“消息”对象。现在,我想向该用户显示未读邮件的数量。
存档的最佳方法是什么?我是否在用户中引入一个字段并在用户收到消息时对其进行计数,并在他阅读消息时减少计数?还是我每次都执行查询以计算标记为未读的用户消息数?
我认为第一种方法更复杂且容易出错,但是会比第二种方法表现更好。
这通常是如何完成的,或者有什么更好的方法?
Answers:
根据数据库理论的教科书解决方案是数据库中没有依赖于其他数据值的值,因为这些值是传递依赖项。具有基于其他字段的计算值的字段违反规范化,因为这会导致冗余信息。
但是,有时教科书所说的和实践中最实用的方法有所不同。计算每个浏览量的未读消息数可能是一个非常昂贵的操作。将数字缓存在user
-table中会更好地提高性能。代价是数据库中可能存在不一致的地方:可能有可能删除,添加或读取一条消息而又不记得还要更新未读计数器。
INSERT
或上调整计数器的触发器轻松解决一致性问题DELETE
。(或UPDATE
,以说明邮件所有者的更改。)。一个好的DBMS将在同一事务中执行该操作并运行触发器,因此全部或全部不会发生。
潜在的问题是性能,但是您还没有性能问题。根据解决方案#1所选择的数据库,您可以做很多事情,包括建立索引,硬件,缓存等。这一切都取决于用户需要多长时间获取一次当前的未读消息数。这些选择中的许多不需要在应用程序端进行自定义编码,因此您可以更改代码或只需很少的代码即可实现它们。使应用程序的增长变得更加容易。
用户连接/登录后,一次从数据库中获取计数并不是一件坏事。您的应用程序是否会维护不断更新的邮件列表,例如电子邮件?从这里获取未读计数不需要再次访问数据库,而要获取新消息则无论如何都要进行数据库访问。
每次读取一条消息以标记IsRead时都要去数据库。一个字段就足够了,而无需重新计算另一个字段。
使用解决方案2(在字段/磁盘中保持计数)时,是否需要例程来在出现问题时定期重建/重新计算该字段?而且总是有问题。您是否要将所有这些包装在交易中?每次有人向他人发送消息时,消息是否会失败,因为由于用户表的锁定而无法更新接收用户的UnreadCount?还是要为此字段创建一个单独的表?