分类
大杂烩

关系型数据库使用中的误区系列:不要把业务放进数据库

    任何东西都不是多多益善,帕累托法则在生活中处处体现,关系型数据库就是一个典型的例子,你会发现80%的业务跑在20%的功能之上。显然,我和帕累托一样,不相信均匀分布在真实生活中体现。

    以下摘录自Andy Warfield的《The 80/20 rule… for storage systems.》,“80/20 法则通常被认为是源于意大利经济学家维尔弗雷多·帕累托。帕累托出生于1848年,他是(至少被认为是)占领运动的早期成员之一。他发现意大利国家财富的80%是掌握在几乎少于20%的人口手中的。由此发散开来看,80/20法则在其他方面的应用同样值得注意,也是很有趣的:因为帕累托观察发现他的园子里的80%的豌豆产自于20%的作物上(他似乎更喜欢数豌豆而不是其他豆子)。"

  很多程序员在做到某个阶段的时候都会来问我,要不要用触发器?要不要用存储过程?等等一系列类似的问题,你也会发现从搜索引擎可以找到很多文章在围绕这个话题展开分析,介绍各种各样的技术等等,但我想申明我的观点,在OLTP的系统设计中,请不要把你的业务逻辑以触发器和存储过程形式放到数据库中!OLTP只能保存关系,也许有些feature一时帮了你的忙,但是后患无穷。就好像你能在任何饭店轻易点到一块巧克力蛋糕,但味道永远不能和专门蛋糕店比。

   回顾一下历史,还记得10-15年前,B/S主流结构还是ASP。PHP的用户不对,这时候大C还没把cdb改成Discuz,VBB里的附件居然是存放在数据库的二进制里,Perl还很热,leobbs如日中天,每个空间商都会标注支持cgi-bin这样的可执行目录,表明这个空间不是静态的。也就在这个时代,关系库真的开始进化,程序员从文本库中解放了出来。

   有了新的工具大家自然要研究透彻,但是工具不是说要把他用足用透才是好的,每个工具都是有他最适合的场景的。DVBBS动网是ASP时代的一个经典产品,记得当时会把高级和普通版本划分成存储过程和非存储过程版本,这导致很多人眼里存储过程是一种高大上的东西,所有不是自己技能栈的东西就高大上,但真的是这样吗?同样的,去一家饭店非要吃遍所有菜才是好的么,我想如果你是帕累托,只会点其中的20%吧。

    我对软件工程的理解之一,业务描述语言必须单一化,面向结果!代码究竟是什么?代码本质是为了提供服务,如果存储过程被引入进来,你的代码中是否包含数据库DDL部分就是一个问题。CVS中推上去的TAG到底包含了DDL语句么?

    当然这对百度型人才来说也不是什么问题,你可以投机取巧一点把DDL放在代码目录下类似script目录,利用hook来实现和代码同步上线,但这合理么?今天不想说怎么自动化上线和我的方案,进一步说,当一个newbie程序员来到你的团队,在review现有代码的时候,是无法用大脑做静态代码分析(Code Static Analysis)的,他会百思不得其解上下文和结果,因为你的代码不连贯,更不语义化,因为SQL是面向过程的。

    触发器也提供了类似效果的诡异陷阱,程序员一遍遍的review代码,但无法找到发生DML的地方,原来一切都是触发器默默的在背后干着坏事。对于外键的使用我也持保留的态度,任何业务关系必须在代码中显式描述,物理数据库利用外键保持数据一致性我认为不合理,例如:物理级别的分表怎么办呢?

    对于数据库的认知是对编程认知的一小部分,看到这里你应该理解了我想表达的观点,业务关系请放在业务代码中描述清楚。不管你认可与否我的观点,这也越来越逼近我们探讨的本质,未来的代码中该怎么描述业务?怎么设计我的架构?设计模式怎么用?

    symfony book中有一句话我很喜欢,build app not build tools,我极其排斥重复造轮子,但是你要知道轮子是怎么造出来的,才能知道以后的轮子长什么样子。请持续关注本订阅号,您的转发是我的动力!
分类
大杂烩

关系型数据库使用中的误区系列:业务字段展示字段傻傻分不清楚

    松本行弘在《代码的未来》中领悟道,这世界上没有java编程,没有ruby编程,更没有php编程,其实这世界上只有编程这两个字呀!

    好喜欢这句话,我觉得数据库编程也是一样的道理,虽然我们在谈数据库,更多的探讨是如何拥有编程的思维去处理这些问题。当碰到跨语言,跨平台的编程时,我们会称之为架构,但其实本质还不是在编程么?最后你会看到,人的架构永远大于软件架构,编程技巧只是人类处理真实世界问题在代码中的体现!这是我的感悟。

    作为系列的第三篇,我们谈谈关系型数据库常见的问题,也是初创型公司不能高速发展乃至转型的羁绊,业务字段展示字段傻傻分不清楚!

    先从一个简单的例子开始说起,我们总会设计各种各样的管理系统,例如酒店管理系统,里面管理着所有的业务实体,酒店实体自然是酒店业务在代码中的映射。我们常常会接到一个类似的需求,需要为菜单中包含宫保鸡丁的酒店标识为上海味道,前台可以基于这个标识筛选出符合期望的酒店。

    很糟糕,这是一个标准的死亡陷阱,程序员先做了第一件事情,为酒店增加了一个属性叫做上海味道,对应的关系表也多一个字段。第二件事,必然的会修改所有可以触发该字段变更的地方加入新逻辑,若这是一个复杂的系统,必然痛苦不已。
    
    所有初创公司的研发团队都消耗在了一些无用的事情之上,很快产生边际效应,他们已经无法应付真正的新品类拓展,光是打补丁便已经停不下来。那么到底是哪里错了呢?

  我要否定的就是这两件事,它们是不对的,首先第一点,我想先解释一个问题,什么是业务?我个人理解业务其实是一套流程,可以用UML工具绘制出来,业务绝对不是一套炫酷后台系统原型,更极端的说,是把真实生活中流程映射到计算机系统层面,他的每个环节对应了不同的部门,对应的产生了一系列的指标,有了指标自然也要有正确方式去使用工具驱动完成这些指标。在我的例子中,上海味道这个字段不是业务流程中驱动业务前进的字段,他的本质只是一个展示字段帮助提高用户格式化数据获得体验。

    这就牵出来第二个问题,业务字段和展示字段是同一个东西?他们都存放在关系型数据库中么?我的回答是否,初创型公司给C端用户体验的网站以及客户端往往都会从直接从数据库中读取数据,虽然很多公司表面上做成了微服务(多端发展导致不得不实施的结果),但他的数据源还是一个问题!试问一下,我能把含有酒店总经理联系方式的酒店实体表供前台网站读取么?即使前台程序员能控制用户的展示,那么前台的程序员真的需要知道这个字段么?万一被黑客攻破了网站难道你的数据就赤裸裸的暴露出来了么?

    终于,我们发现前台展示层最需要的持久层应该是一个文档化的,全文搜索的系统,关系对他只是可选的。他只是存放了业务字段的投影,也可以基于业务字段存放一些自己的复合字段。你根本不用增加一个表字段叫上海味道,也不用在菜单编辑保存的时候更新这个字段,他只是在重建前台index的时候被更新,至于前文的第二件事情,怎么更新呢?我们需要一篇新的文章,基于项目内和项目外的实时异步通讯,在这个文章之前我们还要探讨下本地代码方法和远程RPC到底有什么不同。

    这个问题和《关系型数据库使用中的误区系列:数据的价值》中导致犯错的原因有点类似,需求方的原始需求被错误的分层,业务字段和展示字段傻傻分不清楚!该前台程序员做的事情被扔到了后台来,你甚至可以很简单的理解,后台不用排序筛选的字段都不是业务字段,但具体的应用还要看公司业务的需要!

    后记,这个原则,是在到喜啦团队中反复强调遵守的原则,他真的可以帮你避免了很多无用的工时开销,更好的理解业务!安利时间又到了,在我们首席科学家botao带领下,我们选择solr为前台千万级的PV提供个位数毫秒的数据响应能力,恩。
分类
大杂烩

关系型数据库使用中的误区系列:数据的价值

    数据库这东西说起来真是一发不可收拾,其实本来只想写一篇文章总结,未曾想到写完第一节就超长了,也好,直接上一个系列吧!

    正如前文所说ANSI SQL真是一种功能性极强的DSL,如同打架必备的折椅,睡觉需要的床,踢球要的足球一样,我认为他是当下最适合通过描述过程筛选数据的语言,但注意我说的是过程!例如:我要筛选库存红色的苹果,筛选价格从高到低的订单且只要100条,诸如此类。

    但我们也常在反思对于过程的精确描述究竟是为了什么?这个查询的背后初衷是什么?我的观点是,我们描述了那么多的过程不就是为了得到预期的结果吗?我们为什么不能直接描述结果,让把其他的事情交给计算机来做呢?

   每个小伙子在追GF的过程中包含了吃饭,看电影,打LOL等等过程,所有的这些,都是为了让对方成为你的女朋友这一结果,而且常常为了达到结果你会动态调整你的过程,痛并快乐着。万幸的是,在计算机的世界里不用大费周章,你没有痛,只要你能将结果准确的描述出来,那么程序便会为你实现结果。

    试想一下,描述一句“我需要一个吃素菜的便宜的,而且我邀请朋友都喜欢的饭店”,计算机呈现的结果便会是你需要的那样,那岂不是更好。真心希望各位读者读到此处,从DSL角度,过程描述和结果描述角度,能带来你一点对于编程思想的畅想,我们频繁的使用SQL编程到底是为了什么?有没有可以让计算机学习之后,告诉我结果的技术呢?请带着想法关注本系列,关注budaoxing这个订阅号。

    《关系型数据库使用中的误区系列:最大误区》中我想表达的是在于后台业务代码和ETL之间的分层没做好,简单来说就是业务和报表分离。说到报表,最大的误区在于数据的价值!大部分的报表到底是为了什么制作出来的呢?吾以为,报表只是工具,帮助实施业务策略,提高单项指标以及整体指标。于是乎,对于报表的处理根本不在于你是否能写出这样的查询,几百行的SQL根本不是什么麻烦事,而在于和需求方沟通之后找到对方需要的关键性维度以及基于这些维度的预警和预警后所采取的策略。
   
    例如:CEO可能需要一张客服销售业绩报表,我相信只要有条件描述,SQL总能写出来,但是若能增进一步,你会否思考为什么总是这个SALES排名前列,她有什么独特的技巧和方法可以帮助提升整个团队的业务能力?又有时候需要SEM的相关报表,这些投放报表的意义是什么呢?我想不外乎是降低营销成本吧,那么怎么降低呢?光从API取得的数据足够么?是不是要结合内部的数据,尝试通过组合复合维度,环比同比CPC,CPS等来发现和预警问题,通过分时数据提高系统的敏感性,及时充分的持续微调让系统策略不失真!

    你真的对数据敏感么?每一张的报表都需要花费心思的精心设计,让数据的价值发挥出来,而不是告诉你做就做,它应该是值得你骄傲的作品!中途安利一下,到喜啦的BI系统中有200多张供业务部门查询的报表,运行在4个集群上百个节点上,而这些都是技术团队的工作结晶,所有的一切都是有价值的,保证领先于整个O2O行业。因为我相信,任何的决策都不应该是感性的,是应该基于数据做出理性的判断!

    突然发现,本来写的不是数据价值,老夫只能含泪改副标题了,请原谅我的啰嗦。本篇可能和关系型数据库关系不大,但是我还是放在了这个系列中,因为数据本质都一样,在这个数据库系列中,要多谈谈自己的想法和实践经验。

    最后,程序员在施展的过程中请不要以完成需求而做出一个个慢一拍的东西出来。全栈全业务,思考业务本身,相信自己的能力!在数据的海洋中遨游,终结所有问题!请持续关注本订阅号budaoxing,请帮忙顺手转发!马上回来关系型数据库哦!
