设计电商网站(第一部分)
原文:Design eCommerce Website (Part I)
译者:飞龙
自豪地采用谷歌翻译
在过去几周里,很多人要求我们讨论电子商务网站。这个话题不仅在相当多的系统设计面试中被提出,而且电子商务网站也如此受欢迎,为此开发了大量的技术和研究。
在深入探讨这个话题之前,最好先了解为什么设计电子商务网站在系统设计面试中很受欢迎。首先,建立一个电子商务网站需要数据库设计,系统可用性,并发性考虑等东西。所有这些在今天的分布式系统中都是非常重要的。另外,每个人都使用像亚马逊这样的电子商务网站。如果你对周围环境一般很好奇,你应该已经想过这个话题了。
电子商务模式
在我们的《系统设计面试之前需要知道的八件事》中,我们说系统设计面试的一个共同策略是从简单而基本的事情开始,而不是直接跳到细节。那么如何设计电子商务网站的基本数据结构呢?数据库模式呢?
我将跳过用户模型的数据结构,因为它应该与其他应用程序非常相似。让我们专注于商品。在最简单的情况下,我们需要三个主要对象:商品,用户和订单。
商品定义了购物车中商品的基本模型。一些重要的字段包括价格,余额,名称,描述和类别。类别在这里可能会很棘手。当然,你可以在 SQL 数据库中创建一个字符串字段,但更好的方法是创建一个类别表,包含类别 ID,名称和其他信息。所以每个商品都可以持有一个类别 ID。
订单存储用户所下的所有订单的信息。所以每一行都包含商品 ID,用户 ID,数量,时间戳,状态等等。因此,当用户进行结帐时,我们汇总与此用户关联的所有条目来显示在购物车中(当然,我们应该过滤掉以前购买的商品)。
译者注:订单和订单商品是一对多的关系,所以还得分成两张表。
电子商务中的 NoSQL
在上面的分析中,我们使用了像 MySQL 这样的关系数据库。事实上,NoSQL 数据库有时候可以成为电子商务网站的更好选择。
很多人不知道 NoSQL,通俗地说,NoSQL 数据库试图将一堆东西存储在一行而不是多个表中。例如,我们可以将用户已经购买的所有物品存储在用户表的同一行中,而不是单独的订单表。因此,在获取用户的时候,我们不仅可以获取所有的个人信息,还可以获取他的购买历史。
为什么 NoSQL 在这种情况下可以稍微好一点?我们以商品模型为例。假设我们正在出售书籍。商品具有书籍类别和作者,发布日期,版本,页面数量等属性,这个 SQL 表可能有 20 列。没关系。
而现在,我们也想卖笔记本电脑。因此,商品还应该存储笔记本电脑的属性,包括品牌名称,大小,颜色等等。正如你可以想象的,随着更多类别的介绍,商品表格可以包含大量的列。如果每个类别平均有 10 个属性,它将是 100 列,这还是只支持了 10 个类别!
但是对于像 MongoDB 这样的 NoSQL 数据库来说,一个很大的好处就是它支持像这样的庞大数量的“列”。每行可以有大量的列,但不是全部都设置的。这就像将 JSON 对象存储为一行(实际上,MongoDB 使用的是类似的东西 BSON)。因此,我们可以将商品的所有属性(列)存储在一行中,这正是 NoSQL 数据库所擅长的。
并发
我们继续讨论扩展问题。将电子商务网站扩展到多台机器时,会出现大量问题。最重要的是,电子商务网站对这些问题几乎是零容忍的。
以并发为例。比方说,商店里只剩下一本书,两个人同时购买。没有任何并发机制,它们都成功地购买了这本书是完全可能的。你如何实现电子商务网站的并发?
我们一步一步分析一下。根据我们从操作系统中学到的东西,我们知道锁是保护公共资源最常用的技术。假设用户 A 和 B 都想购买同一本书。我们可以做的是,当 A 获取有关本书的数据时,在这一行上放置一个锁,以便其他人不能访问它。一旦 A 完成购买(减少剩余的数量),我们释放锁,以便 B 可以访问数据。同样的方法应该适用于所有的资源,这可以完全解决这个问题。
上述解决方案称为悲观并发控制。尽管它可以防止并发造成的所有冲突,但缺点是开销较大。显然,对于每一次数据访问,我们都需要创建并释放一个锁,这在大多数情况下可能是不必要的。
我们可以解决这个问题吗?
总结
在下一篇文章中,我们将讨论解决并发问题的更好方法,而不是使用锁。我想讨论很多电子商务网站的话题。
事实上,许多技术在所有分布式系统中都是常见的,重要的是比较每种方法的优缺点,并选择最适合特定应用的方法。
在下一篇文章中,我们将继续讨论并发性,并将讨论系统可用性和一致性。
顺便提一下,如果你想得到资深的面试官的更多指导,可以查看 Gainlo,以便与 Google,Facebook 等公司的工程师进行模拟面试。