途牛原创|基于EAV模型的运营系统架构实践
序
本文将介绍如何基于 EAV 模型,来构造一个准自动化的运营系统,服务运营研发部的相关工作。
我们的痛点
运营研发部对接三端(PC、M、APP)后台工作,劳心劳力。。。
- 头疼的稀疏表( 稀疏表通常会有很多列,但是每一行有值的列又比较少。)+头疼的各种表。
- 持续的迭(xu)代(qiu)升(bian)级(geng)(每一次功能升级,都需要变更表结构)。
- 基础数据的维护代码坑好多,打个标签加个属性,都好怕。
- Code Monkey,熟悉的表+熟悉的套路(设计表单、设计字段、CRUD…)Boom!
漫漫选型路
其实我们的愿景很“简单”。
- 可以舒服地给各种[途牛实体]打标签、扩展属性。
- 可以简单地记录任何结构的新数据,而不需要修改任何数据结构。
- 可以极好地迅速扩展应用,因为它可以防止(属性)不断变化的后果。
漫漫长路。。。
为了高可用&扩展性,我们学习了Drupal的元数据操作、Magento的产品建模、以及各种CMS。
为了解决稀疏表,我们尝试基于 Column Family(列族)来处理,BigTable、Cassandra、HBase,曾经都是我们的“座上客”。(事实上,很多团队已经这样解决掉了)
然而,
踏破铁鞋无觅处,得来全不费工夫。
一种数据模型悄然而至,实体属性值模型。
来自百度百科:实体属性值模型(EAV)是一种用数据模型描述实体的属性(属性,参数),可以用来形容他们潜在巨大,但实际上将适用于给定的实体的数量是相对较少。 在数学中,这种模式被称为一个稀疏矩阵 。 EAV也被称为对象的属性值的模式,垂直的数据库模型和开放式架构。
这里不详细介绍EAV是什么,因为我们的设计在EAV之上。(站在巨人的肩膀上)
下面即将进入全文干货集中地段。^_^
RBZ
系统代号:RBZ(肉包子)
系统构成:EAV+DF+AC+PHP+MYSQL
系统模块:
- 应用中心
- 属性中心
- 标签中心
从技术角度描述RBZ的运转流程大致如下:
- 通过[属性中心]配置和管理属性。
- 通过[标签中心]配置和管理标签。
- 通过[应用中心]选择[实体、属性、标签],自动生成表单,录入数据。
- 通过[CMS]动态模版输出给C端用户。
下面逐一讲解,他们分别是什么。:)无比接近干货地段了。
系统设计
架构
表结构
基于列模式的表设计。(我们常规的工作都是行模式)
举个栗子:A公司售卖鞋子和衣服。(比较极端,勿喷)
行模式(产品表)
PID | PNAME | 类型 | 尺码 | 颜色 |
---|---|---|---|---|
0001 | 鞋子1 | 1 | 42 | 黑色 |
0002 | 衣服1 | 2 | XL | 蓝色 |
列模式(属性表、实体表)
属性表(类型、排序、启用、默认值、可选值、必填…)
属性ID | 属性名称 | 属性字段 | 数据类型 | 属性分组 |
---|---|---|---|---|
1 | 尺码 | size | input | 鞋子 |
2 | 尺码 | size | input | 衣服 |
3 | 颜色 | color | input | 鞋子 |
4 | 颜色 | color | input | 衣服 |
实体表
ID | 应用ID | 实体ID | 属性ID | 属性值 |
---|---|---|---|---|
1 | 1 | 0001 | 1 | 42 |
2 | 1 | 0001 | 3 | 黑色 |
3 | 1 | 0002 | 2 | XL |
4 | 1 | 0002 | 4 | 蓝色 |
这番设计,两个益处。
- 省存储空间。
- 易动态扩展。
动态表单
我们的常规工作是静态表单,避免在Code Monkey的路,越走越远,我们需要改变。
设计动态表单模型,基本的思路应该是数据和表现显示的分离。抛开表现层,一个表单包含的若干个字段和填写的数据。所谓动态,就是这些字段名称可能改变,数量可能有增减。
配置字段(POI中文名称)
配置中。。。
见证奇迹的时刻。(表单自动生成)
这番设计,两个益处。
- 猴子做架构了(再也不用写FORM了)。
- 用户自定义。
CMS
通过CMS定义RBZ标签,结合自定义样式模版,任意组合吐出数据。
用了一个叫 Mustache 的模版语言。
{{#cmsRbzItems}}
中文名称 {{attr_cnname}}
英文名称 {{attr_enname}}
岛屿图片 {{attr_pic}}
所属群礁 {{attr_class}}
酒店品牌 {{attr_hotel}}
费用信息 {{attr_price}}
产品推荐 {{attr_managerrecommend}}
岛屿星级 {{attr_islandstar}}
岛屿排序 {{attr_islandrank}}
上岛时间 {{attr_timecost}}
{{/cmsRbzItems}}
API
为确保RBZ接口的持续交付,我们选择用 Postman 来做接口的自动化测试工作。
某一个请求。
每一次发布。
RBZ-应用
处子秀:马尔代夫选岛工具
需求:
- 提取马尔代夫的所有岛屿(POI)
- 扩展岛屿属性(费用信息、岛屿星级、产品经理推荐)
- 给岛屿打标签(蜜月、亲子、一价全含、WIFI)
- 选岛工具
只需配置,无需研发。
- 配置属性
- 配置标签
- 配置应用
- 选POI
- 编辑属性
- 编辑标签
灯灯灯灯。。。
筛选项:
实体:
在这里,代表官方,诚邀各种应用接入。
RBZ-ROI
浅谈RBZ的回报率。
- 成就工作快,降成本,提效率。(之前这样的后台开发任务至少需要15人天)。
- 可能成为运营层数据字典。
- 聚合页需求配置化。
- 精细化运营:脱离底层数据,在运营层通过属性、标签配置,精细化呈现。
结论
理解EAV模型确实需要时间。它有一个明确的学习曲线,使的初级开发人员在真正理解其概念前,需要为此付出更多的精力。
应用实体-属性-值时,应考虑以下条件:
- 数据是稀疏的、异构的,一个实体的属性范围较广,且常引入新的属性。
- 类的数量非常大,有许多实例类,即使属性是非稀疏的。
结束语
我们的终极目标是:
人人都是程序员。
- PHP-EAV
- 基于Postman的自动化测试
- 美团供应链架构
途牛原创|基于EAV模型的运营系统架构实践相关推荐
- 基于java点播影院运营系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
基于java点播影院运营系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 基于java点播影院运营系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 本源码技术栈: ...
- 基于PAM调制的OFDM系统架构之讯号特点分析(matlab)
基于PAM调制的OFDM系统架构之讯号特点分析(matlab) 不同于基于QAM调制的OFDM系统,通过脉冲振幅调制(PAM)并经过埃尔米特对称处理的讯号本身的特性.讯号调制方面,采用PAM调制的讯号 ...
- 视频教程-基于毫米波雷达的ADAS系统架构-嵌入式
基于毫米波雷达的ADAS系统架构 ADAS研发部门高级工程师 德国汽车电子专业工科硕士,理论电气工程博士,近10年嵌入式软件开发经验,曾参与最前沿ADAS项目的软件开发与集成,之后参与奔驰第一款纯电动 ...
- GIAC 2020 全球互联网架构大会演讲实录:基于TarsGo的微服务技术架构实践
2020年8月14日-15日,GIAC 2020 全球互联网架构大会于上周五正式在深圳开幕. GIAC(GLOBAL INTERNET ARCHITECTURE CONFERENCE)是长期关注互联网 ...
- 微信技术专家:10亿人在用的微信支付系统架构实践!20页ppt详解
点击"技术领导力"关注∆ 每天早上8:30推送 作者:微信高级工程师 方秋枋 背景 作为一个重要业务,微信支付在客户端上面临着各种问题.其中最核心问题就是分平台实现导致的问题: ...
- 大型网站系统架构实践(五)深入探讨web应用高可用方案
从上篇文章到这篇文章,中间用了一段时间准备,主要是想把东西讲透,同时希望大家给与一些批评和建议,这样我才能有所进步,也希望喜欢我文章的朋友,给个赞,这样我才能更有激情,呵呵. 由于本篇要写的内容有点多 ...
- 【风控系统】风控中心—京东基于Spark的风控系统架构实践和技术细节
转自:https://www.jianshu.com/p/9de45d2d16e6 感谢博主! 背景 互联网的迅速发展,为电子商务兴起提供了肥沃的土壤.2014年,中国电子商务市场交易规模达到13.4 ...
- 【采用】【风控系统】风控中心—京东基于Spark的风控系统架构实践和技术细节
转自:https://www.jianshu.com/p/9de45d2d16e6 感谢博主! 背景 互联网的迅速发展,为电子商务兴起提供了肥沃的土壤.2014年,中国电子商务市场交易规模达到13.4 ...
- 干货 | DDD实战:基于洋葱模型的分层代码架构设计
点击上方"中兴开发者社区",关注我们 每天读一篇一线开发者原创好文 ▎作者简介 作者冯丹是一名非常有激情的一线程序员,喜欢java强大的面向对象能力,scala简洁的函数式编程范式 ...
最新文章
- 独家福利 | 科大讯飞全球1024开发者节限时免费门票!
- JavaScript 下载大文件解决方案(Blob+OjbectURL)
- KMP经典算法与变形的应用(字符串parttern匹配问题)
- php 如何缓存数据字典,使用PHP脚本如何导出MySQL数据字典
- java.lang.NumberFormatException: For input string: “name”
- LeetCode 957. N 天后的牢房(查找循环节)
- 解决‘.../rqt_virtual_joy/plugin.xml‘ has no Root Element问题
- 零代码以“王者荣耀”为例解析设计七原则
- 用另一种方式来讲解代理模式~
- [Python] L1-037. A除以B 团体程序设计天梯赛GPLT
- 算法设计 分析篇(摊销分析)
- nginx模块nginx_upstream_check_module来检查后端服务器的健康情况
- SOAOffice和iWebOffice、NTKO的比较及其优势(转)
- MATLAB实现LSBR并采用卡方分析进行分析
- MYSQL之错误代码----mysql错误代码与JAVA实现
- debian系统使用NTP服务器并自动同步时间
- java怎么在控制台输入数字,并保存到数组里?
- sql练习-基础练习
- 如何修改安卓应用图标和程序名称
- 长沙周边最美露营基地:安化云台山风景区星空露营公园
热门文章
- flutter 抓包使用教程
- 大数据处理算法--Bloom Filter布隆过滤
- php转为图片,php中base64转换为图片的方法
- 天嵌TQ335X开发板学习-1
- .NET简单的登录邮箱验证
- Log4j2配置日志写入本地文件出错
- Mysql数据库设计
- 2021巢湖第一中学高考成绩查询,2021年巢湖高中学校排名及录取分数线排名
- 计算机1为什么代表高电平,高电平为什么表示1,低电平为什么表示0?
- java audioinputstream 读取音频文件_从原始文件中获取最多x个字节的AudioInputStream(剪切音频文件)...