分类
大杂烩

关系型数据库使用中的误区系列:最大误区

    开了订阅号,看到序言的PV数往上跳过了自己的期望值,尤其看到订阅者中男女比例已经达到二比一时,小小的脸红之余有了一点小小的膨胀。SO笔耕不能停!虚心接受大家意见,调整了下段落布局,希望大家喜欢。

    这次,我们来简单说说关系型数据库,我喜欢使用大量的引用和比喻来阐述观点,文章会很碎同时也会比较发散,希望能为以后和之前的文章承上启下。最后我也深信一点,能够百度到的“知识”不是“知识",所以我不是百度的搬运工。

    写SQL肯定是一种编程,准确的说是DSL(领域特定语言)编程,ruby之父松本行弘在《代码的未来》一书中用了大量的文字描述这个话题,非常引起我的共鸣,因为我常反思未来是否在业务描述中会有一种DSL可以描述特定业务,那会有多动态,有多抽象,或者这是唯一正确的道路?我想在本文埋下一个伏笔,让大家牵挂着这个问题!这里我最想说的是,主流IT媒体有这样一种观点,“21世纪人人都要学会编程”,我很赞同,但我要补充的说,“21世纪人人都要学会领域特定语言编程”,而不是人人都在写JAVA。

    关系型数据库RDBMS的使用往往陷入“误区”,我仔细分析了下,最大的误区在于场景选择!!你需要的是OLTP还是OLAP,这个误区在当下弥漫,99%的中国互联网企业做的架构有问题,那原因是什么呢?

    首先我们说说OLTP,就是传统的联机事务,你可以理解为存放线上订单的数据,后台编辑的酒店宴会厅关系数据等。OLAP则指的是联机分析,可能基于某些维度绘制出各种变化的表报,例如:酒店销售周汇总,BD人员出勤季报等。而最最要命的是往往这里的OLAP指的是ROLAP也就是带关系联机分析,所以头痛的是,程序员接到需求就一股脑儿的把这些AP的需求放到了生产环境中的TP服务器里。

    这时候一股脑儿的“优化技术”就来了,什么主从分离,方便从库出报表不拖慢主库之类文章百度一搜一大把,试问一下,一个slave能满足报表需求么?生产环境的数据库里的TP表真的能满足你么?外部的三方数据怎么办?SEM的数据难道也扔到宝贵的生产环境里去?你开始有点茅塞顿开,这根本是两种技能栈呀,分属两个部门!TP就应该放在MySQL这样的通常意义上的关系型数据库里,程序员DBA管,而OLTP是应该放在ETL(数据仓库)里由数据仓库管理员处理,你要用SQLServer或者MySQL做数据变形,简直要命!ETL的一些问题,我们将在以后大数据的文章中详细描述。

    那么问题的根本原因是什么呢?第一,需求方只知道需求,大部分产品经理无法区分这样的需求到底是由哪个部门完成,第二,有些公司根本没有数据仓库,这就有点无奈,第三,厂商的胡乱宣传让大家总期待在某一个版本会有一个allinone的东西出现!

    我的建议是,如果是报表类需求请交给ETL来处理,程序员可能只参与到ETL分层中的ODL(原始数据层)那层,区分是否是报表有一个原则很简单,需求中的报表肯定不是实时的!如果实时的报表,那么我认为他其实不是报表,已经是业务的一部分!是一种聚合后的决策用工具,如果这样的需求,必须在你的关系库里完成,当然额外的我想提醒你,如果在这样的查询中出现了select嵌套或者group having之类的聚合后筛选,我可以基本断定你的代码有问题,你缺少一张真正的物化表!不是物化视图,是一张真的表!

    如果你对ETL还有关系型数据库持续感兴趣请关注本公众号budaoxing,因为我接下来就是介绍关系型数据库的第二大误区。