外卖系统,一天一千万条数据,用户需要查到近30天的数据,商家也要查询到30天的数据,怎么设计表?
典型回答 分析一下题干的几个关键信息: 1、一天一千万数据。 2、只查最近30天的数据 3、买家和商家都需要查询 通过以上三个信息,我们可以得出以下结论: 1、单表扛不住: 1天就1000万数据,一年就30多亿数据,那么这个量如果用一张单表存放的话,数据库肯定扛不住。 2、可以做数据归档 因为用户只查询最近30天的数据,所以,可以简单的按照时间来划分冷热数据,30天内的数据为热数据,30天以外的数据为冷数据。冷数据和热数据可以做分离,即针对30天以上的数据做归档。 3、归档后单表还是扛不住 但是,归档之后,热数据的表还要保留30的数据,也就是3个亿,那还是很多的,单靠数据库也扛不住。需要考虑做分库分表 4、分表键不能直接选择买家或者卖家 因为要同时满足买家和卖家的查询,不可能只基于买家或者卖家去做分表。如果按照卖家 id 分表,那么买家的查询就会跨表,查询很慢。按照买家 id 分表也是同理。 5、基本不太可能使用缓存提效 这个很好理解,一方面是数据量太大了,另外一方面订单信息可能会频繁修改,数据一致性不太好保障,这里用缓存不合适。 那么,这个问题最终就变成了一个,如何基于海量数据(3亿)数据走高效查询,并且要支持多个分表键。 分布式数据库 首先,我们可以用支持海量数据存储和查询的各种分布式数据库,如TiDB(pingcap)、OceanBase(蚂蚁)、Spanner(google)等。 ✅什么是分布式数据库,有什么优势? 用了分布式数据库之后,为了提升买家和卖家的查询效率,需要分别创建索引: 1 2 3 4 5 6 7 8 9 10 CREATE TABLE Orders ( order_id BIGINT AUTO_INCREMENT PRIMARY KEY, buyer_id BIGINT NOT NULL, seller_id BIGINT NOT NULL, order_date DATETIME NOT NULL, amout DECIMAL(10, 2), status ENUM('Pending', 'Completed', 'Cancelled', 'Refunded'), INDEX idx_buyer_date (buyer_id, order_date), INDEX idx_seller_date (seller_id, order_date) ); 创建买家ID+时间、卖家 ID+时间等多个联合索引,来提升按照时间查询的效率。 ...