MySQL常见问题

十年热恋 提交于 2020-03-10 20:20:02

1.UUID

– UUID是通用唯一识别码的缩写,其目的是让分布式系统中的所有元素都能有唯一的便是信息,而不需要通过中央控制端来做辨识信息的指定。
– 三部分:时间戳生成的时间信息、主机的硬件时钟序列、主机的唯一机器识别号

SELECT UUID();

– 为了避免每个MySQL各自生成的主键产生重复
– UUID主键好处:
– 1.降低了全局节点的压力,是的主键生成速度快
– 2.全局唯一
– 3.跨服务器合并数据很方面
缺点
– 1.占16个字节,比INT(4),BIGINT(8)占空间
– 2.是字符串类型,查询速度慢
– 3.不是顺序增长的字符串,作为主键,数据写入IO随机性很大
– 主键自动增长的优点
– 1.占空间小;2.检索速度快;3.IO写入连续性好

2.在线修改表结构

– ALTER TABLE缺点:
– 1.修改表的时候是锁表的,影响写入操作
– 2.如果修改表结构失败,必须还原表结构,耗时更长
– 3.大数据表记录多,修改表结构锁表时间长
– 可以用PerconaTookit工具包
– 链接

ALTER USER 'root'@'%' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

– 用PerconaTookit修改t_customer_address中name中varchar(20)(本来是200改成20)
– 在虚拟机终端里面改

pt-online-schema-change --host=自己的IP地址 --port=3306 --user=root --password=自己的MySQL密码 --alter "MODIFY name VARCHAR(20) NOT NULL COMMENT '收货人'" D=NETI,t=t_customer_address --charset=utf8 --print --execute
如果系统上线了,怎么维护表结构?

不影响业务的维护操作(添加索引、修改数据类型等等),可以在线进行,先做好备份,增量备份,若影响业务的维护操作,用PerconaTookit工具

3.订单号和流水号

订单号是唯一编号,经常被用来检索,是数字类型的主键
流水号是打印在购物单据上的字符串,便于阅读,但是不用做查询,可以携带更多的信息
– 流水号规则:(自己规定)
– 1.第一个字符:线上购物E;线下购物S
– 2.6位的零售店/仓库编号
– 3.5位品类编号
– 4.6位购物日期
– 5.10位随机数

4.数据删除

– 物理删除:用DELETE\TRUNCATE\DROP语句删除数据

– 物理删除会造成主键不连续

– 逻辑删除:改变记录的状态
– WHERE is_deleted=0;查出的是没有被删除的,把不用的数据放到另一张表。这是标记那些数据要逻辑删除

– 复制表t_user的结构

CREATE table t_user_history LIKE t_user;

使用逻辑删除,定时归档到history表

5.快速分页

SELECT id,val FROM test LIMIT 10000000000,10;
SELECT id,val FROM test WHERE id>=10000000000 LIMIT 10;
SELECT id,val FROM test WHERE id>=10000000000 AND id<=10000000010;

第二、三种要比第一种快很多!!!!

主键不连续的分页查询,把id提出来查询

SELECT t.id,t.val
FROM test t JOIN
(SELECT id FROM test LIMIT 1000000000,10) tmp
ON t.id=tmp.id
数据记录很多时,如何对分页语句优化?

先用主键索引加速(查出索引),然后用表连接获取具体数据

6.数据库集群(读多写少,写多读少,写多读多)

6.1写多读少解决方案:

(1)如果是低价值的数据,可以采用NoSQL数据库来储存

NoSQL抛弃复杂的表结构和约束,数据的写入速度很快

(2)如果是高价值的数据,TokuDB来保存,写入速度时MySQL的9-20呗

6.2数据库集群方案缺点MyCat:速度低于单节点你数据库

6.3数据库集群优点:能支持更大规模的并发访问,并且存放更多的数据

6.4总结

读多写少:MySQL+NoSQL

写多读少:MySQL+TokuDB

7.删改数据如何避免锁表

7.1锁机制:InnoDB采用行级锁,删改数据时,MySQL会锁住记录,不会锁整张表,对其他没锁的记录还是可以修改

7.2共享锁(S锁):不允许其他事务执行写操作,但是可以读数据(不会改变数据文件)

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

BEGIN; #开启事务
SELECT * FROM t_city WHERE id <= 5 LOCK IN SHARE MODE;    #给选定部分添加共享锁
COMMIT;  # 事务提交,解锁

BEGIN;  #开启事务
UPDATE t_city SET province_id = 2 WHERE id <=8;  
#当未解开锁时(上面),更新语句不会执行
SELECT * FROM t_city;   #未解锁时可以查询数据
SELECT * FROM t_city WHERE id<=6 LOCK IN SHARE MODE; #可以添加多个共享锁
ROLLBACK;  #回滚

7.3排他锁(X锁):不允许其他事务执行写操作,但是可以读数据(不会改变数据文件),同时只要加了排他锁,就不能加其他任何锁了

MySQL会默认给添加、修改和删除记录,设置排他锁

#自动加锁
BEGIN;
UPDATE t_test SET val='ABC' WHERE id<=100;
#执行完之后,会对数据前100条自动加上据排他锁,此时事务不回滚也不提交,意味着数据是加着排他锁的,再再别的面板对前一百条数据进行操作,修改添加等都是不行的,直到执行回滚或者提交。
COMMIT;
ROLLBACK;

#手动加锁for update
BEGIN;
SELECT * FROM t_city WHERE id<=6 FOR UPDATE;
#也不能再加别的锁了

7.4如何减少锁冲突?

把复杂的SQL语句,拆分成多条简单的SQL语句

8.系统内部的业务图片是怎么储存的?

使用图床服务器:Nginx或者云储存

使用MongoDB的Grid FS搭建集群图床服务器

9.怎么避免并发操作的时候,数据不一致?

使用乐观锁机制

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!