故事背景
这是一个发生在2015年的故事。中国的互联网经济进入高速发展的时期。各种互联网创业公司层出不穷,人们争先恐后地加入到这场浪潮中来。
故事的主人公小明是个有远大理想的小朋友,有一些的开发经验,更有敏锐的市场洞察力。 他发现以uber和airbnb为代表的共享经济正在变成一个热点,新加入的“回家吃饭“也是来势汹汹。这些公司涵盖了食、住、行等领域的共享,但市面上还没有衣服共享的公司。他又想到自己有很多闲置的运动鞋,何不开一个在垂直领域共享运动鞋的创业公司。他兴奋得一夜没睡,马上注册了一个叫air-sneakers的公司。召集了几个工程师朋友热火朝天地干起来了。
创业艰辛
首先他们着手设计数据模型。在数据模型中最重要的表叫ATHLETIC_SHOES表。这个表大概长成这样:
小明又为常用的一些品牌,材料,尺码等重要数据建了一些关联表。接着,小明又做好了PRD和wireframe。 小明的工程师们选择了熟悉的java语言来开发。每个页面基本针对一张表的增删改查,用iBatis 之类的OR mapping开发的后端和angular开发的前端很快就完成了。两个月后第一版上线了!
很快,小明注意到了一个问题。并不是很多人都有很多闲置的运动鞋,也不是每个人都喜欢每天穿不同的运动鞋。和公司CFO (小明太太)商量后,他果断决定推出女鞋共享,女人的闲置鞋会多一些。
小明的工程师发现原来设计的数据模型根本不够用。女鞋可不像运动鞋那么简单,光一个单鞋就有什么高跟,低跟,平跟,粗跟,细跟,圆头,尖头,真皮,假皮等等属性,连鞋码都不一样。新的女鞋表大概是这样的.
WOMENS_SHOES
当然还有WOMENS_PUMPS表,WOMENS_BOOTS表,WOMENS_SANDALS表,等等……此处略去10000字
原来的代码基本上没用了,小明还被工程师打了。
新的代码花了很长时间才写出来,特别复杂,到处都是if else之类的判断。总算,新版本上线了。但是用户还是不买账。原来,女人也不喜欢穿别人的旧鞋,也没有那么多人喜欢把自己的鞋借给别人,过上脚气都不知道。
小明再次调整战略,开发出了一版包括所有服装共享的app改名为air-wardrobe。这次新的表结构就没那么简单了,大大小小建了上百张表。
大家天天加班,苦苦干了一年。因为屡次改需求,小明又受伤住院了。
峰回路转
总算,新app上线为小明拉来了第一笔风投。投资方不希望小明只做服装共享,应该涵盖所有家用产品。无奈下,小明找来了一个架构师设计新的数据模型。架构师看到旧的schema设计抚掌大笑,指出了旧schema的最大问题。
传统横向schema的缺点:
新数据模型是这样设计出来的。首先是一张PRODUCT表。这张表包含了世界上所有产品共有的属性。如分类,新旧,价格,数量。
然后,那些为各类商品单独建的表和它们的关联表都不需要了。取代他们的是一个垂直的schema. 首先需要的是一张表描述商品的元数据(meta data)“PROD_ATTRIBUTES”,用来存放所有产品属性的定义。
对于每一种商品,我们只需要定义他们独有的属性,不同商品可以共享一些属性,比如运动鞋和女鞋共享鞋码的属性。
对每样商品的每个属性,我们插入一条数据来保存它。这就需要一个PROD_ATTR_VALUE表
区别只是在显示方向上,过去是横向显示的, 现在是纵向显示的。过去是宽的,现在是窄的。
用旧schema,通常我们会为每张表对应一个类。方便OR mapping。用新schema任何商品只需要一种数据结构来表示,就是Map,准确地说是Multimap,因为考虑到有一对多的属性。 Multimap数据结构和流行的JSON数据结构和Http 请求的query是很相似的,很适合互联网应用。
传统schema里,一对多的关系是通过连接表和外键实现的。比如一双鞋可能包括许多流行元素,假设旧scheme里为这些流行元素的关键字建了一个SHOE_KEYWORDS表,和shoes表为一对多关系。
在垂直schema里,只需要加一个IDX字段可以实现一对多关系。如下表:这个商品101有两个keywords。
如果要保存每次产品更新记录便于存档呢?过去,可能需要加一个类似shoe_edit_history的表。每次改动时把旧数据搬到这张表里,再创建一条新数据。
在新schema里只要加一个ACTIVE字段标识最新的改动,就能达到目的。
过去对于下拉框式的输入的值,传统上我们通常会需要其他表的辅助。
比如在旧表里可能有个HEEL_TYPE_ID的字段,表示不同跟高。另外有一张VALID_HEEL_TYPES表保存所有合法的跟高。或者像小明那样用一个enum之类的hard code在代码里。
在新schema里,我们会用到一个CODE_LIST的关联表,下面这张表描述了鞋码和跟高两个code list。非常适合在下拉框显示它们。
新schema如何把相关的信息组合在一起?只要加一个PROD_ATTR_GROUP表。
事实上应该为这些数据建立一个树状的层级关系:
(注)PROD_ID字段在PROD_ITEM表中出现是一种去范式化,为了更方便查询。
有了这样一个数据模型,录入和显示每种商品用的都是同一套代码,基本不需要为特殊产品和特殊客户改后端的代码。小明的团队做了以下分工:
当然这样的数据模型也是有缺点的:
以上数据模型只是一个简单化例子。这类数据模型比较适合金融,电商,医药等行业。在设计这类模型时需要和传统的关系型模型间找到一个折衷方案。
故事结尾
小明的公司很快拿到了更多投资,一年后上市了。小明和太太在加勒比小岛上live happily ever after。小明的工程师们也分到了期权,工作也很开心,再也不用为改需求大动干戈了。他们向小明道歉并得到了谅解。
这个故事教导我们
本文作者:赵文乐,现任点融网技术team leader,17年软件开发经验,在美国工作学习15年,从事互联网、金融、云计算等行业。
本文首发于点融黑帮(微信号:DianrongMafia),这是一个互联网技术类微信号,汇集了各路创业大牛。
Attention !! 36 氪正在招募全职创业公司作者,如果你对报道互联网创业感兴趣,充满好奇心,善于发现新事物,又能沉心做行业研究,恰好又对企业服务、教育、文创或农业其中一个领域了如指掌,那么你就是我们想要的人 !! 快把简历投至:zhaopin@36kr.com