SQL语句
大约 9 分钟
SQL语句
目录
DDL数据定义语言
表的增删改查
create
drop
alter
show
/desc
CREATE(创建)
create ...
,创建表语句,比较长且繁琐
创建表
create table 表名(
字段名1 数据类型 [补充],
字段名2 数据类型 [补充],
字段名3 数据类型 [补充],
...
);
补充:表名在数据库当中一般建议以:t_
或tbl_
开始
字段数据类型
数据类型
数据类型 | 说明 | 编程语言对应 | 应用 |
---|---|---|---|
int | 整数型 | int | |
bigint | 长整型 | long | |
float | 浮点型 | float / double | |
char | 定长字符串 | String | |
varchar | 可变长字符串 | Java中的 StringBuffer/StringBuilder | |
date | 日期类型 | Java中的 java.sql.Date | |
BLOB | 二进制大对象 | Java中的 Object | 存储图片、视频等流媒体信息(Binary Large Object) |
CLOB | 字符大对象 | Java中的 Object | 存储较大文本,比如可以存储4G的字符串(Character Large Object) |
选用
- char还是varchar
- 存生日定长/日期,存昵称 / 签名可以用动态长度(如1~20)
VARCHAR(50)
,不会浪费空间CHAR(50)
,不满50字符串会填充空格至50字符串,浪费空间
- BLOB还是CLOB
- 以一个电影表为例
- 注意:BLOB不能使用
INSERT
语句插入,需要使用IO流
字段其他属性(约束)
约束类型(Constraint)
约束类型 | 缩写 | 使用 | 约束说明 |
---|---|---|---|
非空约束 | NN | not null | 约束的字段不能为NULL |
唯一约束 | unique | 约束的字段不能重复,但可多个NULL | |
主键 | PK | primary key | 约束的字段不能为NULL且不能重复 |
外键约束 | FK | foreign key | ... |
Oracle数据库有Check约束,但MySQL不支持 | |||
自动增加 | AI | AUTO_Increment | 可以自动维护主键值 |
Default/Expression 默认值 | 默认值 |
非空约束
略
- 列级约束 / 表级约束:只有列级约束、没有表级约束
唯一约束
- 联合唯一性:单个可重复,配对结果不重复。主键同理
- 列级约束 / 表级约束:有列级约束和表级约束,数量任意
drop table if exists t_user;
create table t_user(
id int unique, -- 【列级约束】单个唯一性
usercode varchar(255),
username varchar(255),
unique(usercode,username) -- 【表级约束】联合唯一性
)
主键
drop table if exists t_user;
create table t_user(
id int primary key, -- 【列级约束】单个唯一性(只能有一个)
usercode varchar(255),
username varchar(255)
-- primary key(id,username) -- 【表级约束】联合唯一性(不建议)
)
- 范式规则:每个表中都应该有主键。在一些数据库图形化软件中,若没有主键甚至不允许编辑
- 主键作用:主键是这行记录在这张表中的唯一标识
- 注意要点:一张表的主键约束只能有一个
- 主键分类
- 根据字段数量
- 单一主键(建议使用)
- 复合主键 / 联合主键(不建议,复合主键违背三大范式)
- 根据主键性质
- 自然主键:一个与业务没有任何关系的自然数,例如自然增长的主键id(建议)
- 业务主键:例如银行卡卡号、身份证号码(不推荐使用) (不建议,因为以后业务一旦发生改变,主键值可能也需要发生变化,但变化可能会导致主键重复) (视频里老师说不建议,但我挺有异议的)
- 根据字段数量
- 列级约束 / 表级约束:有列级约束和表级约束,但一张表只能有一个主键约束
主键值自增【MySQL特有】
create table t_user(
id int primary key auto_increment
);
Oracle中也提供了一个自增机制,叫做:序列(Sequence)对象
外键约束
create table t_class( -- 父表,班级表
cno int,
cname varchar(255),
primary key(cno)
);
create table t_student( -- 子表,学生表
sno int,
sname varchar(255),
classno int,
foreign key(classno) references t_calss(cno) -- 外键约束、引用
);
- 作用:表A的字段必须在表B的字段里
- 应用举例:学生表的班级号必须在班级表里面有(学生表是子表,班级表是父表)
- 父子表顺序:先创建父表再创建子表、添加数据先添加父表再添加子表、先删除子表再删除父表
- 注意:外键字段可以为NULL,被引用的字段不一定是主键但一定是有唯一性的
存储引擎、与默认字符集
create table t_table (
id int primary key auto_increment
) engine=innodb default charset=utf8;
- 简概
show create table t_table;
显示出来的create建表语句中:最后可能会带有ENGINE = InnoDB DEFAULT CHARSET=utf8
- 即若不指定存储引擎,默认使用
InnoDB
存储引擎和utd8
字符集
- 数据库差异
- 在MySQL中该机制叫
存储引擎
,但在Oracle中为表的存储方式
- 在MySQL中该机制叫
- 用途
- 每一个存储引擎都有优缺点,可选择合适的存储引擎
- 种类
- 查看当前mysql支持的存储引擎:
show engines \G
- mysql 5.5.36版本支持的有9个
- 查看当前mysql支持的存储引擎:
- 选用
- 一般用innoDB就行了
MyISAM 存储引擎
简概
- 是MySQL最常用的引擎(不是默认引擎)
表的特征
使用三个文件表示每个表
文件 文件名 文件作用 格式文件 mytable.frm
存储表结构的定义 数据文件 mytable.MYD
存储表行的内容 索引文件 mytable.MYI
存储表上索引,索引像是目录,能通过缩小范围来加速查询速度
灵活的AUTO_INCREMENT字段处理
优点
- 可被压缩,节省存储空间
- 可转换为只读表,提高检索效率
缺点
- 不支持事务
InnoDB 存储引擎
- 简概
- 是MySQL的缺省(默认)引擎
- 表的特征
- 每个InnoDB表在数据库目录中以.frm格式文件表示
- InnoDB表空间tablespace被用于存储表的内容(逻辑概念,意味着无法被压缩、无法转换成只读)
- 提供一组用来记录事务性活动的日志文件
- 用COMMIT(提交)、SAVEPOINT及ROLLBACK(回滚)支持事务处理
- 提供全ACID兼容
- 在MySQL服务器崩溃后提供自动恢复
- 多版本(MVCC)和行级锁定
- 支持外键及引用的完整性,包括级联删除和更新
- 优点
- 支持事务、行级锁、外键等。即数据安全性比较好
MEMORY 存储引擎
- 表的特征
- 数据库目录内,每个表均以.frm格式的文件表示
- 表数据及所有被存储在内存中
- 表级锁机制
- 不能包含TEXT或BLOB字段
- 优点
- 查询速度最快
- 缺点
- 不支持事务、数据容易丢失。因为所有数据和索引都是存储在内存当中的
- 补充
- 以前叫做HEPA引擎
DROP(删除)
写法
drop table 表名
,该写法通用drop table if exists demotable;
,当表存在则删除,Oracle不支持这种写法
怎么删除大表?(几亿)
- 删除时间非常长,因为没有释放数据所占空间
truncate table demotable;
,表的截断- 与
delete from demotable
比较:特点是速度快,但表被截断、不可回滚(即无法恢复,需慎重,要再三问清楚) - 与
drop table demotable;
比较,truncate直接截断表中的数据而非删除表
- 与
ALTER(修改)
略,使用工具完成即可
因为开发中表设计后很少会修改表结构,,除非设计得有问题
一般修改表结构语句不会出现在程序代码中,但一般可以使用可视化工具去修改。不是一定要掌握的
SHOW(查看 - 表数据)
show tables form demotable;
,查看指定表show tables;
,查看当前表
show create table demotable
,查看表创建语句
DESC(查看 - 表结构)
desc demotable;
,查看表结构
其他表命令
INDEX(索引)
- 作用
- 相当于一本书的目录,可以快速找到对应的资源
- 查询一张表有两种检索方式:全面扫描和根据索引检索(效率很高)
- 原理
- 作用原理:根本原理是缩小了扫描的范围
- 实现原理:B+树
- 深剖原理流程
- 添加索引时
- 给某个字段添加索引后,会先对该字段进行自动排序并保存(硬盘/内存)为一个对象(叫
索引对象
) - 然后对排序过后的字段进行层层分区
- 给某个字段添加索引后,会先对该字段进行自动排序并保存(硬盘/内存)为一个对象(叫
- 检索时
- 先看条件的字段有没有索引,若有则找到对应的索引对象
- 层层定位,如 “SMITH”,先定位S区,继续定位M区......然后缩小扫描的范围,直接定位到物理地址
- (每一行记录都有一个对应的物理地址,该物理地址在Oracle中叫 rowid)最后想当与
where 物理地址 = 0x???;
- 添加索引时
- 缺点
- 不能随意添加索引,因为所以也是数据库当中的对象,也需要数据库不断的维护,有维护成本
- 比如表中的数据经常被修改就不适合添加索引
- 因为数据一旦修改,索引需要重新排序、进行维护
- 注意:索引可能会失效:当使用模糊查询且第一个通配符为%时
- 使用场景
- 数据量庞大
- 很少的DML操作
- 该字段经常出现在WHERE子句中(当该字段没有索引是进行全表扫描)
- 索引分类
- 单一索引,给单个字段添加索引
- 复合索引,给多个字段联合起来添加1个索引
- 主键索引:主键上会自动添加索引(启示:根据主键查询效率较高,尽量根据主键检索)
- 唯一索引,有unique约束的字段上会自动添加索引(主键和具有unique约束的字段会自动添加索引)
- ......
添加索引
添加索引是给某一字段,或某些字段添加索引
- 添加索引
- 格式:
create index 索引名称 on 表名(字段名);
- 举例:
create index emp_sal_index on emp(sal);
- 格式:
- 删除索引
- 格式:
drop index 索引名称 on 表名;
- 格式:
其他
查看sql语句的执行计划,可以用来验证查询的范围
explain select
如explain select ename,sal from emp where sal = 5000;
VIEW(视图)
- 简概
- 站在不同的角度去看数据
- 使用
- 创建视图:
create view myview as select empno,ename from emp;
- 删除视图:
drop view myview;
- 创建视图:
- 面向视图操作
- 对视图进行增删改查,会影响到原表数据
- 应用
- 可减少列数、使用别名
- 可隐藏表的实现细节,保密级别较高的系统,数据库只对外提供相关的视图。程序员只对视图对象进行CRUD
示例
create table emp1 as select * from emp; -- 创建新表(根据旧表)
select * from emp1; -- 查看表
create view myview as select id,ename from emp1; -- 创建视图(仅显示两个字段)
select * from myview; -- 查看视图
update myview set ename='hehe' where id = 1; -- 更新视图,会影响到原表数据