在MySQL数据库中,常用的引擎主要有:MyIASM和InnoDB。
MyIASM引擎是MySql的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行insert插入和update更新语句时,即执行写操作时需要锁定整个表。所以会导致效率降低。如果表的读操作远远多于写操作时,并且不需要事务支持,可以将MyIASM作为数据库引擎的首选。
InnoDB引擎提供了对数据库ACID事务的支持,并且还提供了行级锁和外键的约束。该引擎不支持全文搜索。MySQL运行的时候,InnoDB会在内存中建立缓冲池,用于缓冲数据和索引。由于锁的粒度小,写操作不会锁定全表,在并发度较高的场景下使用会提升效率。
两者索引的数据结构都是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
select * from tableName where columnName is null;
select * from tableName where columnName is not null;
-- 设为null
update tableName set columnName = null;
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;
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
安全快速修改Mysql数据库名的5种方法
MySQL DATE_FORMAT()函数
mysql> select version();