牛客 sql练习mysql

sql

36 :从一个表中复制想要的字段到另一个新创建的表中

思路:

创建一个表,并且将另一个表中的目标字段导入该表

实例:

create table if not exists actor_name
(
    first_name varchar(45) not null,
    last_name varchar(45) not null
);
insert into actor_name
select first_name,last_name
from actor;

扩展:

1.常规创建表
create table if not exists 目标表
2,复制表格
create 目标表格 like 来源表
3,将table1 的部分拿来创建 table2

1,关键字

1,view

​ mysql视图表(view)是一种虚拟存在的表,它和真实的表一样,但是它依赖于真实的表,即它做了一些筛选,只展示一个表中它想要的字段,或者只展示多个表中它想要的字段。但是当真实的表发生变化的时候,它也会发生变化。

1,创建视图

create view <视图名> as <select 语句>

2,alter

当我们需要修改数据表名或者删除数据表字段时,就需要用到 mysql 的 alter 命令

基本语法:

删除字段

alter table table_name drop i(字段);

添加字段:

alter table table _name add i(字段) int(类型);

示例:

增加字段:

alter table actor add create_date datetime not null 
default '2020-10-01 00:00:00';

3,drop

删除字段

4,add

增加字段

5,trigger

触发器;

基本语法:

create trigger trigger_name
trigger_time trigger_event on tbl_name
for each row
trigger_stmt
  • trigger_name :触发器名称
  • trigger_time :触发时机,取值为before 或者 after
  • trigger_event:触发事件,取值为 insert ,update,delete
  • trigger_stmt:触发器程序体,可以是一句sql语句,或者用 begin 和 end 包含的多条语句,每条语句结束要用分号结尾。

new 和 old 详情:

使用方法:
new.columnName(数据库的某一列	)

用来表示触发器所在表中,触发了触发器的哪一行数据

1,在insert 中,new 用来表示将要(before)或者已经(after)插入的新数据
2,在update 中,old用来表示将要或者已经被修改的原数据,new 表示将要或者已经修改为的新数据
3,在delete中,old用来表示将要或者已经被删除的原数据;

实例:

构造一个触发器:

create trigger audit_log
after insert on employees_test
for each row
begin
insert into audit values(new.id,new.name);
end

2,聚合函数

3,mysql索引

索引效率:

主键索引> 唯一性索引 > 普通索引

1,mysql 索引的建立对于mysql的高效运行是很重要的,索引可以大大提高mysql的检索速度。
2,索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。
3,创建索引的时候,你需要保证该索引是应用在sql查询语句的条件(一般作为where子句的条件)
实际上,索引也就是一张表,该表保存了主键与索引字段,并指向实体表的记录。
4,上面都说使用索引的好处,但过多的使用索引将会造成泛滥,因此索引也会有它的缺点:虽然索引提高了查询效率,但是同时也会降低更新表的速度,那,在 insert,update,delete 的时候,mysql不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。

1,普通索引

这是最基本的索引,它没有任何限制,

create index indexName on table_name(column_name)

修改表结构(添加索引)

alter table tableName add index indexName(column_name)

创建表的时候直接指定:

create table mytable(
id int not null,
    username varcher(10) not null,
    index [indexName](username(length))
);

删除索引的语法:

drop index [indexName] on mytable;

2,唯一索引

它与前面的普通索引类似,不同的就是;索引列的值必须唯一,但允许有空值。如果是组合索引,则列值得组合必须唯一。

创建索引:

create unique index indexName on mytable(username(length))

修改表结构:

alter table mytable add unique [indexName] (username(lengtg))

创建表的时候直接指定:

create table mytable(
id int not null,
    username varchar(10) not null,
    unique [indexName] (username(length))
)

3,使用alter 命令添加和删除索引

有四种方式添加数据表的索引:

alter table tbl_name add primary key (column_list)
该语句添加一个主键,这意味着索引值必须是唯一的,但不能为null
alter table tbl_name add unique index_name (column_list)
这条语句创建索引的值必须是唯一的(除了null值以外,null可能会出现多次)
alter table tbl_name add index index_name (column_list)
添加普通索引,索引值可出现多次
alter table tbl_name add fulltext index_name (column_list)
该语句指定了索引为 fulltext ,用于全文索引

实例

alter table testalter_tbl add index (c)

你还可以在alter 命令中使用 drop 子句来删除索引

alter table testalter_tbl drop index c;


使用alter 命令添加和删除主键

主键作用于列上 (可以一个列或者多个列联和主键),添加主键索引时,你需要确保该主键默认不为空(not null)

alter table testalter_tbl modify i int not null;
alter table testalter_tbl add primary key(i);

你也可以使用alter 命令删除主键:

alter table testalter_tbl drop primary key;

删除主键时,只需指定primary key,但在删除索引时,你必须知道索引名

4,显示索引信息

你可以使用 show index 命令来列出表中相关的索引信息,可以通过添加 \g 来格式化输出信息。

实例:

show index from table_name; \g

5,create 和 alter 的区别

1, alter 可以省略 索引名,数据库会默认根据第一个索引列赋予一个名称;create 必须指定索引名称;

2,create 不能用于创建 primary key 索引

3,alter 允许一条语句同时创建多个索引;create 一次只能创建一个索引。

alter table 表名 add primary key (id) ,add index <索引名> (col1,col2,---)

6,索引深入理解

1,为什么使用索引

一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,我们遇到最多的还是一些复杂的查询操作,因此对于查询语句的优化显然是比较需要的,所以这个时候就是需要索引了。

2,为什么要有索引呢?

索引在mysql中也叫“键“,就是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能,非常关键,尤其是当表中的数据越来越大的时候,索引对于性能的影响更加重要,索引优化应该就是对查询性能优化最有效的手段。索引能够轻易将查询性能提高好几个数量级。索引相当于字典的音序表,直接通过缩小查询范围快速查询。

3,索引的原理

索引的目的在于提高查询效率,与我们查询图书所用的目录是一个道理:先定位到章节,然后再定位到该章节中的某个小节,然后找到页数。类似的有:查字典,查车次
本质都是:通过不断的缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机事件变成顺序的事件,也就是说,有了这种索引机制,我们总是可以用同一种查询方式来锁定数据
1,分段查询,将大量的数据分成相应的段数,当需要查找某个数据时,判断它属于哪个分段的,如此可以省去遍历其他分段的时间。
2,但是当我们遇到千万级的数据时,怎么去分段就成了问题了。可以使用搜索树。
3,数据库实现比较复杂,一方面数据是保存在磁盘上的,另一方面为了提高性能,每次又可以把部分数据读入内存来计算,因为我们知道访问磁盘的成本大概是访问内存的十万倍左右,所以简单的搜索树是难以满足复杂的应用场景。

4,磁盘IO与预读

考虑到磁盘IO是非常昂贵的操作,计算机操作系统做了一些优化,当一次IO时,不光是把当前磁盘的地址的数据,而是把相邻的数据也都读取到内存缓冲区内,因为局部预读性原理告诉我们,当计算机访问一个地址数据的时候,与其相邻的数据很快也会被访问到。每次IO读取的数据我们称之为一页(page)。具体一页有多大的数据跟操作系统有关,一般为4k或者8k,也就是我们读取一页内的数据的时候,实际上才发生一次IO,这个理论对于索引的数据结构设计非常有帮助。

5,索引的数据结构

1,任何一种数据结构都不是凭空产生的,它都有它的背景和使用场景。
2,使用场景:每次查找数据的时候把磁盘IO次数控制在一个很小的数量级,最好是常数数量级。那么我们就想如果一个高度可控的多路搜索树是否能够满足需求呢,就这样,B+树应运而生。
B+树的查找过程[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gC5qq0Jv-1625219504519)(C:\Users\pengzhang1\Desktop\sql\b+树.jpg)]
1,浅蓝色的块,我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项 17 和 35 ,包含指针 p1,p2,p3, p1表示小于17的磁盘块,p2表示在 17 和 35 之间的磁盘块,p3 表示 大于 35 的磁盘块。真实的数据 存在叶子节点即 3,5,9,10,13,15,28,29,36,60,75,79,90,99。非叶子节点只不存存储真实的数据,只存储指引搜索方向的数据项,如 17,35 并不真实存在于数据表中。
如图所示,如果要查找数据项 29,那么首先会把磁盘块1 加载到内存,此时发生一次IO ,在内存中用二分查找确定 29 在 17和35之间,锁定磁盘块 1 的 p2指针,内存时间因为非常短,(相比磁盘的IO)可以忽略不记,通过磁盘块1 的p2 指针的磁盘地址把磁盘块3加载到内存,发生第二次IO,29在26 和 30 之间,锁定磁盘3 的 p2 指针,通过指针加载磁盘块 8 到内存,发生第三次IO,同时在内存中做二分查找找到 29,结束查询,总计三次IO。真实的情况是,三层的b+树可以表示上百万的数据,如果上百万的数据查询只需要三次IO,那么性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本事非常高。

6,b+树的性质

1,索引字段要尽量的小:
通过上面的分析我们知道IO次数取决于b+树的高度h,假如当前数据表的数据为N,每个磁盘块的数据项的数量是m,则有 h = log(m+1)N,当数量N一定的情况下,m越大,h越小;而 m = 磁盘块的大小/数据项的大小,磁盘块的大小也就是一个数据页的大小,是固定的,如果数据项占据的空间越小,数据项的数量越多,树的高度越低。这就是为什么每个数据项,即索引字段要尽量的小,比如int 占 4 个字节,要比 bigint 8个字节少一半。这也就是为什么b+树要求把真实的数据放到叶子节点,而不是内层节点,一但放到内层节点,磁盘块的数据项就会大幅度下降,导致树增高。当数据项等于1时将会退化成线性表。
2,索引的最左匹配特性(即从左往右匹配)

7,mysql索引管理

1,功能

1,索引的功能就是加速查找
2,mysql 中的 primary key,unique ,联合唯一也都是索引,这些索引除了加速查找功能,还有约束的功能。

2,mysql 的索引分类

普通分类:
1,普通索引 index:加速查找
2,唯一索引
	主键索引:primary key:加速查找+约束(不为空且唯一)
	唯一索引:unique:加速查找+约束(唯一)
3,联合索引
	primary key (id,name):联合主键索引
	unique(id,name):联合唯一索引
	index(id,name):联合普通索引
4,全文索引:fulltext :用于搜索很长一篇文章的时候,效果最好
5,空间索引:spatial:了解就好,基本不用

8,强制索引

如果查询优化器忽略索引,您可以使用force index来提示它使用索引

基本语法:

select *
from table_name
force index(index_list)
where condition;

示例:

select *
from salaries force index(idx_emp_no)
where emp_no = 10005

4,mysql 视图

1,mysql 视图是什么

简单的来说:view 就是在数据库表上另外封装的一个表,这个表并不是真实存在的,它依赖于真实的表,相当于对数据库表中的字段做了一个筛选,只显示它想要的字段。

技巧:如果经常需要从多个表查询指定字段的数据,可以在这些表上建立一个视图,通过这个视图显示这些字段的数据

mysql 的视图不支持输入参数的功能,因此交互性上存在缺陷。但对于变化不是很大的操作,使用视图可以很大程度上简化用户的操作。

视图不同于数据库表:

  • 视图不是数据库中真实存在的表,而是一张虚拟的表,其结构和数据是建立在对数据库中真实表的查询基础上的。
  • 存储在数据库中的,它所对应的数据实际上是存储在视图所引用的真实表中的。
  • 视图没有实际的物理记录,不是以数据集的形式存储在数据库中的,它所对应的数据实际上是存储在视图所引用的真实表中的。
  • 视图是数据的窗口,而·表是内容。表是实际数据的存放单位,而视图只是以不同的显示方式展示数据。其数据来源还是实际表。
  • 视图是查看数据表的一种方法,可以查询数据表中某些字段构成的数据,只是一些sql语句的集合。从安全的角度来说,视图的数据安全性更高,使用视图的用户不直接接触数据库表,不知道表结构。
  • 视图的建立和删除只影响视图本身,不影响对应的基本表。

视图的优点:

视图与表在本质上虽然不相同,但是经过定义以后,可以进行查询,修改,更新,删除操作。

1)定制用户数据,聚焦特定的数据

在实际的应用中,不同的用户可能对不同的数据有不同的要求。例如:当数据库同时存在时,如学生基本信息表,课程表和教师信息表等多种表同时存在时,可以根据需求让不同的用户使用各自的数据。学生查看修改自己基本信息的视图,安排课程人员查看修改课程表和教师信息表的视图,教师查看学生信息表和课程信息表的视图。

2)简化数据操作

在使用查询的时候,很多时候要使用聚合函数,同时还要显示其他字段的信息,可能还需要关联到其他表,语句可能会很长,如果这个动作发生的频繁的话,可以创建视图来简化操作。

3)提高数据的安全性

视图是虚拟的,物理上是不存在的,可以只授予用户视图的权限,而不具体指定使用表的权限,来保护基础数据的安全。

4)共享所需的数据

通过使用视图,每个用户不必都定义和存储自己所需的数据,可用共享数据库中的数据,同样的数据只需要存储一次。

5)更改数据格式

通过使用视图,可以重新格式化检索出的数据,并组织输出到其他应用程序中

6)重用sql语句

视图提供的是对查询操作的封装,本身不包含数据,所呈现的数据是根据视图定义从基础表中检索出来的,如果基础表的数据新增或者删除,视图所呈现的也是更新后的数据。视图定义后,编写完所需的查询,可以方便的重用该视图。

注意点:

  • 创建视图需要足够的访问权限
  • 创建视图的数目没有限制
  • 视图可以嵌套,即从其他视图中检索数据的查询来创建视图
  • 视图不能索引,也不能有关联的触发器,默认值或者规则
  • 视图可以和表一起使用
  • 视图不包含数据,所以每次使用视图时,都必须执行查询中所需的任何一个检索操作,如果多个连接和过滤条件创建了复杂的视图或者嵌套了视图,可能会发现系统运行性能下降的十分严重。因此,在部署大量视图应用时,应该进行系统测试

最后:order by 子句可以用在视图中,但若该视图检索数据的select 语句中也有 order by 子句,则该视图中的 order by 子句将被覆盖

2,mysql创建视图

创建视图是指在已经存在的mysql数据库表上建立视图,视图可建立在一张表上,也可以建立在多张表中。

基本语法:

create view 视图名 asselect 语句 

语法说明:

  • 视图名:指定视图的名称,该名称在数据库中必须是唯一的,不能与其他表或者视图同名。
  • select 语句:指定创建视图的select 语句,可用于查询多个基础表或者源视图

对于创建视图中的select 语句的指定存在以下限制:

  • 用户除了拥有create view 权限外,还具有操作中涉及的基础表和其他视图的相关权限。
  • select 语句不能引用系统或者用户变量。
  • select 语句不能包含 from 子句中的子查询
  • select 语句不能引用预处理语句的参数。
with check option 的意思就是:修改视图时,检查插入的数据是否符合 where 设置的条件

99,待解决

1,触发器

猜你喜欢

转载自blog.csdn.net/dearand/article/details/118420852