假设您正在为下一次堆栈溢出设计数据库模式,更具体地说,是为处理问题评级的模式部分。
我假设您会使用如下表格:
rating(question_id, user_id, rating)
... 这将记录评分并确保没有用户对同一问题进行两次投票。
仅该表就可以处理评分数据,但可能会导致查询缓慢。
考虑到性能,您是否考虑将每个问题的评分总和存储在问题表中,即使该数据是多余的,因为它是从评分表中的数据派生而来的?
假设您正在为下一次堆栈溢出设计数据库模式,更具体地说,是为处理问题评级的模式部分。
我假设您会使用如下表格:
rating(question_id, user_id, rating)
... 这将记录评分并确保没有用户对同一问题进行两次投票。
仅该表就可以处理评分数据,但可能会导致查询缓慢。
考虑到性能,您是否考虑将每个问题的评分总和存储在问题表中,即使该数据是多余的,因为它是从评分表中的数据派生而来的?
我通常会首先从规范化模型开始,而不是对问题表中的评分总和进行反规范化。
然后,当应用程序运行得足够好时,我会进行一些性能测试,以确定应用程序处理负载是否足够好——与我期望在生产中具有的负载相比。
如果它不能很好地处理负载,我会检查瓶颈——并纠正最重要的瓶颈,直到应用程序运行良好。
一旦应用程序投入生产,如果网站有很多 opf 用户,就该进行一些额外的优化了。
为了简单起见:
最后,是的,也许,对问题表的评分总和进行非规范化可能会有所帮助;但你需要这样做吗?
这是真正的问题;-)
如果您计划预先聚合表,则值得查看物化视图(T-SQL 中的索引视图)。
一般来说 - 如果您知道数据的读取频率比写入频率高得多,那么它是存储聚合值的有效方法。在这种特定情况下,我还会考虑对答案表进行物理设计,这使得聚合变得便宜。为此,我将在 query_id、answer_id 上定义聚集索引。因此,只会从磁盘中读取几个 DB 页来获取特定查询的所有答案。