一、 订单号和流水号的关系

1. 订单号

订单号既是订单的唯一编号,而且经常被用来检索,所以应当是数字类型的主键

2. 流水号

流水号是打印在购物单据上的字符串,便于阅读,但是不用做查询


二、逻辑删除还是物理删除?

物理删除就是用DELETETRUNCATEDROP语句删除数据。
物理删除是把数据从硬盘中删除,可以释放存储空间,缩小数据表的体积,对性能提升有帮助。


1. 物理删除的代价

  1. 由于物理删除是真删除,所以数据恢复起来难度很大
  2. 物理删除会造成主键的不连续,导致分页查询变慢
SELECT ……  FROM ……  LIMIT 1000, 20;
SELECT ……  FROM ……  WHERE  id>=1000  AND  id<= 1020;

2. 哪些数据不适合物理删除

核心业务表的数据不建议做物理删除,只做状态变更。
比如订单作废、账号禁用、优惠券作废等等。
既不删除数据,又能缩小数据表体积,可以把记录转移到历史表。

逻辑删除就是在数据表添加一个字段(is_deleted),用字段值标记该数据已经逻辑删除,查询的时候跳过这些数据。


三、海量记录快速分页

利用主键索引来加速分页查询

SELECT * FROM t_test WHERE id>=5000000 LIMIT 100;
SELECT * FROM t_test WHERE id>=5000000 AND id<=5000000+100;

如果用物理删除,主键不连续,就不能用主键索引来加速分页,所以只能使用折中的方案

SELECT t.id, t.name FROM t_test t JOIN ( SELECT id FROM t_test LIMIT 5000000, 100) tmp ON t.id = tmp.id;

子查询只查id字段,因为有主键索引所以会很快


四、读多写少和写多读少


1. 读多写少的解决方案

可以把MySQL组建集群,并且设置上读写分离


2. 写多读少的解决方案

冷热数据分离

如果是低价值的数据,可以采用NoSQL数据库来存储这些数据

像滴滴出行实时都在上传位置坐标信息,这些数据写入的多,但是并不是非常重要,偶尔丢失一点也是没关系的,就适合使用NoSQL

如果是高价值的数据,可以用TokuDB来保存
TokuDB的写入速度的是InnoDB9~ 20倍,数据的压缩比更是InnoDB14倍。

3. 读多写多

像微信、QQ离线聊天记录,微信朋友圈信息等,都是读多写多的场景,
普通的关系数据库是不能满足需求的,都是结合NoSQL实现方案


五、删改数据如何避免锁表

InnoDB采用的是行级锁,删改数据的时候,MySQL会锁住记录

行级锁分为

  1. 共享锁(S锁)和
  2. 排它锁(X锁)

共享锁和排它锁,都不允许其他事务执行写操作,但是可以读数据。

排它锁不允许对数据再另行加锁,但是数据加了共享锁,其他事务还可以对其再加共享锁


1. 共享锁

只有serializable事务隔离级别,才会给数据读取添加共享锁

serializable事务隔离级别,一般不建议使用,他是串行执行事务的

SELECT ..... FROM ...... LOCK IN SHARE MODE; # 只有加了 SHARE MODE 才会使用共享锁

添加了共享锁,其他事务只能读取加锁数据,而不能修改和删除,但是其他事务还可以对其再加共享锁

2. 排它锁

MySQL默认会给添加、修改和删除记录,设置排它锁,等事务提交或者回滚的时候,会自动释放排它锁

SELECT ..... FROM ...... FOR UPDATE;

如果不是SELECT,是UPDATEDELETE语句,就会自动设置排它锁


六、系统内部图片怎么存储

  1. 使用图床服务器: Nginx 或者 云存储
  2. 使用MongoDBGridFS搭建集群图床服务器