4.3.3 混用范式化和反范式化
范式化和反范式化的schema 各有优劣,怎么选择***的设计?
事实是,完全的范式化和完全的反范式化schema 都是实验室里才有的东西:在真实世界中很少会这么极端地使用。在实际应用中经常需要混用,可能使用部分范式化的schema、缓存表,以及其他技巧。
最常见的反范式化数据的方法是复制或者缓存,在不同的表中存储相同的特定列。在MySQL 5.0 和更新版本中,可以使用触发器更新缓存值,这使得实现这样的方案变得更简单。
在我们的网站实例中,可以在user 表和message 表中都存储 account_type 字段,而不用完全的反范式化。这避免了完全反范式化的插入和删除问题,因为即使没有消息的时候也绝不会丢失用户的信息。这样也不会把 user_message 表搞得太大,有利于高效地获取数据。
但是现在更新用户的账户类型的操作代价就高了,因为需要同时更新两张表。至于这会不会是一个问题,需要考虑更新的频率以及更新的时长,并和执行SELECT 查询的频率进行比较。
另一个从父表冗余一些数据到子表的理由是排序的需要。例如,在范式化的schema 里通过作者的名字对消息做排序的代价将会非常高,但是如果在 message 表中缓存author_name 字段并且建好索引,则可以非常高效地完成排序。
缓存衍生值也是有用的。如果需要显示每个用户发了多少消息(像很多论坛做的),可以每次执行一个昂贵的子查询来计算并显示它;也可以在 user 表中建一个 num_messages列,每当用户发新消息时更新这个值。
【责任编辑:book TEL:(010)68476606】
点赞 0