1、索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于C语言的链表通过指针指向数据记录的内存地址)
2、使用索引后可以不用扫描全表来定位某行的数据,而是通过索引表找到该行数据对应的物理地址然后访问相应的数据,因此能加快数据库的查询速度
3、索引就好比是一本书的目录,可以根据目录中的页码快速找到所需的内容
4、索引是表中一列或者若干列值排序的方法
5、建立索引的目的是加快对表中记录的查找或排序
1、设置了合适的索引之后,数据库利用各种快速定位技术,能够大大加快查询速度,这是创建索引的最主要的原因
2、当表很大或查询涉及到多个表时,使用索引可以成千上万倍的提高查询速度
3、可以降低数据库的IO成本,并且索引还可以降低数据库的排序成本
4、可以加快表与表之间的连接,可以保证数据表中每一行数据的唯一性
5、可以加快表与表之间的连接
6、在使用分组和排序时,可大大减少分组和排序的时间
7、建立索引在搜索和恢复数据库中的数据时能显著提高性能
1、索引需要占用额外的磁盘空间
对于MySQL引擎而言,索引文件和数据文件是分离的,索引文件用于保存数据记录的地址,二InnoDB引擎的表数据文件本身就是索引文件
2、更行一个包含索引的表需要比更新一个没有索引的表花费更多时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引
create table member id int(10),name varchar(10),cardid int(10),phone int(11),address varchar(50),remark text);
create index name_index on member (name);
修改表方式创建ALTER TABLE 表名 ADD INDEX 索引名 (列名);
创建表的时候指定索引CREATE TABLE 表名 ( 字段1 数据类型,字段2 数据类型[,...],INDEX 索引名 (列名));
#直接创建唯一索引
CREATE UNIOUE INDEX 索引名ON 表名(列名);
create unique index cardid index on member(cardid);
#修改表方式创建
ALTER TABLE 表名 ADD UNIQUE 索引名(列名);
#创建表的时候指定
CREATE TABLE 表名 (字段1 数据类型,字段2 数据类型[,...],UNIQUE 索引名 (列名));
#创建表的时候指定
CREATE TABLE 表名 ([...],PRIMARY KEY (列名));
#修改表方式创建
ALTER TABLE 表名 ADD PRIMARY KEY (列名):
alter table member add primary key (id);
CREATE TABLE 表名(列名1 数据类型,列名2 数据类型,列名3 数据类型INDEX 索引名列名1,列名2,列名3));
select * from 表名 where 列名1='...' AND 列名2= ...' AND 列名3= ...';
#直接创建索引
CREATE FULLTEXT INDEX 索引名ON 表名 (列名);
#修改表方式创建
ALTER TABLE 表名 ADD FULLTEXT 索名 (列名);
alter table member add fulltext remark index (remark);
#创建表的时候指定索引
CREATE TABLE 表名 (字段1 数据类型[,...],EULLTEXT 索引名 (列名));
#数据类型可以为 CHAR、VARCHAR 或者 TEXT
#使用全文索引查询
SELECT * EROM 表名 WHERE MATCH(列名)AGAINST查询内容);
insert into member values(1,'zhangsan',123123,123123,'nanjing','this is member!');
insert into member values(2,'lisi',456456,456456,'beijing','this is vip!');
insert into member values(3,'wangwu',789789,78979,'shanghai','this is vip member!');
select * from member where match(remark) against('vip');
show index from 表名;
show keys from 表名;
#当屏幕显示繁琐或不够时可以把分号改为\G
字段 | 含义 |
---|---|
Table | 表的名称。 |
Non unique | 如果索引不能包括重复词,则为 0;如果可以,则为 1。 |
Keyname | 索引的名称Seq in index:索中的列序号,从 1开始。 |
Column name | 列名称。 |
Collation | 列以什么方式存储在索引中。在 MySQL 中,有值A’(升序)或 NULL (无分类)。 |
Cardinality | 索引中唯一值数目的估计值。 |
Sub part | 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为 NULL。 |
Packed | 指示关键字如何被压缩。如果没有被压缩,则为 NULL |
Null | 如果列含有 NULL,则含有 YES。如果没有,则该列含有 NO。 |
Index type | 用过的索引方法 (BTREE,FULLTEXT,HASH,RTREE)。Comment:备注。 |
#直接删除索引
DROP INDEX索引名ON表名;
#修改表方式删除索引
ALTER TABLE 表名 DROP INDEX 索引名;
#删除主键索引
ALTER TABLE 表名 DROP PRIMARY KEY;
1、事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行要么都不执行
2、事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元
3、事务适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券交易系统等等
4、事务通过事务的整体性以保证数据的一致性。
5、事务能提高在向表中更新和插入信息期间的可靠性
说白了,所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位
2、提交读(Read Committed(RC)):
允许一个事务只能看到其他事务已经提交的修改,未提交的修改是不可见的。防止脏读。
3、可重复读(Repeatable Read(RR)):—mysql默认的隔离级别
确保如果在一个事务中执行两次相同的SELECT语句,都能得到相同的结果,不管其他事务是否提交这些修改。可以防止脏读和不可重复读。
4、串行读(Serializable):—相当于锁表
完全串行化的读,将一个事务与其他事务完全地隔离。每次读都需要获得表级共享锁,读写相互都会阻塞。可以防止脏读,不可重复读取和幻读,(事务串行化)会降低数据库的效率。
mysql默认的事务处理级别是 repeatable read(可重复读) ,而Oracle和SQL Server是 read committed (提交读)。
#查询全局事务隔离级别:
show global variables like '%isolation%';
SELECT @@global.tx_isolation;
#查询会话事务隔离级别:
show session variables like '%isolation%';
SELECT @@session.tx_isolation;
SELECT @@tx_isolation;
#设置全局事务隔离级别:
set global transaction isolation level read committed;
set @@global.tx_isolation='read-committed'; #重启服务后失效
#设置会话事务隔离级别:
set session transaction isolation level repeatable read;
set @@session.tx_isolation='repeatable-read';
总结:在事务管理中,原子性是基础,隔离性是手段,一致性是目的,持久性是结果。
#BEGIN 或 START TRANSACTION:显式地开启一个事务。
#COMMIT 或 COMMIT WORK:提交事务,并使已对数据库进行的所有修改变为永久性的。
#ROLLBACK 或 ROLLBACK WORK:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
#SAVEPOINT S1:使用 SAVEPOINT 允许在事务中创建一个回滚点,一个事务中可以有多个 SAVEPOINT;“S1”代表回滚点名称。
#ROLLBACK TO [SAVEPOINT] S1:把事务回滚到标记点。
SET AUTOCOMMIT=0; #禁止自动提交
SET AUTOCOMMIT=1; #开启自动提交,Mysql默认为1
SHOW VARIABLES LIKE 'AUTOCOMMIT'; #查看Mysql中的AUTOCOMMIT值
#如果没有开启自动提交,当前会话连接的mysql的所有操作都会当成一个事务直到你输入rollback|commit;当前事务才算结束。当前事务结束前新的mysql连接时无法读取到任何当前会话的操作结果。
如果开起了自动提交,mysql会把每个sql语句当成一个事务,然后自动的commit。
当然无论开启与否,begin; commit|rollback; 都是独立的事务。
1、静态(固定长度)表
静态表是默认的存储格式。静态表中的字段都是非可变字段,这样每个记录都是固定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间通常比动态表多。
2、动态表
动态表包含可变字段,记录不是固定长度的,这样存储的优点是占用空间较少,但是频繁的更新、删除记录会产生碎片,需要定期执行 OPTIMIZE TABLE 语句或 myisamchk -r 命令来改善性能,并且出现故障的时候恢复相对比较困难。
3、压缩表
压缩表由 myisamchk 工具创建,占据非常小的空间,因为每条记录都是被单独压缩的,所以只有非常小的访问开支。
#查看系统支持的存储引擎
show engines;
#查看表使用的存储引擎
方法一:
show table status from 库名 where name='表名'\G
方法二:
use 库名;
show create table 表名;
#修改存储引擎
1.通过 alter table 修改
use 库名;
alter table 表名 engine=MyISAM;
2.通过修改 /etc/my.cnf 配置文件,指定默认存储引擎并重启服务
vim /etc/my.cnf
......
[mysqld]
......
default-storage-engine=INNODB
systemctl restart mysql.service
#注意:此方法只对修改了配置文件并重启mysql服务后新创建的表有效,已经存在的表不会有变更。
3.通过 create table 创建表时指定存储引擎
use 库名;
create table 表名(字段1 数据类型,...) engine=MyISAM;
InnoDB行锁是通过给索引项加锁来实现的,如果没有索引,InnoDB将通过隐藏的聚簇索引来对记录加锁。
1)
delete from t1 where id=1;
如果id字段是主键,innodb对于主键使用了聚簇索引,会直接锁住整行记录。
2)
delete from t1 where name='aaa';
如果name字段是普通索引,会先锁住索引的两行,接着会锁住相应主键对应的记录。
3)
delete from t1 where age=23;
如果age字段没有索引,会使用全表扫描过滤,这时表上的各个记录都将加上锁。
死锁一般是事务相互等待对方资源,最后形成环路造成的。
create table t1(id int primary key, name char(3), age int);
insert into t1 values(1,'aaa',22);
insert into t1 values(2,'bbb',23);
insert into t1 values(3,'aaa',24);
insert into t1 values(4,'bbb',25);
insert into t1 values(5,'ccc',26);
insert into t1 values(6,'zzz',27);
session 1 session 2
begin; begin;
delete from t1 where id=5;
select * from t1 where id=1 for update;
delete from t1 where id=1; #死锁发生
update t1 set name='abc' where id=5; #死锁发生
1、for update 可以为数据库中的行上一个排它锁。当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新。
2、共享锁:又叫做读锁,当用户要进行数据的读取时,对数据加上共享锁,共享锁可以同时加上多个。
3、排他锁:又叫做写锁,当用户要进行数据的写入时,对数据加上排他锁,排他锁只可以加一个,它和其它的排他锁,共享锁都相斥。