# 创建、删除、修改、查看数据库
#1.创建数据库
create database xin;
create database if not exists xin; # 没有则创建数据库
create database if not exists xin charset = 'utf8'; #设置字符集utf8
create database if not exists xin character set utf8 collate utf8_general_ci;#设置字符集utf8 并核对
#2.查看
show databases; #查看所有数据库
show create database xin; #查看某个数据库定义时的信息
#3.修改数据库
alter database xin default character set utf8;#修改字符集
#4.删除数据库
drop database xin;
#5.切换数据库
use xin;
#6.查看正在使用的数据库
select database();
#创建、删除、修改、查看表
#1. 创建表
create table student
(
id int,
name varchar(8),
age int(3),
score double(5, 2)
);
create table student2 like student;#快速创建一个表结构相同的表
#2. 删除表
drop table student2;
drop table if exists student2;
#3. 查看表
desc student; #查看表结构
show create table student; #查看创建表时的sql
show tables; #查看某个库中所有的表
#4. 修改表结构
alter table student add gender char(1); # 添加一个字符
alter table student modify id int(8); # 修改某个字段的类型
alter table student change name username varchar(8);# 修改某个字段的名字、类型
alter table student character set utf8; #修改表的字符集
alter table student rename name; # == rename table student to t_student; #重命名表名
insert into student(id, name, age ) value (1,'张三','18');
insert into student(id, name, age, score) value (2,'李四','18',145.50);
insert into student(id, name, age, score) values (3,'王五','18',99.50),(4,'赵六','25',80);
insert into student value (5,'李七','30',101.11);
create table man_stuent like student;
insert into man_stuent select * from student where gender = '男';
update student set id = 2 where score is null;
update student set age =26,score=97.1 where id = 2;
#3. delete 数据
delete from student where id = 2;
delete from student where age = 18 and score > 100;
delete from student where age between 17 and 20;
delete from student; #全删,逐条删除
truncate table student; #全删,drop表,新建一个结构一样的新表
# * 全查,效率慢
-- 1.性能损失 * 需要有mysql程序解析
-- 2.性能损失 * 代表所有字段 不管需要还是不需要都会查询
select * from student;
# 所有字段全查,推荐
select id, name, age , score from student;
# 查询,显示时给与别名
select id ID, name 姓名, age 年龄, score 分数 from student;
# 查询 去除重复数据,一般都是查单列时使用
select distinct age from student;
select distinct name,age from student; #两个字段都一样才算重复
# 字段可以参与运算
select age + 1 from student;#所有人年龄加一
# case when ... then when ...then else... end
select ename,
sal,
case
when sal >= 3000 then '三级'
when sal > 2000 then '2级'
else '1级'
end
from emp;
select * from t_student where age>35 and gender='男';
select * from t_student where age>35 or gender='男';
select * from t_student where english between 75 and 90;
select id ,ifnull(salary,'没有工资') from t_student;
# id 在(1,2,3)之中的, 等价于 id = 1 or id = 2 or id =3
select * from student where id in (1, 2, 3);
# id 不在(1,2,3)之中的, 等价于 id != 1 and id != 2 and id =3
select * from student where id not in (1, 2, 3);
# %多个占位符
select * from student where name like '%三';
# _单个占位符
select * from student where name like '_三';
-- 聚合函数 select 聚合函数名(列表) from xx表 ....
-- count 数数
-- max 最大值
-- min 最小值
-- sum 求和
-- avg 求平均值
-- 查询所有学生的总数
-- select count(*) from xx表
-- 查询个数 鼓励 select count(*) mysql底层专门做了优化
select count(*) from t_student;
select gender,round(avg(score),2) from student group by gender;
select gender,max(age),avg(score) from student group by gender;
select age,name from student group by age having age = 18;
select * from student having age > 18;
select * from student group by age having age >20;
# order by 字段 asc . 升序
# order by 字段 desc . 降序
# order by 字段1,字段2 . 在字段1升序排的基础上按字段2降序排
select * from student order by age ;
select * from student order by age desc ;
select * from student order by age desc,score desc;
select * from student limit 0,10; 起始索引,查询条目数
计算公式:起始索引=(当前页码-1)* 每页条数
select empno from emp
where sal >= all(select sal from emp); sal 大于等于 all()最大值
select empno from emp
where sal >= any(select sal from emp); sal >= any()最小值
MySQL中ALL 和 ANY的用法
# 创建新用户 CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
create user 'zhx'@'localhost' identified by '123456';#
create user 'zhx'@'%' identified by '123456'; # 任意远程主机登陆,可以使用通配符%
# 授权 GRANT 权限1, 权限2... ON 数据库名.表名 TO '用户名'@'主机名';
# grant xx权限(create、drop、alter、insert、update、delete、select...) on 库.表 to 哪个用户
grant select,delete on *.* to 'zhx'@'localhost'; # 给zhx用户授予对所有库所有表的全部权限。
# 移除权限
revoke delete on *.* from 'zhx'@'localhost';
# 删除用户
drop user 'zhx'@'localhost';
# 修改管理员密码
# 要在未登陆MySQL的情况下操作。新密码不需要加上引号
# mysqladmin -u root -p password 新密码
# 修改普通用户密码
set password for '用户名'@'主机名' = password('新密码');
select * from user;
PRIMARY KEY
: 主键约束 (B+ 二分查找树 ,查询快)UNIQUE
: 唯一约束NOT NULL
: 非空约束DEFAULT
: 默认值 了解FOREIGN KEY
: 外键约束PRIMARY KEY
# 1. 在创建表的时候给字段添加主键
字段名 字段类型 PRIMARY KEY
# 2. 在已有表中添加主键(了解)
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);
字段名 字段类型 PRIMARY KEY AUTO_INCREMENT
AUTO_INCREMENT
表示自动增长(字段类型必须是整数类型)
# DELETE和TRUNCATE的区别
- DELETE 删除表中的数据,但不重置AUTO_INCREMENT的值。
- TRUNCATE 摧毁表,重建表,AUTO_INCREMENT重置为1
# insert 失败 主键也会加一
字段名 字段类型 UNIQUE
字段名 字段类型 NOT NULL
字段名 字段类型 DEFAULT 默认值
说明:如果两张表是多对多的关系,需要创建第三张表,并在第三张表中增加两列,引入其他两张表的主键作为自己的外键。
foreign key( 当前表中的列名 ) references 被引用表名(被引用表的列名);
foreign key( coder_id ) references coder(id);
constraint [外键约束名称] foreign key(当前表中的列名) references 被引用表名(被引用表的列名)
举例:constraint coder_project_id foreign key(coder_id) references coder(id);
关键字解释:
constraint: 添加约束,可以不写
foreign key(当前表中的列名): 将某个字段作为外键
references 被引用表名(被引用表的列名) : 外键引用主表的主键
外键的级联
在修改和删除主表的主键时,同时更新或删除从表的外键值,称为级联操作
ON UPDATE CASCADE
– 级联更新,主键发生更新时,外键也会更新
ON DELETE CASCADE
– 级联删除,主键发生删除时,外键也会删除
-- 添加外键约束,并且添加级联更新和级联删除
constraint c_id_fk foreign key(coder_id) references coder(id) ON UPDATE CASCADE ON DELETE CASCADE,
);
级联更新:ON UPDATE CASCADE 主键修改后,外键也会跟着修改
级联删除:ON DELETE CASCADE 主键删除后,外键对应的数据也会删除
#备份数据,将数据的表、数据,转成sql保存
mysqldump --no-defaults -u root -p 要备份的数据库名 > 硬盘SQL文件绝对路径
mysqldump --no-defaults -u root -p webdb2 > d:\aa.sql
#恢复数据,其实就是执行sql语句
恢复数据库语法:mysql -u 用户名 -p 导入库名 < 硬盘SQL文件绝对路径
mysql -u root -p webdb2 < d:\aa.sql
# 内连接
# 隐式内连接
select * from student a,teacher b where a.id = b.id;
# 显式内连接
select * from student a inner join teacher b on a.id = b.id;
select * from student a join teacher b on a.id = b.id;
# 外连接
# 左外连接 左边的是主表
select * from student a left join teacher b on a.id = b.id;
select * from student a left outer join teacher b on a.id = b.id;
# 右外连接 右边的是主表
select * from student a right outer join teacher b on a.id = b.id;
# select 嵌套
select * from student where age >(select avg(age) from student);
外键=主键
)事务的操作 | MySQL操作事务的语句 |
---|---|
手动开启事务 | start transaction |
手动提交事务 | commit |
手动回滚事务 | rollback |
设置回滚点 | savepoint 名字 |
回到回滚点 | rollback to 名字 |
查询事务的自动提交情况 | show variables like ‘%commit%’; |
设置事务的手动提交方式 | set autocommit = 0 – 关闭自动提交 |
# commit
start transaction #开启事务
update emp set salary = salary + 500 where id = 1001 and ename = '迪丽热巴';
update emp set salary = salary - 500 where id = 1002 and ename = '杨幂';
...
commit;# 多条sql都执行成功,commit
# rollback
start transaction #开启事务
update emp set salary = salary + 500 where id = 1001 and ename = '迪丽热巴';
update emp set salary = salary - 500 where id = 1002 and ename = '杨幂';
...
rollback;# 有一条sql执行失败就必须rollback回滚,撤销已经成功执行的sql语句,回到开启事务之前的状态.
# 注意:只要提交事务,那么数据就会长久保存了,就不能回滚事务了。即提交或者回滚事务都是代表结束当前事务的操作。
# 使用回滚点
start transaction;
update emp set salary = salary + 1000 where id = 1002;
update emp set salary = salary - 1000 where id = 1003;
savepoint a;
update emp set salary = salary + 2000 where id = 1004;
update emp set salary = salary - 2000 where id = 1005;
rollback to a; //回滚到a
commit ;
package transaction_demo;
import mysql_use.DruidUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Demo01 {
public static void main(String[] args) throws SQLException {
//工具类获取连接
Connection connection = DruidUtil.getConnection();
try {
connection.setAutoCommit(false);//开启事务
addMoney(connection, 500, 1002); //给1002转入500
subMoney(connection, 500, 1003); // 1003转出500
connection.commit(); //都成功则提交
} catch (Exception e) {
connection.rollback();//异常则回滚,保证原子性,一致性
e.printStackTrace();
} finally {
connection.close();
}
}
public static void addMoney(Connection connection, Object... args) throws SQLException {
connection = DruidUtil.getConnection();
String sql = "update emp set salary = salary + ? where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i + 1, args[i]);
}
preparedStatement.executeUpdate();
preparedStatement.close();
}
public static void subMoney(Connection connection, Object... args) throws SQLException {
connection = DruidUtil.getConnection();
String sql = "update emp set salary = salary - ? where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i + 1, args[i]);
}
preparedStatement.executeUpdate();
preparedStatement.close();
}
}
并发访问的问题 | 含义 |
---|---|
脏读 | 一个事务读取到了另一个事务中尚未提交的数据。最严重,杜绝发生。 |
不可重复读 | 一个事务中两次读取的数据内容不一致,这是事务update时引发的问题 |
幻读(虚读) | 一个事务内读取到了别的事务插入或者删除的数据,导致前后读取记录行数不同。这是insert或delete时引发的问题 |
级别 | 名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 |
---|---|---|---|---|---|---|
1 | 读未提交 | read uncommitted | 是 | 是 | 是 | |
2 | 读已提交 | read committed | 否 | 是 | 是 | Oracle和SQL Server |
3 | 可重复读 | repeatable read | 否 | 否 | 是 | MySQL |
4 | 串行化 | serializable | 否 | 否 | 否 |
2、安全和性能对比
安全性:serializable > repeatable read > read committed > read uncommitted
性能 : serializable < repeatable read < read committed < read uncommitted
3、注意:其实三个问题,开发中最严重的问题就是脏读,这个问题一定要避免,而关于不可重复读和虚读其实只是感官上的错误,并不是逻辑上的错误。就是数据的时效性,所以这种问题并不属于很严重的错误。如果对于数据的时效性要求不是很高的情况下,我们是可以接受不可重复读和虚读的情况发生的。
MySQL 存储过程
# 准备数据,使用存储过程插入10000000条数据
create database itcast01;
use itcast01;
-- 1. 准备表
CREATE TABLE user(
id INT,
username VARCHAR(32),
password VARCHAR(32),
sex VARCHAR(6),
email VARCHAR(50)
);
-- 2. 创建存储过程,实现批量插入记录
DELIMITER $$ -- 声明存储过程的结束符号为$$
-- 可以将下面的存储过程理解为java中的一个方法
CREATE PROCEDURE auto_insert()
BEGIN
DECLARE i INT DEFAULT 1;
START TRANSACTION; -- 开启事务
WHILE(i<=10000000)DO
INSERT INTO user VALUES(i,CONCAT('jack',i),MD5(i),'male',CONCAT('jack',i,'@itcast.cn'));
SET i=i+1;
END WHILE;
COMMIT; -- 提交
END$$ -- 声明结束
DELIMITER ; -- 重新声明分号为结束符号
-- 3. 查看存储过程
SHOW CREATE PROCEDURE auto_insert;
-- 4. 调用存储过程,插入千万条数据
CALL auto_insert();
-- 创建普通索引
create index 索引名 on 表名(字段);
-- 创建唯一索引
create unique index 索引名 on 表名(字段);
-- 创建普通组合索引
create index 索引名 on 表名(字段1,字段2,..);
-- 创建唯一组合索引
create unique index 索引名 on 表名(字段1,字段2,..);
# 显示索引
show index from 表名;
# 删除索引
drop index 索引名 on 表名;
# 修改表时删除
alter table 表名 drop index 索引名;
MySQL |菜鸟教程
B站黑马程序员
MySQL中ALL 和 ANY的用法
如何理解事务一致性?
百度百科