MySQL数据库常用知识点

MySQL的常用引擎

在MySQL数据库中,常用的引擎主要有:MyIASM和InnoDB
MyIASM引擎是MySql的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行insert插入和update更新语句时,即执行写操作时需要锁定整个表。所以会导致效率降低。如果表的读操作远远多于写操作时,并且不需要事务支持,可以将MyIASM作为数据库引擎的首选。
InnoDB引擎提供了对数据库ACID事务的支持,并且还提供了行级锁和外键的约束。该引擎不支持全文搜索。MySQL运行的时候,InnoDB会在内存中建立缓冲池,用于缓冲数据和索引。由于锁的粒度小,写操作不会锁定全表,在并发度较高的场景下使用会提升效率。

InnoDB和MyIASM使用的索引的数据结构

两者索引的数据结构都是B+树。
MyIASM引擎,B+树的数据结构中存储的内容实际上是实际数据的地址值。也就是说它的索引和实际数据是分开的,只不过使用索引指向了实际数据。这种索引的模式被称为非聚集索引
Innodb引擎的索引的数据结构也是B+树,但数据结构中存储的是实际的数据,这种索引又被称为聚集索引。这个索引的key就是数据表的主键,因此InnoDB表数据文件本身就是主索引。

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
和MyISAM不同,InnoDB的辅助索引数据域存储的也是相应记录主键的值而不是地址,所以当以辅助索引查找时,会先根据辅助索引找到主键,再根据主键索引找到实际的数据。所以Innodb不建议使用过长的主键,否则会使辅助索引变得过大。建议使用自增的字段作为主键,这样B+Tree的每一个结点都会被顺序的填满,而不会频繁的分裂调整,会有效的提升插入数据的效率。

备注:
(1) B+树中的B并不是二叉树(Binary)的意思,这里的B表示Balance,即平衡的意思。B+树其实就是平衡查找树,其满足两个条件:平衡树和查找树。
(2) B+树真实的数据存在于叶子节点。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项。
(3) B-树和B+树最重要的一个区别就是B+树只有叶节点存放数据,其余节点用来索引;而B-树是每个索引节点都会有Data域。

扩展阅读:
为什么要用B+树结构——MySQL索引结构的实现

数据库自增主键可能产生的问题

使用自增主键对数据库做分库分表,可能出现一些诸如主键重复等的问题,或者在数据库导入的时候,可能会因为主键出现一些问题。
数据库自增主键可能产生的问题

常用脚本

查看表信息:表名、行数和大小等

MySQL数据库的表信息存在INFORMATION_SCHEMA库的TABLES表中,可使用如下sql语句查询表信息如表名、行数和大小等。

SELECT
	TABLE_NAME,
	TABLE_ROWS,
	DATA_LENGTH / 1024 / 1024 "DATA_LENGTH(M)",
	CREATE_TIME,
	TABLE_COLLATION
FROM
	INFORMATION_SCHEMA. TABLES
WHERE
	TABLE_SCHEMA = 'demo'
ORDER BY
	TABLE_ROWS DESC;

说明:TABLE_SCHEMA条件右侧填入要查询的数据库名。

创建表

DROP TABLE IF EXISTS `code_dictionary`;
CREATE TABLE `code_dictionary` (
  `id` char(32) NOT NULL COMMENT 'ID',
  `code` varchar(32) NOT NULL COMMENT '编码',
  `name` varchar(64) NOT NULL COMMENT '名称',
  `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
  `created_time` datetime NOT NULL COMMENT '创建时间',
  `last_modified_time` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

MySQL表注释和字段注释

增加/修改/删除列

alter table table_name add column `column_name` char(32) 
	DEFAULT '6e5fcd86944441eaa4282f6172f88ab6' COMMENT '编码' AFTER `config`;

alter table table_name modify `column_name` char(32) 
	DEFAULT '6e5fcd86944441eaa4282f6172f88ab6' COMMENT '编码' AFTER `config`;

alter table table_name drop column `column_name`;

null值查找与设置

-- 查询字段为null或者不为null
select * from tableName where columnName is null;
select * from tableName where columnName is not null;
-- 设为null
update tableName set columnName = null;

从A表中取数据插入B表

INSERT INTO tableB(user_id, branch_id, created_time, last_modified_time)
	SELECT id, 1, now(), now()
		FROM tableA WHERE age > 20;

删除业务逻辑上重复的记录

(需要借助中间表)
DELETE
FROM
	user_role
WHERE
	id NOT IN (
		SELECT
			tmp.id
		FROM
			(
				SELECT
					min(id) id
				FROM
					user_role
				GROUP BY
					role_id,
					user_id
			) tmp
	);

级联更新

UPDATE contest_season s
SET attendee_cnt = (
	SELECT
		count(DISTINCT user_id)
	FROM
		contest_detail d
	WHERE
		d.season_id = s.id
)
WHERE
	EXISTS (
		SELECT
			1
		FROM
			contest_detail d
		WHERE
			d.season_id = s.id
	);

复制表

-- 复制表结构和数据
create table tableB as select * from tableA;
create table tableB select * from tableA;

-- 复制表结构
create table tableB as select * from tableA where 1=0;
create table tableB select * from tableA where 1=0;


-- 复制表数据(应确保表结构相同,最好写列名,否则复制的列值可能会错乱)
insert into tableB select * from tableA;

授权远程IP访问

GRANT ALL PRIVILEGES ON *.* TO [email protected] IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

导入导出

-- 导出数据库
mysqldump -uxxxx -pxxxx -h xxxx db_name > db_name_dump.sql
-- 导入脚本到数据库
mysql -uxxxx -pxxxx -h xxxx db_name < 1.sql

常用函数

IFNULL(expr1,expr2)

如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2
IFNULL(gender, 'unknown')

IF(expr1,expr2,expr3)

如果expr1是TRUE(expr1<>0且expr1<>NULL),则返回expr2,否则返回expr3
IF(city='苏州','本市','外市')

CASE WHEN

CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END
value=compare-value时返回result
CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END
    
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END    
如果第一个条件为真,返回result。如果没有匹配的result值,那么结果在ELSE后的result被返回。如果没有ELSE部分,那么NULL被返回。
CASE WHEN 1>0 THEN "true" ELSE "false" END

CONCAT(str1,str2,…)              

返回结果为连接参数产生的字符串。如有任何一个或多个参数为NULL ,则返回值为 NULL。
CONCAT('My', 'SQL')

DATE_FORMAT(date,format)

format字符串格式化date值
DATE_FORMAT(modify_date, "%Y-%m-%d %H:%i:%s")

安全快速修改Mysql数据库名的5种方法
MySQL DATE_FORMAT()函数

查看MySQL的版本

(1) 在终端下
mysql -V。
(2) 在mysql中
mysql> status;

mysql> select version();

MySQL三大分支

Percona
MariaDB
Drizzle

你可能感兴趣的:(数据库)