MySql入门必备
一、DDL操作
1、库操作
1)创建库
create database [数据库名称];
2)使用库
use [数据库名称];
3)删除库
drop database [数据库名称];
4)查看数据库
show databases;
2、表操作
1)创建表
#方式一:
CREATE TABLE [表名](
[字段名] [字段数据类型],
[字段名] [字段数据类型]
);
#方式二:
CREATE TABLE [表名] AS SELECT [任意字段名] FROM [其他表名];
2)更改表
#修改字段的类型
ALTER TABLE [表名] MODIFY COLUMN [字段名] [字段数据类型];
#修改字段的名称
ALTER TABLE [表名] CHANGE COLUMN [字段名] [更改后的字段名] [字段数据类型];
#修改表名
ALTER TABLE [表名] RENAME TO [更改后的表名];
3)删除表及字段
#删除表
DROP TABLE [表名];
#删除字段
ALTER TABLE [表名] DROP COLUMN [字段名];
4)添加字段
#添加字段
ALTER TABLE [表名] ADD COLUMN [字段名] [字段数据类型];
二、DML操作
1、表操作
1)新增数据
#向表中插入数据
#格式: insert into 表名(字段名1,字段名2.....) values(值1,值2.......)
#注意:values中的数据位置一定会字段对应
INSERT INTO person(id,pname,score,info) VALUES(1,"ruige",10.5,"ruigewoaini");
#对上面的操作简化-只有对全字段插入数据时才能使用下面的写法
INSERT INTO person VALUES(2,'haoge',12.3,'haogehaogezuixxx');
#一次插入多条数据
#value和values都可以在插入多条数据时value和values要快一点
INSERT INTO person(id,pname,score,info)
VALUES(1,"aa",10.5,"ruigewoaini"),
(1,"bb",10.5,"ruigewoaini"),(1,"cc",10.5,"ruigewoaini");
#基于现有数据插入到当前表中 - 注意:字段的类型
INSERT INTO person(id,pname)
SELECT employee_id,first_name
FROM myemployees.`employees`;
2)删除表数据
#删除数据
#格式: delete from 表名 [where 过滤条件]
DELETE FROM person WHERE id < 5;
DELETE FROM person WHERE pname='longge';
#下面的写法会将表中所有的数据全部删除
DELETE FROM person;
#TRUNCATE TABLE 表名:删除表中所有的内容
TRUNCATE TABLE person;
/*
DELETE FROM person和TRUNCATE TABLE person的区别?
1.如果要清空表中的内容那么TRUNCATE比delete效率高
2.TRUNCATE清空掉的数据不能回滚,delete删除掉的数据是可以回滚(撤销)的。
*/
3)更改表数据
#修改数据
#格式:update 表名 set 字段名1=值1,字段名2=值2 [where 过滤条件]
UPDATE person SET pname='longge' WHERE id=100;
UPDATE person SET pname='cangjie',score=100 WHERE id=100
#下面的写法会将表中所有的该字段的内容全部进行修改
UPDATE person SET pname='longge';
4)查询表数据
1.过滤
#过滤:
select [字段名]
from [表名]
where [过滤条件]
#注意:
1.where在form的后面。
2.模糊查询
select [字段名]
from [表名]
where [字段名] like '_[任意字段]%'
#[%]:任意数量的任意字符,“匹配所有”
#[_]:一个任意字符,“占一个位置”
3.排序
select [字段名]
from [表名]
where [过滤条件]
order by [字段名] [desc/asc]
#desc:倒叙
#asc:正序,“默认正序,可省略不写”
4.多表查询
1.左连接与右连接
select [任意字段]
from [表A] A
left [outer] join [表B] B on A.x=B.y ;
#通过x,y关联字段连接
#显示左表全部内容,右表不匹配的值不显示
2.全连接的实现
#mysql不支持全连接
#通过左连接union右连接获得全连接的效果
select [任意字段]
from [表A] A
left [outer] join [表B] B on A.x=B.y
union
select [任意字段]
from [表A] A
right [outer] join [表B] B on A.x=B.y ;
#union 获取去重的结果
#union all 获取不去重的结果
#使用union时SELECT语句必须拥有相同数量的列,列也必须拥有相似的数据类型,列的顺序必须相同。
5.单行函数
/*
大小写控制函数:
lower : 将所有字符变为小写
upper : 将所有字符变为大写
*/
SELECT LOWER([字符串]);
SELECT UPPER([字符串]);
/*
字符控制函数
CONCAT('Hello', 'World') : 字符串拼接
SUBSTR('HelloWorld',1,5) : 截取子串。
1指的是从字符串的哪个索引开始(默认是从1开始的)
5指的是长度。
LENGTH('HelloWorld') : 获取字符串长度
INSTR('HelloWorld', 'W') : 获取w在字符串中的位置(从前向后)
LPAD(salary,10,'*') : 右对齐
10:指的是设置的字符串的长度。
*:指的是如果字符串长度不够10用*补
RPAD(salary, 10, '*') :左对齐
10:指的是设置的字符串的长度。
*:指的是如果字符串长度不够10用*补
TRIM('H' FROM 'HelloWorld') : 去除字符串两端指定的字符
REPLACE('abcd','b','m') :替换字符串中的某个字符
*/
/*
数字函数
ROUND: 四舍五入
ROUND(45.926, 2) 45.93
TRUNCATE: 截断
TRUNCATE(45.926) 45
MOD: 求余
MOD(1600, 300) 100
*/
/*
日期函数 : now()
*/
/*
通用函数:
ifnull(字段,具体的值) : 如果该字符的内容为null就用具体的值来替代。
*/
/*
if(比较运算,数值1,数值2) : 如果比较运算的结果为true返回数值1否则返回数值2
*/
/*
case表达式:
格式:
1.等值
case 字段
when 值 then 返回的值
when 值 then 返回的值
......
else
返回的值
end; #表示结束
2.非等值
case
when 条件表达式1 then 返回的值
when 条件表达式2 then 返回的值
......
else
返回的值
end; #表示结束
*/
6.分组函数
/*
分组函数:
AVG()
SUM()
MAX()
MIN()
COUNT()
*/
/*
AVG() 和 SUM()只能操作数值型的数据
注意 :avg在做运算时不包括字段为null的那个数据。
*/
/*
MAX() 和 MIN() 对任意类型进行运算
*/
/*
COUNT() : 求数据的个数
count(字段名) : 求的是数据不为null的个数、
count(*) : 求表中数据的个数(某个字段为null没有影响)。
count(数值) : count(数值)和count(*)效果是一样的。
count(数值)比count(*)效率高一些。
*/
/*
注意:以下错误写法
原因 :因为平均薪水没有对应的姓名和employee_id。
(不要理解成和平均薪水一样薪水的那个人的信息)
如何避免 :在select后面如果出现了组函数那么就不能再写其它的字段。
除非该字段出现在group by的后面
*/
7.分组和过滤
/*
分组 : group by
格式:
select ....
from 表名
where 过滤条件
group by 字段名1,字段名2......
*/
/*
过虑 : having
格式:
select ..
from 表名
where 过滤条件
group by 字段名1,字段名2
having 过滤条件
总结:where和having的区别是什么?
where用在from的后面,过滤条件不能出现组函数
having用在group by的后面,过滤条件可以出现组函数
*/
8.子查询
/*
子查询 :在a查询语句中嵌套一个b查询。
那么b查询叫作子查询(内查询),a叫作主查询(外查询)。
说明:
1.先执行子查询再执行主查询
2.子查询分为:单行子查询 vs 多行子查询
单行和多行指的是子查询返回的结果的条数
3.单行子查询可以使用的运算符 : > >= < <= !=
4.多行子查询使用的运算符 : in any all
*/
5)查看表结构
desc [表名]
三、约束
1.约束分类
NOTNULL #非空约束,规定某个字段不能为空
UNIQUE #唯一约束,规定某个字段在整个表中是唯一的
PRIMARYKEY #主键(非空且唯一)
FOREIGNKEY #外键
CHECK #检查约束
DEFAULT #默认值
四、分页
SELECT * FROM [表名] LIMIT([当前页数] - 1)*[每页条数],[每页条数];
五、事务的四大特性(ACID)
4.1、原子性(Atomicity)
指事务中的操作要么全部成功,要么全部失败,如一段SQL语句提交之前,要么正确提交,要么提交失败,数据回滚。
4.2、一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态,如一个银行账户,不管如何操作,其
(转出额度+余额)永远不变
4.3、隔离性(Isolation)
多个用户并发访问数据库时,数据库为每一个用户开启一个新的事务,事务间相互隔离,不相互影响
4.4、持久性(Durability)
一个事务一旦被提交,它对数据的改变是永久性的
五、事务的隔离级别
多个线程开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。
5.1、事务不考虑隔离性可能会引发的问题
如果事务不考虑隔离性,可能会引发如下问题:
1、脏读
脏读指一个事务读取了另外一个事务未提交的数据。
这是非常危险的,假设A向B转帐100元,对应sql语句如下所示
1.update account set money=money+100 where name=‘B’;
2.update account set money=money-100 where name=‘A’;
当第1条sql执行完,第2条还没执行(A未提交时),如果此时B查询自己的帐户,就会发现自己多了100元钱。如果A等B走后再回滚,B就会损失100元。
2、不可重复读
不可重复读指在一个事务内读取表中的某一行数据,多次读取结果不同。
例如银行想查询A帐户余额,第一次查询A帐户为200元,此时A向帐户内存了100元并提交了,银行接着又进行了一次查询,此时A帐户为300元了。银行两次查询不一致,可能就会很困惑,不知道哪次查询是准的。
不可重复读****和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。
很多人认为这种情况就对了,无须困惑,当然是后面的为准。我们可以考虑这样一种情况,比如银行程序需要将查询结果分别输出到电脑屏幕和写到文件中,结果在一个事务中针对输出的目的地,进行的两次查询不一致,导致文件和屏幕中的结果不一致,银行工作人员就不知道以哪个为准了。
3、虚读(幻读)
虚读(幻读)是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
如丙存款100元未提交,这时银行做报表统计account表中所有用户的总额为500元,然后丙提交了,这时银行再统计发现帐户为600元了,造成虚读同样会使银行不知所措,到底以哪个为准。
5.2、事务隔离性的设置语句
MySQL数据库共定义了四种隔离级别:
- Serializable(串行化):可避免脏读、不可重复读、虚读情况的发生。
- Repeatable read(可重复读):可避免脏读、不可重复读情况的发生。
- Read committed(读已提交):可避免脏读情况发生。
- Read uncommitted(读未提交):最低级别,以上情况均无法保证。
mysql数据库查询当前事务隔离级别:select @@tx_isolation
例如:
mysql数据库默认的事务隔离级别是:Repeatable read(可重复读)
mysql数据库设置事务隔离级别:set transaction isolation level 隔离级别名