MySql的主要存储引擎有哪些,主要区别?
MYISAM INNODE MEMORY
区别:
MYISAM: 它不支持事务,也不支持外键
INNODE: InnoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全.但是对比MyISAM的存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引
MEMORY: 使用存在内存中的内容来创建表
sql功能分类
DDL: 数据定义语言 用来定义数据库对象:创建库、表、列等
DML: 数据操作语言 用来操作数据表中的记录
DQL: 数据查询语言 用来查询数据
DCL: 数据控制语言 用来定义访问权限和安全级别
Mysql数据类型分三类
1.数值
2.字符串
3.时间日期
常见的数据类型:
1.double浮点型
2.char固定长度字符串
3.varchar可变长字符串类型
4.text长字符串
5.blob二进制类型
6.date日期类型格式为:yyyy-MM-dd
7.time时间类型格式为:hh:mm:ss
DDL(数据定义语言)
1.创建数据库
create database 数据库名 charset=utf8;
2.使用(切换)数据库
use 数据库名;
3.添加一列
ALTER TABLE 表名 ADD 列名 数据类型;
4.删除一列
ALTER TABLE 表名 DROP 列名;
5.删除表
DROP TABLE 表名
7.修改表的字段类型
ALTER TABLE 表名 MODIFY 字段名 数据类型;
8.修改表的列名
ALTER TABLE 表名 CHANGE 列名 新列名 数据类型
9.修改表名
RENAME TABLE 原始表名 TO 要修改的表名;
10.修改表的字符集gbk
ALTER TABLE 表名 charset gbk;
11.查看表的字段信息
desc 表名;
12.查看表的创建细节
SHOW CREATE TABLE 表名;
数据库操作语言DML
查询表中的所有数据
SELECT * FROM 表名;
查询指定的列
SELECT 列名1,列名2 FROM 表名;
插入数据
INSET INTO 表名(列名1,列名2)VALUES(列值1,列值2);
插入多条
INSERT INTO 表名(列名1,列名2....) VALUES(列值1,列值2),(列值1,列值2)....;
更新操作
UPDATE 表名 SET 列名1=列值1, 列名2=列值2... WHERE 列名=值;
修改数据库密码
mysqladmin -u root -p password 123456
删除制定某一条数据
DELETE FROM 表名 WHERE name='zwz';
删除所有数据
TRUNCATE TABLE 表名;
DELETE 与 TRUNCATE的区别:
DELETE可以删除指定数据也能删除所有数据 TRUNCATE只能删除所有数据
DELETE删除表中的数据,表结构还在;删除后数据还可以找回
TRUNCATE删除是把表直接DROP掉,然后再创建一个同样的新表.删除的数据不能找回.执行速度比DELETE快
条件查询
条件查询就是在查询时给出WHERE子句,在WHERE子句中可以使用一些运算符以及关键字
BETWEEN...AND; 值在什么范围
IN(set);
IS NULL; (为空)
IS NOT NULL; (不为空)
AND; 与
OR; 或
NOT; 非
举例:
查询性别为男,并且年龄为20的学生记录
SELECT * FROM students WHERE gender='男' AND age=20;
查询学号为1001 或者 名为 zs 的记录
SELECT * FROM students WHERE id=1001 OR name='zs';
查询学号为1001 , 1002 ,1003的记录
SELECT * FROM students WHERE id IN(1001,1002,1003) ;
查询年龄为null的记录
SELECT * FROM students WHERE age IS NULL;
查询年龄在18-20之间的学生记录
SELECT * FROM students WHERE age>= 18 AND age<=20;
SELECT * FROM students WHERE age BETWEEN 18 AND 20;
查询性别非男的学生记录
SELECT * FROM students WHERE gender != '男';
查询姓名不为null的学生记录
SELECT * FROM students WHERE name IS NOT NULL;
模糊查询
根据指定的关键字进行查询
使用LIKE关键字后跟通配符
通配符
_:任意一个字母
%:任意0~n个字母
- 查询姓名由5个字母构成的学生记录
可以事先自己添加好各种数据
5个字母就是5个下划线
SELECT * FROM students WHERE name LIKE '_____';
- 查询姓名由5个字母构成,并且第5个字母为's'的学生记录
SELECT * FROM students WHERE name LIKE '____s';
- 查询姓名以'm'开头的学生记录
SELECT * FROM students WHERE name LIKE 'm%';
- 查询姓名中第二个字母为'u'的学生记录
SELECT * FROM students WHERE name LIKE '_u%';
- 查询姓名中包含's'字母的学生记录
SELECT * FROM students WHERE name LIKE '%s%';
正则表达式匹配查询
基本语法:
字段名 REGEXP '匹配方式'
^ 匹配以特定字符或者字符串开头的记录
$ 匹配以特定字符或字符串结尾的记录
. 匹配任意字符串中任意一个字符,包括回车和换行符
[字符集合] 匹配'字符集合'中任意一个字符
[^字符集合] 匹配除'字符集合'以外任意一个字符
S1|S2|S3 匹配S1、S2、S3中的任意一个字符串
* 匹配多个该符号之前的字符,包括0个或者1个
+ 匹配多个该符号之前的字符,包括1个(至少有1个)
字符串{N} 匹配字符串出现N次
字符串{M,N} 匹配字符串出现至少M次,最多N次
- 匹配指定字符中的任意一个
select * from students where name regexp '[zsl]';
- 匹配以指定的字符开头和结束的字符
正则表达式中,^表示字符串的开始位置,$表示字符串的结束位置。
select address from students where name regexp '^l..i$';
字段控制查询
去除重复记录
查询所有学生name信息,去除重复信息
SELECT DISTINCT name FROM students;
把查询字段的结果进行运算,必须都要是数值型
SELECT *,字段1+字段2 FROM 表名;
排序
- 关键字 ORDER BY
- 排序类型(默认是ASC))
升序ASC 从小到大
降序DESC 从大到小
查找工作表按工资从大到小,id从小到大
SELECT * FROM employee ORDER BY salary DESC,id ASC;
聚合函数
- 对查询的结果进行统计计算
- 常用聚合函数
COUNT():统计指定列不为NULL的记录行数;
MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算
SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;
- COUNT 使用
查询employee表中记录数:
SELECT COUNT(*) FROM employee;
查询员工表中月薪大于2500的人数:
SELECT COUNT(*) FROM employee WHERE salary > 2500;
统计月薪与绩效之和大于5000元的人数:
SELECT COUNT(*) FROM employee WHERE IFNULL(salary,0)+IFNULL(performance,0)>5000;
查询有绩效的人数,和有管理费的人数:
SELECT COUNT(performance),COUNT(manage) FROM employee;
- SUM 使用
查询所有雇员月薪和
SELECT SUM(salary) FROM employee;
查询所有雇员月薪和,以及所有雇员绩效和
SELECT SUM(salary),SUM(performance) FROM employee;
查询所有雇员月薪+绩效和
SELECT SUM(salary+IFNULL(performance,0)) FROM employee;
- AVG
统计所有员工平均工资
SELECT AVG(salary) FROM employee;
- MAX和MIN
查询最高工资和最低工资
SELECT MAX(salary),MIN(salary) FROM employe
分组查询 GROUP BY
- 按性别分组查询
SELECT gender FROM employee GROUP BY gender;
- GROUP_CONCAT(字段名)可以作为一个输出字段来使用
表示分组之后,根据分组结果,使用group_concat()来 放置每一组的某字段的值的集合
SELECT gender,GROUP_CONCAT(name) FROM employee GROUP BY gender;
- GROUP BY +聚合函数
查看部门平均薪资
SELECT department,GROUP_CONCAT(salary),SUM(salary) FROM employee GROUP BY department;
查看每个部门的最高薪资
SELECT department,GROUP_CONCAT(salary),MAX(salary) FROM employee GROUP BY department;
查询每个部门的部门名称和每个部门的人数
SELECT department,GROUP_CONCAT(name),COUNT(*) FROM employee GROUP BY department;
查询每个部门的部门名称以及每个部门工资大于1500的人数
SELECT department,GROUP_CONCAT(salary),COUNT(*) FROM employee WHERE salary>1500 GROUP BY department;
- GROUP BY + having
用分组查询后指定一些条件来输出查询结果
having作用和where一样,但是having只能用于GROUP BY
筛选出工资大于9000的同事,部门,总和
SELECT department,GROUP_CONCAT(salary),SUM(salary)
FROM employee
GROUP BY department
HAVING SUM(salary)>9000;
HAVING和WHERE的区别
HAVING是在分组后对数据进行过滤;
WHERE是在分组前对数据进行过滤;
HAVING后面可以使用分组函数(统计函数);
WHERE后面不可以使用分组函数;
WHERE是对分组前记录的条件,如果某行记录没有满足where子语句的条件,那么这行记录不参与分组;而HAVING是对分组后的数据约束
工资总和
SELECT department,GROUP_CONCAT(salary),SUM(salary)
FROM employee
WHERE salary > 2000
GROUP BY department
HAVING SUM(salary)>9000;
ORDER BY SUM(salary) DESC;
书写顺序
SELECT --> FROM --> WHERE --> GROUP BY --> HAVING --> ORDER BY --> LIMIT执行顺序
FROM => WHERE => GROUP BY => HAVING => SELECT => ORDER BY => LIMIT
分页 LIMIT
- 从哪一行开始查,总共要查几行
- LIMIT 参数1, 参数2
参数1:从哪一行开始查
参数2:一共要查几行 - 角标是从0开始
- 格式
SELECT * FROM 表名 LIMIT 0,5; - 分页思路
curPage = 1 # 当前页
pageSize = 3 # 每页显示多少条
当前页为1 第一页从0开始 (1-1)3 = 0
当前页为2 第二页从3开始 (2-1)3 = 3
当前页为3 第三页从6开始 (3-1)3 = 6
当前页为4 第四页从9开始 (4-1)3 = 9
SELECT * FROM employee
LIMIT (curPage-1)*pageSize,pageSize;
查询student表的第2条到第4条记录
(其中1表示从第二条记录开始查询,3表示查询出3条记录)
SELECT * FROM student LIMIT 1,3;
约束类型
主键约束(primary key)
唯一约束(unique)
自动增长(auto_increment)
- 添加主键约束 PRIMARY KEY
CREATE TABLE 表名(字段名1 数据类型 primary key,字段名2 数据类型);
CREATE TABLE 表名(字段1 数据类型,字段名2 数据类型,primary key(要设置主键的字段));
先创建表再添加主键
ALTER TABLE student ADD CONSTRAINT primary key(sid);
- 唯一约束UNIQUE
CREATE TABLE students(
id INT primary key,
name VARCHAR(50) UNIQUE
)
- 自动增长列 auto_increment
CREATE TABLE 表名(
字段名1 数据类型 primary key AUTO_INCREMENT,
字段2 数据类型 UNIQUE);
域完整性
- 数据类型
数值类型
日期类型
字符串类型 - 非空约束(NOT NULL)
CREATE TABLE stu(
id int primary key auto_increment,
name varchar(20) unique not null,
gender char(1) default '男'
)
- 默认值约束(DEFAULT)
CREATE TABLE 表名(
字段名1 数据类型 primary key AUTO_INCREMENT,
字段2 数据类型 UNIQUE NOT NULL,
字段3 数据类型 DEFAULT '默认值');
外键
对已有表添加外键关系
ALTER TABLE score ADD CONSTRAINT sc_st_fk FOREIGN KEY(sid) REFERENCES student(id);
删除外键关系的语法:
ALTER + TABLE + 外键所在表的表名 + DROP + FOREING KEY + 外键名)
数据库设计三范式
设计数据库表的时候所依据的规范,共三个规范:
第一范式: 要求每一个字段原子性不可在分
第二范式: 要求所有非主键字段完全依赖主键,不能产生部分依赖
第三范式: 所有非主键字段和主键字段之间不能产生传递依赖
修改表内容
- 将name字段的数据类型改为VARCHAR(30),且保留非空约束。
参考:
ALTER TABLE animal CHANGE name VARCHAR(30);
- 将behavior 字段的位置改到legs字段的前面。
参考:
ALTER TABLE animal MODIFY legs INT(4) AFTER behavior;
- 将kinds字段改名为category。
参考:
ALTER TABLE animal CHANGE kinds category VARCHAR(8) NOT NULL;
- 在表中增加fur字段,数据类型为VARCHAR(10)
ALTER TABLE animal ADD fur VARCHAR(10)
- 删除legs字段
ALTER TABLE animal DROP legs;
- 将animal表的储存引擎更改为MyISAM类型
ALTER TABLE animal engine = MyISAM;
- 将animal表更名为animalInfo
RENAME TABLE animal TO animalInfo;
合并结果集UNION与UNION_ALL
合并结果集就是把两个SELECT语句的查询结果合并到一起展示
- UNION 合并时去除重复记录
SELECT * FROM 表1 UNION SELECT * FROM 表2;
- UNION ALL合并时不去除重复记录
SELECT * FROM 表1 UNION ALL SELECT * FROM 表2;
多表联查,如何保证数据正确(解决笛卡尔集现象)
在查询时要把主键和外键保持一致
要保证我们当时建表的时候,关系的那个键保持一致
SELECT *
FROM students,score
WHERE students.id = score.sid
多表查询_内连接之等值连接 INNER JOIN
内连接分为:等值连接,非等值连接
内连接写法
SELECT * FROM students st INNER JOIN score sc ON st.id = sc.sid
多表联查后还有条件
SELECT st.id,st.name,sc.score FROM students st INNER JOIN score sc ON st.id = sc.sid WHERE sc.score >60 AND st.age>10;
多表查询_左外连接(LEFT_JOIN)
两表满足条件相同的数据查出来,如果左边表当中有不相同的数据,也把左边表当中的数据查出来.(换句话说就是左边表数据全部查询出来,右边表只查询满足条件的)
SELECT *
FROM students st
LEFT OUTER JOIN score sc
ON st.id = sc.sid;
多表查询_右外连接(RIGHT_JOIN)
使用右连接,就把右边表当中的数据全部查出,左边查出满足条件的
SELECT *
FROM students st
RIGHT OUTER JOIN score sc
ON st.id = sc.sid;
多表查询_多表联合查询
多表连接属于内链接
SELECT *
FROM students st
JOIN score sc
ON st.id = sc.sid
JOIN course co
ON sc.cid = co.id;
多表查询_非等值连接实现
SELECT e.ename,e.salary,d.dname
FROM emp e,dept d,salgrade g
WHERE e.deptno = d.deptno
AND e.salary >= g.lowSalary
AND e.salary <= g.highSalary;
SELECT e.ename,e.salary,d.dname
FROM emp e,dept d,salgrade g
WHERE e.deptno = d.deptno
BETWEEN g.lowSalary AND g.highSalary;
SELECT * FROM emp e
JOIN dept d ON e.deptno = d.deptno
JOIN salgrade g ON e.salary BETWEEN g.lowSalary AND g.highSalary;
子查询
- 什么是子查询
一个select语句中包含另外一个完整的select语句
或者说两个以上select,那么就是子查询语句了 - 子查询出现的位置
where后,把select查询出的结果当做另外一个select的条件值
from后,把查询出的结果当作一个新表
从emp表里查询名字和部门和项羽是一个部门的人
SELECT ename,deptno FROM emp
WHERE deptno = (SELECT deptno FROM emp WHERE ename = '项羽');
查询30号以内大于2000薪水的人
SELECT ename FROM (SELECT ename,salary,deptno FROM emp WHERE deptno=30) AS s
WHERE s.salary > 2000;
查询工资高于程咬金的员工
SELECT ename,salary FROM emp
WHERE salary > (SELECT salary FROM emp WHERE ename = '程咬金')
常用函数
函数分类:
- 字符串函数
- 数值函数
- 日期和时间函数
- 流程函数
- 其他函数(数据库、系统相关)
一、字符串函数
字符串函数concat(s1,s2....sn)
将传入的字符串连成一个字符串
任何字符串与null进行连接的结果都是nullinsert(str,x,y,instr)
将字符串str从x位置开始,y个字符串长的子串替换为指定的字符LOWER(Str)和UOOER(str)
把字符串转换成小写或者大写LEFT(str,x)和RIGHT(str,x)
分别返回字符串最左边的x个字符和最右边的x个字符
如果第二个参数为null,那么就不返回任何字符LAPD(str,n,pad)和RPAD(str,n,pad)
用字符串pad对str最左边或最右边进行填充,直接到长度为n个字符串长度LTRIM(str)和RTRIM(str)
去掉字符串当中最左侧和最右侧的空格TRIM(str)
去掉字符串左右的空格REPEAT(str,x)
返回str重复x次结果REPLACE(str,a,b)
用字符串b替换字符串str中所有出现的字符串aSUBSTRING(str,x,y)
返回字符串str中的第x位置起y个字符串长度的字符
二、数值函数
ABS(x)
返回x的绝对值CEIL(x)
小数部位零部分上取整,即向上取最近的整数(只要有小数点就进1)FLOOR(x)
向下取整MOD(x,y)
返回x/y的摸(余数)RAND()
返回0-1内容的随机数
三、日期相关函数
CURDATE()
返回当前日期(年月日)CURTIME()
返回当前的时间(时分秒)NOW()
返回当前的日期和时间(年月日时分秒)UNIX_TIMESTAMP()
返回当前的时间戳FROM_UNIXTIME(unixtime)
将一个时间戳转换成日期WEEK(DATE)
返回当前是一年中第几周YEAR(DATE)
返回所给日期是哪一年HOUR(TIME)
返回当前时间的小时MINUTE(TIME)
返回当前分钟DATE_FORMAT(date,fmt)
按字符串格式化日期date值
SELECT DATE_FORMAT(now(),'%M,%D,%Y');
- DATE_ADD(date,interval expr type)
计算日期间隔
SELECT DATE_ADD(now(),interval 31 day)
- DATEDIFF(date1,date2)
计算两个日期相差天数
四、流程函数
- IF(value,t,f)
如果value是真,返回t,否则返回f
SELECT IF(2>3,'yes','no')
IFNULL(value,value2)
如果value1不为空,返回value1否则返回value2CASE WHEN THEN END
判断
SELECT CASE WHEN 2>3 THEN '对' ELSE '错' END;
五、其他函数(重点))
DATABASE()
返回当前数据库名称
SELECT DATABASE();VERSION()
返回当前数据库版本USER()
返回当前登录用户PASSWORD()
对str进行加密
返回str的MD5值
事务的ACID
- 原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚 - 一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另外一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态
让数据保持一定上的合理性
一个商品出库时,仓库商品数量-1,对应用户的购物车中商品+1 - 隔离性(Isolation)
事务的隔离性是指并发的事务相互隔离,不能相互干扰 - 持久性(Durability)
事务的持久性是指事务一旦提交,对数据的状态变更应该被永久保存
事务的使用
开启事务
strat transaction;
提交事务
commit;
回滚事务
rollback;在提交之前可以回滚
视图
定义视图(v开头)
create view 视图名称 as select语句;
查看视图
show tables;
使用视图
select * from v_stu_score;
删除视图
drop view 视图名;