数据库***MySQL基础/(反射理解应用)1

一、使用终端cmd练习MySQL数据库:

1、连接

这里是找到mysql的bin路径之后从路径选中输入cmd进入的

如果直接打开cmd

可以输入:cd ...bin路径

 2、show databases; 展示已有数据库

3、create database 数据库名;创建新的数据库。

 4、create table 表名(
列名   类型......):

创建数据库表并展示 详细操作:

 use 数据库名; 用于选中数据库。

5、 插入与查询:

查询:select 字段,字段 from 表名(较快) 或者 select * from 表名(较慢)

插入: 

insert into 表名(列名,列名) value/values (列值,列值) 

insert into 表名 values (列的值)

如果 不指定列名,values后小括号中必须包含所有列的值,并且,数值的顺序必须是表中列的顺序 

6、 清除 clear();

7、修改 update........

8、 删除

!!!清空表 :1)delete from t_student;  2)truncate 表名;

这两种哪种性能好?

drop 最高 truncate 效率更高 delete最慢

删除表:drop table t_student;  表没有了,上面的表还有是空的 效率最高!!!

9、查询select 专门查询属性

也可以根据where id/name 等属性来查询特定数据:

10、使用as起别名:

 

 11、多条件查询

 12、去除掉重复的结果。

!!!!!!! 生效,去重成功。

distinct是对结果集去重,不能对某个列去重。

 所以没有生效。

二、数据库常用语句练习

0、MySQL查询执行的顺序是一个关键的概念,它涉及到SQL语句如何被解析和执行。

1、创建数据库和注释语法:

create DATABASE easy0702a CHARACTER set 'utf8';
drop DATABASE easy0702a;

#注释
-- 注释(--后加空格)
#关系型数据库 其中表是存储数据的基本单位

2、创建表(基本语法和实现)

create table student(
id int auto_increment PRIMARY key,
code int,
name varchar(30) ,有唯一要求就加一个unique 没有key
height double(3,2)

 3、MySQL中常用类型

整数型 tityint (1一个字节) SMALLINT(两个字节) MEDIUMINT(3个字节)int(4个字节) BIGINT(8个字节)
字符型 char(定长的字符) varchar(变长字符) Text(长文本)
char 定长 存入数据不满足总长度,数据所占用的空间还是总长度 手机号 身份证号 学号 最大长度 255
varchar 变长 存入数据所占的空间就是存入数据的个数
最大长度 65535个字节 根据数据结构字符集,行长度等原因,最大长度需要计算
Text 
float double decimal-- BigDecimal
时间 Date time DateTime

4、ALTER相关用法

# 重新定义表
# 重命名
ALTER TABLE `user` RENAME as usertable;
# 设置编码集
ALTER TABLE usertable CHARACTER SET 'utf8mb4';
# 添加列
ALTER TABLE usertable ADD COLUMN `code`
VARCHAR(10);
#重新定义列
ALTER TABLE usertable MODIFY `code` VARCHAR(
10) AFTER id; #after id 变成first 首列

ALTER TABLE usertable MODIFY `code` int;
#列重命名
ALTER TABLE usertable CHANGE `code` usercode;
VARCHAR(10)
#删除列
ALTER TABLE usertable DROP COLUMN usercode;
#删除表
DROP TABLE usertable;

4、DDL 数据库定义语言 和查询语句

对数据库中的数据操作(增删改) DML

4.1 添加数据

INSERT INTO student(id,`code`,`name`,height)
value (1,1001,'张三三',1.75);

INSERT INTO student (`code`,id,height,`name`)
VALUES (1002,2,1.75,'李思思'),(1003,3,1.75,'王舞伍');

INSERT INTO student (`code`,`name`)
VALUES (1004,'赵柳柳');

INSERT INTO student VALUES(5,1005,'冯琪琪',1.75);
 

4.2 删改查清数据 

# 修改数据
update student set code=1105,name='冯琦琦',
height=1.72 WHERE id=5;

# 删除数据 最慢 最快的是drop
DELETE FROM student WHERE id=51;
# 清空表 ----- 保留表结构
TRUNCATE student;
#DQL 数据库查询语言
SELECT id,code,name,height from student;
SELECT 1,id,`name`,'你好' FROM student;
# * 能代表所有字段
SELECT * FROM student;
#整个结果集去重 
SELECT DISTINCT height,code from student;

4.3 合并结果集 

SELECT id,code FROM student
UNION
SELECT `name`,height FROM student;

SELECT id,code FROM student
UNION all
SELECT id,code FROM student;(合并重复的字段加all)

-- union前后SQL语句字段必须相同

4.4 as起别名 

select student_id as studentid from student;

select count(*) as '数量' from student;

4.5 where条件查询

 

#where 条件
select * from student;
#数据判断 = > < !=
select * from student where gender='女'

select * from student where student_id<3
select * from student where student_id<=3
select * from student where student_id!=4
# in not in
select * from student where student_id in (1,3,5,7,9,30)
select * from student where student_id not in (1,3,5,7,9,30)

# 对null值的判断
alter table student modify student_name varchar(10)
insert into student(birthday,gender) values(now(),'女')
select * from student
-- 为空
select * from student where student_name is null;
-- 非空
select * from student where student_name is not null

4.6 where 逻辑判断and or between - and 范围判断

-- 逻辑判断
select * from student where student_id<10 and gender='女'
select * from student where student_id<10 or gender='女'
-- 范围判断
select * from student where student_id BETWEEN 3 and 5

4.7 模糊查询 like %任意个数任意字符 _有且仅有一个字符

select * from student where student_name like '张%'
select * from student where student_name like '张_'
select * from student where student_name like '_三'
select * from student where student_name like '___' -- 三个下划 名字有三个字符的
select * from student where student_name like '%王%'

4.8 子查询  (里面是子查询语句 ) 

#子查询
#当做数据集使用
select * from student where student_id in (
select student_id from score where score >90
)
#当做表使用
select student_id from (
select * from student ) as a 

select * from student where not exists (
  select * from score where score>90
)#后面的结果集没有数据 前面的结果集就有数据了
select * from student where not exists (
  select * from score where score>100
)

 4.9、any all

重点!!! 详细见下图

 比如:

-- 查询有任意一门成绩比1号学生的的各科成绩中一个大的学生id
select student_id from score where score > any(
select score from score where student_id=1
)

4.10 排序!!!!! 

#排序 order by 正序 asc 倒序 desc
select * from student order by student_id asc

select * from student order by student_id desc

select * from student order by student_id #默认正序

select * from score order by score asc , student_id desc 
-- 优先使用第一个列进行排序,第一个列有重复值时排第二个列
select * from score order by score , student_id desc #第一个列asc

4.11 部分查询 limit

#部分查询 limit
#  limit 5 查询前5个
#  limit 0,8 limit start,count
select * from score order by score limit 3
select * from score order by score desc limit 5,3

4.12 case when then 

#case when then
select student_id,student_name,
  case gender when '男' then '男孩子' when '女' then '女孩子'
  else '未知' end as '性别' from student -- end后as可以省略

select *,case when score >= 80 then '优秀' when score >= 60
then '及格' else '不及格' end as '等级' from score 

 4.13 分组查询 group by

select count(*) ,gender from student group by gender
select count(*) ,student_name,gender from student group 
by gender

4.14 聚合函数 count() sum() avg() max() min()

 select count(*) '数量',sum(score) '总成绩',avg(score)
'平均成绩',max(score) '最高成绩',min(score) '最低成绩',
student_id
from score group by student_id -- as省略了

4.15 having 对分组之后的数据进行筛选 

#having 对分组之后的数据进行筛选 和select的数据无关
#where是筛选表中原有的数据
select count(*) '数量',
student_id
from score group by student_id having avg(score)>=60

4.16 count() 

#count
select * from student;
select count(*) from student;
select count(student_name) from student; -- 不计算null值的数据
select count(1) from student; -- 相当于count(* ,1)
select count(student_id) from student; -- 有主键的查询效率很快

4.17 关联表 join

#关联表 join
#学生的姓名和成绩 student score
select student_name,score from student as a 
join score as b on a.student_id=b.student_id -- 通过id关联姓名和成绩
#学生的姓名和成绩以及科目 student score course 
select a.student_name,c.course_name,b.score
from student as a join score as b on a.student_id=b.
student_id
join course as c on b.course_id=c.course_id

4.18 内链接inner join  left join right join

# 内链接 inner join  外连接left join  right join  Oracle还支持 full join
# 内链接 结果集中只会显示A表和B表有关联的数据
# 内链接 也可以直接使用join

select a.*,b.* from student as a 
inner join score as b on a.student_id=b.student_id
# 左外链接 以左表为主表,展示出主表中所有的数据 下面主表为student
select a.*,b.* from student as a 
left join score as b on a.student_id=b.student_id
# 右链接 以右表为主表,结果集中显示主表中所有的数据
select a.*,b.* from student as a 
right join score as b on a.student_id=b.student_id

select a.*,b.* from student as a 
left join score as b on a.student_id=b.student_id where b.student_id is null
union
select a.*,b.* from student as a 
right join score as b on a.student_id=b.student_id where a.student_id is null -- 两圆相交取没交上的

4.19 交叉链接 Cross join 笛卡尔积 

select a.*,b.* from student as a ,score as b where a.student_id=b.student_id

4.20 行列转换 

SELECT *,1 FROM t_score;
#行列转换
SELECT *,
case when `subject`='数学' then fraction else 0 end as 
'数学',
case when `subject`='语文' then fraction else 0 end as
'语文',
case when `subject`='英语' then fraction else 0 end as
'英语' 
 FROM t_score;
 
SELECT `name`,
sum(case when `subject`='数学' then fraction else 0 end )as -- fraction 分数
'数学',
sum(case when `subject`='语文' then fraction else 0 end )as
'语文',
sum(case when `subject`='英语' then fraction else 0 end )as
'英语' 
FROM t_score group by `name`;

 三、Java反射概念及理解:

java是面向对象,在java内存中的数据都是对象
java的类也应该有一段内存来记录java类的信息

这段信息用来描述某个类中定义了那些属性,方法以及构造方法
这段描述类定义的信息也是一个对象,
这个用来描述<类的定义>的对象属于Class类型
java程序中每一个类都有一个<类对象>用来描述这个类的定义

在程序中我们可以利用每个类的类对象,动态地获取类中已经定义好的属性,方法以及构造方法
并且可以获取/修改对象中的属性,也可以调用对象中的方法

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class EasyA {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        //获取类的类对象 描述类中定义的属性,方法。。。看上面
        //通过类型.class
        Class clazz=User.class;
        //对象.getClass()
        clazz=new User().getClass();
        //Class.forName()
        clazz=Class.forName("com.easy728.User");

        //获取类中的属性
        //只能获取public修饰的属性
        Field codeField=clazz.getField("code");
        //只能获取到该类中定义的属性
        Field nameField=clazz.getDeclaredField("name");
        //所有使用public修饰的顺序
        Field[] publicFieldArr=clazz.getFields();
        //获取到该类中定义的所有的属性
        Field[] declaredFirldArr=clazz.getDeclaredFields();

        //获取对象中的属性
        User user = new User(222,"easy10001","张三");
        System.out.println(user);
        Object obj = codeField.get(user);
        System.out.println(obj);
        codeField.set(user,"Easy2222");
        System.out.println(user);

        nameField.setAccessible(true);
        obj = nameField.get(user);
        System.out.println(obj);
        //反射可以破坏类的封装性

        //通过类中定义的方法  方法名  参数列表
        Method testaMethod=clazz.getMethod("testa");
        testaMethod=clazz.getDeclaredMethod("testa");
        //调用方法
        testaMethod.invoke(user);

        Method testbMethod=clazz.getMethod("testb",int.class,String.class);
        Object returnObj = testbMethod.invoke(user,23,"张三11111");
        System.out.println(returnObj+"-------------------int string");
        testbMethod=clazz.getMethod("testb", double.class, String.class);
        returnObj = testbMethod.invoke(user,32.88,"李思思22222");
        System.out.println(returnObj+"-------------------double string");

        //构造方法
        Constructor con=clazz.getConstructor();
        con=clazz.getConstructor(int.class,String.class,String.class);

        Object instance = con.newInstance(1002,"easy1002","李思思");
        System.out.println(instance);
        //就是调用的无参构造方法实例化对象
        clazz.newInstance();

    }
}

class User{
    int id;
    public String code;
    private String name;

    public User(){}

    public User(int id,String code,String name){
        this.id=id;
        this.code=code;
        this.name=name;}

    public void testa(){
        System.out.println("User类中的testa方法");
    }

    public void testb(int num,String name){
        System.out.println("num="+num);
        System.out.println("name="+name);
        System.out.println("User类中testb方法,接受 int,String 无返回");
    }
    public String testb(double num,String name){
        System.out.println("num="+num);
        System.out.println("name="+name);
        System.out.println("User类中testb方法,接受 double,String 无返回");
        return "testb return String";
    }

    @Override
    public String toString() {
        return "User{" +
                "code='" + code + '\'' +
                ", id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class EasyB {

    //模拟数据库中的数据转换成java中的对象
    //数据库中的数据 List<Map<String,?>>
    public static <T> List<T> convert(List<Map<String,?>> data,Class<T> clazz) throws InstantiationException, IllegalAccessException {
        Field[] fieldArr=clazz.getDeclaredFields();
        for(Field field:fieldArr){
            field.setAccessible(true);
        }
        List<T> result = new ArrayList<>();
        //转换每一行数据 item是每一行数据
        for(Map<String,?> item:data){
            T t=clazz.newInstance();
            //给t对象设置每个属性
            for (Field f:fieldArr){
                //类中的属性名和表中的字段名是一样的
                String name = f.getName();
                if(item.containsKey(name)){
                    Object obj = item.get(name);
                    f.set(t,obj);
                }
            }
            result.add(t);
        }
        return result;
    }
}

四、视图 函数 触发器 存储过程 索引 事务 

4.1 视图

 view
create view v_student_score AS
select a.student_name,c.course_name,b.score from student as a 
left join score as b on a.student_id=b.student_id
left join course as c on b.course_id=c.course_id
视图可以当做表格进行查询
select * from v_student_score 
视图中不存储真实数据的,其中存储的是一个已经编译好的SQL语句
删除视图
drop view v_student_score
drop view IF exists v_student_score -- 这个没有视图也能运行,不报异常
修改视图的定义  删除掉原视图 重新创建

 4.2 触发器 增删改

触发器 增删改 Trigger
DROP trigger trigg_b_i_student
create trigger trigg_b_i_student before insert on student
for each ROW
BEGIN
   insert into score (student_id,course_id,score) VALUE(new.
   student_id,1,80);

END;

insert into student(student_id,birthday,gender) value (16,now(),'男') 每次运行trigger也运行

4.3 三大范式 !! 好,不是一定要遵守

三范式 三大范式的概念
第一范式:表中每个字段都不可以在分割
第二范式:在第一范式基础上,每个字段必须完全依赖主键,不可部分依赖
第三范式:在第二范式基础上,每一个字段必须直接以来主键,不可传递依赖

4.4 事务

四大特性:原子性 一致性 隔离性 持久性

4.5 函数

4.5.1 常用的数值型函数,很重要!

4.5.2 向上转型ceil 向下转型floor 四舍五入round

函数 存储过程 循环结构 事务 索引
函数 function
已经用过的函数 count sum avg min max now
select ceil(12.01),floor(12.999),round(12.49),round(12.51),RAND()*12 

4.5.3 随机获取数据rand 和sign函数

 随机获取数据
select * from student order by rand() limit 3

select * from student order by rand() limit 3

select sign(12),sign(-22)

 SIGN() 函数,它的作用是 返回数值的符号(正数、负数或零)

1 → 如果 number > 0(正数)

-1 → 如果 number < 0(负数)

0 → 如果 number = 0(零)

4.5.4 字符串函数 

#字符串函数 mysql不能使用+拼接字符串


select concat('你好','hello','mysql','java')


#length 字节数 char_length 字符数


select length('你好'),length('ab'),
CHAR_LENGTH('你好'),CHAR_LENGTH('123')

select substring('abcdef',2),
substring('abcdef' from 2),
substring('abcdef',2,3),
substring('abcdef' from 2 for 3)

select replace('abcdef','cd','CD')

select '  abcdef  ',trim('  abcdef  ')

select left('abcdef',3),right('abcdef',3)

select REVERSE('abcdef')

 

4.5.5 自定义函数 

#自定义函数
set global log_bin_trust_function_creators=TRUE;
create function funa( num int) returns INT 
BEGIN
    #声明变量
    DECLARE result int DEFAULT 0;
    #变量赋值
    set result = num*2;
    return result;
END;

select funa(score) from score 

4.5.6 时间函数

这是时间格式化各种练习的记录网站

 MySQL DATE_FORMAT() 函数

获取当前时间
select now(),SYSDATE()
select CURRENT_DATE,CURRENT_TIME

时间格式化
select DATE_FORMAT(now(),'%Y年%m月%d日 %H:%i:%S')

4.5.7 自定义函数隐藏电话号码 

create function funb(phone varchar(20))
returns varchar(20)
BEGIN
  DECLARE leftstr varchar(20);
  DECLARE rightstr varchar(20);
  DECLARE star varchar(20) default '****';
  DECLARE result varchar(20);
  set leftstr=left(phone,3);
  select substring(phone,8,4) into rightstr;
  set result=CONCAT(leftstr,star,rightstr);
  return result;
END;

select funb('13388886543')

-- 结果表示 133****6543

4.6 存储过程 

# 存储过程
# 存储过程的参数的作用 in out inout

# stuid couid 锁定学生课程的id score随机生成一个替换并返回
create PROCEDURE proa(in stuid int,in couid int,out score int)
BEGIN
  DECLARE sc int ;
  set sc=floor(rand()*101);
  update score set score=sc where student_id=
  stuid and course_id=couid;
  set score=sc;
  
END;

call proa(4,3,@val);
select @val 

4.7 索引 加快检索数据效率的数据结构

其数据结构图表:

 4.7.0 索引的概念:
索引是一种特殊的文件 InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所
有记录的 引用指针
索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新
数据库表中数据。 索引的实现通常使用 B 树及其变种 B+ 树。 更通俗的说,索引就相当于目录。为了方便
查找书中的内容,通过对内容建立索引形成目录。而且索引是一个文件,它是要占据物理空间的。
MySQL 索引的建立对于 MySQL 的高效运行是很重要的,索引可以大大提高 MySQL 的检索速度。比如我
们在查字典的时候,前面都有检索的拼音和偏旁、笔画等,然后找到对应字典页码,这样然后就打开字
典的页数就可以知道我们要搜索的某一个 key 的全部值的信息了。
4.7.01 索引的优缺点
1)索引的优点
可以大大 加快数据的检索速度 ,这也是创建索引的最主要的原因。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
2)索引的缺点
时间方面: 创建索引和维护索引要耗费时间 ,具体地,当对表中的数据进行增加、删除和修改的时
候,索引也要动态的维护,会降低增 / / 删的执行效率;
空间方面: 索引需要占物理空间

4.7.1 创建普通索引语句解析

CREATE INDEX index_student_name ON student(student_name(3));

   在 student 表的 student_name 列上创建名为 index_student_name 的索引

(3) 表示这是一个前缀索引,只对 student_name 列的前3个字符建立索引

适用于较长的字符串列,可以节省索引存储空间

4.7.2  索引使用情况分析
情况1:简单查询(未使用索引)
SELECT student_name FROM student;

这个查询会进行全表扫描,不会使用索引

原因:没有WHERE条件,需要返回所有记录

情况2:条件查询(使用索引)
SELECT * FROM student WHERE student_name='张三';

这个查询可能会使用我们创建的索引

但因为是前缀索引(只索引前3个字符),如果"张三"长度超过3个字符,索引效果会降低

4.7.3. 查看索引使用情况
EXPLAIN SELECT student_name FROM student;
EXPLAIN SELECT * FROM student WHERE student_name='张三';

EXPLAIN 命令显示MySQL如何执行查询

  • 关键字段:

    type:显示访问类型,ALL为全表扫描,refrange表示使用了索引
  • key:显示实际使用的索引
  • rows:预估需要检查的行数
4.7.4、!!! 索引的类型及创建语句!!!

#索引 索引是一种能够加快检索数据效率的数据结构

#作用加快检索效率
#分类 主键索引 唯一索引 普通索引 联合索引 全文索引

#!!!1 创建普通索引 见上分析
create index index_student_name on student(
student_name(3))
#怎么用索引
select student_name from student;#用不到索引
select * from student where student_name='张三'
#查看是否使用到了索引
有加法不行 
explain select student_name from student;
explain select * from student where 
student_name='张三';
#为什么会加快检索效率
#如果不使用索引会怎样?全文检索


#短索引  ... 15~20


#!!!2 联合索引  将两个或更多字段的值放在索引结构上 后面的字段一般用来排序
create index index_student_name_birthday on student(student_name(10),birthday)
#最左匹配原则
#当使用联合索引查询数据,必须要使用到该索引的最左侧列
explain select * from student where student_name='张三'
explain select * from student where birthday<now();

#!!!3 主键索引 表中创建(设置)主键,表中就拥有了主键索引

#主键列的值不能为空,不能重复
#主键索引也叫做聚簇索引,也叫做聚集性索引
#创建索引之后,所有的数据在逻辑上都聚集在索引结构下
#主键索引直接关联每一行数据
#非主键索引叶子节点记录的是主键值

explain select * from student where student_id=1


#!!!4 唯一索引
#约束:唯一索引的列的值不能重复,可以为null
create unique index unindex_student_name ON student(student_name(10))

#!!!5 全文索引
-- CREATE FULLTEXT INDEX index_content ON table_name(content)
-- 用的很少

4.8 索引的需求 

那些列上需要创建索引 
1、经常检索数据的字段需要创建索引
2、经常排序的字段

哪些字段不需要创建索引
数据重复率特别高  例如性别  星期

4.9 索引失效 

#索引失效  使用索引列但是没有用到索引的情况
#1、使用or  如果or两边的字段都是索引列还是会使用到索引
#2、模糊查询 使用like 第一个字符是非确定字符(_%)
#3、没有遵循最左匹配(最左前缀匹配)原则 一般前三个字符
#4、类型发生转换时
#5、索引列经过函数处理
#6、mysql觉得不需要索引

explain select * from student where substring (student_name,1,1)='张' -- 经过函数处理了
explain select * from student where student_name like '张_'
explain select * from student where student_name like '_三' -- 没使用到索引
explain select * from student where student_id =1; -- 类型发生转换,索引失效
explain select * from student where student_id ='1';

5 存储过程 

#循环结构
# loop  while repeat


create PROCEDURE proc(in num int)
BEGIN
  loopa: LOOP 
  IF num=0 THEN 
  leave loopa;
  end if;
  insert into teacher(teacher_name) value ('name');
  SET num=num-1;
  end loop; -- 相当于}

END;

drop PROCEDURE proc; -- 想改里面条件要先删除再运行才生效


call proc(5);

create PROCEDURE prod(in num int)
BEGIN
  REPEAT
    insert into teacher(teacher_name) value ('repeat');
  SET num=num-1;
UNTIL num=0 END REPEAT;
END;

call prod(4)

create PROCEDURE proe(in num int)
BEGIN
  WHILE num>0 DO
    insert into teacher(teacher_name) value ('while');
  SET num=num-1;
END WHILE;
END;

call proe(5)

delimiter -- 重新设置默认分割符,原来是;

 6 事务

# 事务
START TRANSACTION;

update student set student_name='赵老大' where student_id=1;

update student set student_name='钱多多' where student_id=2;
#提交 使上面语句生效 提交之后不能回滚
commit;
#回滚 撤回上面语句,不生效
ROLLBACK;

 

五、视图的作用和优点 

5.1 视图的概念:

视图是数据库中的一个虚拟表,它基于一个或多个实际表(称为基表)的查询结果。视图不直接存储数据,而是存储查询定义,当访问视图时,数据库引擎会动态执行存储的查询并返回结果。

5.2 视图的特性:

  1. 虚拟性

    • 视图不存储实际数据,只保存查询语句

    • 每次访问视图都会重新执行底层查询

  2. 动态性

    • 视图数据会随基表数据变化自动更新

    • 实时反映基表的最新状态

  3. 派生性

    • 视图数据完全来源于基表

    • 不能脱离基表独立存在

5.3 视图的作用:

1)简化了操作,把经常使用的数据定义为视图。

2)安全性,用户只能查询和修改能看到的数据。

3)逻辑上的独立性,屏蔽了真实表的结构带来的影响。

以往当我们查询数据时,一定要很认真的地从设计select语句开始,将需要查询的每个字段写在sql语句里,每次你要以同样的条件来查询数据时,那么每次都要重复输入相同的查询语句,效率很低。若将这个经常要重复使用的查询语句创建成视图,就不用那么麻烦了!直接用select * from 视图名就行了,其实将查询语句创建成视图,不仅仅是简化查询的动作;更重要的是,视图具备数据表的特性,还可以衍生出更多的应用。

5.4、视图的优缺点

5.4.1 优点

1)简化了操作,把经常使用的数据定义为视图。

我们在使用查询时,在很多时候我们要使用聚合函数,同时还要 显示其它字段的信息,可能还会需要关联到其它表,这时写的语句可能会很长,如果这个动作频繁发生的话,我们可以创建视图,这以后,我们只需要select * from view就可以啦,这样很方便。

2)安全性,用户只能查询和修改能看到的数据。

因为视图是虚拟的,物理上是不存在的,只是存储了数据的集合,我们可以将基表中重要的字段信息,可以不通过视图给用户,视图是动态的数据的集合,数据是随着基表的更新而更新。同时,用户对视图不可以随意的更改和删除,可以保证数据的安全性。

3)逻辑上的独立性,屏蔽了真实表的结构带来的影响。

视图可以使应用程序和数据库表在一定程度上独立。如果没有视图,应用一定是建立在表上的。有了视图之后,程序可以建立在视图之上,从而程序与数据库表被视图分割开来。

5.4.2 缺点

1)性能差

数据库必须把视图查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,数据库也要把它变成一个复杂的结合体,需要花费一定的时间。

2)修改限制

当用户试图修改视图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,对于简单的视图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值