我们使用SQL时多是执行增删改查,但遇到复杂问题,感觉像是不够用,这时MySql特有的语法就会发挥效用。下面进行汇总。
我们常用的防止重复插入的方法是先检查是否已经存在,不存在再插入。如下:
/*若重复插入一个有唯一性索引的数据,系统会抛出异常*/
insert into user_info (username,mobile,update_time) values('test','13836968688', now());
/*我们常用的方式是先检查,不存在再插入*/
insert into user_info (username,mobile,update_time)
select 'test','13836968688', now() from user_info where not exists (select 1 from user_info where username = 'test');
/*第二种办法是使用 ignore关键字,以忽略插入异常,并返回修改行数。*/
insert ignore into user_info (username,mobile,update_time) values('test','13836968688', now());
/*若系统中无相关数据,则新增;若有则更新指定字段;用来处理高并发情况下的数据插入。*/
/*注意:在高并发的场景下使用on duplicate key update语法,可能会存在死锁的问题,所以要根据实际情况酌情使用。*/
INSERT into user_info (username,mobile,update_time) values('test','13836968688', now())
on duplicate key update mobile='13836968688',edit_date=now();
Mysql自身都有悲观锁,InnoDB在增删改查时使用的是基于数据行的行锁,且使用了MVCC(多版本并发控制)。为了防止在基于原有数据进行更新时有重复操作,需要在查询时加上悲观锁,在本事务提交之前防止对此数据的其他修改操作。但这种操作一般适用于并发量不大的数据操作。
begin;
select * from user_score where username = 'test' for update;
/*统计需要新增的积分*/
update user_score set score = score + 10 where username = 'test';
commit;
我们在客户端有时候想快速了解数据表的结构,一般会通过客户端提供的数据表查看功能,但有更方便的方式,就是通过Sql命令的方式查看。
/*查看数据表中的字段信息*/
desc user_info;
/*查看数据表的索引信息*/
show index from user_info;
/*通过生成创建数据表的Sql查看数据表结构(包括字段和索引等全部信息)*/
show create table user_info;
/*查询分析,重点分析每一步的扫描行数和索引使用情况*/
explain select * from user_info where username = 'test';
一般情况下我们备份整个数据库,但有时仅需备份一个数据表,这时我们通常先新建一个形同结构的数据表,然后再复制数据。但还有一步到位的方法,如下:
/*新建相同结构的数据表,新建的数据表与原来的一样,包括字段和索引*/
create table tmp_user_info like user_info;
/*复制数据*/
insert into tmp_user_info select * from user_info;
/*一步到位的备份方法,但是仅创建了相同的字段,却没有创建索引。*/
create table tmp_user_info select * from user_info;
当遇到数据库锁死时,或者执行很慢时,或者并发比较高时,都可以通过查看当前线程来协助分析。
/*显示当前数据库的运行线程,由于线程池的存在,当前线程包括正在执行的线程和空闲的线程。
线程信息包括执行线程的用户,客户端Host,执行时长,状态和命令信息。*/
show processlist;
在数据库迁移时,搭建测试环境时,为了数据安全考虑定时备份数据库时都可以通过命令备份数据库。
/*备份数据库*/
mysqldump -h 192.22.25.226 -u root -p123456 dbname > backup.sql;
/*还原数据库*/
use dbname;
source backup.sql;
若数据库比较大,则需要压缩备份后的文件。可以先如上备份,然后再通过压缩程序压缩。还原时,先解压再还原。但这样不免有些麻烦,我们完全可以利用管道一次性备份和压缩及一次性解压和还原,代码如下:
/*备份并使用gzip压缩脚本文件,其中>代表输出。*/
mysqldump -h192.168.1.20 -uadmin -padmin123456 good_life | gzip > good_life.sql.gz
/*使用gzip解压脚本文件并还原,其中<代表输入。*/
gzip -d < good_life.sql.gz | mysql -h192.168.1.100 -uadmin -padmin123456 good_life
/*只要压缩软件支持管道都可以用来压缩备份文件,例如7z.其中a表示加入压缩文件,-si表示输入,-mmt6表示开启6个线程.*/
mysqldump -h192.168.1.20 -uadmin -padmin123456 good_life | 7z a -si good_life.sql.7z -mmt6 -mx3 -aoa
/*使用7z解压并还原数据库,其中x表示解压,-so表示输出*/
7z x -so good_life.sql.7z | mysql -h192.168.1.100 -uadmin -padmin123456 good_life