电子商务网站设计(第一部分)

今天我们讨论电子商务网站的设计。这不仅是一个在系统设计面试中高频出现的话题,而且由于电子商务在当今社会的普及性,围绕其开发的技术与研究也非常丰富。

在深入探讨之前,我们先了解为什么设计电子商务网站在系统设计面试中如此受欢迎。首先,构建一个电子商务网站涉及数据库设计系统可用性并发控制等核心要素,这些都是现代分布式系统的关键组成部分。此外,大多数人都有使用电子商务网站(如亚马逊)的经验。如果您通常对周围的技术环境感到好奇,应该已经对此类主题有过思考。

macbook692573_640.jpg

电子商务模式

正如我们在指南《系统设计面试前您需要知道的 8 件事》中所述,系统设计面试的常见策略是从简单的基础知识开始,而不是直接陷入细节。那么,如何设计电子商务网站的基本数据结构?数据库模式(Schema)又该如何规划?

我们将跳过用户模型的数据结构,因为它与其他应用程序类似。让我们专注于核心业务对象。在最简单的情况下,我们需要三个主要对象:Product(产品)、User(用户)和 Order(订单)。

  • Product:定义了购物车中商品的基本模型。一些重要字段包括:

    • 价格
    • 剩余数量
    • 名称
    • 描述
    • 类别

    类别字段在这里可能比较棘手。当然,您可以在 SQL 数据库中将其设置为字符串字段,但更好的方法是使用一个包含类别 ID、名称以及其他信息的 Category 表。因此,每个产品只需保留一个类别 ID 即可。

  • Order:存储有关用户所有订单的信息。每一行通常包含:

    • 产品 ID
    • 用户 ID
    • 数量
    • 时间戳
    • 状态等

    当用户进行结账时,我们将汇总与该用户关联的所有条目以显示在购物车中(当然,应该过滤掉已完成购买的商品)。

电子商务中的 NoSQL

在上述分析中,我们默认使用的是 关系数据库,例如 MySQL。实际上,NoSQL 数据库有时可能是电子商务网站的更好选择。

为了方便理解,用通俗的术语来说,NoSQL 数据库尝试将一堆相关数据存储在一行(文档)中,而不是分散在多个表中。例如,除了拥有一个单独的 Order 表之外,我们还可以将用户购买的所有商品存储在 User 表的同一行中。结果是,在获取用户信息时,我们不仅会获得所有个人信息,还会直接获得其购买历史记录。

在这种情况下,为什么 NoSQL 会更好?让我们以 Product 模型为例。

假设我们正在卖书。产品具有“书”类别和大量的属性,如作者、发布日期、版本、页数等,此 SQL 表可能包含 20 列。这没问题。

现在,我们也想出售笔记本电脑。因此,产品还应该存储笔记本电脑的属性,包括品牌名称、尺寸、颜色等。如您所想,引入更多类别后,Product 表中可能会有许多列。如果每个类别平均有 10 个属性,那么支持 10 个类别就将导致 100 列!

但是,对于像 MongoDB 这样的 NoSQL 数据库,一个很大的优点是它支持这种灵活的“列”结构。每行可以有大量字段,但并非所有字段都必须设置。这就像将 JSON 对象存储为一行一样(实际上,MongoDB 使用的是非常相似的 BSON 格式)。结果,我们可以将产品的所有这些属性存储在一行中,这正是 NoSQL 数据库所擅长的。

movie918655_640.jpg

并发控制

让我们继续讨论扩展问题。将电子商务网站扩展到多台计算机时,会出现很多问题。最重要的是,电子商务网站对大多数此类问题的容忍度几乎为零。

并发为例。假设商店里只剩下一本书,两个人同时购买。如果没有任何并发机制,那么两个人都有可能成功购买它。您如何在电子商务网站中实现并发控制?

让我们逐步分析这一点。从操作系统课程中我们学到,锁(Lock) 是保护共享资源的最常用技术。假设用户 A 和 B 都想购买同一本书。我们可以做的是,当 A 拿到有关这本书的数据时,在这一行上加一个锁,这样其他人都无法访问它。一旦 A 完成购买(减少剩余数量),我们就释放锁,以便 B 可以访问数据。相同的方法应该适用于所有资源,这可以完全解决问题。

上述解决方案称为 悲观并发控制。尽管它可以防止由并发引起的所有冲突,但缺点是成本很高。显然,对于每次数据访问,我们都需要创建和释放一个锁,这在大多数时候可能是不必要的。

我们可以不加锁地解决问题吗?

总结

在下一篇文章中,我们将讨论一种更好的并发问题解决方案,而无需使用锁。关于电子商务网站,我想讲的话题太多。

实际上,许多技术在所有分布式系统中都是通用的。重要的是比较每种方法的利弊,并选择最适合特定应用的方法。

说明:本文旨在探讨系统设计面试中的基础架构思路。文中提到的将订单历史直接嵌入用户文档的 NoSQL 设计模式,在实际高并发生产环境中需谨慎使用(可能导致文档过大),建议根据具体业务规模权衡读写比例与数据一致性要求。