SQL语言(关键字是不区分大小写的,建议大写)
SQL结构化查询语言 Structured Query Language
1. DDL(Data Definition Language) 数据定义语言
用来创建、删除、修改数据库中的对象(表格、用户、索引、视图、存储过程、触发器)
create创建、drop删除、alter修改
2. DML(Data Manipulation Language)数据操作语言
用来操作数据库表格中的具体数据(信息)(CURD)
写数据:insert新增、delete删除、update修改
读数据:select查询
由于读数据的操作很多、很重要,所以有人给他单独起了一个名字DQL(Data Query language)数据查询语言
select、where条件、group by分组、having条件、order by排序
3. DCL(Data Control Language)数据控制语言
用来控制用户权限
赋予:grant 权限 to 用户
回收:revoke 权限,权限 from 用户
4. TPL(Transcation Process Language)事务处理语言
可以理解为多线程并发访问同一个文件资源 带来的安全问题
begin Transcation
commit提交、rollback回滚、save point A 保存还原点
DDL 数据定义语言
- 创建database
// 默认创建数据库,字符集有默认值,为latin1
// 当前数据库中的所有表格都按照这个字符集进行处理,不能存储中文
create database name;
// 创建数据库的时候可以修改默认字符集,通常设置为utf8,注意中间没有杠
create database 数据库名 default character set = 'utf8';
// 查看数据库的默认字符集,默认为latin1,所以处理不了中文
select schema_name, default_character_set_name from information_schema.schemata where schema_name = "数据库名";
// 可以查看到数据库当中某个表的字符集
show table status from 数据库名 like '表名';
// 如果不想让数据库中所有的表格存储中文,只单纯的某一张表格需要中文,可以在创建表格的时候设置字符集
- 创建table
create table 表名(
列名 数据类型(长度),
列名 数据类型(长度),
列名 数据类型(长度)
);
// 创建表格的时候设置字符集
create table 表名(
列名 数据类型(长度),
列名 数据类型(长度),
列名 数据类型(长度)
) character set utf8 [collate utf8_general_ci];
// collate utf8_general_ci设置的是排序规则,
// utf8_general_ci是默认值,性能比较高,可能不太精确
// utf8_unicode_ci,性能表较低,扩展性好
// 查看表格的描述(即列名、列类型等,不显示表格的内容)
desc 表名;
- 数据库中的数据类型
按照存储数据的方式来分类:
-
数值型
- 整数:tinyint、smallint、mediumint、int(4字节、32bit)/integer、bigint
- 小数:float(4字节)、double(8字节)、decimal、numeric
float(m, n) 总共可以存储m位,小数点之后有n位
m取值范围为1-65,n取值范围是0-30
如果不写的话,默认情况下m是10,n是0 -
字符串
- char、varchar(可变字符串,variable)数据库里面所有的字符串类型用单引号
- binary(二进制)、varbinary(可变二进制)
- blob(二进制大文本)、text(正常字符大文本)
-
日期/时间
- date(日期)、time(时间)、datetime(日期&时间)、timestamp(时间戳)
- 修改表格结构
- 修改表格名字
alter table 原表名 rename [to] 新表名;- 修改原有的列(列名错了、列类型不对、列长度不够)
alter table 表名 change 原列名 新列名 新类型 新长度; // 新列名、新类型、新长度都可以和原来的一样- 新增一个列
alter table 表名 add 新列名 新类型 新长度;- 删除一个原有的列
alter table 表名 drop 列名;- 删除table、删除database
drop table 表格名字; drop database 数据库名字;
DML 数据操作语言
操作的是表格中的数据信息
分类:写入信息、读取信息
1. 写入信息(数据库中的信息发生了真实的改变)
insert新增、delete删除、update修改
2. 读取信息(数据库中的信息没有发生改变 读取信息展示出来)DQL
select 查询
新增记录
insert into 表名(列名, 列名, 列名) values(值, 值, 值);
// 没写的列名默认为null
// 如果新增加全部表格的列,就不用写列了,省略表名后面的括号内容
// 但是要求值的顺序、类型、个数必须与表格中的列一致
insert into 表明 values(值,值,值,值);
// 也可以一条insert语句,新增多个记录
insert into 表名(列, 列) values(值, 值), (值, 值), (值, 值);
删除记录
delete from 表名 [where ...];
修改记录
update 表名 set 列=值 [, 列=值] [where ...];
查询记录
select 列, 列 from 表名 [where ...];
select * from 表名
// 可以修改查出的结果的列名,
select 列名 as 列名 from 表名
条件筛选
- 除了insert以外的其他三个语句都可以做筛选。where是一个关键字,拼接在除了insert语句以外的其他语句基本结构之后
delete from 表 where
update 表 set 列=值 where...
select 列 form 表 where...; - 筛选用来筛出符合条件的记录行数,并不是控制显示的列
- where后面按照某一个列或者是某一写条件进行筛选
- where后面具体怎么使用、连接什么东西?
- 比较运算符:>、>=、<、<=、!=、=
- 算数运算符:+、-、*、/
- 逻辑运算符:and、or、not
如果and和or同时出现的话,and的级别更高 - [not] between and
两边都是闭区间,只需要循环一次 - [not] in (条件, 条件)
满足其中一个条件 - [not] like
模糊查询:%代表0-n个字符,_代表1个字符(有且只有一个)
select * from student where chinese>=95 and english >=95;
// 数据库底层做的事情:
// 1. 解析SQL
// 2. 从表格中将全部数据都读取出来,放在数据库缓存,集合list
// 3. 将list集合做一个循环遍历,每一次拿到一个元素(一行记录)条件
假设我们的表格有7行记录
如果只写一个where条件
执行7次循环就可以比较出来了
如果有and连接不止一个条件
先按照第一个条件先进性筛选
在按照第二个条件再筛选
// 4. 如果以后再语句中使用了and,尽量将条件苛刻的写在前面,这样可以提高代码效率
排序
- 连接在查询语句之后的,先查出来,再排序
- 按照某一个列进行排序的
order by 列 - 排序有两种方式:
升序 asc 默认
降序 desc - 可以联合排序
order by 列名 [升序/降序],[列名 升序/降序]
函数
mysql里面的返回值都是由返回值的
- 函数可以放置的位置?
- 查询中用来显示的部分
select 函数(列) from 表格
- 条件筛选后面
select 列 from 表格 where sal > 函数(值)
- 常用函数:按照功能来进行划分
- 比较函数
- ifnull(值) 是空值返回1,不是返回0
- 数学函数(数值函数)
- abs绝对值
- floor向下取整
- mod(5, 2)取余数
- pow求次方
- round()
- 日期和时间
- now()
- yaer() month() day() week()
- 控制流程函数(转换函数)
- if(条件, 值1, 值2)
- ifnull(值, val) 如果值为空,就显示val,否则正常显示值
- 字符串函数
- length()
- concat()
- substr()
- instr()
- replace()
- upper()
- lower()
- ltrim() rtrim()
- lpad() rpad()
- reverse()
- 分组函数(聚合函数)+ 分组条件
- 去重复 distinct
- distinct 列 如果有一样的列信息,将一样的信息合并。行数会减少,查询的每一个列。行数个数需要一致
- distanct 列, 列 如果有两个以上的列,将两个以上或多个列的组合当作整体。如果整体有一样的信息,则才会去重复,否则就全部显示
- count()
- max()
- min()
- avg()
- sum()
- 去重复 distinct
select count(列) from student group by classid;
查询student表个人中所有的18岁同学,都在哪个班级 先进行条件筛选,后分组 查询student表格中语文平均成绩高于90分的班级 先进性分组,然后再进行筛选(having) having 关键字的使用与where类似 优先级:where、 group by、having、order by
分组条件+分组函数查询
- 在查询之前需要先考虑,到底是先分组,还是先筛选条件 先筛选 后分组:where group 先分组 后筛选:group having
- 在查询的时候一旦分组了,行数会减少 想要展示的信息,个数需要与分组条件的个数一致
嵌套
一个完整的SQL语句中,嵌套了另一个完整的SQL语句
- 嵌套可以将查询的结果当作条件再次查询
- 可以将查询的最终结果当作一张表格,在表格的基础上再次查询 注意:再将结果当作表格的时候,需要将表格起别名
- 嵌套将某一个查询的结果当作条件的时候,表格可以不是一张,我们可以将另一张表格查询的信息,当作当前表格的条件
几个比较重要的关键字的使用
- in 满足查询子集中的某一个即可 in后面的自己括号内,可以是常量固定值、也可以是通过另一条sql语句查询出来的结果 如下的三个使用起来与in类似,查询是否满足后面的子集中的条件 但是一下三个关键字的后面不允许写固定值,只允许写sql语句(只能通过嵌套来获取子集)
- any 满足查询子集中的某一个即可
- some 与any完全一致
- all 满足查询自己种的全部才可以
集合操作:
union 并集 (oracle数据库有----> intersect交集 minus差集)
select tid, tname, tsex from teacher union select sid, sname, ssex from student;
- 要求是前后两个查询子集的列数必须是一致的
- 类型没有要求
- 拼接后显示的列名是前一个自己默认的列名
- 注意:union和union all的区别:
- union合并后做去重的处理,性能表较慢。如果产生重复元素,记录的是第一次出现的那一行。
- union all 将两个查询的字节直接做合并,不做任何处理,性能比较快。建议以后使用union all来进行合并处理
列的约束
- 主键约束(Primary Key) 主键约束要求当前的列不能为null 主键约束要求当前的列 值是唯一的,不能存在
alter table 表名 add constraint 约束名字 约束类型(列);
// 可以简写为:
alter table 表名 add primary key (classid);
// 添加了主键值之后若想要让主键自增,可以做相应的设计:
alter table 表名 modify classid int(4) auto_increment;
// 如果没有做起始值的说明,会从1开始
alter table 表名 auto_increment = 10;
// 删除主键约束
alter table 表名 drop primary key;
注意:删除主键约束以后,不重复的特性取消了,非空特想还在
alter table 表名 modify 列 int(4) null;
- 唯一约束 可以为表格中的某一个列添加唯一约束,唯一与主键类似 唯一约束表示的是列的值,不能重复,可以为空 唯一约束在表格中可以存在多个列
alter table 表名 add constraint 约束名 约束类型(列);
alter table myclass add constraint uk_myclass unique [key] (loc);
可以简写为:
alter table myclass add unique key(loc); // 约束名默认为列名
// 删除唯一约束:
alter table myclass drop index 约束名;
- 非空约束 可以给表格中的某一列上添加非空约束 当前列的值不能为null
alter table 表名 modify 原列名 原类型 原长度 [not] null;
alter table myclass modify cname barchar(20) null;
- 外键约束(Foreign Key) 表格中可以有多个列被设置为外键约束,当前列的值可以为空,可以重复 但是当前列的值不能随便的填写,值取另外一张表格内寻找 外键是当前列的值受到另外一张表格某一列的影响。 另外一张表格的列,必须是唯一约束
alter table 表名字 add constraint fk_当前表_关联表 约束类型(列) references 另一个表(列);
alter table student add cosntraint fk_student_myclass foreign key(classid) references myclass(classid);
// 查看
show keys from 表;
desc 表;
// 删除外键约束
alter table 表名字 drop foreign key 外键名;
// 注意:通过上面的语句其实已经将外键约束删掉了;自动在当前表格内添加一个新的key;
// 需要再次手动将这个生成的key删掉,外键约束才真的删除干净。
alter table 表名 drop key 约束名字;
// 简写:
alter table student add foreign key(列) references 另一个表(列);
注意:按照默认的方式添加外键,外键的名字不是默认类名
alter table student drop foreign key student_ibfk_1;
alter table student drop key classid;
- 检查约束
列在存值的时候做一个细致的检查,范围是否合理等
alter table student add constraint ck_sage check(sage>15 and sage< 30);
在mysql里面不好用
表格之间的关系
-
一对多
班级(一端)和学生(多端)的关系,班级表的主键id作为学生表的外键
-
多对多
老师和学生的关系,需要一个中间表,把老师和学生的编号当作组件,老师编号和学生编号都是外键
-
一对一
人和身份证的关系, 给人的身份证那一列添加外键和唯一约束
表格之间的联合查询
-
等值连接
select * from table1, table2; // 这样得到的是一个笛卡尔积,即将两张表格或多张表格进行无条件的拼接
select * from table1, table2 where table1.no = table2.no; // 等值连接,等值连接的意思就是在笛卡尔的基础上进行筛选,筛选条件不一定是等号(通常是等号);
-
外连接
select * from A left/right [ outer] join B on 条件
两张表格A和B,查询的时候谁放在左边显示,谁就写在前面,谁在右边显示,谁就写在后面
left和right来控制以哪一个表格的数据作为基准,作为基准的表格数据必须全部显示出来,非基准的表格按照on条件与之拼接,若找到条件拼接,则正常显示,若找不到满足条件的则null
外连接查询结果有可能比等值连接的最终结果多一部分数据
外连接不写on关键字是不能进行拼接的
-
内连接(自连接)
select * from A inner join B on 条件; 在当前表格中再次查询当前表格的信息
A和B可以是不同的两张表格,也可以是相同的两张表格
行列互换
select wname as '仓库名',
max( if(wmonth='一月份', winvenroty, 0)) as '一月份',
max( if(wmonth='二月份', winventory, 0)) as '二月份',
max( if(wmonth='三月份', winventory, 0)) as '三月份',
from warehouse
group by wname;
分页
limit a, b; a代表想要显示的起始行索引,包括此行(索引从0开始),也叫做偏移量。b代表想要显示的行数
DCL 数据控制语言(Data Control Language)
控制用户的权限、grant赋予、remove回收
-
我们现在的身份是一个SYSDBA管理员
管理员可以操作其他普通用户的权限
通过root账号查看mysql数据库中的user表格
记录着所有的用户信息:一般只查询下面吉列:(一共有两百多列)
user列、host列、password列、authentication_string列
-
创建一个新的用户
create user '用户名'@'IP地址' identified by '密码';
用户被创建成功之后值只有一个默认的权限 Usage只允许登录,不允许做其他事情
show frants for '用户名'@'IP';
-
给新的用户赋予权限
grant 权限 on 数据库名.表 to '用户名'@'IP';
赋予权限之后,最好做一个刷新:flush privileges
-
退出当前用户,登录刚刚创建的新用户
退出用户:exit;
登录新用户:mysql -u zzt -p
-
回收用户的权限
Usage权限是无法回收的,因为创建用户的时候他就默认有了
revoke 权限 on 数据库名.表名 from '用户名'@'IP';
-
修改用户的密码
update user set authentication_string = password(值) where user = 'gyq';
-
删除用户
drop user '用户名'@'IP';
数据库设计的范式--表之间的范式
可以理解为Java当中的设计模式
设计数据库时,遵循的不同规范,这些规范统称为范式。
范式的目的是为了减少数据库中的冗余,管理表格的时候变得容易(修改、删除),查询的时候可能就涉及到表格联合的问题
Normal From(标准话形式-普通范式)
-
第一范式
数据的原子性:数据库中的每一张表格的每一个列都是不可分割的,即行列交叉点的单元格只存储一个数据
每一个表格必须有主键约束(作用是可以快速查询某一行记录)
-
第二范式
在满足第一范式的前提下,不允许出现部分依赖性(非主键列不能受到主键列或主键的一部分影响)
当产生了非主键列受到主键或主键的部分影响,将数据拆开存储在两张表格里
-
第三范式
在满足前两个范式的前提下,不允许出现传递依赖性(非主键列不能受到非主键列或非主键列的一部分影响)
当产生了非主键列受到非主键列的影响时,将没有关系的数据拆开单独存放在表格里
事务及隔离级别
事务Transaction
- 事务可以理解为是让数据库做的事情
- 有些时候事情之内不止一条sql,存在多个组成单元。比如:张三给李四转100块钱,在数据库中,要给张三金减掉100,李四要加100。这个就是不止一条sql语句
- 一件事情中的所有操作应该是统一的,即要么都成功,要么都失败
- 事物的本质:可以理解为多线程并发操作同一张表格可能带来的安全问题
- 事务的四大特性:(ACID)
-
Atomicity原子性: 一个事务中的所有操作是一个整体,不可再分。事务中的所有操作要么都成功,要么都失败。
-
Consistency一致性: 一个用户操作了数据提交了以后,另一个用户看到的数据与之前用户看到的效果是一致的。
-
Isolation隔离性: 指的是多个用户并发访问数据库时,一个用户操作数据库,另一个用户不能有所干扰,多个用户之间的数据操作事务要相互隔离。
事务的隔离级别:级别越高越安全,性能慢
-
Durability持久性: 指的是一个用户操作数据的事务一旦被提交(缓存-->文件),他对数据库底层真实的改变时永久性的,不可返回。