某滴面试题,请教答案

2020-12-16 22:17:29 +08:00
 nightspirit

订单列表上,用户可以看到他下的单一页的,好多,那么表数据很多,有好多亿条,那么怎么设计?

答:水平分表,使用用户 id 做 hash

那么已知订单 id,怎么获取订单详情?

答:union 订单表

上万的表直接联合么?

思考。。。答:可以维护 uid->订单 id 的 k-v 结构在 redis 中

扩展下,已知 XX (忘了啥字段了,当时紧张了)获取订单详情呢?

答:那就存个 hash 对应关系

司机的 APP 也能显示订单,怎么获取呢?

思考。。。答:不会了,之前公司都是千万级数据,没做过水平拆分

面试官怒了,你可以滚了,回去等消息吧

好的,我滚了。。。。(确实没做过啊,能想的我都想了)

当时太紧张了,前面的算法没答上来,有点自暴自弃,现在想想有了点答案了,只是我不知道对不对,请教大神这题答案

5195 次点击
所在节点    职场话题
37 条回复
wellsc
2020-12-17 09:38:09 +08:00
@nightspirit 滴滴外卖不是几年前就无了,难道是滴滴海外?
DebugTy
2020-12-17 10:04:08 +08:00
如果真的是详情数据落在了很多表里面需要聚合, 这个可以考虑用宽表 tidb 把所有信息聚合到宽表中, 如果订单需要筛选可以先查询 es 只筛选出订单号, 再去查 tidb 补充详细信息;
nightspirit
2020-12-17 10:05:36 +08:00
@wellsc 海外
rming
2020-12-17 10:17:17 +08:00
基因法,让大部分查询条件都带上用户 ID 的基因,冗余关联表也是个办法,还是回答不够系统和完整,可能面试官期望回答是一套系统的总结分析和实践经验
murmur
2020-12-17 10:23:03 +08:00
@zardly666 这个是微博和朋友圈用的逻辑啊,每个人冗余一条时间线,不要求实时性只要求缓存定时更新就可以

订单这种实时性的怎么做
lasuar
2020-12-17 10:35:06 +08:00
还是没太看懂描述,说说我的理解:
1. 用户要在一页内显示完所有的订单(不分页?)
答:个人觉得可以在(user_order_ref)表内存储 uid 和 order_id_list 的关联关系,order_id_list 字段是 json 数组,mysql/mongodb 都可以容易的做 json 对象的操作,那么这张表的数据量就<=user 表,不会太大,也就不需要分表,那么这里就可以拿到用户所有的订单 id 。 (有的人也许会考虑部分 rows 的 order_id_list 字段过长带来的一些对表空间的影响,其实我认为可以忽略,因为一个用户的订单量上天了也不过几千几万,这点量不会有什么影响)
然后就像楼主说的,订单详情表使用订单 id 做 hash 水平分表,这里就能查到一个用户所有的订单详情了。
2. 司机的 APP 也能显示订单
答:司机 APP 显示自己的订单,其实与用户订单没啥不同,按照前面的做法,是可以实现按排序分页的(计算出要读哪些订单表,然后 union+orderby )。

个人愚见。
yzbythesea
2020-12-17 10:41:34 +08:00
一般大公司面试两个技巧,

1. 存数据用 nosql
2. table 拆得越细越好,别把逻辑分给 database 。

你这个可以是 3 个 table,

order table, oder ID -> order
user table, user ID -> order ID
driver table, driver ID -> user ID
f12998765
2020-12-17 13:54:27 +08:00
第一反应是来个 kylin 吧
DoctorCat
2020-12-17 15:44:19 +08:00
公有云上丢 DynamoDB 给他看 ,私有化部署用 Cassandra
告诉面试官:您知道么,mysql 不能 allin 所有的业务场景的。
zhengdai1990
2020-12-17 15:53:19 +08:00
走 ES 啊,哈哈哈哈哈
lewis89
2020-12-17 17:32:58 +08:00
所有的分库分表实际上 处理问题的方式 都是差不多的,要么冗余数据 要么冗余关系
zhangyp123
2020-12-17 18:03:05 +08:00
基因分库 + 数据冗余 解决 “多 key” 类业务 参考: https://cloud.tencent.com/developer/article/1689831
melkor
2020-12-17 18:49:28 +08:00
单据维度数据按 ID hash 拆分存,用户维度的存用户 ID 到单据 ID 的映射,司机维度的也一样。用户也不会一次看所有的单,可以按用户维度预缓存一页的单。如果用户要看后面的单再去查存储。
nightspirit
2020-12-18 11:29:01 +08:00
@yzbythesea
我理解一下这三个表,看是你说的这样不
order table, oder ID -> order 订单 i 按照 id 取模分表
user table, user ID -> order ID 用户表 然后 nosql 存储用户 uid->订单 id
driver table, driver ID -> user ID 司机表,nosql 存储 司机 id->订单 id
yzbythesea
2020-12-18 11:37:24 +08:00
@nightspirit 是的。甚至 order table 也可以是 nosql,然后 order 的内容纯成 json,读到你 service 里在取各项的值。

想了下觉得 driver ID -> order ID 要好一些。因为同用户肯定乘坐了不同的司机。
nightspirit
2020-12-18 11:40:20 +08:00
@lasuar 分页,他意思是订单表太大,怎么查订单列表
你说的这个我不是很理解 uid 和 order_list 的关联关系数据量怎么会小于用户表?用户对订单是一对多的关系,那如果是 order_list 存数组,你说的数组增加影响可以忽略,我没这么做过,不了解,还有就是用户表了,我认为滴滴用户也不少,有可能一人有多个账号,我觉得数据量也不小。
lasuar
2020-12-18 13:22:46 +08:00
@nightspirit 我写的应该足够清晰,你可以在读一遍; user 表是否再分表也是没关系的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/736186

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX