MYSQL笔记

MYSQL

Structure Query Language(结构化查询语言)简称SQL


MySQL是基于SQL查询的开源跨平台数据库管理系统(DBMS),MYSQL是一个关系数据库管理系统(RDBMS)


MYSQL分为了三个部分:

  1. 数据库管理系统
  2. 数据库管理系统包括多个数据库
  3. 数据库包括多张表,和其他的数据对象
  4. 表由行和列构成
  5. 每一行叫做一条记录,在Java中一条记录就是一个对象

数据库本质是一个文件夹,数据库表本质是一个文件。

SQL的分类

1、DDL(Data Definition Language) 数据定义语言,用来操作数据库、表、列等; 常用语句:CREATE(创建)、 ALTER()、DROP

2、DML(Data Manipulation Language) 数据操作语言,用来操作数据库中表里的数据;常用语句:INSERT(插入)、 UPDATE(修改)、 DELETE(删除)

3、DCL(Data Control Language) 数据控制语言,用来操作访问权限和安全级别; 常用语句:GRANT(授权)、REVOKE(撤回)、DENY(否认)

4、DQL(Data Query Language) 数据查询语言,用来查询数据 常用语句:SELECT(选择)

MySQL的基本数据类型

根据数值取值范围的不同MySQL 中的整数类型可分为5种,分别是TINYINT、SMALUNT、MEDIUMINT、INT和 BIGINT。下图列举了 MySQL不同整数类型所对应的字节大小和取值范围,而最常用的为INT类型的

如果没有指定 unsinged,则默认为有符号

整数类型

数据类型 字节数 无符号数的取值范围 有符号数的取值范围
TINYINT 1 0~255 -128~127
SMALLINT 2 0~65535 -32768~32768
MEDIUMINT 3 0~16777215 -8388608~8388608
INT 4 0~4294967295 -2147483648~ 2147483648
BIGINT 8 0~18446744073709551615 -9223372036854775808~9223372036854775808

小数类型

数据类型 字节数
FLOAT 4
DOUBLE 8
DECIMAL(M,D) M+2

DECIMAL(M,D)中的M表示这个数一共又多少位,D表示小数点后有多少位。例如DECIMAL(5,2)就表示三位整数,两位小数的数。如果D为零,即表示一个整数了,应为没有小数位。所以DECIMAL不仅可以表示小数,还可以表示整数。

M的默认值位10,D的默认值位2。M的最大值为65,D的最大值位30。由此可见DECIMAL是可以表示非常大的值的

字符串类型

CHAR(size),表示存放固定长度的字符串,括号中的的参数设置字符串的长度,最大为255个字符

VARCHAR(size),表示存放可变长度字符串,最大为65535个字节。这里明确字符和字节的区别,在不同的编码中一个字符所占的字节是不同的。而亲还要留出3个字节的空间来保存所存放字符串的大小,所以字符的可用字节为65532个字节。

4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 
5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节 

一个字母,数字,汉字就是一个字符,而位和字节是两个单位

计算机存储信息的最小单位,称之为位(bit),音译为比特,二进制的一个“0”或一个“1”叫一位。

计算机存储容量基本单位是字节(Byte),音译为拜特,8个二进制位组成1个字节。一般而言:一个标准英文字母占一个字节位置,一个标准汉字占二个字节位置。

UTF-8编码中:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。

CHAR和VARCHAR的区别

CHAR存放的的是固定长度的字符串,即使你没有添加够字符长度,也会自动填充。VARCHAR存放可变长度的字符串,会根据添加的字符来确定字符串的大小。另外VARCHAR还会预留1~3个字节来存放字符串的长度。

如果我们已经知道要存放数据的大小,我们应该选用CHAR,反之,使用VARCHAR。因为CHAR比VARCHAR的查询速度快。

文本数据类型

也是用来存放字符串,相对比较简单,不需要指定size

数据类型 储存范围
TINYTEXT 0~255字节
TEXT 0~65535字节
NEDIUMTEXT 0~16777215字节
LONGTEXT 0~4294967295字节

日期与时间类型

数据类型 日期格式
YEAR YYYY
DATE YYYY-MM-DD
TIME HH:MM:SS
DATETIME YYYY-MM-DD HH:MM:SS
TIMESTAMP YYYY-MM-DD HH:MM:SS

可通过设置

TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

来当前TIMESTAMP 为默认时间戳

SQL常用语句

创建语句

  • 创建数据库

    CREATE DATABASE mydb3;
    
  • 创建表

    CREATE TABLE t2(
    	birthday DATE,
    	job_time DATETIME,
    	log_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    );
    

查询语句

  • 查询所有数据库

    SHOW DATABASES;
    
  • 查询数据库的创建信息

    SHOW CREATE DATABASE mybd2;
    
  • 查询当前数据库中的所有表

    SHOW TABLES;
    
  • 查询指定表的创建信息

    SHOW CREATE TABLE t2;
    
  • 查询表结构

    DESC t2;
    
  • 查询表中的数据

    SELECT* FROM t2;
    

插入语句

  • INSERT INTO t4(birthday,job_time) VALUES('2021-8-5','2021-8-5 11:10:30');
    
  • INSERT INTO t2 VALUE(10);
    
  • INSERT INTO t1(id,`name`) VALUES(6,'erha'), (5,'元芳');
    

注意点:

  1. 当要为每一列都插入数据时,可以不写表名后的字段列表
  2. 如果不知道个一个字段赋什么值时,在创建表时,如果允许为null,这可以赋值为null。
  3. 如果在创建表时,指定不能为空,并指定了默认值,可以在赋值的不赋值,自动以默认值赋值
  4. 支持第三种赋值方式

修改语句

  • 增加一列

    alter table `emp` add image VARCHAR(32) not null default '' after resume;
    
  • 修改列

    alter table `emp` modify jod VARCHAR(32) not null default '';
    
  • 删除列

    alter table `emp` drop sex;
    
  • 修改字符集

    alter table `employee` character set utf8;
    
  • 修改列名

    alter table employee change `name` `user_name` varchar(32) not null default '';
    
  • 修改表名

    rename table `emp` to `employee`;
    
  • 修改表中数据

    update employee set salary=5000;
    update employee set salary=2000 where user_name='元芳';
    update employee set salary=salary+1000 ,jod='元帅' where user_name='元芳';
    

删除语句

  • 删除数据库

    drop database myda3;
    
  • 删除表

    drop table t2;
    

    因为执行指令是在一个数据库中执行的,所以可以不用指定是哪个数据库的表名

  • 删除列

    alter table `emp` drop sex;
    
  • 删除一行

    delete from employee where user_name='狄仁杰';
    
  • 删除所有行

    delete from employee;
    

select语句

  • 查询所有列

    #select 后就是要查询的列,*表示通配
    select * from student;
    
  • 查询指定列

    select distinct `name`,`english` from student;
    
  • as起别名

    select `name` ,(math+english+chinese) as sum_score from student;
    
  • where子句的使用

    select * from student where `name`='小华';
    select * from student where english>90;
    select * from student where (math+english+chinese)>250;
    select * from student where math >80 and id>3;
    select * from student where math>english;
    select * from student where (math+english+chinese)>250 and math=80 and math<=90;
    #between and 是一个闭区间
    select * from student where math between 80 and 90;
    select * from student where math in(80,89,81);
    
  • order by 子句

    select * from student order by math; 
    #升序
    select * from student order by math desc;
    #降序
    select `name`, (math+english+chinese) as sum_score from student where sum_score>240;
    #where中不能使用别名 
    select *, (math+english+chinese) as sum_score from student WHERE (math+english+chinese)>240 ORDER BY sum_score;
    

    需要注意的是在where中不可以使用别名

函数


数学函数

#统计满足条件的行数
select count(*) from student;
select count(*) from student where math>80;
#select(*)和select(`id`)的区别#select(*)返回所有的行,select(`id`)返回id不为空的行 
select count(`id`) from student;
#sum
select sum(math) from student;
select sum(math),sum(chinese),sum(english) from student;
select sum(math+chinese+english) from student;
select sum(math)/count(*) from student;
select sum(salary)/count(*) from employee;#avgselect avg(math) from student;
#不会统计salary为空的行select avg(salary) from employee;
#分组  group by 是对employee的一个分组 ,having是对分组后内容的一个过滤
select avg(salary) from employee group by id having avg(salary)>6000;
#max min
select max(math),min(math) from student;

字符串函数

#查询字符集
select charset(dname) from dept;

#将多列拼接成一列
select CONCAT(dname,' 在 ',loc) from dept;

#查找子串开始的位置  dual是系统默认的一个表
select instr('zhouzhihao','hao') from dual;

#转大写
select ucase(dname) from dept;

#转小写
select lcase(dname) from dept;

#从左边开始在n个
select left(loc,2) from dept;

# 从右边开始在n个
select right(loc,2) from dept;

#查看字符串长度 按字节放回
select `loc`,length(loc) from dept;
select length('周志浩') from dept;

#替换字符串
select replace(loc,'ShangHai','上海') from dept;

#字符串比较 相同返回0 ,大于返回1 ,小于返回-1
select strcmp(loc,dname) from dept;

#查找子串 从1开始找,包含1,找两个
select substring(loc,1,2) from dept;

#去空格
select ltrim(loc),rtrim(loc),trim(loc) from dept;

#练习
select CONCAT(ucase(substr(dname,1,1)),substr(dname,2)) as new_name from dept;
select CONCAT(ucase(left(dname,1)),substr(dname,2)) as new_name from dept;

时间函数

#当前日期
select current_date from dual;
#当前时间
select current_time from dual;
#当前时间戳
select current_timestamp from dual;
#只显示日期,不显示时间
select date(log_time) from t4;
#增加时间
select * from t4 where date_add(log_time,interval 3 day)>=now();
#相差多少天
select datediff(now(),log_time) from t4;
#相差多少天
select datediff('2081-12-04',NOW()) from dual;
#相差多少时间
select timediff('10:20:20','10:10:10');
#只返回当前的年  月 日
select year(now()) from dual;
select month(now()) from dual;
select day(now()) from dual;
#返回1970-1-1到现在的秒数
select unix_timestamp() from dual;
#把unix_timestamp的秒数 转换为指定的日期格式(格式是固定的)
#在开发中可以存放一个整数,将其转为一个日期
select from_unixtime(unix_timestamp(),'%Y-%m-%d') from dual;
select from_unixtime(unix_timestamp(),'%Y-%m-%d %H:%i:%s') from dual;

加密函数

#查看登录到mysql的用户以及用户IP
select USER() from dual;
#查看当前使用的数据库表名
select database();
#MD5(str) 为字符串算出一个32位字符串进行加密
select MD5('xx666666');
select length(MD5('xx66666'));
#PASSWORD(str)加密函数,数据库的用户密码就用的是这个加密
select PASSWORD('xx666666');
select * from mysql.user;

流程控制函数

#IF() 相当于一个三元运算符  第一个如果是一个字符串的话就会认为是一个false
select if(false,'hello','get') from dual;
select if(true,'hello','get') from dual;
#IFNULL expr1 不为空,就返回expr1 否则返回expr2
select ifnull(null,'hello');
select ifnull('zzh','hello');
#case 相当于多重判断
select case
		when false then 'hello'
		when true then 'zzh'
		else 'world' end;
#练习
desc t4;
select * from dept;
select if(job_time is null,CURRENT_TIMESTAMP,job_time) from t4;
select ifnull(job_time,CURRENT_TIMESTAMP) from t4;

select dname, (select case when dname='accounting' then '财务部'
			when dname='research' then '研发部'				
			when dname='sales' then '销售部'			
			when dname='operations' then '监管部'			
			else dname end 			
) as job from dept;

分页查询

#分页查询
#从start+1开始查询,查找三行
#第一页
select * from emp order by empno  limit 0,3;
#第二页
select * from emp order by empno  limit 3,3;
#第三页
select * from emp order by empno  limit 6,3;
#最后一页
select * from emp order by empno  limit 12,3;
#下面关键字必须按顺序来  empno不能使用下面的语句
#empno是一个非聚合列,不能使用group by 
select empno,avg(sal) as avg_sal from emp group by deptno having avg_sal>1000 order by avg_sal desc limit 0,2;  																				

group by子句后用having代替where使用

多表查询

select ename,sal,dname,emp.deptno from emp,dept1 where emp.deptno=dept1.deptno;

select ename,sal,dname,emp.deptno 
				from emp,dept1 
				where emp.deptno=dept1.deptno and emp.deptno=10;
				
select ename,sal,grade from emp,salgrade where sal between losal and hisal;
select ename,sal,dname from emp,dept1 where emp.deptno=dept1.deptno;
select * from dept1;
select * from salgrade ;

自连接

#自链接 一张表当两张表使用 返回了169条记录  13*13 
#worker和boss相当于时emp的别名
select * from emp worker,emp boss;
#添加条件
select worker.ename as '员工',boss.ename as 'leader' 
			from emp worker ,emp boss
			where worker.mgr=boss.empno;
/*
自连接的特点:
	一张表当作两张表来使用
	需要给表别名  原表名 空格 别名
	如果列名不清晰,可起别名
*/

子查询

#子查询:select语句嵌套在select语句中
select deptno from emp 
		where ename='SMITH';
#单行子查询:子查询的查询结果只有一行
select deptno,ename from emp where deptno=(
			select deptno from emp where ename='SMITH'		
		);

#多行子查询:子查询的查询结果多行
select deptno,job from emp where deptno=10;

select ename,job,sal,deptno from emp where job in (
	select job from emp where deptno=10
)and deptno!=10;
#多行子查询,还可以当作一张临时表使用

#all操作符
select ename,sal,deptno from emp where sal>all(
	select sal from emp where deptno=30 
);
select ename,sal,deptno from emp where sal>(
	select max(sal) from emp where deptno=30 
);
#any操作符
select ename sal,deptno from emp where sal>any(
	select sal from emp where deptno=30
);
select ename sal,deptno from emp where sal>(
	select min(sal) from emp where deptno=30
);
#多列子查询
select deptno,job from emp where ename='ALLEN';
#where括号中内容与查询的内容一一对应进行比较
select * from emp where(deptno,job)=(
	select deptno,job from emp where ename='ALLEN'
)and ename<>'ALLEN';

表的复制和去重

#复制表结构
create table temp_emp like emp;
desc temp_emp;
#复制表内容
#采用这种方式可以不断地给表中添加数据,当数据够大时,可通过海量数据来测试SQL语句的效率
insert into temp_emp select * from emp;
select * from temp_emp;


#表中删除重复数据的思路
#创建临时表
create table temp_emp1 like temp_emp;
desc temp_emp1;
insert into temp_emp1 select distinct * from temp_emp;
delete from temp_emp;
insert into temp_emp select * from temp_emp1;
drop table temp_emp1;
select count(*) from temp_emp;

合并查询

#union all 关键字可以合并两条select语句查询结果,不去重
select empno,ename,sal from emp where sal>2000;
union all
select empno,ename,sal from emp where deptno=20;
select count(*) from emp where sal>2000;
select count(*) from emp where deptno=20;
select count(*) from 
(select empno,ename,sal from emp where sal>2000
union all
select empno,ename,sal from emp where deptno=20)  temp;
#union all 关键字可以合并两条select语句查询结果,去重
select count(*) from 
(select empno,ename,sal from emp where sal>2000
union 
select empno,ename,sal from emp where deptno=20)  temp;

左外连接和右外连接

#左外连接 显示左表的所有内容 左表在右表中没有的内容显示为null
select dname,ename,	job
from dept1 left join emp
on dept1.deptno=emp.deptno; 
#左外连接 显示右表的所有内容 右表在左表中没有的内容显示为null
select dname,ename,	job
from emp right join dept1
on dept1.deptno=emp.deptno;
#实际开发中最常用还是内连接,多表查询

主键

#在创建表的时候可以定义主键,表示改内容在表中不能重复出现
# primary key 不能重复且,不能为空。
create table t5(
	id int primary key,
	`name` varchar(10),
	job varchar(10)
)
desc t5;
#主键只有一个,但可以有复合主键:只有两个值都相等时,才算重复
create table t6(
 id int,
 `name` varchar(10),
 job varchar(10),
 primary key(id,`name`)
)
desc t6;
#也可以采用创建符合主键的方式,来创建单个主键
create table t7(
 id int,
 `name` varchar(10),
 job varchar(10),
 primary key(id)
)
desc t7;
#在实际开发中,往往每个表都会设计一个主键

外键

/*创建外键的条件:
	1.创建一个主表,主表中被主键或unique约束的字段,可作为为从表外键的依赖
	2.创建一个从表,在从表中可以设置某个字段为外键
外键的特性:
	1.主表中主键的字段添加的数据不能重复
	2.从表中为外键外键的字段可以重复,但必须是外键依赖中有的字段
*/
	create table class(
		class_id int primary key,
		`name` varchar(10)
	);
	desc class;
	create table stu(
		id int primary key,
		`name` varchar(10),
		class_id int,
		foreign key (class_id) references class(class_id) 
	);
desc stu;
insert into class values(100,'java'),(200,'wab'),(300,'PHP');
insert into stu values(1,'erha',100),(2,'yf',200),(3,'gg',300);
insert into stu values(4,'zzh',400);
select *from stu;
/*
外键的使用细节
	1.外键指向的表的字段,要求是primary key或unique
	2.表的类型是Innodb,这样才支持外键
	3.外键字段的类型要和主键字段的类型相同(长度可以不同)
	4.外键字段的值,必须在主键中出现过,或者为null(前提是外键没有设置not null)
	5.一个表中可以有多个外键
	6.一旦建立外键的关系,数据不能随意删除了,两个表建立了依赖关系
*/

check约束

#check约束  对添加数据进行校验
create table t9 (
	id int,
	sex varchar(10) check(sex in('man','woman')),
	sal int check(sal>1000 and sal<2000)
);

insert into t9 values(1,'mid',1);  #添加失败  Check constraint 't9_chk_1' is violated.
insert into t9 values(1,'man',1500);
select * from t9;

自增长

#自增长
create table t10(
	id int primary key auto_increment,
	`name` varchar(10)
);
#两种插入方式
insert into t10 values(null,'erha');
insert into t10 (`name`) values('yuanfang');

/*
	自增长一般于主键配合使用,或者使用unique约束
	自增长一般修饰整型(小数也可以,但用的很少)
	自增长默认从一开始
	可以修改自增长的起始值
*/
alter table t10 auto_increment=10;

索引

/*
	索引的原理:
		1.底层是一个二叉树
		2.占用内存空间
		3.对dml语句的效率有影响,因为要重构二叉树
		4.对那个字段建立索引才会,提高那个字段的查询效率
	为什么没有索引会很慢?
		当要查询一条数据时,都会进行一次全表扫描
	索引的分类:
		1.主键索引
		2.唯一索引(unique)
		3.普通索引(index 开发中常用的索引,可以提高查询速度,又可以让数据有重复)
		4.全文索引(一般开发中不使用MySql自带的全文索引,会使用全文搜索的框架:Solr和ElasticSearch)
		
*/
create table t11(
	id int,
	`name` varchar(10)
);
#查询表中是否有索引
show index from t11;
#添加唯一索引
create unique index id_index on t11(`id`);
#添加普通索引
create index name_index on t11(`name`);
alter table t11 add index name_index (`name`);
#unique索引的优点:查询快

#添加主键索引
#在创建表的时候,添加组件就是一个主键索引
alter table t11 add primary key (id);

#删除普通索引
drop index `name_index` on t11;
#删除主键索引
alter table t11 drop primary key;
#修改索引:先删除,后添加

#查找索引
show index from t11;
show indexes from t11;
show keys from t11;
desc t11;

/*
那些列适合创建索引
	1.较频繁的作为查询条件的字段,应当创建索引
	2.唯一性太差的索引不适合创建索引
	3.更新非常频繁的字段不适合创建索引
	4.不会出现在where子句的字段不适合创建索引
*/

事务

create table t12 (
	id int,
	`name` VARCHAR(6)
);
select * from t12;
#开始一个事务
start transaction;
#设置保存点a
savepoint a;
insert into t12 values(1,'erha');
#设置保存点b
savepoint b;
insert into t12 values(2,'yfang');
#回退到保存点a
rollback to b;
#回退到保存点a
rollback to a;
#回退全部事务:之前的保存点会被删除
rollback
#提交事务:删除所有的保存点,不能再回滚事务
commit;
/*
	事务的细节:
		1.如果不开启一个事务,默认情况下是自动提交,没有自动回滚的功能
		2.在开启事务时,不创建保存点,也会默认有一个保存点,可使用rollback实现回退
		3.mysql的事务机制需要Innodb存储引擎才可以使用
		4.也可以使用SQL语句:set autocommit=off; 来开启事务(就是关闭自动提交的意思)
*/

事务的隔离级别

概念:多个连接开启各自事务操作数据库中的数据时,数据库系统要负责隔离操作,以保证各个连接的在获取数据时的准确性。

通俗解释:当有多个连接在开启事务时,就会保存当前数据库表的所有数据。当连接要对同一张表进行操作(insert into,delete,alter)时,不应该影响到其他事务保存的数据库表中的数据。就是不同事务之间是隔离开来的,事务之间互不影响

MySql有四种隔离级别:定义事务与事务之间的隔离程度

  • 读未提交(Read uncommited)
  • 读已提交(Read commited)
  • 可重复读(Repeated read)
  • 可串行化(Serializable)线程之间的串行

三种读取状态:

  • 脏读:一个事务读取到了另外一个未提交的数据
  • 不可重复读:一个事务读取到了另外一个事务已提交的修改或删除的数据
  • 幻读:一个事务读取到了另外一个事务的已提交的插入的数据

不可重复读和幻读都强调:一个事务读取到另外一个事务已经提交的数据。

  • 不可重复读强调已提交的修改或删除的数据
  • 幻读强调已提交的插入的数据

四种隔离级别的区别:

隔离级别 脏读 不可重复读 幻读
读未提交
读已提交
可重复读
可串行化

强调:事务隔离的前提是,开启事务

默认的隔离级别是:可重复读(REPEATABLE READ)。

#查询隔离级别
show variables like '%isolation%';
#修改隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

事务的四个特性(ACID):

  • 原子性(Atomicity):事务中各项操作,要么全做要么全不做,任何一项操作的失败都会导致整个事务的失败;
  • 一致性(Consistency):事务结束后系统状态是一致的;
  • 隔离性(Isolation,又称独立性):并发执行的事务彼此无法看到对方的中间状态;
  • 持久性(Durability):事务完成后所做的改动都会被持久化,即使发生灾难性的失败。通过日志和同步备份可以在故障发生后重建数据。
create table t12 (
	id int,
	`name` VARCHAR(6)
);
select * from t12;
#开始一个事务
start transaction;
#设置保存点a
savepoint a;
insert into t12 values(1,'erha');
#设置保存点b
savepoint b;
insert into t12 values(2,'yfang');
#回退到保存点a
rollback to b;
#回退到保存点a
rollback to a;
#回退全部事务
rollback
#提交事务:删除所有的保存点,不能再回滚事务
commit;
/*
	事务的细节:
		1.如果不开启一个事务,默认情况下是自动提交,没有自动回滚的功能
		2.在开启事务时,不创建保存点,也会默认有一个保存点,可使用rollback实现回退
		3.mysql的事务机制需要Innodb存储引擎才可以使用
		4.也可以使用SQL语句:set autocommit=off; 来开启事务(就是关闭自动提交的意思)
*/

存储引擎

/*
	Innodb:
		1.支持事务和外键
		2.支持行级锁,所以插入数据的效率会受到影响
	MyISAM:
		1.不支持事务和外键
		2.支持表级锁,插入数据的效率高
	MEMORY:
		1.不支持事务和外键
		2.数据存储在内存中,所以不能存储较大的数据库表,查询速度快
		3.适用于临时表
		4.默认支持索引(hash表)
*/
#查看所有的存储引擎
show engines;
#创建表时设置存储引擎
create table t14(
	id int,
	`name` varchar(10)
)engine MyISAM;
#修改表存储引擎
alter table t14 engine=INNODB;
/*
	如何选择存储引擎
		1.如果你的应用不需要事务,只是简单的CRUD操作,那么可以选择MYISAM
		2.如果需要支持事务,选择Innodb
		3.如果像用户在线状态这种寻求就可以采用MEMORY
*/

视图

/*
	1.视图是根据基表来创建的,视图是虚拟的表(在创建数据库文件中,只有一个结构文件,没有数据文件)
	2.视图也有列,数据来自基表
	3.通过视图改变可以修改基表
	4.基表的改变也会影响数据的数据
	5.视图中还可以创建视图,数据仍然来自基表
*/

#创建视图
create view emp_view01 
		as select empno,ename,job,deptno from emp;
#查看视图结构
desc emp_view01;
#查看表中数据
select * from emp_view01;
#修改视图中列
alter view emp_view01 as select empno,ename,job from emp;
#查看创建视图的指令
show create view emp_view01;
#删除视图
drop view emp_view01;
#修改视图  会影响到基表
update emp_view01 set job='SALESMAN' where empno=7369;
#修改基表  也会影响视图
update emp set job='CLERK' where empno=7369;
#视图中创建视图
create view emp_view02 as select empno,ename from emp_view01;
select * from emp_view02;
#多表为基表创建视图
create view emp_view03 as
		select empno,ename,emp.deptno,salgrade.grade 
		from emp,salgrade,dept1
		where emp.deptno=dept1.deptno and
		emp.sal>salgrade.losal and emp.sal<salgrade.hisal;
select * from emp_view03;
/*
	视图的优点:
		1.方便向用户展示想要展示的表内容
		2.可以通过视图的方式来结合多张表中的数据,方便操作
*/

你可能感兴趣的:(MYSQL笔记,mysql)