系统设计的衡量指标
可靠性
可维护性
可扩展性
数据库
关系数据库&文档数据库
关系数据库 | 文档数据库 | |
不同点 | 大表更新较慢,如增加字段,全表更新非常慢(可以考虑新增字段设为null,后续读取时更新) | 灵活,增加字段容易 |
相同点 id | 外键 | 文档引用 |
索引
适当的索引可以加快读取查询、但是每个索引都会减慢写的速度。
简述 | 优缺点 | 应用 | |
哈希索引 | 1、使用hashmap(或者内存表)或者hash函数记录value的字符偏移量,其实这个内存表就是索引 2、内存表分段存储(大小不一),达到一定大小合并相同的key | – 缺点:key的量不能过大,否则hash冲突处理麻烦。区间查询效率不高 | |
SSTables和LSM-Tree 1 | 内存表key是有序的、一般为树状结构、大于阈值时写入磁盘 | 优点:相比于哈希索引,合并key更容易、区间查询效率也更高 缺点:查找不存在的key效率差-布隆过滤器 | Lucene\Elasticsearch\Solr 的全文索引(倒排索引) HBase\LevelDB RocksDB |
B-Trees2 | 1、索引分段存储,大小相同(页)4KB,某一页作为根, | 相比于LSM-Tree读性能好但写性能差 | MySQL的InoDB |
主键索引 vs 二级索引
主键索引:通过唯一字段设置的索引,用于直接定位行(关系数据库)、文档(文档数据库)、顶点(图形数据)。InoDB如果没有指定主键,则优先指定唯一索引作为主键,再次默认生成一个隐藏字段(6Byte)作为唯一索引。 一般,工程中将id 作为主键。
二级索引:除主键索引之外的附加索引,用于加速非主键列的查询操作,InoDB的二级索引的叶子节点存储了主键值,再利用主键索引查找对应的数据,这个操作也叫回表。
聚集索引(Clustered Index)vs 非聚集索引
简单来说聚集索引就是索引和数据放在一起,INnoDB B+树的主键索引是聚簇索引,他的叶子阶段存放了完整的行数据信息。他的非聚簇索引存储了数据的引用,可以引用主键,从而回表查询。在这二者之间,有一种折中的设计——覆盖索引,其索引包含了查询的所有列,不用再回表查询了。
todo: 补全这部分
组合索引vs多维索引
组合索引(一般也叫级联索引)就是多个列组成的索引,这种索引受限于索引构建的顺序,只有遵从最左匹配原则才能充分的利用索引。
多维索引:相较于组合索引,不受限于索引构建的顺序,对于索引内的查询条件同时生效,一般对于地理空间位置来说,构建这种索引非常重要,例如,查询特定经纬度范围内的地点,如果用组合索引,不能同时查询经度和维度,只能按照一定顺序依次查找。
对于地理位置查询,方案①可以利用空间填充曲线将二维空间映射为一维数字,方案②(常用)用一些专门的空间索引,如R树索引。 这种索引还常用于 色彩(RGB值)、空间碰撞检测、多维特征向量 等领域的检索。
全文索引 和 模糊查询
模糊查询技术有很多实现方式,目前主流的实现方式是根据编辑距离+全文索引的方式实现,全文索引3也叫倒排索引 底层使用了 SSTable + LSM Tree 。
内存数据库
上述的索引结构都是为了满足磁盘的限制,为了获取良好的读写性能,需要精心安排磁盘上的数据布局。
内存数据库,顾名思义是将数据放在内存中存储,数据丢失在一定程度上可以容忍,定期的将更改日期或者快照写入磁盘
与直觉相反,内存数据库的性能优势并非他们不需要从磁盘读取,而是尽可能的不写磁盘数据,或者说它降低了为了适应磁盘数据格式而对内存数据重新编码的开销。此外内存数据库实现了磁盘数据库难以实现的一些数据结构模型,如Redis的跳表等。
发表回复