在 “软件设计要素初探” 一文,尝试从软件设计的整体角度,综合讨论了软件设计的各种要素。本文探讨软件详细设计中的关键环节:存储设计。
存储设计是领域建模的设计细化,决定数据的结构以及领域对象的表达。 存储设计通常要考虑读写操作的性能、容量、并发、事务、搜索。
关系型数据设计###
业务型/事务型应用通常采用关系型数据库实现存储设计,通过规范化范式达成数据的一致性和完整性,尽可能少的冗余。领域建模是关系型存储设计的前置工作。
采用关系型数据库进行存储设计时,重点有:
-
数据库设计很大程度上是领域模型的表达和呈现;因此领域模型的质量决定了数据库设计完成后是否需要做频繁的变更;
-
尽可能采用规范化的关系范式,除非有足够理由打破范式。
-
仔细设计实体映射关系,尤其是一对多关系时;仔细设计外键引用。通常是多的方引用一的方的主键作为外键。
-
仔细设计字段名称、类型。字段具有单一含义,名称尽量贴切而具有描述性;主键类型通常采用自增的 bigint;字符串尽可能采用VARCHAR;枚举采用字符串更易理解;日期采用Date;增加极少量的扩展字段;加上字段注释COMMENT。熟悉和使用字段设计套路可提升设计效率。
-
根据业务查询和更新场景,仔细设计好索引。设计组合索引时,区分度高的字段放前面。索引应少而实用,覆盖性高。熟悉和使用索引设计套路可提升设计效率。
-
考虑运维和排查问题的需要。比如日期采用字符串比时间戳更直观可读。
-
寻找经验丰富的高级开发者和DBA给出中肯的Review意见并进行完善。
大数据存储设计###
海量数据的搜索/导出/计算应用通常采用大数据存储,比如Hadoop, ES, Hbase, Storm, Hive, Spark等。
Hadoop是分布式系统基础设施的一种实现,提供了分布式文件服务HDFS和批处理模型Map-Reduce,可用于全量数据同步;
ES(Elasticsearch)是水平可扩展的可靠的分布式文档存储/查询/分析系统,通常用于海量数据的准实时联合搜索与分析,提供了RestFul接口风格的API。相比关系型数据库,ES的优点在于可以存储文档和对象的完整体,适合多字段的灵活的联合搜索和全文搜索;ES不适合于事务型应用以及对数据丢失零容忍的应用。通常使用DB+ES的组合,DB用于主存储,ES用于准实时联合搜索。
Hbase适用于海量数据的存储,设计合适的 rowkey 非常重要,通常关乎性能、吞吐量和负载均衡。比如订单详情通常是获取单个或少量订单的详情,Rowkey设计更注重负载均衡,高位作为散列字段; 订单导出则需要批量获取大量订单的所有详情,Rowkey设计既要注重负载均衡,也要充分考虑Rowkey排序的特性,保证大批量获取数据的效率。这样,订单导出的Rowkey可以业务属性来设计,比如店铺ID+订单号,或买家ID+订单号。当然,这种做法的不足在于,对于某些频繁导出大订单量的VIP商家,导出的热点就常常分布在少数的Region上。可以统计下导出的店铺分布及导出报表行数量,越分散,这种Rowkey设计越有利。
Storm可用于实时数据同步和计算; Hive用于离线统计,提供了类SQL语句; Spark 用于离线计算。由于这些我接触很浅,咱不多述。