#创建数据库
CRETAE DATABASE Mankind
CREATE DATABASE test
#显示所有数据库
show databases;
#删除test数据库
DROP DATABASE test
Show databases;
#使用数据库
Use Mankind
#创建表
create table user(
id int not null primary key,
name varchar(20) not null unique,
sex varchar(2) not null
);
#显示所有表
show tables;
#查看user表的状况
desc user;
#增加一列
alter table user add column age int;
alter table user add column birthday date;
#指定位置的增加
alter table user add password varchar(50)first;
alter table user drop column password;
alter table user add password varchar(50)after name;
#删除一列
alter table user drop column birthday;
alter table user drop column password;
#插入数据
insert into user values(1,”XiaoMing”,20,”1”);
insert into user values(2,”XiaoKai”,30, “1”);
insert into user values(3,”MM”,16,”0”);
insert into user values(4,”GG”,12,”1”);
#修改主键为自动增长并设置初始值
alter table user modify id intauto_increment;
alter table user auto_increment=5;
#指令列的插入数据
insert into user(id , name ,age,sex)values(null, “Xiao He”,10,”0”);
#查询表
select * from user;
#针对某一列的查询
select name from user;
#使用where进行条件查询
select name , age from user where id=5;
#更新语句
update user set age=18 where id=1;
#删除语句
delete from user where id=5;
#like模糊搜索
select * fromuser where name like ”%Xiao%”;
#排序
select * fromuser order by age asc;(默认升序,可以省略asc)
select * fromuser order by age desc;
#总数
select count(*)as totalcount from user;
#求和
select sum(age)as sumvalue from user;
#平均
select avg(age)as avgvalue from user;
#最大
select name,max(age)as maxAge from user;
#最小
select name , min(age)as minvalue from user;
#and语句
select * fromuser where age>1 and age<20;
#or语句
select * fromuser where id=1 or id>3;
#between 语句
select * fromuser where id between 2 and 5;
# in 语句
select * fromuser where id in (1,3,4);
#limit a,b 显示a后面b条数据 数据的id是从0开始的
select * from userlimit 1,3;
#分组查询
select name,max(age),sex from user group by sex; #按性别分组查年龄最大值
#创建另外一张订单表,标识购买的东西名称及对应的主人
create table goods(
orderid int primarykey not null auto_increment,
goods_namevarchar(20) not null,
goods_number intnot null,
owner_id int notnull
)ENGINE=InnoDB DEFAULT CHARSET=GBK;
#插入对应的订单
insert goodsvalues(null,”可乐”,3,1);
insert goodsvalues(null,”新奇士”,3,3);
insert goodsvalues(null,”啤酒”,3,4);
insert goodsvalues(null,”橙汁”,1,1);
insert goodsvalues(null,”酸奶”,1,1);
#MySQL 连接之inner join(内连接)获取两个表中字段匹配关系的记录。(省略inner也可以)
select a.id,a.name,b.goods_name,b.goods_number FROM user aINNER JOIN goods b ON a.id=b.owner_id;
等价于
select a.id,a.name,b.goods_name,b.goods_number FROM user a,goods b WHERE a.id=b.owner.id;
#MySQL 连接之 leftjoin(左连接)会读取左边数据表的全部数据,即便右边表无对应数据。
select a.id,a.name,b.goods_name,b.goods_number FROM user aLEFT JOIN goods b ON a.id=b.owner_id;
#MySQL 连接之right join(右连接)会读取右边数据表的全部数据,即便左边表无对应数据。
select a.id,a.name,b.goods_name,b.goods_number FROM user aRIGHT JOIN goods b ON a.id=b.owner_id;
NULL值处理
#创建NULL测试表并插入测试数据
create table testnull(
name varchar(20) not null,
age int default null
);
#一次性插入多条数据
insert testnull values(“A”,10),(“B”,NULL),(“C”,NULL),(“D”,20);
#关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值。
select * from testnull where age=NULL;
select * from testnull where age!=NULL;
在MySQL中,NULL值与任何其它值的比较(即使是NULL)永远返回false,即NULL = NULL 返回false 。
MySQL中处理NULL使用IS NULL和IS NOT NULL运算符。
#IS NULL当列的值是NULL,此运算符返回true;
select * fromtestnull WHERE age IS NULL;
#IS NOT NULL,当列的值不是NULL时,此运算符返回true;
select * fromtestnull WHERE age IS NOT NULL;
#<=> 不同于=运算符,当比较的的两个值为NULL时返回true。
select * fromtestnull WHERE age <=> NULL;
MySQL事务
事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。 事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作。
所谓事务,必须满足4个条件(ACID),
Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
1、原子性:一组事务,要么成功;要么撤回。
2、稳定性 :有非法数据(外键约束之类),事务撤回。
3、隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
4、可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit选项 决定什么时候吧事务保存到日志里。
事务隔离级别
SQL标准定义了4种隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。
低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
注意:以下通过2个MySQL窗口来模拟2个事务,需要通过修改隔离级别。并且需要将事务自动提交设置为0(两个窗口都要)set autocommit = 0;
create table transaction(
id int NOT NULL primary key auto_increment,
num int default 0
);
insert transaction values(null,1),(null,2),(null,3);
第1级别:ReadUncommitted(读取未提交内容)
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
#修改隔离级别为Read-Uncommited
set tx_isolation='READ-UNCOMMITTED';
#开启一个事务A
start transaction;
select * from ts;
#开启事务B
start transaction;
update ts set num=10 where id=1;
#在事务A中select * from ts;
#将事务B的结果rollback;
#在事务A中select * from ts;
可以看到,在事务B中发生的任何变化,在事务A中都可以实时看到,也就是说,事务A得到的数据有可能事务B 还未提交的数据,这样的数据被称为脏数据,这样的情况被称为脏读。
第2级别:ReadCommitted(读取提交内容)
(1)这是大多数数据库系统的默认隔离级别(但不是MySQL默认的) (2)它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变 (3)这种隔离级别出现的问题是——不可重复读(Nonrepeatable Read):不可重复读意味着我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果。
#修改隔离级别为read-committed
set tx_isolation='read-committed';
set autocommit = 0;
#事务A跟事务B启动一个事务
#事务A查询
#事务B修改数据但并不提交
#事务A查询不到改变
#事务B提交事务
#事务A查询到改变
这种隔离等级下,两个交叉的事务A和B,A并不能实时看到B中改变的数据,只有当B提交了数据之后,A才能看到改变的数据,防止了脏读,但这又造成一种情况就是,从事务A的角度来看,同一个事务中执行完全相同的语句有可能得到不一样的结果,即不可重复读(Nonrepeatable Read)。
第3级别:RepeatableRead(可重读)
(1)这是MySQL的默认事务隔离级别 (2)它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行 (3)此级别可能出现的问题——幻读(Phantom Read):当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影”行 (4)InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题
#修改隔离级别为repeatable-read set tx_isolation='repeatable-read';
#开启事务A和事务B
#事务B进行数据修改并提交
#事务A中进行数据查询
#事务A提交后再次查询
由此我们可以知道,第三隔离级别解决了不可重复读问题,保证了事务A在整个过程中同样的操作不会有第二种情况出现。然而又产生了新的问题,假设事务B对数据进行了删除,那么事务A此时还是能够看到那些被删除的数据,就像产生了幻觉一样,这种情况被称为幻读。一般解决幻读的方法是增加范围锁RangeS,锁定检索范围为只读,这样就避免了幻读。
第4级别:Serializable(可串行化) (1)这是最高的隔离级别 (2)它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。 (3)在这个级别,可能导致大量的超时现象和锁竞争
#修改隔离级别为serializable
set tx_isolation='serializable';
#开始事务A
#开始事务B并修改数据
#在事务A中对数据进行修改和访问
#提交事务B
#事务A可以进行查询
也就是说当隔离级别最高时,事务开始后如果对某个表进行了修改,那么其他事务不可以对这个表进行各种各样的操作。
在事务A,事务B开启后,事务B 先对ts表进行数据修改和访问,而事务A则不可以,它必须等事务B提交后才可以执行。这种情况下没有所谓的幻读现象了,然而可能导致大量的超时现象和锁竞争。
MySQL索引
索引的存在,是为了解决以下这种情况,首先假设有一张表有100W条数据,我们需要在这之中寻找一条name=‘XiaoMing’的数据,正常的select * from table where name=’XiaoMing’需要扫描100W个数据来查找这个数据,如果我再name=‘XiaoMing’的数据上建立了索引,那么我们可以以O(1)的效率直接找到这个数据。我们可以把所以想象成数据结构学过的哈希查找。
mysql的索引分为单列索引(主键索引,唯索引,普通索引)和组合索引.
单列索引:一个索引只包含一个列,一个表可以有多个单列索引.
组合索引:一个组合索引包含两个或两个以上的列,
首先我们创建一张表
CREATE TABLE people(
idint NOT NULL AUTO_INCREMENT,
accountvarchar(20) NOT NULL DEFAULT ‘’,
passwordvarchar(50) NOT NULL DEFAULT ‘’
);ENGINE=InnoDB AUTO_INCREMENT=1
#创建单列索引
① create INDEX id_Index ON people(id);
② ALTER TABLE people ADD INDEXid_Index(id);
#创建唯一索引
唯一索引要求所有的类的值是唯一的,这一点和主键索引一样.但是他允许有空值,
create UNIQUE INDEX id_unique_index ONpeople(id);
#创建主键索引。主键索引,不允许有空值
主键索引建立的规则是 int优于varchar,一般在建表的时候创建,最好是与表的其他字段不相关的列或者是业务不相关的列.一般会设为 int 而且是 AUTO_INCREMENT自增类型的
create table a(
id int primary key auto_increment,
name varchar(20) not null default ''
);//这里id就是表的主键
#组合索引
一个组合索引包含两个或两个以上的列,
create INDEX id_account_index ON people(id,account);
它实际上包含的是2个索引(id)和(id,account)
在匹配的时候遵循最左前缀规则,简单来说,就是在使用where语句查询的时候,要按照索引中字段的顺序来,即where id=1 或者where id=1 and account=‘Mankind’ 之类的,就会使用到上面的索引,如果是where account=‘Mankind’。并且不能有范围查询,像like“
