数据库就是==存储数据的仓库==,其本质是一个文件系统,按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作
RDBMS
)INSERT
, SELECT
)。结构化查询语言(Structured Query Language)简称SQL,是关系型数据库管理系统都需要遵循的规范,是数据库认识的语句。不同的数据库生产厂商都支持SQL语句,但都有特有内容。
CREATE
, ALTER
, DROP
(定义表结构)。SELECT
, INSERT
, UPDATE
, DELETE
(操作数据)。SELECT ... JOIN
、GROUP BY
、HAVING
等高级查询。GRANT
, REVOKE
(权限管理)。COMMIT
, ROLLBACK
(事务管理)。① SQL语句可以单行或多行书写,以分号结尾。
select * from students;
② 可使用空格和缩进来增强语句的可读性
select
*
from students;
③ MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
SELECT * FROM user;
等价于
select * from user;
MySQL是一个关系型数据库管理系统,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件,它是由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品,MySQL 是最流行的关系型数据库管理系统中的一个。
MySQL是开源的,所以你不需要支付额外的费用。
MySQL支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
MySQL使用标准的SQL数据语言形式。
MySQL可以安装在不同的操作系统,并且提供多种编程语言的操作接口。这些编程语言包括C、C++、Python、Java、Ruby等等。
我使用MySQL8.0版本, MySQL Community Server进行学习。 通过docker安装的mysql
docker-compose.mysql.yml
services:
# 名为 mysql 的服务
mysql:
# 使用官方 MySQL 镜像 mysql:8.3.0
image: mysql:8.3.0
command:
# 设置默认身份验证插件为 mysql_native_password
--default-authentication-plugin=mysql_native_password
#设置服务器默认字符集为 utf8mb4
--character-set-server=utf8mb4
#设置默认排序规则为 utf8mb4_general_ci
--collation-server=utf8mb4_general_ci
environment:
# 设置 MySQL root 用户的密码为
- MYSQL_ROOT_PASSWORD='密码'
# 设置表名是否区分大小写: 需确保应用代码中的表名与数据库中的大小写完全一致
- MYSQL_LOWER_CASE_TABLE_NAMES=0
ports:
- "3306:3306"
volumes:
- ./data/mysql:/var/lib/mysql
连接
# 进入 MySQL 容器的命令行(b-express-mysql-1 容器名称)
docker exec -it b-express-mysql-1 bash
# 在容器内使用 MySQL 客户端(root角色)
#-p 表示登录时使用的密码。
#-u 表示以哪个用户身份登录 MySQL
mysql -u root -p
# 使用 --password= 参数
mysql -u root --password=’密码‘
一个MySQL DBMS可以同时存放多个数据库,理论上一个项目就对应一个数据库。如博客项目blog数据库、商城项目shop数据库、微信项目wechat数据库。
一个数据库中还可以同时包含多个数据表,而数据表才是真正用于存放数据的位置。(类似我们Office软件中的Excel表格),理论上一个功能就对应一个数据表。如博客系统中的用户管理功能,就需要一个user数据表、博客中的文章就需要一个article数据表、博客中的评论就需要一个message数据表。
一个数据表又可以拆分为多个字段,每个字段就是一个属性。
一个数据表除了字段以外,还有很多行,每一行都是一条完整的数据(记录)。
# 基本语法: api_development
mysql> create database 数据库名称 [设置编码格式];
# 创建api_development库
mysql>create database api_development;
# 创建api_development库并指定默认字符集
mysql>create database api_development default charset gbk;
/**
# 设置默认身份验证插件为 mysql_native_password
--default-authentication-plugin=mysql_native_password
#设置服务器默认字符集为 utf8mb4
--character-set-server=utf8mb4
**/
# 安装mysql 设置了默认的字符集为 utf8mb4
编码格式
# 查看数据库编码格式
mysql> SHOW CREATE DATABASE api_development;
+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database |
+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| api_development | CREATE DATABASE `api_development` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
/**
编码格式,常见的gbk(中国的编码格式)与utf8(国际通用编码格式)
国内汉字无法通过256个字符进行描述,所以国内开发了自己的编码格式gb2312,升级gbk
支持多国语言,标准化组织开发了一套通用编码utf8,后来5.6版本以后又进行了升级utf8mb4
**/
# 语法
mysql> show databases;
# 语法
mysql> drop database 数据库名称;
# 删除api_development数据库
mysql> drop database api_development;
# 语法
mysql> use 数据库名称;
# 选择api_development数据库
mysql>use api_development;
# 查看正在使用的数据库(8.0以后版本需要基于select查询来获取当前数据库)
mysql> select database();
# 基本语法
mysql> create table 数据表名称(
字段1 字段类型 [字段约束],
字段2 字段类型 [字段约束],
...
);
# 创建一个user_table用户表,拥有3个字段(编号、用户名称、用户密码)
mysql> create table user_table(
id tinyint,
username varchar(255),
password char(255)
) engine=innodb default charset=utf8mb4;
# ENGINE=InnoDB 指定表的存储引擎为 InnoDB(支持事务、行级锁、外键等)
# default charset=utf8mb4 设置表的默认字符集为 utf8mb4
# 显示所有数据表(当前数据库)
mysql> show tables;
#语法
# 显示数据表的创建过程(编码格式、字段等信息)
mysql> desc 数据表名称;
# 查看user
desc user_table;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(255) | YES | | NULL | |
| password | char(255) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
# 语法
mysql> alter table 数据表名称 add 新字段名称 字段类型 first|after 其他字段名称;
’/**选项说明:
first:把新添加字段放在第一位
after 字段名称:把新添加字段放在指定字段的后面
**/
# user_table表中添加一个addtime字段,类型为date(年-月-日),添加到username字段后面
mysql> alter table user_table add addtime date after addtime;
mysql> desc user_table;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(255) | YES | | NULL | |
| addtime | date | YES | | NULL | |
| password | char(255) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
4 rows in set (0.02 sec)
# 修改名称和字段类型
# user_table表 username 类型 varchar(255)改成 varchar(40);且名称username改为name
mysql> alter table user_table change username user varchar(40);
mysql> desc user_table;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| user | varchar(40) | YES | | NULL | |
| addtime | date | YES | | NULL | |
| password | char(255) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.02 sec)
# 基本语法
mysql> alter table user_table drop 字段名称;
# 删除 addtime
mysql> alter table user_table drop addtime;
rename table 旧名称 to 新名称;
分类 | 类型名称 | 说明 |
---|---|---|
==tinyint== | 很小的整数 | -128 ~ 127 |
smallint | 小的整数 | -32768 ~ 32767 |
mediumint | 中等大小的整数 | -8388608 ~ 8388607 |
==int(integer)== | 普通大小的整数 | -2147483648 ~ 2147483647 |
整数类型的选择,看数字范围!
unsigned无符号型,只有正数,没有负数情况,tinyint unsigned,表示范围0-255
浮点类型(精度失真情况)和定点类型(推荐使用定点类型)
分类 | 类型名称 |
---|---|
float | 单精度浮点数 |
double | 双精度浮点数 |
==decimal(m,d)== | 定点数,decimal(10,3) |
decimal(10,2) :代表这个数的总长度为10 = 整数长度 + 小数长度,3代表保留3位小数
分类 | 类型名称 |
---|---|
year | YYYY 1901~2155 |
==time== | HH:MM:SS -838:59:59~838:59:59 |
==date== | YYYY-MM-DD 1000-01-01~9999-12-3 |
==datetime== | YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00~ 9999-12-31 23:59:59 |
timestamp | YYYY-MM-DD HH:MM:SS 1970~01~01 00:00:01 UTC~2038-01-19 03:14:07UTC |
日期时间类型的选择主要看格式!
类型名称 | 说明 |
---|---|
==char(m)== | m为0~255之间的整数定长(固定长度) |
==varchar(m)== | m为0~65535之间的整数变长(变化长度) |
==text== | 允许长度0~65535字节 |
mediumtext | 允许长度0~167772150字节 |
longtext | 允许长度0~4294967295字节 |
255个字符以内,固定长度使用char(字符长度),变化长度使用varchar(字符长度)
假设:有一个数据,一共有5个字符,char(11),实际占用11个字符,相同长度数据,char类型查询要比varchar要快一些;变化长度varchar(11),实际占用5个字符长度。
超过255个字符,选择text文本类型!
ENUM
和 SET
:字符串对象类型
类型 | 描述 | 示例 |
---|---|---|
ENUM | 只能存储预定义值中的一个(单选)。 |
|
SET | 可以存储预定义值中的多个(多选,最多 64 个值)。 |
|
类型 | 最大容量 | 典型用途 |
---|---|---|
| 255 字节 | 小图标、短二进制数据 |
| 65,535 字节 | 图片、文档 |
| 16,777,215 字节 | 高清图片、视频片段 |
| 4,294,967,295 字节 | 大型文件(如 PDF、ISO 镜像) |
# 基本语法: INSERT INTO 是 SQL 中用于向数据库表中插入数据的语句
mysql> insert into 数据表名称([字段1,字段2,字段3...]) values (字段1的值,字段2的值,字段3的值...);
特别注意:在SQL语句中,除了数字,其他类型的值,都需要使用引号引起来,否则插入时会报错。
# 创建数据表
mysql> create table tb_user(
id int,
username varchar(20),
age tinyint unsigned,
gender enum('男','女','保密'),
address varchar(255)
) engine=innodb default charset=utf8mb4;
#gender enum('','',''), 在cmd中可以无法显示中文
# SET NAMES 'utf8mb4'; MySQL 客户端字符集设置
# 使用insert语句插入数据
mysql> insert into tb_user values (1,'张三',22,'男','武汉市');
mysql> insert into tb_user(id,username,age) values (2,'李四',44);
#批量插入多条数据
mysql> insert into tb_user values (3,'王五',19,'女','上海市浦东新区'),(4,'赵六',18,'女','北京'),(5,'孙七',26,'男','天津');
# 基本语法
mysql> update 数据表名称 set 字段1=更新后的值,字段2=更新后的值,... where 更新条件;
# 如果在更新数据时,不指定更新条件,则其会把这个数据表的所有记录全部更新一遍。
update tb_user set gender='保密',address='深圳市' where id=2;
# 基本语法
mysql> delete from 数据表名称 [where 删除条件];
# 删除tb_user表中,id=1的用户信息
mysql> delete from tb_user where id=1;
# delete from与truncate清空数据表操作
mysql> delete from 数据表;
mysql> truncate 数据表;
delete from与truncate区别在哪里?
delete from与truncate区别在哪里?
主键的选择标准
# 创建数据表 主键约束
mysql> create table tb_user2(
id int PRIMARY KEY, # 主键约束
username varchar(20)
) engine=innodb default charset=utf8mb4;
# 删除主键约束:如需撤销 PRIMARY KEY 约束,请使用下面的 SQL
alter table tb_user2 drop primary key;
我们通常希望在每次插入新记录时,数据库自动生成字段的值。
# 创建数据表 auto_increment (自动增长列)
mysql> create table tb_user3(
id int auto_increment PRIMARY KEY, # 主键约束
username varchar(20)
) engine=innodb default charset=utf8mb4;
# 添加数据
insert into tb_user3 values(null,'张三'),(null,'李四');
insert into tb_user3(username) values('Bill','Gates');
# 创建数据表 非空约束 not null
mysql> create table tb_user3(
id int,
username varchar(20) not null # 非空约束
) engine=innodb default charset=utf8mb4;
外键约束(==多表==关联使用)
成绩表中的学生ID应该在学生表中是存在的 我们应该让成绩表中的ID只能引用学生表中的ID,它们的值应该是一一对应的,也就是说成绩表中的ID是成绩表中的外键,对应学生表的主键 ,这样就可以保证数据的引用完整性
MySQL中的标识列(Identity Column),也称为自增列(Auto Increment Column),是一种特殊的列,它会在插入新行时自动为该列生成唯一的值。这个特性通常用于主键(Primary Key)列,以确保每行都有一个唯一的标识符。
MySQL中的标识列主要通过AUTO_INCREMENT
属性来实现。它通常应用于整数类型的列(如INT
、BIGINT
等)。
五子句查询
# select 查询
select * from 数据表 [where子句] [group by分组子句] [having子句] [order by子句] [limit子句];
# WHERE 子句过滤数据
① where子句
# GROUP BY 分组
② group by子句
# 筛选分组后的结果进行筛选的子句 它与 GROUP BY 子句配合使用,类似于 WHERE 子句
③ having子句
# ORDER BY 排序
④ order by子句
# LIMIT 限制结果
⑤ limit子句
注意:在以上5个子句中,五子句的顺序不能颠倒!
创建表
# 商品
CREATE TABLE product
(
pid INT PRIMARY KEY, #商品id
pname VARCHAR(20), #商品名称
price DOUBLE, # 价格
category_id VARCHAR(32)# 分类
);
数据
INSERT INTO product VALUES (1,'联想电脑',5000,'电脑');
INSERT INTO product VALUES (2,'苹果电脑',9000,'电脑');
INSERT INTO product VALUES (3,'华为电脑',5000,'电脑');
INSERT INTO product VALUES (4,'小米汽车',70000,'汽车');
INSERT INTO product VALUES (5,'BYD汽车',60000,'汽车');
INSERT INTO product VALUES (6,'长城汽车',44000,'汽车');
INSERT INTO product VALUES (7,'安踏鞋',200,'鞋');
INSERT INTO product VALUES (8,'李宁鞋',600,'鞋');
INSERT INTO product VALUES (9,'NINK鞋',800,'鞋');
INSERT INTO product VALUES (10,'白象方便面',15,'方便面');
INSERT INTO product VALUES (11,'娃哈哈纯净水',2,'水');
INSERT INTO product VALUES (12,'特步鞋',100,'鞋');
INSERT INTO product VALUES (13,'怡宝纯净水',1,'水');
INSERT INTO product VALUES (14,'康师傅方便面',1,'方便面');
INSERT INTO product VALUES (15,'三太子方便面',1,'方便面');
# 1.查询所有的商品.
select * from product;
# 2.查询商品名和商品价格.
select pname,price from product;
# 3.查询结果是表达式(运算查询):将所有商品的价格+10元进行显示.
select pname,price+10 from product;
运算符 | 说明 |
---|---|
加运算,求两个数或表达式相加的和,如1+1 | |
减少减运算,求两个数或表达式相减的差,如4-1 | |
乘运算,求两个数或表达式相乘的积,如2*2 | |
/ | 除运算,求两个数或表达式相除的商,如6/4的值为1 |
% | 取模运算,求两个数或表达式相除的余数,如:6%4的值为2 |
运算符 | 说明 |
---|---|
AND | 当且仅当两个布尔表达式都为true时,返回TRUE |
OR | 当且仅当两个布尔表达式都为false,返回FALSE |
NOT | 布尔表达式的值取反 |
运算符 | 说明 |
---|---|
= | 等于 |
大于 | |
< | 小于 |
<> | 不等于 |
| 大于等于 |
<= | 小于等于 |
!= | 不等于 |
# 查询商品名称为“苹果电脑”的商品所有信息:
SELECT * FROM product WHERE pname = '苹果电脑';
# 查询价格不是9000的所有商品
SELECT * FROM product WHERE price != 9000;
SELECT * FROM product WHERE price <> 9000;
# 查询商品价格小于等于800元的所有商品信息
SELECT * FROM product WHERE price <= 800;
# 查询商品价格在1000到10000之间所有商品
SELECT * FROM product WHERE price BETWEEN 1000 AND 10000;
# 查询商品价格是200或5000的所有商品
SELECT * FROM product WHERE price IN (200,5000);
# 查询商品价格在200到1000之间所有商品
SELECT * FROM product WHERE price >= 200 AND price <=1000;
# 查询商品价格是200或800的所有商品
SELECT * FROM product WHERE price = 200 OR price = 800;
# 查询价格不是800的所有商品
SELECT * FROM product WHERE NOT(price = 800);
# 查询以'小'开头的所有商品
SELECT * FROM product WHERE pname LIKE '小%';
# 查询第二个字为'想'的所有商品
SELECT * FROM product WHERE pname LIKE '_想%';
# 通过order by语句,可以将查询出的结果进行排序。暂时放置在select语句的最后。
格式:SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;
ASC 升序 (默认)
DESC 降序
# 1.使用价格排序(降序)
SELECT * FROM product ORDER BY price DESC;
# 2.在价格排序(降序)的基础上,以分类排序(降序)
SELECT * FROM product ORDER BY price DESC,category_id DESC;
之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个单一的值;==另外聚合函数会忽略空值==。
聚合函数 | 作用 |
---|---|
count() | 统计指定列不为NULL的记录行数; |
sum() | 计算指定列的数值和,如果指定列类型不是数值类型,则计算结果为0 |
max() | 计算指定列的最大值,如果指定列是字符串类型,使用字符串排序运算; |
min() | 计算指定列的最小值,如果指定列是字符串类型,使用字符串排序运算; |
avg() | 计算指定列的平均值,如果指定列类型不是数值类型,则计算结果为0 |
# 1、查询商品的总条数
SELECT COUNT(*) FROM product;
# 2、查询价格大于200商品的总条数
SELECT COUNT(*) FROM product WHERE price > 200;
# 3、查询分类为'电脑'的所有商品的总和
SELECT SUM(price) FROM product WHERE category_id = '电脑';
# 4、查询分类为'汽车'所有商品的平均价格
SELECT AVG(price) FROM product WHERE categrory_id = '汽车';
# 5、查询商品的最大价格和最小价格
SELECT MAX(price),MIN(price) FROM product;
分组查询就是将查询结果按照指定字段进行分组,字段中数据相等的分为一组。
#基本语法
GROUP BY 列名 [HAVING 条件表达式] [WITH ROLLUP]
group by可用于单个字段分组,也可用于多个字段分组
-- 根据gender字段来分组
select category_id from product group by category_id;
mysql> select category_id from product group by category_id;
#
+-------------+
| category_id |
+-------------+
| 电脑 |
| 汽车 |
| 鞋 |
| 方便面 |
| 水 |
+-------------+
5 rows in set (0.00 sec)
-- 根据pname和category_id字段进行分组
select pname, category_id from product group by pname, category_id;
-- 统计不同类型商品的平均价格
select category_id,avg(price) from product group by category_id;
+-------------+--------------------+
| category_id | avg(price) |
+-------------+--------------------+
| 电脑 | 6333.333333333333 |
| 汽车 | 58000 |
| 鞋 | 425 |
| 方便面 | 12.333333333333334 |
| 水 | 2.5 |
+-------------+--------------------+
-- 统计不同类型商品的个数
select category_id,count(*) from product group by category_id;
+-------------+----------+
| category_id | count(*) |
+-------------+----------+
| 电脑 | 3 |
| 汽车 | 3 |
| 鞋 | 4 |
| 方便面 | 3 |
| 水 | 2 |
+-------------+----------+
5 rows in set (0.00 sec)
# 统计各个分类商品的个数,且只显示个数大于1的信息
SELECT category_id ,COUNT(*) FROM product GROUP BY category_id HAVING COUNT(*) > 1;
+-------------+----------+
| category_id | COUNT(*) |
+-------------+----------+
| 电脑 | 3 |
| 汽车 | 3 |
| 鞋 | 4 |
| 方便面 | 3 |
| 水 | 2 |
+-------------+----------+
SELECT 字段1,字段2... FROM 表名 LIMIT M,N
M: 整数,表示从第几条索引开始,计算方式 (当前页-1)*每页显示条数
N: 整数,表示查询多少条数据
SELECT 字段1,字段2... FROM 表名 LIMIT 0,5
SELECT 字段1,字段2... FROM 表名 LIMIT 5,5
# 从零开始
SELECT* FROM product LIMIT 0,5;
#从5开始
SELECT* FROM product LIMIT 5,5;
+-----+-----------------+-------+-------------+
| pid | pname | price | category_id |
+-----+-----------------+-------+-------------+
| 6 | 长城汽车 | 44000 | 汽车 |
| 7 | 安踏鞋 | 200 | 鞋 |
| 8 | 李宁鞋 | 600 | 鞋 |
| 9 | NINK鞋 | 800 | 鞋 |
| 10 | 白象方便面 | 15 | 方便面 |
+-----+-----------------+-------+-------------+
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。