SQL分类
- DDL(Data Defnition Language):数据定义语言,用来定义数据库对象(数据库database、表table、列column等),关键字:create、drop、alter等;
- DML(Data Manipution Language):数据操作语言,用来对数据库表的数据进行增删改,关键字:insert,update,delete等;
- DQL(Data Query Language):数据库查询语言,用来查询数据库表的记录(数据),关键字:select、where等;
- DCL(Data Control Language):数据控制语言,用来定义数据库的访问权限和安全级别、及创建用户、关键字:grant、revoke等;
这里面我简要分析一下,第一个的DDL语句,也就是操作表结构的一些,我觉得可以适当了解了解,但并不一定要特别的记忆,首先表结构这些操作在图形化工具的帮助下,完成是可以被取而代之的,其次表结构这些语句应该在项目初期就已经确定了,而且也轮不到我们这种初级的程序员设计表结构吧(这句话是我的猜想),所以你大致了解一下,象征性地说几个技术点。
// 创建表
- create database mydatabase(
id int primary key auto_increment -- int不规定括号里的数字,即默认为10个数字长度
username varchar(20) not null unique -- 这个20并不是必须,我觉得用户名这个字段用20个字符长度足够了
constraint 'FK_ID' foreign key(id)references anthor_table(id);--这边只是大概的举了个例子
);
// 修改表名
alter table mytable rename to newMyTable;
//添加一列
alter table mytable add newColoum varchar(255);
// 修改列名称类型
alter table mytable change coloum newColoum varchar(255);
alter table mytable modify coloum char(10);
// 删除表
drop table if exists mytable;
// 添加非空约束
alter table mytable modify username varchar(20) not null;
// 删除非空约束
alter table mytable modify username varchar(20);--只是重置了一下
// 添加唯一约束
alter table mytable modify username varchar(20) unique;
// 删除唯一约束
alter table mytable drop username index unique;--这个和删除not null不一样
// 删除主键
alter table mytable drop primary key;--不需要指定哪个字段,因为一张表只有一个主键
// 添加主键
alter table mytable modify id int primary key;
// 删除外键
alter table mytable drop foreign key 外键名称;(如何查看这张表的外键,show create table mytable就能在create table mytable这列下看到了)
// 添加外键
alter table mytable constraint 'FK_ID' foreign key(id) references anthor_table(id);
// 级联操作
alter table mytable constraint 'FK_ID' foreign key(id) references on update cascade on delete cascade;--这样父表的语句删除,子表的语句也会相应被删除,更新也是同步的。
DML&&DQL
这块是核心!
这个应该是开发时间的核心工作。
// 添加一条记录
insert into mytable (id,username) values(1,"zhangsan");
// 删除一条记录
delete from mytable where username = 'zhangsan';
// 更改一条记录
update mytable set gender = '男' where username = 'zhangsan';
// 查询一条记录
select * from mytable where username = 'zhangsan';
大体的语句的结构就如上所示。这部分呢最难的当属于查询语句,单表查询是比较简单的,最多玩个自查询,将一张表看成两张表;难在多表联查上面,三张表或者更多的一个联查,这个你必须掌握,如果数据库这块你掌握不好,连进公司活儿都没法干,因为做web项目的话什么事要和数据库打交道。
接下来我拆分着讲,主要讲思维,这类复杂的筛选条件多的查询语句,就是要拆着看,看其中包含多少个限制条件,多读几句,用语文那种饱含情感的思想去感受一句查询条件,用理性的断句“我要查询部门为‘10001’的!工资大于‘5000‘的‘到目前的’!员工的‘职位’、‘编号’,按编号升序,只显示第二条,不允许用limit。
要查询什么字段
select '职位', '编号'
这一步不难,如上面的例子,很明显按照人们的说话、表述,他将最终要查的字段放在了最后,怎么样的……怎么样的……员工的‘职位’、‘编号’。
怎么加入表
接下来开始准备加入表了,开始from tableA,tableB
还是tableA left join tableB
,到这一步就不是机械式的了,开始第一步思考了,根据我一开始读出来的语义,很明显这就是个等值查询,一 一对应的,而不是类似于有些人没‘部门’也要查出来,这个句子里面没有主附表之分,没有侧重 “ 要看那张表的全部数据,即使有些在另外一张表对应着的字段可能没有,也要查询出来 “这种语义。那就from tableA,tableB
或者inner join。
查询条件
这个就是最主要的,怎么筛选,怎么从语句里面体会出那些明显的、隐含的过滤条件,当然,我们可以先不动脑子的把上一步两张表要连接起来的语句先写起来,where A.id = B.id外键字段,接下来就比如A,salary>5000 and A.dept_no = 10001 and to-date = '目前日期' order by B.emp_no
这一段大体能写出来。
再筛选一层
经过上一步已经基本能把整个语句写出来了,还有一个苛刻的条件,有时候可能会有几个,按照emp_no排序,升序,取第三个,不许用limit?好,我本来还准备order by之后用limit 2,1,现在被限制住了。那就这样,再加个and条件,即and B.emp_no=((select max(emp_no)from ……where emp_no >(select min(emp_no) from ……))省略号即再把上面的筛选条件写一下,嵌套一个子查询作为结果,再查一遍满足上述条件结果的最小编号,也就是升序排在第一个的,然后小于第一个的不是一大堆吗?我们再取这一大堆里面编号最大的不就是第二个吗?
好了,这基本就是查询语句的一些思路,因为没有好的例子,所以只能靠脑补。
DCL
这个方面,就是数据控制语言,属于了解部分,涉及操作授权、创建用户的一些,感觉这些是DBA授权给程序员的吧,我们应该还没到主动授权、主动写这些sql语句的份,属于被动方。
还有就是数据库的事务、隔离级别、索引、视图、存储引擎、三范式。
事务:
原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败;
持久性:当事务提交或回滚后,数据库会持久化的保存数据;
隔离性:多个事务之间,相互独立;
一致性:事务操作前后,数据总量不变。
隔离级别
概念:多个事务之间是隔离的,相互独立的,但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题;
存在问题:
- 脏读:一个事务读取到另一个事务中没有提交的数据;
- 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样,也就是第一次读取一条记录是A,第二次被另一个事务删了delete 或者update更改了,变成了B,则第一个事务再次读的时候就已经不是原来的数据A这条记录了,注意:这是个问题,这是个问题,不可重复读是个问题,需要被解决,我就是要重复读!保证读取的前后数据一致,别面试时记忆模糊,不确定;
- 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务会发现多了条数据,是实实在在能看到多了一条数据,而不可重复读虽然也是前后不一致了,但我理解的是不可重复读读到的是被更改的数据或者察觉到被删除了一条记录,而幻读是新增了一条实实在在的记录。
隔离级别:
- read uncommitted 读未提交
产生的问题:脏读、不可重复读、幻读 - read commited 读已提交(oracle默认级别)
产生问题:不可重复读、幻读 - repeatable read:可重复读(mysql默认)
产生问题:幻读 - serializable:串行化
可以解决所有问题
注意:隔离级别从小到大安全性越来越高,但是效率越来越低。
数据库隔离级别设置:
set global transaction isolation level 级别字符串。
索引
// 创建了一个username的索引
create index username_index on mytable(username);
创建索引很简单,但什么时候创建呢?
- 数据量庞大,
- 该字段很少的DML操作。(因为字段进行修改操作,索引也需要维护),
- 该字段经常出现在where子局中。(经常根据哪个字段查询)
索引底层采用的B+tree,但是索引具体的执行过程是什么呢,B+tree的数据结构又是怎样的呢?这些底层原理要经得起面试官的深挖,每回答一个知识点就要准备好接受他的“为什么”,至于底层原理是什么,我也会继续去探索,后续的文章会出,单独出一个专题。
视图
感觉这个用的比较少,操作视图的话也会影响到原来表的记录
create view myview as select * from mytable;
drop view myview;
视图有什么作用呢?
视图可以隐藏表的实现细节,保密级别较高的系统,数据库只对外提供相关的视图,java程序员只对视图对象进行CRUD,至于操作还是和正常的表一样操作;
至于还有一些三范式以及存储引擎的概念,我这里就不再说了,小伙们可以去网上再查阅查阅,后者呢是一些概念上的东西,面试的时候可能会考到,当然了不同的存储引擎也有其对应的应用场景,各有各的优缺点;三范式呢,主要就是解决非主属性之间的依赖,至于什么是主属性,即:码属性组中的所有属性,至于什么是码,即:如果在一张表中,一个属性或者属性组被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码。