第一章 数据库介绍
1.1数据库概述
-
什么是数据库(DataBase、DB)
数据库就是存储数据的仓库,本质就是一个文件系统,数据按照特定的格式存储,用户可以对数据库中的数据 进行 增加,修改,删除以及查询操作。
-
什么是数据库管理系统
数据库管理系统(DataBase Managenment System,DBMS):一种操作和管理数据库的软件,用于建立、使用和维护数据库,对数据库进行统一的管理和控制。保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中表内的数据。
-
数据库与数据库管理系统的关系
数据库和数据库管理系统之间的关系可以用一个简单的比喻来描述:数据库就像一个巨大的仓库,DBMS则是负责管理和维护仓库的管理员。仓库越大,管理员的角色就越重要,以确保仓库的安全、整洁和高效运作。
1.2数据库表
数据库中以表为组织单位存储数据
表类似我们的java类 每一个字段都有对应的数据类型。
发现关系:
类---表
类中属性----表中字段
对象----表中的一条记录
1.3表数据
根据表字段规定的数据类型,我们可以一条一条的添加数据,表中的每条数据类似于类中的实例对象。表中一行一行的信息,我们叫做记录。
-
表记录与java类对象的对应关系
表记录中的每个字段对应Java类对象中的一个属性(字段)。
表记录中的数据类型对应Java类对象中的数据类型。
表记录中的关系(如主键、外键等)可以映射到Java类对象之间的关系(如单例、继承、关联等)。
1.4常见数据库
-
常见的数据库管理系统
MYSQL: 开源的免费的数据库,小型的数据库,已经被Oracle收购了,Mysql6.x版本开始收费。我们学习5.7
Oracle: 收费的大型的数据库,Oracle公司的产品。Oracle收购了SUN公司,收购了MYSQL。
SQLite: 嵌入式的小型数据库,应用在手机端
SQLServer:微软公司的收费数据库,C,.net常用
......
常用数据库: Mysql、Oracle
我们学习Mysql数据库。MySql可以有很多数据库,数据库中表格才是真正存储数据的地方。
第二章 SQL语句
2.1SQL概述
SQL语句的介绍
数据库是不认识JAVA语言的,但是我们同样要与数据库进行交互,需要使用数据库认识的语言: SQL语句,它是数据库的代码。
结构化查询语言 (Structured Query Language) 简称sql,是数据库管理系统都需要遵循的规范, 不同的数据库生产商,都支持sql语句 但是都有特有内容。
SQL的分类
-
数据定义语言:简称DDL, 用来定义数据库对象:数据库,表,列。
-
关键字:create,alter,drop等(重要)
-
-
数据操作语言:简称DML,用来对数据库中表的记录进行更新。
-
关键字:insert,delete,update等(非常重要)
-
-
数据控制语言:简称DCL,用来定义数据数据库的访问权限和安全级别,以及创建用户。
-
数据查询语言:简称DQL,用来查询数据库表中的记录。
-
关键字:select,from,where等(非常重要)
-
SQL通用语法
-
SQL语句可以单行或者多行书写,以分号结尾。
-
可以使用空格或者缩进来增强可读性。
-
mysql数据库的sql语句不区分大小写,关键字建议使用大写。
-
例如 : SELECT * FROM user;
-
-
注释: /**/的方式 完成注释
-
Mysql中常用的数据类型
类型名称 | 说明 |
---|---|
int(integer) | 整数类型 |
double | 小数类型 |
decimal(m,d) | 指定整数位与小数位长度的小数类型decimal(10,2) |
date | 日期类型,格式yyyy-MM-dd ,包含年月日 不包含时分秒 |
datetime | 日期类型,格式YYYY-MM-DD HH:MM:SS ,包含年月日 时分秒 2024-05-06- 09:09:09 |
timestamp | 时间戳 |
varchar(M) | 文本类型,M位0~65535之间的整数 |
2.2DDL之数据库操作:database
1.创建数据库
2.使用数据库
3.查看数据库中的定义
4.查看所有数据库
5.查看正在使用的数据库
6.删除数据库
创建数据库
格式:
create database 数据库名;
create database 数据库名 character set 字符集;
查看数据库
查看mysql服务器中所有的数据库
SHOW DATABASES;
查看某个数据库的定义信息
SHOW CREATE DATABASE 数据库名;
删除数据库
DROP DATABASE 数据库名;
使用数据库
-
查看正在使用的数据库
select database();
-
切换数据库
use 数据库名;
2.3DDL之表的操作
创建表
-
格式: [ ]代表可以写也可以不写 注意 最后一个字段不用加逗号
create table 表名(
字段名 类型(长度) [约束] ,
字段名 类型(长度) [约束] ,
字段名 类型(长度) [约束] ,
...
);
类型 :
varchar (n) 字符串
int 整形
double 浮点
date 时间
timestamp 时间戳
约束:
primary key 主键 ,被主键修饰的字段,不能重复,不能为空,常用于id 、编号 等唯一属性。
例如 : 创建分类表
CREATE TABLE category(
cid int primary key,
cname varchar(20)
);
查看表
-
查看数据库中所有的表
show tables;
-
查看表结构
desc 表名;
删除表
-
格式
drop table 表名;
修改表结构格式
-
修改表 添加列
alter table 表名 add 列名 类型(长度) [约束];
ALTER TABLE category add `desc` varchar(20);
-
修改表 修改列的类型长度和约束
alter table 表名 modify 列名 类型(长度) [约束];
ALTER TABLE category MODIFY `desc` VARCHAR(50) NOT NULL;
-
修改表 修改列名
ALTER TABLE 表名 CHANGE `原列名` `新列名` 类型(长度) [约束];
ALTER TABLE category CHANGE `desc` `description` VARCHAR(30);
-
修改表 修改表名
RENAME TABLE 表名 to 新表名;
RENAME TABLE category to category2;
-
修改表 删除字段
ALTER TABLE 表名 DROP 列名;
ALTER TABLE category2 drop description;
2.4DML语言 数据操作语言
查询表中所有数据
select * from 表名;
插入表记录:insert
-
语法:
-- 向表中插入某些字段
insert into 表 (字段1,字段2,字段3) values (值1,值2,值3);
-- 向表中插入所有字段,字段的顺序位创建表时的顺序
insert into 表 values (值1,值2,值3.....);
-
注意:
-
值与字段必须一一对应, 个数相同,类型相同。
-
值的数据大小必须在字段的长度范围内。
-
除了数值类型外,其他字段的值必须使用单引号引起。
-
例如: '你好','2023-12-25'
-
如果要插入空值, 可以不写这个字段 或者直接插入null;
-
-
例如
INSERT INTO category2 (cid,cname,description) values (100,'book','书籍');
INSERT INTO category2 (cid,cname) VALUES (101,'电器');
INSERT INTO category2 VALUES (103,'化妆品');
INSERT INTO category2 (cid) VALUES(102);
更新表记录:update
用来修改指定条件的数据, 将满足条件的记录指定列修改成指定值。
-
语法:
-
更新所有记录的指定字段
-
update 表名 set 字段名=值,字段名=值......;
-
更新符合条件的记录的指定字段
update 表名 set 字段名=值,字段名=值,...... where 条件;
-
注意:
-
列名的类型和修改的值的类型必须相同。
-
修改值的时候不能超过最大长度。
-
除了数值类型之外,其他字段类型必须使用单引号引起。
-
-- 修改全部记录
update category2 set cname ='book';
-- 修改指定记录
update category2 set cname ='化妆品' where cid =102;
update category2 set cname ='服装' where cid =103;
-- 要修改的字段有多个 用逗号连接 如果条件有多个 用and 连接
update category2 set cid =104 ,cname ='裤子' where cid =103 and cname='服装';
删除记录:delete
-
语法:
-- delete from 表名 [where 条件];
-- 根据条件删除
delete from category2 where cname ='book' and cid =100;
-- 删表中所以内容
delete from category2 ;
第三章 约束
3.1主键约束
PRIMARY KEY 约束标识 数据库表中的每条记录:
-
主键必须包含唯一的值。
-
主键不能包含NULL值
-
每个表都应该有一个主键,并且每个表都只能有一个主键。
添加主键约束
-
方式一:创建表时,在字段描述处,声明指定字段位主键。
CREATE TABLE persons( pid int PRIMARY KEY , lastname varchar(255), firstname varchar(255) );
方式二:创建表时,可以在constraint约束区域,声明指定字段为主键。
-
格式 : [constraint 名称 ] primary key (字段列表)
-
关键字constraint可以省略,如果需要为主键命名,constraint 不能省略,主键名称一般情况下没用。
-
字段列表需要使用小括号括住,如果有多个字段需要使用逗号分割,声明两个以上的字段为主键,我们叫联合主键。
-
联合主键: 声明多个字段联合作为一个主键, 不能两条记录中的联合主键的字段为相同数据。
CREATE TABLE persons(
firstname varchar(255),
lastname varchar(255),
city varchar(255),
CONSTRAINT pk_persons PRIMARY KEY (firstname,lastname)
);
方式三: 创建表之后,通过修改表结构,声明指定字段为主键。
-
格式:
ALTER TABLE persons ADD [CONSTRAINT 名称] PRIMARY KEY (字段列表)
CREATE TABLE persons(
firstname varchar(255),
lastname varchar(255),
city varchar(255)
)
ALTER TABLE persons ADD PRIMARY KEY (firstname,lastname);
删除主键约束
ALTER TABLE persons DROP PRIMARY KEY;
3.2自动增长列
我们希望在每次插入新记录时,数据库自动生成字段的值。
我们可以在表中使用auto_increment(自动增长列) 关键字, 自动增长列类型必须是整形,自动增长列 一般情况下 都是主键。
-- 创建表 pid 为主键 自增
CREATE TABLE persons(
-> pid int PRIMARY KEY AUTO_INCREMENT,
-> lastname varchar(255),
-> firstname varchar(255),
-> city varchar(255));
-- 新增一条记录 不写主键列 会自增
INSERT INTO persons (lastname,firstname) values ('3','zhang');
-- 新增一条记录 写主键列 但是写null 会自增
INSERT INTO persons (pid ,lastname,firstname) values (null,'4','li');
-- 也可以指定主键值 但是不能写已经存在的主键
-- 指定后 会根据 最大值递增
INSERT INTO persons (pid ,lastname,firstname) values (6,'4','li');
-
拓展: 默认自增从1开始,修改为从100开始:
ALTER TABLE persons AUTO_INCREMENT=100;
3.3非空约束& 唯一约束
NOT NULL 约束强制列不接收NULL值;
UNIQUE 唯一约束 约束唯一标识数据库中的每条记录;
-- 创建学生表
CREATE TABLE students(
-> sid int UNIQUE ,
-> lastname varchar(255) NOT NULL,
-> firstname varchar(255)
-> );
-- 新增一条数据
INSERT INTO students (sid,lastname,firstname) values (1,'zhang','3');
-- 新增失败 因为sid 唯一约束
INSERT INTO students (sid,lastname,firstname) values (1,'li','4');
-- 新增失败 因为lastname 非空约束
INSERT INTO students (sid,firstname) values (2,'4');
第四章 DQL查询语句
数据准备:
CREATE TABLE product(
pid int PRIMARY KEY,
pname VARCHAR(20),
price DOUBLE ,
category_id VARCHAR(20)
);
INSERT INTO product (pid,pname,price,category_id) VALUES (1,'联想',5000,'c001');
INSERT INTO product VALUES (2,'海尔',3000,'c002');
INSERT INTO product VALUES (3,'雷神',5000,'c001');
INSERT INTO product(pid,pname,price,category_id) VALUES(4,'JACK JONES',800,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(5,'真维斯',200,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(6,'花花公子',440,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(7,'劲霸',2000,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(8,'香奈儿',800,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(9,'相宜本草',200,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(10,'面霸',5,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(11,'好想你枣',56,'c004');
INSERT INTO product(pid,pname,price,category_id) VALUES(12,'香飘飘奶茶',1,'c005');
INSERT INTO product(pid,pname,price,category_id) VALUES(13,'果9',1,NULL);
select * from product;
4.1语法
select [distinct]
列名,列名
from 表
where 条件
4.2简单查询
#查询所有商品
select * from product;
# 查询商品名和商品价格
select pname ,price from product;
# 别名查询
select pname '商品名称' from product;
# 去掉重复值
select DISTINCT price from product;
# 运算查询 : 将所有商品的价格+10元并别名price显示
select pname ,price +10 price from product;
4.3条件查询
比较运算符 | <,<=,>,>= ,!=,= | |
---|---|---|
逻辑运算符 | BETWEEN...AND.... | 显示再某一区间的值(含头含尾) |
IN(值1,值2....) | 显示再in列表中的值,例:in(100,200) | |
LIKE '张 pattern' | 模糊查询,Like语句中 可以使用%、_。%代表0或者多个字符,_代表一个字符。 | |
IS [NOT] NULL | 判断是否为空 | |
and | 多个条件同时成立 | |
or | 多个条件任一成立 | |
not | 不成立 |
#查询商品名称为联想的商品信息
select * from product where pname ='联想';
#查询价格为800的商品
SELECT * FROM product where price =800;
#查询价格不是800的商品
SELECT * FROM product where price != 800;
#查询商品价格大于60的商品
SELECT * FROM product where price >60;
#查询商品价格在200到1000的所有商品
SELECT * FROM product where price BETWEEN 200 AND 1000;
SELECT * FROM product where price >=200 and price <=1000;
#查询商品价格200或者800的所有商品
SELECT * FROM product where price IN (200,800);
SELECT * FROM product where price =200 OR price =800;
#查询含霸字的所有商品
SELECT * FROM product where pname LIKE '%霸%';
#查询以香开头的所有商品
SELECT * FROM product where pname LIKE '香%';
#查询第二个字为想的所有商品
SELECT * FROM product where pname LIKE '_想%';
#查询没有商品分类的商品
SELECT * FROM product where category_id IS NULL;
#查询有商品分类的商品
SELECT * FROM product where category_id IS NOT NULL;
4.4排序查询
通过order by 语句 可以将查询出来的结果进行排序 , 暂时放置在select语句最后。
格式:
SELECT * FROM 表 ORDER BY 排序字段 [ASC|DESC];
#ASC 升序(默认)
#DESC 降序
# 使用价格排序
SELECT * FROM product ORDER BY price;
SELECT * FROM product ORDER BY price DESC;
SELECT * FROM product ORDER BY price ASC;
# 在价格排序的基础上,按照pid排序(降序)
SELECT * FROM product ORDER BY price ASC ,pid DESC;
#查询id 为1 3 5 7 的商品 并按照价格降序排列
select * from product where pid in (1,3,5,7) order by price desc ;
4.5聚合查询
之前我们查询都是横向查询,根据条件一行一行判断,而使用聚合查询是纵向查询,是一列一列进行计算,然后返回单一的值;另外:聚合函数 会忽略空值。
-
count:统计指定列不为null的记录行数
-
sum:计算指定列的数值和,如果指定列不是数值,结果为0
-
max: 计算指定列的最大值,如果指定列是字符串,那么使用字符串排序运算。
-
min:计算指定列的最小值,同上
-
avg:计算指定列的平均值,如果指定的不是数值,结果为0
4.6分组查询
分组查询是使用group by 对查询信息进行分组
格式:
SELECT 字段 ... from 表名 group by 分组字段 having 分组条件
分组操作中的having子语句, 是用于在分组后对数据进行过滤的,作用类似于where
-
having和where的区别:
-
having是在分组之后对数据进行过滤
-
where是在分组之前对数据进行过滤
-
having后面可以使用聚合函数
-
where后面不可以使用聚合函数
-
#统计各个分类商品的个数
select category_id ,count(*) from product GROUP BY category_id ;
#统计各个分类商品的个数 不显示没有 分类的个数
select category_id ,count(*) from product GROUP BY category_id
HAVING category_id is not null;
select category_id ,count(*) from product where
category_id is not null group by category_id;
# 统计各个分类的商品个数,且只显示个数大于1的信息
select category_id , count(*) from product GROUP BY category_id
HAVING count(*) >1;
#统计各个分类商品的平均价格
select category_id ,avg(price) from product GROUP BY category_id;
#统计各个分类的平均价格 ,且只能显示平均价格>800的信息。
select category_id ,avg(price) from product GROUP BY category_id
HAVING avg(price) >800;
第五章 多表操作
实际开发中,一个项目通常需要很多张表完成:之前我们都是在单表的基础上操作,下面我们就要学习多表查询。
5.1表与表之间的关系
-
一对多关系:
-
常见实例:客户和订单,分类和商品,部门和员工。
-
-
多对多关系:
-
常见实例:学生和课程 , 用户和角色。
-
-
一对一关系:
-
在开发中应用几乎没有,因为一对一关系可以建成一张表。
-
一对多:一对多建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键。 创建的这个字段 叫做外键
多对多:多对多建表原则:
需要创建第三章表作为中间表,中间表 至少两个字段,这两个字段分别作为外键指向各自一方的主键。
5.2外键约束
例如我们现在有两张表 分类表和商品表,为了明确商品属于哪个分类,通常情况下,我们都会在商品表上添加一列,用于存放分类cid的信息,此列称为:外键
-
外键的特点:
-
从表外键的值是对主表主键的引用
-
从表外键类型,必须与主表主键类型一致
-
外键的值,主键中必须存在。
-
-
声明外键约束
语法:
alter table 从表 add [ constraint 外键名称 ] foreign key 从表名(从表外键字段名) references 主表名(主表的主键)
一对多操作:
# 创建分类表
create table category(
cid varchar(30) PRIMARY KEY,
cname varchar(100)
);
#添加外键约束
ALTER TABLE product add FOREIGN KEY
(category_id) references category (cid);
#向商品表中添加普通数据 没有外键数据 默认为null
INSERT INTO product (pid,pname,price)
values (20,'商品名称',500);
#向商品表中添加普通数据 ,含有外键信息
INSERT INTO product (pid,pname,price,category_id)
values (21,'商品名称1',555,'c001');
#向商品表中添加数据, 含有外键信息 但是category表中不存在此主键 会报错
INSERT INTO product(pid,pname,price,category_id)
values (22,'商品名称2',666,'c999');
# 删除指定分类(分类被商品使用中) --不能删除
DELETE FROM category where cid ='c001';
# 在从表中添加新数据时要添加主表中存在的主键分类,如从表添加category_id
#为‘c555’,这个在主表中没有cid等于它,所以不可以
#要删除主表中某cid时,若从表列表中有使用它的数据,就不能删除成功
# 如果删除主表数据成功成功,被删除的主键从表中不能再使用
select * from product ;
多对多操作:
# 商品和订单存在多对多关系,拆分成两个一对多
# product为商品表,为其中一个一队多的主表,提供主键pid
# order订单表,为另一个一对多的主表,提供主键oid
# orderitem 中间表 为添加的第三张表,需要提供两个外键 oid和pid
CREATE TABLE `order`(
oid varchar(20) PRIMARY KEY,
totalprice double
);
CREATE TABLE `orderitem`(
oid varchar(20),
pid int
);
#订单表 和订单商品中间表主外键关系
ALTER TABLE orderitem add FOREIGN KEY (oid) REFERENCES `order` (oid);
#商品表 和订单商品中间表主外键关系
ALTER TABLE orderitem add FOREIGN KEY (pid) REFERENCES product (pid);
#向订单表中添加数据
INSERT INTO `order` (oid,totalprice) values ('o001',100.1);
INSERT INTO `order` (oid,totalprice) values ('o002',200.2);
select * from `order`;
#向中间表中添加数据(添加主键存在的值)
INSERT INTO orderitem (pid,oid) values (1,'o001');
INSERT INTO orderitem (pid,oid) values (1,'o002');
INSERT INTO orderitem (pid,oid) values (2,'o002');
#添加不存在的值 报错
INSERT INTO orderitem (pid,oid) values (1,'o222');
#删除中间表的数据
delete from orderitem where pid =2 and oid='o002';
#删除主表数据 (外键存在 无法删除 外键不存在 可以删除)
delete from product where pid =20;
select * from orderitem;
5.3 外键优缺点分析
1.外键优点:
-
保证数据的完整性和一致性。
-
将数据完整性判断托付给了数据库完成,减少程序的代码量。
-
保证级联操作。
-
防止误操作。
2.外键缺点:
-
性能开销:外键约束会增加数据库的复杂性,导致性能下降。例如当执行插入,修改或者更新时,数据库都需要检查外键是否违反约束。
-
灵活性:外键约束会限制数据库设计的灵活性,导致删除或者更新表记录其他表中的数据变得无效或者不一致。
-
数据完整性?:虽然外键可以完全保证数据完整性,但是我们可以通过其他方式实现,例如触发器或者应用程序的验证。
-
复杂性和维护性: 外键约束会增加数据库的复杂性,并且需要额外的维护工作。
-
可拓展性差:由于分布式系统,外键约束称为性能瓶颈。
-
处理大量临时数据或者一次性数据时,性能差。
外键弊大于利。一般情况下都不使用。对于数据的主动权 掌握在程序员手中。
第六章 多表关系查询
准备数据
# 分类表
CREATE TABLE category (
cid VARCHAR(32) PRIMARY KEY ,
cname VARCHAR(50)
);
#商品表
CREATE TABLE products(
pid VARCHAR(32) PRIMARY KEY ,
pname VARCHAR(50),
price double,
flag VARCHAR(2), #是否上架标记为:1表示上架、0表示下架
category_id VARCHAR(32),
);#分类
INSERT INTO category(cid,cname) VALUES('c001','家电');
INSERT INTO category(cid,cname) VALUES('c002','服饰');
INSERT INTO category(cid,cname) VALUES('c003','化妆品');
#商品
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p001','联想',5000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p002','海尔',3000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p003','雷神',5000,'1','c001');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p004','JACK JONES',800,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p005','真维斯',200,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p006','花花公子',440,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p007','劲霸',2000,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p008','香奈儿',800,'1','c003');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p009','相宜本草',200,'1','c003');
6.1内连接
# 多表查询 交叉连接查询,得到的是两个表的乘机,笛卡尔积
select * from category,product;
#内连接查询 (使用关键字 inner join inner 可以省略)
#隐式内连接: select * from A,B where 条件
#显示内连接: select * from A inner join B on 条件
#显式内连接的方式查询所有商品信息
SELECT * FROM category c INNER JOIN product p on c.cid=p.category_id;
SELECT * FROM product p INNER JOIN category c on c.cid=p.category_id;
#显式内连接的方式 查询化妆品信息
SELECT * FROM category c INNER JOIN product p on c.cid= p.category_id
and c.cname='化妆品';
SELECT * FROM category c INNER JOIN product p on c.cid= p.category_id
WHERE c.cname='化妆品';
#隐式内连接查询所有商品信息
select * from category ,product where category.cid =product.category_id;
#隐式内连接查询所有分类为化妆品的商品信息
select * from category ,product where category.cid =product.category_id
AND category.cname='化妆品';
#隐式内连接给表取别名
select * from category c,product p where c.cid=p.category_id and c.cname='化妆品';
6.2外连接
#外连接查询 (使用关键字 outer join outer 可以省略)
#左外连接 left outer join
# select * from A left outer join B on 条件;
#右外连接 right outer join
# select * from A right outer join B on 条件;
#商品表中新增一条数据
insert into product VALUES ('p010','方便面',3,1,'c004');
# 左外连接: 查询左表的全部以及右表的交集(查询的是左边的全部,右表没有的用null表示)
#查询所有商品信息
select * from category c left join product p on c.cid=p.category_id;
select * from category c RIGHT JOIN product p on c.cid=p.category_id;
#内连接
select * from category c join product p on c.cid=p.category_id;
#向分类表中新增一条数据
insert into category VALUES ('c005','生鲜');
#查询两个表中所有数据
select * from category c left join product p on c.cid=p.category_id
union
select * from category c right join product p on c.cid=p.category_id ;
6.3子查询
#子查询
# 一条select 语句的结果作为另外一条select语法的一部分(查询条件,查询结果,表等等)
#语法 select 查询字段 from 表 where 查询条件
#查询product 表中化妆品的商品信息 无法得知c003就是化妆品的 分类编号
select * from product where category_id ='c003';
# 查询分类名称为化妆品的分类id信息
select cid from category where cname ='化妆品';
#查询化妆品商品信息 等价于 将查询到的结果当作值用
select * from product where category_id in
(select cid from category where cname ='化妆品');
#查询product表中化妆品和家电商品的信息 要求使用子查询
select * from product where category_id in
(select cid from category where cname ='化妆品' or cname ='家电');
#把查询结果做为表来使用
#查询所有化妆品的商品信息 查询结果当作一张伪表来使用
select * from (select * from category where cname ='化妆品') c ,product p
where c.cid=p.category_id;
# 查询所有化妆品和家电
select * from (select * from category where cname ='化妆品' or cname ='家电') c ,
product p where c.cid =p.category_id;
#利用右外连接
select * from product p right join (select * from category where cname ='化妆品' or cname ='家电') c on p.category_id=c.cid;
select * from product p right join (select * from category ) c on p.category_id=c.cid where cname ='化妆品' or cname ='家电';
第七章 常用函数
-- 常用函数
-- 数据函数
SELECT ABS(-8);/*绝对值*/
SELECT CEILING(9.4);/*向上取整*/
SELECT FLOOR(9.4);/*向下取整*/
SELECT RAND();/*随机数,返回一个0-1之间的随机数*/
SELECT SIGN(2);/*符号函数 负数返回-1 正数返回1 ,0返回0*/
-- 字符串函数
SELECT CHAR_LENGTH('好好学习');/*返回字符串包含的字符数*/
SELECT CONCAT('%','学','%');/*合并字符串,参数可以有多个*/
SELECT LOWER('AAAaaa');/*小写*/
SELECT UPPER('AAAaaa');/*大写*/
SELECT LEFT('hello,world',5)/*从左边截取*/
SELECT RIGHT('hello,world',5)/*从右边截取*/
SELECT REPLACE('AABBCC','AA','DD')/*替换字符串*/
SELECT SUBSTR('AABBCCDD',4,3)/*截取字符串*/
select REVERSE('ABC')/*反转字符串*/
update student set `name`= REPLACE(`name`,'A','');
update student set `name`= CONCAT(`name`,'A');
-- 日期和时间
select CURRENT_DATE(); /*获取当前日期*/
SELECT NOW();/*获取当前日期和时间*/
-- 获取年月日 时分秒
select YEAR(NOW());
select MONTH('2024-01-16 8:08:08');
select DAY(NOW());
select HOUR(NOW());
select MINUTE(NOW());
select SECOND(NOW());
SELECT VERSION();# 查询当前sql版本
第八章 事务
8.1事务概述
-
事务就是将一组sql语句放在同一批次内去执行
-
如果一个sql语句出问题,则该批次所有sql都会取消执行。
8.2事务的ACID 百度ACID
原子性
要么都执行,要么都不执行。
-
整个事务中,所有操作,要么都成功,要么都失败,不能停滞在某个环节,事务执行过程中如果发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有发生过一样。
一致性
事务前后,数据的完整性必须保持一致
-
事务必须始终保证系统处于一致的状态,也就是说,系统也必须如同串行事务一样操作,主要就是保护不变性。以转账为例,假如有5个账户,那么五个账户的总额是500元,无论并发转账多少次 多少钱,五个账户查询总额都应该是500元,这就是保证一致性。
隔离性
多个事务并发访问不能互相干扰
-
隔离状态执行事务,使事务是系统在给定时间内的唯一操作,如果有两个事务,在运行时间内,执行相同功能,事务的隔离性会保证每一个事务在系统中认为只有该事务在使用系统。在同一时间只能有一个请求使用于同一个数据。
持久性
事务一旦发生,改变就是永久性的。
-
在事务完成以后,该事务对数据库所有做的更改都应该持久的保存在数据库中,不会被回滚。
8.3mysql中操作事务
例如转账事务,当A 向B转1000块,必须A账户少1000的同时B账户也增加1000元。不能如果执行完A少1000块然后因为一些异常而停止执行导致总金额不对,所以就需要用事务将AB捆绑起来,让他俩要么同时正常执行,出现错误也同时撤销回上一步。
create table `account`(
id int PRIMARY KEY auto_increment,
`name` varchar(30) ,
`cash` double
);
INSERT INTO account VALUES
(1,'A',2000),
(2,'B',10000);
SELECT * FROM ACCOUNT;
-- 事务基本语法
set autocommit=0; /*关闭*/
set autocommit=1; /*开启*/
-- 注意: mysql中默认自动提交事务 所以我们使用时应该关闭自动提交
-- 测试
-- 转账实现
set autocommit=0;
-- 开启事务
START TRANSACTION;
update account set cash=cash-1000 where `name`='A';
update account set cash =cash+1000 where `name`='B';
ROLLBACK; -- 回滚事务
COMMIT; -- 提交事务
set autocommit=1;