1、sql语句分类:
- DDL:数据定义语言(create drop)
- DML:数据操作语句(insert update delete)
- DQL:数据查询语句(select )
- DCL:数据控制语句,进行授权和权限回收(grant revoke)
- TPL:数据事务语句(commit collback savapoint)
3、数据库三范式:
-
第一范式:1NF是对属性的原子性约束,要求字段具有原子性,不可再分解;(只要是关系型数据库都满足1NF)
-
第二范式:2NF是在满足第一范式的前提下,非主键字段不能出现部分依赖主键;解决:消除复合主键就可避免出现部分以来,可增加单列关键字。
- 第三范式:3NF是在满足第二范式的前提下,非主键字段不能出现传递依赖,比如某个字段a依赖于主键,而一些字段依赖字段a,这就是传递依赖。解决:将一个实体信息的数据放在一个表内实现。
4、脏读&不可重复读&幻读
脏读: 是指事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。
不可重复读 :是指在数据库访问时,一个事务范围内的两次相同查询却返回了不同数据。在一个事务内多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么在第一个事务中的两次读数据之间,由于第二个事务的修改,第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
幻读: 是指当事务不是独立执行时发生的一种现象,比如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么就会发生,操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
5、不可重复读&幻读区别:
如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。
不可重复读重点在于update和delete,而幻读的重点在于insert。如何通过锁机制来解决他们产生的问题
6、CHAR和VARCHAR的区别:
- CHAR和VARCHAR类型在存储和检索方面有所不同
- CHAR列长度固定为创建表时声明的长度,长度值范围是1到255
- 当CHAR值被存储时,它们被用空格填充到特定长度,检索CHAR值时需删除尾随空格
7、Mysql中有哪几种锁?
- MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁
- 表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低
- 行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高
8、delete、drop、truncate区别
- truncate 和 delete只删除数据,不删除表结构 ,drop删除表结构,并且释放所占的空间。
- 删除数据的速度,drop> truncate > delete
- delete属于DML语言,需要事务管理,commit之后才能生效。drop和truncate属于DDL语言,操作立刻生效,不可回滚。
- 使用场合:
- 当你不再需要该表时, 用 drop;
- 当你仍要保留该表,但要删除所有记录时, 用 truncate;
- 当你要删除部分记录时(always with a where clause), 用 delete.
注意: 对于有主外键关系的表,不能使用truncate而应该使用不带where子句的delete语句,由于truncate不记录在日志中,不能够激活触发器
9、MySQL数据库的四类索引:
index ---- 普通索引,数据可以重复,没有任何限制。
unique ---- 唯一索引,要求索引列的值必须唯一,但允许有空值;如果是组合索引,那么列值的组合必须唯一。
primary key ---- 主键索引,是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值,一般是在创建表的同时创建主键索引。
组合索引 ---- 在多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。
fulltext ---- 全文索引,是对于大表的文本域:char,varchar,text列才能创建全文索引,主要用于查找文本中的关键字,并不是直接与索引中的值进行比较。fulltext更像是一个搜索引擎,配合match against操作使用,而不是一般的where语句加like。
注:全文索引目前只有MyISAM存储引擎支持全文索引,InnoDB引擎5.6以下版本还不支持全文索引
所有存储引擎对每个表至少支持16个索引,总索引长度至少为256字节,索引有两种存储类型,包括B型树索引和哈希索引。索引可以提高查询的速度,但是创建和维护索引需要耗费时间,同时也会影响插入的速度,如果需要插入大量的数据时,最好是先删除索引,插入数据后再建立索引。
10、事务四大特性
- 原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态
- 一致性:如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的;
- 隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
- 持久性:事务一旦提交,其结果就是永久的。即便发生系统故障,也能恢复。
11、分区和分表的区别:
分表就是按照一定的规则把一张大表给分成多张小表,在数据库中看到的是几张不同的表,在硬盘上也是不同的文件,因此在进行增删改查操作的时候要根据同样的规则去找到具体操作的表。
分区是按照一定的规则把一张大表分成不同的区块,在数据库中看到的还是一张表,只不过在硬盘上存储的时候分成了几个不同的文件。这样在进行增删改查操作的时候就像操作一张普通的表一样简单方便。
他们都是为了处理单张表的大数据量问题,都能提高性能。
12、悲观锁/乐观锁:
悲观锁(Pessimistic Lock), 每次去查询数据的时候都认为别人会修改,所以每次在查询数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了这种锁机制,比如通过select ....for update进行数据锁定。
乐观锁(Optimistic Lock), 每次去查询数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号,时间戳等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。
13、SQL语句的执行顺序:
查询中用到的关键词主要包含六个,并且他们的顺序依次为
select--from--where--group by--having--order by
其中select和from是必须的,其他关键词是可选的,这六个关键词的执行顺序 。执行顺序与sql语句的书写顺序并不是一样的,而是按照下面的顺序来执行
from--where--group by--having--select--order by,
from:需要从哪个数据表检索数据
where:过滤表中数据的条件
group by:如何将上面过滤出的数据分组
having:对上面已经分组的数据进行过滤的条件
select:查看结果集中的哪个列,或列的计算结果
order by :按照什么样的顺序来查看返回的数据
14、简述触发器、函数、视图、存储过程?
触发器:触发器是一个特殊的存储过程,它是Mysql在insert、update、delete、的时候会自动执行代码块。
函数:MySQL中提供了许多内置函数,还可以自定义函数(实现程序员需要sql逻辑处理)。
视图:视图是由查询结果形成的一张虚拟表,是表通过某种运算得到的一个投影。
存储过程:把一段代码封装起来,当要执行这一段代码的时候,可以通过调用该存储过程来实现(经过第一次编译后再次调用不需要再次编译,比一个个执行sql语句效率高)
15、连接数据库操作
连接mysql
mysql -h 地址 -P 端口 -u 用户名 -p 密码
例如: mysql -h 127.0.0.1 -P 3306 -u root -p ****
/*退出mysql*/
exit;
16、数据库操作
#数据库操作
/*关键字:create 创建数据库(增)*/
create database 数据库名 [数据库选项];
例如: create database test default charset utf8 collate utf8_bin;
/*数据库选项:字符集和校对规则*/
字符集:一般默认utf8;
校对规则常见: ⑴ci结尾的:不分区大小写 ⑵cs结尾的:区分大小写 ⑶bin结尾的:二进制编码进行比较
/*关键字:show 查看当前有哪些数据库(查)*/
show databases;
/*查看数据库的创建语句*/
show create database 数据库名;
/*关键字:alter 修改数据库的选项信息(改)*/
alter database 数据库名 [新的数据库选项];
例如: alter database test default charset gbk;
/*关键字:drop 删除数据库(删)*/
drop database 数据库名;
/*关键字:use 进入指定的数据库*/
use 数据库名;
17、创建表
#表的操作
/*关键字:create 创建数据表(增)*/
create table 表名(
字段1 字段1类型 [字段选项],
字段2 字段2类型 [字段选项],
字段n 字段n类型 [字段选项]
)表选项信息;
例如: create table test(
id int(10) unsigned not null auto_increment comment 'id',
content varchar(100) not null default '' comment '内容',
time int(10) not null default 0 comment '时间',
primary key (id)
)engine=InnoDB default charset=utf8 comment='测试表';
语法解析(下文MySQL列属性单独解析):
如果不想字段为NULL可以设置字段的属性为NOT NUL,在操作数据库时如果输入该字段的数据为NULL,就会报错.
AUTO_INCREMENT定义列为自增的属性,一般用于主键,数值会自动加1.
PRIMARY KEY关键字用于定义列为主键.可以使用多列来定义主键,列间以逗号分隔.
ENGINE 设置存储引擎,CHARSET 设置编码, comment 备注信息.
18、表的操作
/*关键字:show 查询当前数据库下有哪些数据表(查)*/
show tables;
/*关键字:like 模糊查询*/
通配符:_可以代表任意的单个字符,%可以代表任意的字符
show tables like '模糊查询表名%';
/*查看表的创建语句*/
show create table 表名;
/*查看表的结构*/
desc 表名;
/*关键字:drop 删除数据表(删)*/
drop table [if exists] 表名
例如: drop table if exists test;
/*关键字:alter 修改表名(改)*/
alter table 旧表名 rename to 新表名;
19、修改表定义
/*修改列定义*/
/*关键字:add 增加一列*/
alter table 表名 add 新列名 字段类型 [字段选项];
例如: alter table test add name char(10) not null default '' comment '名字';
/*关键字:drop 删除一列*/
alter table 表名 drop 字段名;
例如: alter table test drop content;
/*关键字:modify 修改字段类型*/
alter table 表名 modify 字段名 新的字段类型 [新的字段选项];
例如: alter table test modify name varchar(100) not null default 'admin' comment '修改后名字';
/*关键字:change 重命名字段*/
alter table 表名 change 原字段名 新字段名 新的字段类型 [新的字段选项];
例如: alter table test change name username varchar(50) not null default '' comment '用户名字';
20、数据操作
#数据操作
/*关键字:insert 插入数据(增)*/
insert into 表名(字段列表) values(值列表);
例如: create table user(
id int(10) unsigned not null auto_increment comment 'id',
name char(10) not null default '' comment '名字',
age int(3) not null default 0 comment '年龄',
primary key (id)
)engine=InnoDB default charset=utf8 comment='用户表';
--插入数据
insert into user(id,name,age) values(1,'admin_a',50);
insert into user(name) values('admin_b');
/*关键字:delete 删除数据(删)*/
delete from 表名[删除条件];
例如: delete from user where age<1;--删除age小于1数据
/*关键字:update 修改数据(改)*/
update 表名 set 字段1=新值1,字段n=新值n [修改条件];
例如: update user set age=100 where name='admin_a';
21、MySQL数据类型
MySQL三大数据类型:数值型、字符串型和日期时间型
22、JDBC连接数据库(编辑)步骤(主要有六个步骤)
1、注册驱动: Class.forName("com.mysql.jdbc.Driver");显示的加载到JVM中
2、获取连接:Connection conn=DriverManager.getConnection(url,user,pass);
DriverManager下的方法:getConnection(String url,String username,String password)
3、创建一个Statement语句对象:
Statement stmt=conn.createStatement();
PreparedStatement pstmt = conn.PreparedStatement() ;
4、执行SQL语句: ResultSet rs=stmt.executeQuery(Sql); 除了查询语句是executeQuery();其他全部是executeUpdate();
5.处理结果集:ResultSet对象的getXxxx方法,取决于数据库中表的字段的类型
6、关闭资源: 操作完以后要关闭jdbc来释放jdbc资源。先开后关