mariadb数据库(三)

数据库查询——连接查询,视图,索引,外键

1.连接查询

--创建学生表
create table students (
id int unsigned not null auto_increment primary key,
name varchar(20) default '',
age tinyint unsigned default 0,
high decimal(5,2),
gender enum('男', '女', '中性', '保密') default '保密',
cls_id int unsigned default 0,
is_delete bit default 0
);

    --创建班级表
    create table classes(
    id int unsigned auto_increment primary key not null,
    name varchar(20) not null
    );
--往students表里插入数据
insert into students values
(0,'小明',18,180.00,2,1,0),
(0,'小月月',19,180.00,2,2,0),
(0,'彭于晏',28,185.00,1,1,0),
(0,'刘德华',58,175.00,1,2,0),
(0,'黄蓉',108,160.00,2,1,0),
(0,'凤姐',44,150.00,4,2,1),
(0,'王祖贤',52,170.00,2,1,1),
(0,'周杰伦儿',34,null,1,1,0),
(0,'程坤',44,181.00,1,2,0),
(0,'和珅',55,166.00,2,2,0),
(0,'刘亦菲',29,162.00,3,3,0),
(0,'金星',45,180.00,2,4,0),
(0,'静香',18,170.00,1,4,0),
(0,'郭静',22,167.00,2,5,0),
(0,'周杰',33,178.00,1,1,0),
(0,'钱小豪',56,178.00,1,1,0),
(0,'谢霆锋',38,175.00,1,1,0);

``

  --向classes表里插入数据
    insert into classes values (0, '云唯_01期'),(0, '云唯_02期');
1)内关联

inner join … on
两个表连接查询

select * from 表1  inner join 表2  on ...

查询能够对应班级的学生以及班级信息

select * from students inner join classes on students.cls_id=classes.id;

按照要求显示姓名,班级

select students.name,classes.name from students inner join classes on students.cls_id=classes.id;

给数据表起名字

select s.name,c.name from students as s inner join classes as c on s.cls_id=c.id;

查询有能够对应班级的学生以及班级信息,显示学生的所有信息,只显示班级名称

select students.*,classes.name from students inner join classes on students.cls_id=classes.id;

查询将班级和姓名显示在前列

select classes.name,students.* from students inner join classes on students.cls_id=classes.id;

查询有能够对应班级的学生以及班级信息,按照班级进行排序

select classes.*,students.name from students inner join classes on students.cls_id=classes.id order by classes.id;

当是同一个班级的时候,按照学生的id从小到大

select classes.name,students.* from students inner join classes on students.cls_id=classes.id order by classes.id,students.id;
2)左关联,右关联

左关联,以左边表为基准,条件对应不上的显示null

select * from students left join classes on students.cls_id=classes.id;

右关联,以右边表为基准,条件对应不上的显示null

select * from students  right join classes on students.cls_id=classes.id;


select * from classes left join students on students.cls_id=classes.id;
3)自关联
创建地区表
create table areas(
aid int primary key auto_increment,
name varchar(20),
pid int
);

添加数据

--省份
insert into areas(aid,name,pid) values(1,'北京市',null);  
insert into areas(aid,name,pid) values(0,'天津市',null);  
insert into areas(aid,name,pid) values(0,'河北省',null);  
insert into areas(aid,name,pid) values(0,'山西省',null);  

--地级市
insert into areas(aid,name,pid) values(0,'海淀区',1);  
insert into areas(aid,name,pid) values(0,'滨海区',2);  
insert into areas(aid,name,pid) values(0,'沧州市',3);  
insert into areas(aid,name,pid) values(0,'大同市',4);

insert into areas(aid,name,pid) values(0,'朝阳区',1);  
insert into areas(aid,name,pid) values(0,'武清区',2);  
insert into areas(aid,name,pid) values(0,'石家庄',3);  
insert into areas(aid,name,pid) values(0,'太原市',4);

--县级市
insert into areas(aid,name,pid) values(0,'西二旗',5);  
insert into areas(aid,name,pid) values(0,'大港',6);  
insert into areas(aid,name,pid) values(0,'任丘市',7);  
insert into areas(aid,name,pid) values(0,'清徐',8);    

insert into areas(aid,name,pid) values(0,'中关村',5);  
insert into areas(aid,name,pid) values(0,'汉沽',6);  
insert into areas(aid,name,pid) values(0,'河间市',7);  
insert into areas(aid,name,pid) values(0,'阳曲',8);   

查询出河北省所有市

select * from areas as p inner join areas as q on p.aid=q.pid where p.name='河北省';

select * from areas as p inner join areas as q on p.aid=q.pid having p.name='河北省';
子查询

标量子查询
查询出北京所有区的信息

select * from areas where pid=(select aid from areas where name='北京市');

2.视图

对于复杂的查询,在多个地方被使用,如果需求发生了改变,需要更改sql语句,则需要在多个地方进行修改,维护起来非常麻烦

假如因为某种需求,需要将user拆房表usera和表userb,该两张表的结构如下:
测试表:usera有id,name,age字段
测试表:userb有id,name,sex字段

这时如果php端使用sql语句:select * from user;那就会提示该表不存在,这时该如何解决呢。解决方案:创建视图。以下sql语句创建视图:

create view user as select a.name,a.age,b.sex from usera as a, userb as b where a.name=b.name;

视图本质就是对查询的封装
定义视图,建议以v_开头

create view 视图名称 as select 语句;

查看视图:查看表会将所有的视图也列出来

show tables;

删除视图

drop view 视图名称;

使用:视图的用途就是查询
例:

学生表
在这里插入图片描述
班级表
在这里插入图片描述

select classes.c_name as '班级',stus.name as '姓名' from stus inner join classes on stus.cls_id=classes.id order by classes.id;

在这里插入图片描述

create view v_stus_info as select classes.c_name as '班级',stus.name as '姓名' from stus inner join classes on stus.cls_id=classes.id order by classes.id;

在这里插入图片描述
在这里插入图片描述

3.事物

为什么要有事务

事务具有ACID特性:原子性(A,atomicity)、一致性(C,consistency)、隔离性(I,isolation)、持久性(D,durabulity)。
 
事务广泛的运用于订单系统、银行系统等多种场景
例如:A用户和B用户是银行的储户,现在A要给B转账500元,那么需要做以下几件事:
检查A的账户余额>500元;
A 账户中扣除500元;
B 账户中增加500元;
上述3个步骤的操作必须打包在一个事物中,任何一个步骤失败,则必须回滚所有步骤
可以用start transaction语句开始一个事物,然后要么使用commit提交将修改的数据持久保存,要么使用rollback撤销所有修改,事物sql的样本如下:

start transation;
select balance from checking where customer_id=1024232;
update checking set balance=balance-200.00 where customer_id=1024232;
update savings set balance=balance+200.00 where customer_id=1024232;
commit;

原子性:事务内的所有操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
一致性:数据库总是从一个一致性的状态转换到另一个一致性的状态(在前面的例子当中,一致性确保了,即使在执行第三、四条语句之间系统崩溃,支票账户也不会损失200美元,因为事物最终没有被提交,所以事物中所做的修改也不会保存到数据库中)
隔离性:一个事物所做的修改在最终提交之前,对其他事物是不可见的(在前面的例子中,当执行完第三条语句、第四条语句还未开始时,此时有另外一个账户汇总程序开始运行,则其看到的支票账户的余额并没有被减去200美元。)
持久性:事务完成后,该事务内涉及的数据必须持久性的写入磁盘保证其持久性。当然,这是从事务的角度来考虑的的持久性,从操作系统故障或硬件故障来说,这是不一定的。

事务命令

要求:表的引擎类型必须是innodb类型才可以使用事务,这是mysql表的默认引擎
查看表的创建语句,可以看到engine=innodb

show create table students;

修改数据的命令会触发事务,包括insert、update、delete

开启事务
开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中

begin;或 start transation;

提交事务
将缓存中的数据变更维护到物理表中

commit;

回滚事务
放弃缓存中变更的数据

rollback;

4.索引

索引用于查询数据量较大,复杂查询操作
当数据库存在大量读写操作,添加的索引尽量要少避免影响数据库性能

查看索引

show index from 表名;

创建索引
方式一:随表一起创建

create table create_index(
id int primary key,
name varchar(10) unique,
age int,
key (age)
);

方式二:已存在的表,添加索引
如果指定字段是字符串,需要指定长度,建议长度与定义字段时的长度一致
字段类型如果不是字符串,可以不填写长度部分

create index 索引名称 on 表名(字段名称(长度))

例:

create index age_index on create_index(age);

删除索引

drop index 索引名称 on 表名;

测试时间

set profiling=1;#打开sql语句执行时间

show profiles;#查看sql执行时间

5.外键foreign key

如果一个实体的某个字段指向另一个实体的主键,就称为外键。被指向的实体,称之为主实体(主表),也叫父实体(父表)。负责指向的实体,称之为从实体(从表),也叫子实体(子表)。

对关系字段进行约束,当为从表中的关系字段填写值时,会到关联的主表中查询此值是否存在,如果存在则填写成功,如果不存在则填写失败并报错。

查看外键

show create table 表名

添加外键

alter table  子表名 add constraint fk foreign key (子表字段)  references grade(父表主键);

添加可级联删除的外键

alter table  子表名 add constraint fk foreign key (子表字段)  references grade(父表主键) on delete cascade;

删除外键

alter  table 子表名 drop foreign key 外键名字;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值