Mysql基础语法(一)

Mysql基础语法(一)

在这个基础语法(一)中,仅讲解简单的DDL、DML和DQL语句使用。

一、基本概念

Mysql是一种关系型数据库,即由多张相互连接的二维表组成。参考下面这幅图,员工表的dept_id字段关系到部门表的id字段,也就是两张二维表具有关系。

  • **二维表:**Mysql中的表都是二维的,也就是行与列,除此之外,没有第三维度。

二、数据类型

Mysql数据库中的数据类型一般分为三大类,数值类型、字符串类型和时间类型。

2.1 数值类型

Mysql中的数值类型一共有8个(主要掌握INT和FLOAT),其中包括整型和浮点数类型,如下:

类型 大小 范围(有符号) 范围(无符号) 描述
TINYINT 1 btye -2^8 ~ 2^7-1 0 ~ 2^8-1 小整数
SMALLINT 2 btye -2^15 ~ 2^15-1 0 ~ 2^16-1 大整数
MEDIUMINT 3 btye -2^23 ~ 2^23-1 0 ~ 2^24-1 大整数
INT / INTEGER 4 btye -2^31 ~ 2^31-1 0 ~ 2^32-1 大整数
BIGINT 8 btye -2^63 ~ 2^63-1 0 ~ 2^64-1 极大整数
FLOAT 4 btye 单精度浮点数
DOUBLE 8 btye 双精度浮点数
DECIMAL 小数值
  • 1 byte指的是占一个比特,一个比特占8个二进制位(每个二进制位都是0或者1),在无符号中,一个比特能最大表达2的八次方减一(即2^8 - 1),这是由于即使你8个二进制位都是1,即11111111。那也就是(2的8次方-1),由于其无法占用到第九位,因为28的二进制是100000000,所以1个比特最大能表达(2的8次方-1)。
  • 有符号 中,一个比特(8位),需要用一位来记录正负符号(符号位一般是最高位,0表示正数,1表示负数),所以只有七位用于记录数的大小,那么在正数部分,最大能表达(2的7次方-1),那为何负数能表达到(2的7次方)呢,这是由于符号位的存在,0表示为00000000,那么当符号位为负数时,100000000表示-0,虽然看着是0,但是这个数被二进制使用,表示负数的最大数,即2^7。
  • 以上说的这些二进制计算,和计算机组成原理有关系,这里稍微拓展了一下。

2.2 字符串类型

字符串类型一共有10种,其中主要是CHAR和VARCHAR类型。

  • VARCHAR是一种不定长字符串,也就是说他会根据实际内容来占用空间;而CHAR是一种定值占用空间的类型。
sql 复制代码
-- 下面同样定义30比特空间大小的两个字符串类型,例如插入abcd,四个英文字符,理论占用4的字节的空间
-- VARCHAR的占用的空间,会根据实际插入字符的大小来决定,abcd占4个字节
VARCHAR(30);

-- CHAR则是定值空间占用,即使abcd占不到30比特,但是他会在空间中占用30个比特的大小
CHAR(30);
  • 所以VARCHAR的优势很明显,对于不定长的字段(例如游戏名称,有长有短),可以根据这个来定义,能节省空间。
  • 对于定长,例如电话号码,身份证号,使用CHAR,因为CHAR插入效率高,VARCHAR需要计算字符串大小,效率低。

2.3 时间类型

Mysql的时间类型主要有五个,主要掌握DATE、DATETIME和TIME。

  • DATE是日期,TIME是具体时间、DATETIME是具体日期的具体时间

三、通用语法

3.1 语法规则

​ 在数据库中,有一种通用的SQL语法,该SQL语法在Mysql之外的其他数据库也适用,例如Oracle。SQL语法用着下面三个规则:

  • SQL默认都是;(英文分号)结尾,在识别到结尾符号之前,SQL可以写多行,也可以写一行,直到;符号结束
sql 复制代码
-- 可以写成一行
select * from tb_user;	

-- 也可以写成多行,一般复杂的SQL就会写成多行
select *
	from
	tb_user;
  • SQL中每个关键字或者表面之间可以隔离多个空格
sql 复制代码
-- 下面两句SQL是等价的,两个单词或者关键字之间可以有多个空格
select * from tb_user;

select        *    from     tb_user;
  • SQL中关键字(例如select、update等等)不区分大小写
sql 复制代码
-- 等效
select * from tb_user;

SELECT * from tb_user;

3.2 SQL语法

SQL的主要语法分为四大类,DDL(定于数据库和表)、DML(增删改)、DQL(查询)和DCL(系统控制)。

(注:个人觉得使用层面上,最重要的就是DQL,其次是DDL和DML,DCL的话一般运维人员用得多,我们一般很少用)

3.2.1 DDL语句(于数据库和表)
  • 查看数据库
sql 复制代码
show databases;
  • 切换数据库(注意,一定要切换数据库,才能使用数据库下面的表,不然调用数据表会报错,这里用database_name表示要创建的数据库名字)
sql 复制代码
use database_name;
  • 创建数据库(if not exists 可以不写,但是规范建议写)
sql 复制代码
create database database_name if not exists;
  • 删除数据库(if exists 可以不写,但是规范建议写)
sql 复制代码
drop database if exists database_name;
  • 查看表(目前所处于什么数据库,就会查看什么数据库下面的表)
sql 复制代码
show tables;
  • 创建表(column_name是字段名,column_type字符的数据类型,comment是备注信息,if not exists可省略)
sql 复制代码
create table if not exists table_name(
	column_name column_type comment '',
    column_name column_type comment '',
    ....
    column_name column_type comment ''
)comment '';
  • 查看表的结构(查看建表语句)
sql 复制代码
DESC table_name;
  • 删除表(删除表和表中的数据,和下面的truncate有点区别)
sql 复制代码
drop table if exists table_name;
  • 删除表(但是会同时创建一个结构一样,但是没有数据的新表)
SQL 复制代码
truncate table table_name;
  • 除此之外还有一些增加表字段,修改表字段的alter语句,这里就不作展示了。
3.2.2 DML语句(增删改)
  • 添加数据
sql 复制代码
-- 插入完整的数据,第一个是插入一行完整数据,第二个是插入多行完整数据
insert into table_name values (xxx,xxx,xxx);
insert into table_name values (xxx,xxx,xxx),(xxx,xxx,xxx),(xxx,xxx,xxx);

-- 插入表中指定字段的数据,可以插入个别字段的数据,也可以把表的所有字段都列出来,相当于上面的插入完整数据
insert into table_name(column_1,column_2....) values (xxx,xxx....);
insert into table_name(column_1,column_2....) values (xxx,xxx....),(xxx,xxx....),(xxx,xxx....);
  • 修改数据
sql 复制代码
-- 修改制定字段的值,如果后面不加where条件的话,会修改所有该字段的值,也可以修改多个值
update table_name set column_name = xxxx where 条件
update table_name set column_1 = xxxx , column_2 = xxx where 条件
  • 删除数据
sql 复制代码
-- 删除数据,不加where条件就会删除整个表的数据
delete from table_name where 条件
3.2.3 DQL语句(查询)
  • 简单查询
sql 复制代码
-- *代表所有数据,这个就是查询全部数据
select * from table_name;  

-- 这个是插叙制定字段的数据,如果把全部字段都列出来的话,相当于select *,但是虽然都是查询全部数据,但是有区别
select column_1,column_2 from table_name;  

-- 给查询结果起别名
select column_1 as other_name , column_2 as other_name from table_name; 
-- as 可以省略,效果一样
select column_1  other_name , column_2  other_name from table_name; 
  • 简单来说,select * 的话简单便捷,但是可读性较差,他的输出字段顺序取决于定义表时的顺序,较为固定,而且不能起别名。
  • select全部字段的话,可以增强可读性,但是不好维护,万一表结构更新,需要改动较大。
  • where条件过滤
sql 复制代码
-- where 条件过滤有多个过滤方式
-- 这里举个例,可以进行大小等值比较
where id > 10;
where id == 10;
where id >=10;

-- 范围查询
where id between 1 and 10;
where id in (1,10);

-- 模糊查询,一般使用字符串字段匹配,例如电话,名字,用法有百分号%和下划线_两种
where name like '张%'	-- 匹配张开头的字段,张xx,张x,张xxx,只要是张开头,后面不管是什么就会被匹配上

where name like '%杰'	-- 匹配杰结尾的,xx杰,x杰,xxx杰,只要是杰结尾,前面不管是什么就会被匹配上

where name like '%杰%'	-- 匹配杰字在中间的,x杰x,只要是杰在中间出现过,前面和后面不管是什么就会被匹配上

where name like '张_'	-- 下划线代表占位符,例如这里是查询张x,只能是两个字

where name like '___'	-- 下划线代表占位符,例如这里是三个下划线,只能是三个任意的字
  • 去重distinct
sql 复制代码
-- distinct关键字能去掉该字段重复的数据,如果是多个字段返回的话,会全部字段都相同才会被当作重复数据
select distinct column_name from table_name; 
  • 聚合函数
sql 复制代码
-- 聚合函数是Mysql中提供的方便用户调用的函数,其中null值不参加聚合函数的运算
-- 统计这张表的数据行数
select count(*) from table_name;

-- 统计某一字段的和,sum函数的参数只能是一个字段列或者表达式
select sum(column_name) from table_name;

-- AVG()平均数
select AVG(column_name) from table_name;

-- MIN()最小值
select MIN(column_name) from table_name;

-- MAX()最大值
select MAX(column_name) from table_name;
  • 分组查询
sql 复制代码
-- 关键字 group by 字段,根据该字段分组,后面可以接having关键字,表示分组后的结果进行条件过滤,有点像where,不过where是针对分组之前,having是针对分组之后

select * from table_name where xxx group by column_name having xxx;
  • 排序
sql 复制代码
-- 默认ASC升序(即使不写ASC,也是默认升序),DESC降序
-- 根据某个字段(column_name)升降序展示
select * from table_name order by column_name ASC / DESC;
  • 分页查询
sql 复制代码
-- 使用limit关键字,用法为limit(起始行,展示多少行),起始行从0开始计算,例如数组。
select * from table_name limit (0,10); -- 从第1行数据开始,展示10条数据

select * from table_name limit (11,10); -- 从第12行数据开始,展示10条数据
  • SQL执行顺序 (如上面所示,介绍的这么多关键字用法,排序、分组、分页等等,全都可以放在一起使用,不过有先后顺序

    • 先是 FROM 关键字,从哪张表中查询数据,
    • 然后是 where 过滤
    • 然后是 group by 分组和having过滤
    • 然后才是 select 挑选返回结果字段
    • 然后到 order by 排序
    • 最后到 limit 分页
  • 也许大家很好奇,执行顺序在这里有什么用吗,其实主要关系到一个别名问题,我们在写SQL时避免不了要给表或者字段起别名,而Mysql有一个规则,当你给表起了别名之后,那么你后续调用这个表就需要使用别名,如下:

sql 复制代码
-- 例如我有一张表叫做sys_test表
select * from sys_test as s where s.id = 1;		-- 正确

select * from sys_test as s where sys_test.id = 1;	-- 错误,会报错
  • 从上面的例子,大家应该能比较直观感受到这个规则,后续的问题引入,执行顺序关系到你能不能调用这个表的别名。大家从上面能知道 from 是先执行的,如果在 from 的时候,我已经给表起了别名,那么后续的where、select使用这个表的时候都要使用表的别名;相反,如果在执行你这个关键字之前,没有人给表起别名,你只能使用表的原名。大家再结合下面的例子好好理解一下:
sql 复制代码
-- 正常执行顺序,没问题
select age,name from emp where age > 20 order by age ASC limit 5; 

-- 由于先执行from 再到where,from时已经为表emp起了别名e,故后续where 使用e.age没问题
select age,name from emp e where e.age > 20 order by age ASC limit 5;

-- 由于先执行where,再到select,所以select时起的别名e_age在where之前没生效,故where处无法生效吗,故错误
select age as e_age , name as e_name from emp where e_age> 20 order by age ASC limit 5;
相关推荐
新时代的弩力12 分钟前
Cesium添加WMS,WMTS,地形图图,3D Tiles数据
数据库·3d
钢铁男儿21 分钟前
C# 方法(局部函数和参数)
java·数据库·c#
文牧之36 分钟前
PostgreSQL 的 pg_ls_waldir 函数
运维·数据库·postgresql
小小不董1 小时前
Oracle OCP认证考试考点详解083系列09
linux·数据库·oracle·dba
木木子99991 小时前
MySQL 比较运算符详解
数据库·sql
尤物程序猿2 小时前
[2025]MySQL的事务机制是什么样的?redolog,undolog、binog三种日志的区别?二阶段提交是什么?ACID怎么保证的?主从复制的过程?
数据库·mysql
高铭杰2 小时前
Postgresql源码(144)LockRelease常规锁释放流程分析
数据库·postgresql··lockrelease·regularlock
star_and_sun3 小时前
SQL笔记——左连接、右连接、内连接
数据库·笔记·sql
kngines4 小时前
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.4 数据抽样(简单随机抽样/分层抽样)
数据库·postgresql·数据分析·分层抽样·简单抽样·neyman 分配法·tablesample