MySql基础
Posted Al_tair
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql基础相关的知识,希望对你有一定的参考价值。
mysql基础
MySql基础
大家好,我是小笙!经过了一周的数据库学习,我开始掌握了一些数据库基础,还需继续努力,以下是我个人的笔记!(部分学习自SQL)
数据库的初识
1.1数据库是什么?
数据库: 英文DataBase 简称DB
数据库,顾名思义就是存储数据的仓库,实际上就是一些文件,用来存储特定格式的数据!
1.2数据库管理系统是什么?
数据库管理系统:英文DataBaseManagement 简称 DBMS
数据库管理系统是专门用来管理数据库中的数据,可以对数据库中的数据进行增删改查
常见的数据库管理系统: MySql Sqlserver Oracle等等
1.3SQL是什么?
SQL 结构化查询语言
我们可以通过学习SQL语言对数据库管理系统进行操作来实现对数据库中的数据增删改查,并且SQL在不同的数据库管理系统中普遍使用
1.4三者有什么关系?
我们编写SQL数据库语言,通过数据管理系统实现对数据库中的数据增删改查
简述:DBMS ----- 执行 —> SQL ---- 操作 —> DB
常用数据类型
数据类型图
代码示例
# 文本类型
# 注意区别字符和字节的区别
# size 都指代字符(数字或者汉字)
CHAR(size) -- 固定字符串 最大存储 = 255字符(无论数字还是中文都是一个字符)
VARCHAR(size) -- 可变长度字符串 最大存储 = 65532字节(还有3字节用来记录该字符串长度)
# 如果VARCHAR 不够用,可以考虑使用 MEDIUMTEXT 或者 TEXT 或者 LONGTEXT
# 日期类型
CREATE TABLE `date`(
birthday DATE,
job_time DATETIME,
login_time TIMESTAMP
NOT NULL DEFAULT CURRENT_TIMESTAMP # 默认当前时间戳
ON UPDATE CURRENT_TIMESTAMP # 更新时间戳
)
# 插入语句
INSERT INTO `date`(birthday,job_time)
VALUES('2022-11-11','2022-11-11 10:10:10');
数据库的操作
三种注释方式
# 注释
-- 快捷键:ctrl + / ; 取消注释: ctrl + shift + /
/*
多行注释
*/
创建和切换数据库
# 关键字create [if not exists]如果存在该数据库则不会再创建
create database[if not exists]db_name
[DEFAULT]character set:utf8 #默认字符集utf-8
[DEFAULT]collate:utf8_general_ci #默认不区分大小写;utf8_bin区分大小写
# 代码示例
# 解说:创建了一个字符集为utf8的区分大小写的数据库
CREATE DATABASE test CHARACTER SET utf8 COLLATE utf8_bin
# 创建数据库,表的名字的时候为了规避关键字可以使用反引号来解决
CREATE DATABASE `CREATE`
# 切换成test数据库
USE test
查看和删除数据库
# 显示数据库
SHOW DATABASES
# 删除数据库
Drop DATABASE xxx
创建和删除表
# 创建表
CREATE TABLE person
(
# 列名 字段类型
field1 dataType,
field1 dataType,
field1 dataType,
)CHARACTER SET 字符集 COLLATE 校对规则 ENGINE 引擎
CHARACTER SET 字符集:默认为所在数据库字符集
COLLATE 校队规则:默认为所在数据库校对规则
# 代码示例
CREATE TABLE `person`
(
# 无符号整形
`id` INT UNSIGNED,
`name` VARCHAR(255),
`pwd` VARCHAR(16),
`birthday` DATE
)
# 删除表
DROP TABLE person
# 查看test表的结构
desc test;
修改表
# 修改表名
RENAME TABLE test to new_test;
# 修改test表的字符集
ALTER TABLE test CHARACTER SET utf8;
# 添加列
ALTER TABLE test ADD col VARCHAR(10);
# 修改列
ALTER TABLE test MODIFY salary DOUBLE;
# 删除列中image列
ALTER TABLE test DROP image;
# 修改列名
ALTER TABLE test CHANGE `name` another_name VARCHAR(30);
数据操作CRUD
# 操作表emp
CREATE TABLE emp(
id INT, NOT NULL
`name` VARCHAR(20),
sex CHAR(1),
birthday DATE,
entry_date DATE,
job VARCHAR(20),
salary FLOAT, NOT NULL DEFAULT 2200 # 默认2200
resume TEXT
)CHARACTER SET utf8
insert
# 注意细节
# 1.'123' 可以放入到INT类型的数据里
# 2.列出的数据位置必须与列的排列顺序要一致
# 3.字符和日期类型插入的数据需要单引号或者双引号引上
INSERT INTO emp # 添加全部数据
VALUES(1,'罗念笙','男','2001-03-18','2022-03-26','XXX',20000,'加油');
INSERT INTO emp (id,`name`,sex) # 添加部分数据
VALUES(2,'陈勇军','男');
# 复制表 将xxx表中的eid,ename,ejob的数据复制到yyy表中id,name,job
INSERT INTO yyy(id,name,job) SELECT eid,ename,ejob FROM xxx
update
UPDATE emp SET salary = 2000; -- 把所有员工的工资改成2000
UPDATE emp SET salary = 2000 WHERE id = 1; -- 把id=1的员工的工资改成2000 WHERE是条件语句
delete
DELETE FROM emp; -- 把所有员工记录删除
DELETE FROM emp WHERE id = 1; -- 把id=1的员工记录删除
select
# 基本语法
# DISTINCT(可选):去重 ; * 查找所有列 ; column指的是列名
SELECT [DISTINCT] *|column1,column2,column3... FROM emp;
# 给列取别名 (可以分别对多个列名进行设置不同的别名)
# 格式:SELECT 列名 as 别名 FROM 表名;
过滤
不进行过滤的数据非常大,导致通过网络传输了多余的数据,从而浪费了网络带宽。因此尽量使用 SQL 语句来过滤不必要的数据,而不是传输所有的数据到客户端中然后由客户端进行过滤。
where语句
注意:between small and big 范围前面小于后面
通配符
通配符也是用在过滤语句中,但它只能用于文本字段。
-
% 匹配 >=0 个任意字符
-
_ 匹配 ==1 个任意字符
# 使用 Like 来进行通配符匹配 SELECT *FROM emp WHERE `name` LIKE '罗%'; -- 以罗开头的任意字符
排序
使用order by语句进行排序(位置位于SELECT语句结尾)
- ASC[默认升序]
- DESC[降序]
# 显示的列 根据哪个列来排序
# 格式:SELECT 列名或者别名 FROM 表名 WHERE... ORDER BY 列名或者别名 ASC或者DESC
函数
统计函数
MySql的主要函数
函 数 | 说 明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
COUNT(行数)
# 查询所有记录的个数
SELECT COUNT(*) FROM emp
# 查询该列的所有行数(注意:排除null)
SELECT COUNT(`name`) FROM emp
SUM(求和)
# 查询该列所有值之和
SELECT SUM(salary) FROM emp
AVG(平均值)
# 查询该列所有值的平均值
SELECT AVG(salary) FROM emp
MAX(最大值)
# 查询该列所有值的最大值
SELECT MAX(salary) FROM emp
# 查询该列所有值的最小值
SELECT MIN(salary) FROM emp
字符串函数
SELECT CHARSET(`name`) FROM emp; -- 返回字符串的字符集
SELECT CONCAT(`name`,'job is',job) FROM emp; -- 连接字符串
# dual 亚元表,系统表,可以用来作为测试表
SELECT INSTR('woshiluoniansheng','sheng') FROM dual; -- 返回substring 在string中出现的位置,没有则返回0
SELECT UCASE(`name`) FROM emp; -- 转换成大写
SELECT LCASE(`name`) FROM emp; -- 转换成小写
SELECT LEFT(`name`,2) FROM emp; -- 从String2中的左边起取length个字符
SELECT LEFT(`name`,2) FROM emp; -- 从String2中的右边起取length个字符
SELECT LENGTH(`name`) FROM emp; -- string长度[按照占用字节]
SELECT REPLACE(`name`,'lns','zlr') FROM emp; -- 用replace_str替换search_str字符串
SELECT STRCMP('lns','zlr') FROM dual; -- 比较字符串
SELECT SUBSTRING(`name`,1,2) FROM emp; -- 从str的position开始[从1开始],取length个字符
SELECT LTRIM(' LNS ') FROM dual; -- 去掉前面的空格
SELECT RTRIM(' LNS ') FROM dual; -- 去掉后面的空格
SELECT TRIM(' LNS ') FROM dual; -- 去掉前后的空格
数学函数
SELECT ABS(-10) FROM dual; -- 10
SELECT CEILING(-1.1) FROM dual; -- -1
SELECT FLOOR(1.1) FROM dual; -- 1
SELECT FORMAT(78.2356,2) FROM dual; -- 78.24
SELECT RAND() FROM dual; -- 返回随机数 范围[0,1.0]
SELECT RAND(3) FROM dual; -- 返回随机数 范围[0,1.0] 但是seed = 3不变,该随机数也就不变了
时间日期
SELECT CURRENT_DATE() FROM dual; -- 当前日期 2022-03-28
SELECT CURRENT_TIME() FROM dual; -- 当前时间 16:41:27
SELECT CURRENT_TIMESTAMP() FROM dual; -- 当前时间戳 2022-03-28 16:42:18
SELECT DATE(CURRENT_TIMESTAMP()) FROM dual; -- 显示日期 2022-03-28
SELECT NOW() FROM dual; -- 当前日期和时间 2022-03-28 16:50:55
SELECT DATE_ADD(CURRENT_TIMESTAMP(),INTERVAL 10 MINUTE) FROM dual; -- 2022-03-28 16:59:34 十分钟以后
SELECT DATEDIFF(NOW(),'2001-3-18') FROM dual; -- 我活了7680天
SELECT UNIX_TIMESTAMP FROM dual; -- 返回的是1970-1-1 到现在的秒数
# 意义:开发中,可以存放一个整数,然后表示,通过FROM_UNIXTIME转换
SELECT FROM_UNIXTIME(1618483408,'%Y-%m-%d %H:%i:%s') FROM dual; -- 2021-04-15 18:43:28
流程控制函数
# 说明
IF(expr1,expr2,expr3); -- 等价于java的三元运算
IFNULL(expr1,expr2); -- 等价于如果expr1不为NULL返回expr1,反之返回expr2
加密函数(扩展)
# md5加密
SELECT MD5('LUO12345') FROM dual; -- 70e4a6f2316f83d10718b2d251ec8c58 32位十六进制密文
# PASSWORD(str)加密 MYSQL数据库密码就是用这个函数加密的
SELECT PASSWORD('LUO12345') FROM dual; -- D0D23440C6FBE6CD05E079658CE805F8A3589D1C
雇员系统表
# 部门表
CREATE TABLE dept(
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
dname VARCHAR(20) NOT NULL DEFAULT "",
loc VARCHAR(13) NOT NULL DEFAULT ""
);
INSERT INTO dept VALUES(10, 'ACCOUNTING', 'NEW YORK'), (20, 'RESEARCH', 'DALLAS'), (30, 'SALES', 'CHICAGO'), (40, 'OPERATIONS', 'BOSTON');
# 创建表EMP雇员
CREATE TABLE emp
(empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, -- 编号
ename VARCHAR(20) NOT NULL DEFAULT "", -- 名字
job VARCHAR(9) NOT NULL DEFAULT "", -- 工作
mgr MEDIUMINT UNSIGNED , -- 上级编号
hiredate DATE NOT NULL, -- 入职时间
sal DECIMAL(7,2) NOT NULL, -- 薪水
comm DECIMAL(7,2) , -- 红利
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 -- 部门编号
);
INSERT INTO emp VALUES(7369, 'SMITH', 'CLERK', 7902, '1990-12-17', 800.00,NULL , 20),
(7499, 'ALLEN', 'SALESMAN', 7698, '1991-2-20', 1600.00, 300.00, 30),
(7521, 'WARD', 'SALESMAN', 7698, '1991-2-22', 1250.00, 500.00, 30),
(7566, 'JONES', 'MANAGER', 7839, '1991-4-2', 2975.00,NULL,20),
(7654, 'MARTIN', 'SALESMAN', 7698, '1991-9-28',1250.00,1400.00,30),
(7698, 'BLAKE','MANAGER', 7839,'1991-5-1', 2850.00,NULL,30),
(7782, 'CLARK','MANAGER', 7839, '1991-6-9',2450.00,NULL,10),
(7788, 'SCOTT','ANALYST',7566, '1997-4-19',3000.00,NULL,20),
(7839, 'KING','PRESIDENT',NULL,'1991-11-17',5000.00,NULL,10),
(7844, 'TURNER', 'SALESMAN',7698, '1991-9-8', 1500.00, NULL,30),
(7900, 'JAMES','CLERK',7698, '1991-12-3',950.00,NULL,30),
(7902, 'FORD', 'ANALYST',7566,'1991-12-3',3000.00, NULL,20),
(7934,'MILLER','CLERK',7782,'1992-1-23', 1300.00, NULL,10);
# 工资级别表
CREATE TABLE salgrade
(
grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, -- 工资级别
losal DECIMAL(17,2) NOT NULL, -- 该级别的最低工资
hisal DECIMAL(17,2) NOT NULL -- 该级别的最高工资
);
INSERT INTO salgrade VALUES (1,700,1200);
INSERT INTO salgrade VALUES (2,1201,1400);
INSERT INTO salgrade VALUES (3,1401,2000);
INSERT INTO salgrade VALUES (4,2001,3000);
INSERT INTO salgrade VALUES (5,3001,9999);
分组查询
分组就是把具有相同的数据值的行放在同一组中。
# 显示每个部门的平均工资和最高工资 注意题目:每个部门
SELECT deptno,AVG(sal) AS avgSal, MAX(sal) AS maxSal FROM emp GROUP BY deptno
# WHERE 过滤行,HAVING 过滤分组,行过滤应当先于分组过滤 这就是为什么这里用 HAVING
# 显示平均工资低于2000的部门号和它的平均工资 注意题目:平均工资低于2000
SELECT deptno,AVG(sal) AS avgSal FROM emp GROUP BY deptno HAVING avgSal < 2000
注意细节
- 排列顺序:GROUP BY 子句出现在 WHERE 子句之后,ORDER BY 和 HAVING子句之前
- NULL 的行会单独分为一组
- 大多数 SQL 实现不支持 GROUP BY 列具有可变长度的数据类型
分页查询
# 基本语法:SELECT ... LIMIT start,rows
# 限制返回的行数。可以有两个参数,第一个参数start为起始行,从 0 开始;第二个参数rows为返回的总行数。
SELECT * FROM 表名 ORDER BY 列名 LIMIT 每页显示记录数*(第n页数-1),每页显示的记录数
语句顺序
总结顺序:where -> group by -> having -> order by -> limit
SELECT column1,column2,column3... FROM table
WHERE ... -- 行过滤
GROUP BY column -- 分组查询
HAVING ... -- 分组过滤
ORDER BY column -- 按字段排序 ASC DESC
limit start,rows; 以上是关于MySql基础的主要内容,如果未能解决你的问题,请参考以下文章