数据库相关
应用
十万条数据插入数据库,怎么去优化和处理高并发情况下的DB插入
首先是优化方面,对于十万条数据,如果处理每条数据时构建一个实例化对象,处理具体业务逻辑,然后进行一次io操作,十万条数据要构建十万个对象,操作十万次io,对于内存和io方面来说这显然是不现实的。整体的思路可以考虑构建一个生产消费者模式,即一个生产队列,一个消费队列。十万条数据可以到生产队列中依次排队,每条数据出队列时先到实例享元池中进行过滤(每条数据在处理完成后进行一次对象回收,回收到享元池中,下一条数据发现享元池中已经存在该对象就不重新构建而是拿来直接使用,可以避免在两次gc之间瞬时内存过大的情况)。假设这十万条数据可能分属十张表中,那么在每张表之前构建一个消费队列,从生产队列出来的数据到各自的消费队列中依次进行业务处理,处理完的数据归属到各个表的内存中(如果只考虑插入数据的话基本包括添加、更新、删除这几个操作,对于一些异常情况,例如后面的操作先进入了队列,可以将该数据放入队列尾部重新排队。
如果考虑高并发的情况,也就是在插入数据时同时要读取数据,那么需要构建两个消费队列,即一个读取队列,一个插入队列,两个队列为互斥的,对于这种情况处理就会更加复杂)。当每张表的数据处理完成后,将该表进行一次io操作,把内存中的数据同步更新到数据库中。当然如果考虑一些容灾或者宕机的场景,可以将内存中的数据每隔一段时间进行一次redis备份。
数据库中什么是 left join 和 right join 有什么区别(todo)
要不要使用外键?为什么?
外键提供的几种在更新和删除时的不同行为都可以帮助我们保证数据库中数据的一致性和引用合法性,但是外键的使用也需要数据库承担额外的开销,在大多数服务都可以水平扩容的今天,高并发场景中使用外键确实会影响服务的吞吐量上限。在数据库之外手动实现外键的功能是可能的,但是却会带来很多维护上的成本或者需要我们在数据一致性上做出一些妥协。我们可以从可用性、一致性几个方面分析使用外键、模拟外键以及不使用外键的差异:
不使用外键牺牲了数据库中数据的一致性,但是却能够减少数据库的负载; 模拟外键将一部分工作移到了数据库之外,我们可能需要放弃一部分一致性以获得更高的可用性,但是为了这部分可用性,我们会付出更多的研发与维护成本,也增加了与数据库之间的网络通信次数;
使用外键保证了数据库中数据的一致性,也将全部的计算任务全部交给了数据库; 在大多数不需要高并发或者对一致性有较强要求的系统中,我们可以直接使用数据库提供的外键帮助我们对数据进行校验,但是在对一致性要求不高的、复杂的场景或者大规模的团队中,不使用外键也确实可以为数据库减负,而大团队也有更多的时间和精力去设计其他的方案,例如:分布式的关系型数据库。
总之,靠这个保持一致性意义不大。
参考: