MySQL-优化
概述
表关联查询时务必遵循 小表驱动大表 原则;
使用查询语句 where 条件时,不允许出现 函数,否则索引会失效;
使用单表查询时,相同字段尽量不要用 OR,因为可能导致索引失效,比如:SELECT * FROM table WHERE name = '手机' OR name = '电脑',可以使用 UNION 替代;
LIKE 语句不允许使用 % 开头,否则索引会失效;
组合索引一定要遵循 从左到右 原则,否则索引会失效;比如:SELECT * FROM table WHERE name = '张三' AND age = 18,那么该组合索引必须是 name,age 形式;
索引不宜过多,根据实际情况决定,尽量不要超过 10 个;
每张表都必须有 主键,达到加快查询效率的目的;
分表,可根据业务字段尾数中的个位或十位或百位(以此类推)做表名达到分表的目的;
分库,可根据业务字段尾数中的个位或十位或百位(以此类推)做库名达到分库的目的;
表分区,类似于硬盘分区,可以将某个时间段的数据放在分区里,加快查询速度,可以配合 ...
面向对象的特征
概述面向对象的三个基本特征是:封装、继承、多态。
封装封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
继承面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
多态多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。 实现多态,有二种方式,覆盖,重载。
final,finally,finalize
final用于声明属性,方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承.
finally是异常处理语句结构的一部分,表示总是执行.
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等. JVM不保证此方法总被调用.
聊聊 MongoDB 使用场景
高伸缩性的场景MongoDB 非常适合高伸缩性的场景,它是可扩展性的表结构。基于这点,可以将预期范围内,表结构可能会不断扩展的 MySQL 表结构,通过 MongoDB 来存储,这就可以保证表结构的扩展性。
日志系统的场景日志系统数据量特别大,如果用 MongoDB 数据库存储这些数据,利用分片集群支持海量数据,同时使用聚集分析和 MapReduce 的能力,是个很好的选择。
分布式文件存储MongoDB 还适合存储大尺寸的数据,之前介绍的 GridFS 存储方案,就是基于 MongoDB 的分布式文件存储系统。
选择合适的数据存储方案
选择合适的数据存储方案关系型数据库 MySQLMySQL 是一个最流行的关系型数据库,在互联网产品中应用比较广泛。一般情况下,MySQL 数据库是选择的第一方案,基本上有 80% ~ 90% 的场景都是基于 MySQL 数据库的。因为,需要关系型数据库进行管理,此外,业务存在许多事务性的操作,需要保证事务的强一致性。同时,可能还存在一些复杂的 SQL 的查询。值得注意的是,前期尽量减少表的联合查询,便于后期数据量增大的情况下,做数据库的分库分表。
内存数据库 Redis随着数据量的增长,MySQL 已经满足不了大型互联网类应用的需求。因此,Redis 基于内存存储数据,可以极大的提高查询性能,对产品在架构上很好的补充。例如,为了提高服务端接口的访问速度,尽可能将读频率高的热点数据存放在 Redis 中。这个是非常典型的以空间换时间的策略,使用更多的内存换取 CPU 资源,通过增加系统的内存消耗,来加快程序的运行速度。
在某些场景下,可以充分的利用 Redis 的特性,大大提高效率。这些场景包括缓存,会话缓存,时效性,访问频率,计数器,社交列表,记录用户判定信息,交集、并集和差集,热门列 ...
ObjectId 规则
时间戳
机器码
PID
计数器
0,1,2,3
4,5,6
7,8
9,10,11
前四位是时间戳,可以提供秒级别的唯一性。
接下来三位是所在主机的唯一标识符,通常是机器主机名的散列值。
接下来两位是产生 ObjectId 的 PID,确保同一台机器上并发产生的 ObjectId 是唯一的。
前九位保证了同一秒钟不同机器的不同进程产生的 ObjectId 时唯一的。
最后三位是自增计数器,确保相同进程同一秒钟产生的 ObjectId 是唯一的。
选择合适的分布式主键方案
数据库自增长序列或字段
UUID
使用 UUID to Int64 的方法
Redis 生成 ID
Twitter 的 snowflake 算法
利用 zookeeper 生成唯一 ID
MongoDB 的 ObjectId
limit 20000 加载很慢怎么解决
MySQL 的性能低是因为数据库要去扫描 N + M 条记录,然后又要放弃之前 N 条记录,开销很大
解决思路:
前端加缓存,或者其他方式,减少落到库的查询操作,例如某些系统中数据在搜索引擎中有备份的,可以用 es 等进行搜索
使用延迟关联,即先通用 limit 得到需要数据的索引字段,然后再通过原表和索引字段关联获得需要数据
select a.* from a,(select id from table_1 where is_deleted='N' limit 100000,20) b where a.id = b.id
从业务上实现,不分页如此多,例如只能分页前 100 页,后面的不允许再查了
不使用 limit N,M, 而是使用 limit N,即将 offset 转化为 where 条件。
聚集索引与非聚集索引的区别
聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个
聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续
聚集索引:物理存储按照索引排序;聚集索引是一种索引组织形式,索引的键值逻辑顺序决定了表数据行的物理存储顺序
非聚集索引:物理存储不按照索引排序;非聚集索引则就是普通索引了,仅仅只是对数据列创建相应的索引,不影响整个表的物理存储顺序.
索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
为什么要用 B-Tree
一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘 I/O 消耗,相对于内存存取,I/O 存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘 I/O 操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘 I/O 的存取次数。