MySql常用命令

添加表字段

alter  table  table_name add  column  temperature  varchar(10) comment '温度' ;

删除表字段

alter table id_name drop column age,drop column address;

修改表字段

  • 修改字段类型
    #alter  table 表名 modify  column 字段名 新数据类型;
    alter  table user modify  column money double(10,7)
    
  • 修改默认值
    #alter table 表名 alter column 字段名 drop default; (若本身存在默认值,则先删除)
    #alter table 表名 alter column 字段名 set default 默认值;(若本身不存在则可以直接设定)
     alter table user alter column create_time set default CURRENT_TIMESTAMP
    
  • 修改注释
     # alter table 表名 modify   column  字段名   数据类型  comment  '修改后的字段注释';
     alter table user modify column  create_time  datetime    comment '创建时间'  
     #注意如果有默认值的话,要把默认值也加上了,不加的话,修改后就没有默认值了
    
# 一次性都修改
ALTER  TABLE 表名 MODIFY COLUMN 字段名 新数据类型 新类型长度  新默认值  新注释; -- COLUMN可以省略
alter  table user modify  column  money double(10,7) DEFAULT NULL COMMENT '收入'; 

mysql修改字段名(重命名):

ALTER  TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型;  
alter  table table1 change column1 column1 varchar(100) DEFAULT 1.2 COMMENT '注释'; -- 正常,此时字段名称没有改变,能修改字段类型、类型长度、默认值、注释
alter  table table1 change column1 column2 decimal(10,1) DEFAULT NULL COMMENT '注释' -- 正常,能修改字段名、字段类型、类型长度、默认值、注释
alter  table table1 change column2 column1 decimal(10,1) DEFAULT NULL COMMENT '注释' -- 正常,能修改字段名、字段类型、类型长度、默认值、注释
alter  table table1 change column1 column2; -- 报错  

修改表名

ALTER TABLE user10 RENAME TO user11;

修改表注释

# alter table 表名 comment '修改后的表的注释';
alter table user comment '用户表'

char 和varchar的区别

char:定长,效率高,一般用于固定长度的表单提交数据存储  ;例如:身份证号,手机号,电话,密码等
varchar:不定长,效率偏低

获取时间戳,单位是秒(s)

select unix_timestamp()

在navicat中查看数据库大小

  • 1、进入information_schema 数据库(存放了其他的数据库的信息)
image.png
  • 2、查询所有数据库的大小
select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES;
image.png
  • 3、查询指定数据库大小
select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES
WHERE TABLE_SCHEMA = 'bmt-oauth'
  • 4、查询指定数据库中指定表的大小
select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES
WHERE TABLE_SCHEMA = 'bmt-oauth' AND TABLE_NAME='sys_user'
  • 5、查看指定数据库指定表单的其他大小
select 
concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data_size,
concat(round(sum(MAX_DATA_LENGTH/1024/1024),2),'MB') as max_data_size,
concat(round(sum(INDEX_LENGTH/1024/1024),2),'MB') as index_size,
concat(round(sum(DATA_FREE/1024/1024),2),'MB') as data_free
from TABLES
WHERE TABLE_SCHEMA = 'bmt-oauth' AND TABLE_NAME='sys_user'

添加索引

  • 普通索引
alter table test add index index_name(name) USING BTREE
  • 唯一索引
alter table test add unique  index index_name(name) USING BTREE
  • 全文索引
alter table test add fulltext  index index_name(name) USING BTREE
  • 多列索引、组合索引、复合索引
alter table test add index index_name(name,age) USING BTREE

注:name,age为表中字段名称

常用函数

  • 替换字符串 REPLACE
update 表名 set 字段名=REPLACE (字段名,'原来的值','要修改的值')
update aaa set ac_name = REPLACE(ac_name,'积分星球','积分中心')  where ac_name like '%积分星球%';

存在,则更新,不存在则插入

某些情况下,比如同步数据,批量 插入数据,我们会有一种需求,
当主键或者unique索引没有冲突的时候,直接执行插入操作,如果有冲突则不做任何操作,避免重复插入
即,如果插入的数据会导致UNIQUE索引或PRIMARY KEY发生冲突/重复,则执行更新操作

  • on duplicate key update
    如果指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行UPDATE操作
    如果行作为新记录被插入(没有冲突),则受影响行的值为1;
INSERT  INTO `wasabi`.`experiment_user_index`(`user_id`, `context`, `app_name`,  `experiment_id`) VALUES ('1', 'DEV', 'a2' ,'c083afde-951e-4356-bde3-f79dfb322b82')
ON DUPLICATE KEY UPDATE context = 'PROD'
> Affected rows: 1
> 时间: 0.062s

如果原有的记录被更新(有冲突),则受影响行的值为2。

INSERT  INTO `wasabi`.`experiment_user_index`(`user_id`, `context`, `app_name`,  `experiment_id`) VALUES ('11a', 'DEV', 'a2' ,'c083afde-951e-4356-bde3-f79dfb322b82')
ON DUPLICATE KEY UPDATE context = 'PROD'
> Affected rows: 2
> 时间: 0.062s
  • replace into
    首先尝试插入数据到表中, 1. 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。 2. 否则,直接插入新数据。
replace into tbl_name(col_name, ...) values(...)
replace into tbl_name(col_name, ...) select ...
replace into tbl_name set col_name=value, ...
  • 性能
    在数据库数据量很少的时候, 这两种方式都很快,无论是直接的插入还是有冲突时的更新,都不错,但在数据库表的内容数量比较大(如百万级)的时候,两种方式就不太一样了,

    首先是直接的插入操作,两种的插入效率都略低, 比如直接向表里插入1000条数据(百万级的表(innodb引擎)),二者都差不多需要5,6甚至十几秒。究其原因,我的主机性能是一方面,但在向大数据表批量插入数据的时候,每次的插入都要维护索引的, 索引固然可以提高查询的效率,但在更新表尤其是大表的时候,索引就成了一个不得不考虑的问题了。

    其次是更新表,这里的更新的时候是带主键值的(因为我是从另一个表获取数据再插入,要求主键不能变) 同样直接更新1000条数据, replace的操作要比insert on duplicate的操作低太多太多, 当insert瞬间完成(感觉)的时候,replace要7,8s, replace慢的原因在于,当更新数据的时候,要先删除旧的,然后插入新的,在这个过程中,还要重新维护索引,所以速度慢,但为何insert on duplicate的更新却那么快呢。 在向老大请教后,终于知道,insert on duplicate 的更新操作虽然也会更新数据,但其对主键的索引却不会有改变,也就是说,insert on duplicate 更新对主键索引没有影响.因此对索引的维护成本就低了一些(如果更新的字段不包括主键,那就要另说了)。

存在,则不做操作,不存在则插入

某些情况下,比如同步数据,批量 插入数据,我们会有一种需求,
当主键或者unique索引没有冲突的时候,直接执行插入操作,如果有冲突则不做任何操作,避免重复插入
即,如果插入的数据会导致UNIQUE索引或PRIMARY KEY发生冲突/重复,则忽略此次操作/不插入数据

//插入成功
INSERT IGNORE INTO `wasabi`.`experiment_user_index`(`user_id`, `context`, `app_name`,  `experiment_id`) VALUES ('0', 'DEV', 'a2' ,'c083afde-951e-4356-bde3-f79dfb322b82')
> Affected rows: 1
> 时间: 0.062s

//有重复,忽略不做操作
INSERT IGNORE INTO `wasabi`.`experiment_user_index`(`user_id`, `context`, `app_name`,  `experiment_id`) VALUES ('0', 'PROD', 'a2' ,'c083afde-951e-4356-bde3-f79dfb322b82')
> Affected rows: 0
> 时间: 0.061s

查询当前数据库有多少表,每张表多少条数据

  • 模糊查询:通过MySQL自带的统计信息
SELECT TABLE_NAME,TABLE_ROWS FROM
 INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '库名' ORDER BY TABLE_ROWS DESC

注:可以同时统计库内的多张表,但是数据并不是很精确,通常比实际数据要少一点,但是对于精确性要求不高的话,是个很实用的方法,性能很好,毕竟不用扫描全表

  • 精确查询:
select count(*) from tableName
  • 多张表同时count
    分库分表后,如果需要直接在navicat中查询多张表中的统计次数,每张表单独count查询太麻烦,也不利于统计。(当然,如果公司有自己的SQL平台,支持分库分表查询的话,那就不用这么麻烦了)

比如,我现在需要从xxx_user_0 到 xxx_user_9 这些表中统计user_id总数,那么可以使用union all 连接多张表,然后sum 累加统计

SELECT sum(cnt) FROM(
SELECT count(user_id) as cnt FROM xxx_user_0 WHERE CHAR_LENGTH(user_id) > 40  UNION ALL
SELECT count(user_id) as cnt  FROM xxx_user_1 WHERE CHAR_LENGTH(user_id) > 40  UNION ALL
SELECT count(user_id) as cnt  FROM xxx_user_2 WHERE CHAR_LENGTH(user_id) > 40 UNION ALL
SELECT count(user_id)as cnt  FROM xxx_user_3 WHERE CHAR_LENGTH(user_id) > 40 UNION ALL
SELECT count(user_id) as cnt  FROM xxx_user_4 WHERE CHAR_LENGTH(user_id) > 40 UNION ALL
SELECT count(DISTINCT(user_id)) as cnt  FROM xxx_user_5 WHERE CHAR_LENGTH(user_id) > 40 UNION ALL
SELECT count(DISTINCT(user_id)) as cnt  FROM xxx_user_6 WHERE CHAR_LENGTH(user_id) > 40 UNION ALL
SELECT count(DISTINCT(user_id)) as cnt  FROM xxx_user_7 WHERE CHAR_LENGTH(user_id) > 40 UNION ALL
SELECT count(DISTINCT(user_id)) as cnt  FROM xxx_user_8 WHERE CHAR_LENGTH(user_id) > 40 UNION ALL
SELECT count(DISTINCT(user_id)) as cnt  FROM xxx_user_9 WHERE CHAR_LENGTH(user_id) > 40
)as countdata

注:union all 与 union的区别
效率上,union all比union更好一点。因为union在执行的时候会把结果集进行排序并删除重复的记录,而union all则会把两个结果集原封不动地合并在一起

delete 和 truncate 区别

delete 和 truncate都能删除表中数据,但是有以下几个不同点:

  • 1.条件删除
    delete可以带where执行条件删除,但是truncate不能;所以delete可以条件删除,而truncate就是清空表中多有数据

  • 2.事务
    delete是数据操作语言DML,操作时原数据会被放到rollback segment中,可以被回滚;而truncate是数据定义语言DDL, 操作时不会进行存储,不能进行回滚

  • 3.速度
    truncate > delete
    delete语句是逻辑删除,及逐行删除数据,然后在事务日志中为所删除的每行记录一行;
    而truncate是物理删除,直接清空物理文件,再重新创建表。

  • 4.物理空间
    从上面的提到的逻辑删除和物理删除可以看出来,truncate清空数据后,物理空间就直接释放了,但是delete不会, delete 进行删除操作的时候,只会将已经删除的数据标记为删除,并没有把数据文件删除,因此并不会彻底的释放空间。这些被删除的数据会被保存在一个链接清单中,当有新数据写入的时候,MySQL 会重新利用这些已删除的空间进行再写入。

    如果delete操作后,想要立即释放空间,可以执行optimize table table_name语句,OPTIMIZE TABLE 将重新组织表数据和相关索引数据的物理存储空间,减少存储空间并提高I/O访问效率。关于optimize 可见
    Mysql表空间碎片释放

  • 5.主键id
    主键id通常都是自增的,从上面的提到的逻辑删除和物理删除可以看出来,delete删除数据后,id水位线并不会变更,而truncate相当于是重建表了,那id水位当然是再次从1开始了;

你可能感兴趣的:(MySql常用命令)