MYSQL基础语法二

1、数据类型

1.1、数值型

MySQL支持多种数值型数据类型,包括整数型、小数型和布尔型。

1.1.1、整数型

MySQL支持多种整数型数据类型,包括TINYINT、SMALLINT、MEDIUMINT、INT和BIGINT。

  • TINYINT:1字节,取值范围为-128到127或0到255。
  • SMALLINT:2字节,取值范围为-32768到32767或0到65535。
  • MEDIUMINT:3字节,取值范围为-8388608到8388607或0到16777215。
  • INT:4字节,取值范围为-2147483648到2147483647或0到4294967295。
  • BIGINT:8字节,取值范围为-9223372036854775808到9223372036854775807或0到18446744073709551615。

1.1.2、小数型

MySQL支持多种小数型数据类型,包括FLOAT、DOUBLE和DECIMAL。

  • FLOAT:4字节,单精度浮点数,精度为7位。
  • DOUBLE:8字节,双精度浮点数,精度为15位。
  • DECIMAL:可变长度,用于存储精确的小数,精度和数据长度可以自定义。

1.1.3、布尔型

MySQL支持布尔型数据类型,即BOOLEAN或BOOL。它只占用1位,取值为TRUE或FALSE。

1.2、日期型

MySQL支持多种日期型数据类型,包括DATE、TIME、DATETIME、TIMESTAMP和YEAR。

  • DATE:用于存储日期,格式为YYYY-MM-DD。
  • TIME:用于存储时间,格式为HH:MM:SS。
  • DATETIME:用于存储日期时间,格式为YYYY-MM-DD HH:MM:SS。
  • TIMESTAMP:用于存储时间戳,格式为YYYY-MM-DD HH:MM:SS。
  • YEAR:用于存储年份,格式为YYYY。

1.3、字符串型

MySQL支持多种字符串型数据类型,包括CHAR、VARCHAR、TEXT、BLOB和ENUM。

1.3.1、CHAR和VARCHAR

CHAR和VARCHAR都用于存储字符串,但它们的存储方式不同。CHAR是一种固定长度的字符串类型,VARCHAR是一种可变长度的字符串类型。

  • CHAR:用于存储固定长度的字符串,长度为0到255个字符。
  • VARCHAR:用于存储可变长度的字符串,长度为0到65535个字符。

1.3.2、TEXT和BLOB

TEXT和BLOB用于存储大量的文本或二进制数据。

  • TEXT:用于存储大量的文本数据,最大长度为65535个字符。
  • BLOB:用于存储大量的二进制数据,最大长度为65535个字节。

1.3.3、ENUM

  • ENUM用于存储枚举类型的数据,如性别、状态等。

1.4、二进制型

MySQL支持多种二进制型数据类型,包括BIT、BINARY和VARBINARY。

  • BIT:用于存储比特位,长度为1到64个比特位。
  • BINARY:用于存储固定长度的二进制数据,长度为0到255个字节。
  • VARBINARY:用于存储可变长度的二进制数据,长度为0到65535个字节。

五、其他类型

MySQL还支持多种其他类型的数据,包括SET、JSON和Geometry。

  • SET:用于存储一组可选值,最多可以有64个选项。
  • JSON:用于存储JSON格式的数据。
  • Geometry:用于存储几何类型的数据,如点、线、面等。

2、常用语法

MySQL常用列属性有:null、not null、default、primary key、auto_increment、comment。

2.1、空属性: null和not null

sql 复制代码
/*空属性: null和not null*/
空属性: null(空,默认) 和 not null(不为空). mysql数据库默认字段都是为null的,实际开发过程中尽可能保证所有的数据都不应该为null,空数据没有意义.
例如: create table test(
    a int not null,
    b int
);
insert into test (a,b) values(10,null);
insert into test (a,b) values(null,10);--报错

2.2、默认值:default

sql 复制代码
/*默认值: default*/
default: 自定义默认值属性,通常配合not null一起使用.
例如: create table test1(
    a int not null default 200,
    b int
);
insert into test1(b) values(20);--或 insert into test1(a,b) values(default,20);

2.3、主键:primary key

sql 复制代码
/*主键|唯一索引*/
Mysql中提供了多种索引? (下文索引更多解析)
1.主键索引:primary key
2.唯一索引:unique key
3.全文索引:fulltext index
4.普通索引:key 或 index

主键:primary key  一张表中只能有一个字段可以使用对应的主键,用来唯一的约束该字段里面的数据,不能重复和不能为null.
设置主键有两种方式:
(1)在定义一个字段的时候直接在后面进行设置primary key
例如: create table test2(
  id int(10) unsigned not null primary key,
  name char(20) not null default ''
);
(2)定义完字段后再定义主键
例如: create table test3(
  id int(10) unsigned not null,
  name char(20) not null default '',
  primary key (id)
);
唯一键:unique key 解决表中多个字段需要唯一性约束的问题.
例如:create table test4(
  id int(10) unsigned not null,
  name char(20) not null default '',
  goods varchar(100) not null default '',
  primary key (id),
  unique key (name,goods)
);

2.4、自增长:auto_increment

sql 复制代码
/*自动增长: auto_increment*/
自增长属性:每次插入记录的时候,自动的为某个字段的值加1(基于上一个记录). 通常跟主键搭配.
自增长规则:(1)任何一个字段要做自增长前提必须是一个索引  (2)自增长字段必须是整型数字
例如: create table test5(
  id int(10) unsigned not null auto_increment,
  name char(20) not null default '',
  primary key (id)
);

2.5、列描述:comment

sql 复制代码
/*列描述 comment*/
列描述(注释):comment 与其他的注释符不同之处在于,这里的注释内容属于列定义的一部分.
例如:create table user(
  id int(10) unsigned not null auto_increment comment 'id',
  name char(20) not null default '' comment '名字',
  primary key (id)
)engine=InnoDB default charset=utf8 comment='用户表';

2.6、索引

sql 复制代码
#索引
/*索引的概述和优缺点和种类*/
什么是索引?
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.
类比理解:数据库中的索引相当于书籍目录一样,能加快数据库的查询速度.
没有索引的情况,数据库会遍历全部数据后选择符合条件的选项.
创建相应的索引,数据库会直接在索引中查找符合条件的选项.

索引的性质分类:
索引分为聚集索引和非聚集索引两种,聚集索引是索引中键值的逻辑顺序决定了表中相应行的物理顺序,而非聚集索引是不一样;
聚集索引能提高多行检索的速度,而非聚集索引对于单行的检索很快.

索引的优点:
(1)加快数据检索速度 (创建索引主要原因)
(2)创建唯一性索引,保证数据库表中每一行数据的唯一性
(3)加速表和表之间的连接
(4)使用分组和排序子句对数据检索时,减少检索时间
(5)使用索引在查询的过程中,使用优化隐藏器,提高系统的性能

索引的缺点:
(1)创建索引和维护索引要耗费时间,时间随着数据量的增加而增加
(2)索引需要占用物理空间和数据空间
(3)表中的数据操作插入、删除、修改, 维护数据速度下降

索引种类
(1)普通索引: 仅加速查询
(2)唯一索引: 加速查询 + 列值唯一(可以有null)
(3)主键索引: 加速查询 + 列值唯一(不可以有null)+ 表中只有一个
(4)组合索引: 多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
(5)全文索引: 对文本的内容进行分词,进行搜索 (注意:目前仅有MyISAM引擎支持)

/*创建表时直接指定索引*/
--创建主键索引
例如:create table student(
  id int(10) unsigned not null auto_increment comment 'id主键索引',
  name char(20) not null default '' comment '名字',
  class varchar(50) not null default '' comment '班级',
  seat_number smallint(5) not null default 0 comment '座位编号',
  primary key (id)
)engine=InnoDB default charset=utf8 comment='学生表';
/*创建索引*/
create [unique唯一索引][clustered聚集索引] index <索引名>
on <表名>(<列名称>[<排序>],<列名称>[<排序>]...);

语法解析:其中unique和clustered为可选项. 注意:基本表上最多仅仅能建立一个聚集索引.
"列名称":规定需要索引的列. "排序":可选asc(升序)和desc(降序)缺省值为asc.
--创建唯一索引(unique key 简写 unique)
例如:create unique index number on student(seat_number desc);
--创建普通索引
例如:create index name_class on student(name asc,class desc);
/*删除索引*/
drop index <索引名> on 表名;
例如:drop index number on student;

2.7、外键

sql 复制代码
/*外键约束: foreign key */
外键约束: foreign key 被约束的表叫做副表,外键设置在副表上面,外键引用主键字段所在的表叫做主表. (作用:约束两张表的数据)
外键定义语法: constraint 外键约束名称 foreign key(外键字段) references 主表名称(引用字段)
外键数据操作:
1.当有外键约束之后,添加数据的时候,先添加主表数据,再添加副表数据
2.当有了外键约束,修改数据的时候,先改副表的数据,在修改主表的数据
3.当有了外键约束,删除数据的时候,也是先删除副表的数据,再删除主表的数据
外键注意事项:
1.外键约束只有InnoDB存储引擎才支持.
2.实际项目中往往会用到外键的设计思想,但往往不会真正的从语法上进行外键约束. 因为外键约束的级联操作可能会带来一些现实的逻辑问题. 另外使用外键会较低mysql的效率.

2.8、储存引擎

sql 复制代码
/*储存引擎: engine*/
常见的引擎:Myisam InnoDB BDB Memory Archive 等

不同的引擎在保存表的结构和数据时采用不同的方式?
MyISAM表文件含义:.frm表定义,.MYD表数据,.MYI表索引
InnoDB表文件含义:.frm表定义,表数据空间文件(存放表的数据和索引)和日志文件

2.9、innodb与myisam的区别

sql 复制代码
MySQL中innodb与myisam的区别
(1):InnoDB支持事物,MyISAM不支持事物
(2):InnoDB支持行级锁,MyISAM支持表级锁
(3):InnoDB支持快照数据(MVCC),MyISAM不支持
(4):InnoDB支持外键,MyISAM不支持
(5):InnoDB不支持全文索引,MyISAM支持

innodb使用的是行级锁:只有在增删改查时匹配的条件字段带有索引时,innodb才会使用行级锁.(行级锁:要为匹配条件字段加索引)
innodb使用的是表级锁:如果增删改查时匹配的条件字段不带有索引时,innodb使用的将是表级锁.(表级锁:数据库全表查询,需要将整张表加锁,保证查询匹配的正确性)
触发读锁:就是用select命令时触发读锁.
触发写锁:就是在你使用update,delete,insert时触发写锁,并且使用rollback或commit后解除本次锁定
更好的区分:读写锁和表级锁行级锁. 将读写锁叫做权限锁(决定了加锁后用户有哪些操作权限),将表级锁行级锁叫做对象锁(决定将锁加在某一行还是整张表)

MVCC多版本并发控制,也可称之为一致性非锁定读;它通过行的多版本控制方式来读取当前执行时间数据库中的行数据. 实质上使用的是快照数据.
为什么要使用MVCC?
消除锁的开销. (如果要保证数据的一致性,最简单的方式就是对操作数据进行加锁,但是加锁不可避免的会有锁开销. 所以使用MVCC能避免进行加锁的方式并提高并发.)

2.10、运算符和逻辑运算符

sql 复制代码
--比较运算符(常用示例) <, >, <=, >=, =, !=或<>, IS NULL
    between and | not between and --例如: between A and B; 相当于区间[A,B]; 
    in | not in --例如:in表示某个值出现; 
    not in表示没出现在一个集合之中; 
    is null | is not null --空值查询; 
    like --通配符;  
    _  代表任意的单个字符; 
    %  代表任意的字符;
--逻辑运算符
    &&(AND), ||(OR), !(NOT), XOR异或

2.11、group by

sql 复制代码
--group by子句 (分组)
  --group by 字段/别名 [排序方式]    分组后排序: asc 升序(默认),desc 降序
  --统计函数需配合group by使用:
  count 返回不同的非NULL统计值  count(*)、count(字段)
  sum 求和; max 求最大值; min 求最小值; avg 求平均值
select class, sum(score) as sum 
from student 
group by class desc;--查询各个班级总成绩,分组班级降序.

select id,class, max(score) as max 
from student where score>80  
group by class;--查询各个班级最高成绩,分数要大于80,分组班级升序.

2.12、having

sql 复制代码
--having 子句 (条件查询)
 --where功能、用法相同,执行时机不同.
 --本质区别:where子句是把磁盘上的数据筛选到内存上,而having子句是把内存中的数据再次进行筛选.
 --where不可以使用统计函数. 一般需用统计函数配合group by才会用到having
例如:
select class, min(score) as min 
from student 
where min(score)>80 
group by class;--报错

select class, min(score) as min 
from student 
group by class 
having min(score)>80;--查询各个班级最低成绩,分组班级,最低分数大于80

2.13、order by

sql 复制代码
--order by子句  (排序)
  --order by 字段1[asc|desc],字段n[asc|desc]
  --排序: asc 升序(默认),desc 降序
例如:
select * from 
student 
where score > 80 
order by score,name desc;--查询score大于80,排序score升序和name降序

2.14、联合查询

sql 复制代码
/*联合查询 关键字:union*/ 
--联合查询:就是将多个查询结果进行纵向上的拼接. (select语句2的查询结果放在select语句1查询结果的后面)
--语法:
  select语句1
  union [all | distinct]
  select 语句2
  union [all | distinct]
  select 语句n

例如:查询A班级最高成绩和B班级最低成绩? 
(select name, class,score from student where class='A' order by score desc limit 1)
union
(select name, class,score from student where class='B' order by score limit 1);

2.15、连接查询

sql 复制代码
/*连接查询*/
 将多个表的字段进行连接,可以指定连接条件.
--交叉连接 cross join
select  *|字段列表 from 表名1 cross join 表名2;

一张表的一条记录去连接另一张表中的所有记录,并且保存所有的记录包含两个表的所有的字段.
结果上看,就是对两张表做笛卡尔积,有n1*n2条记录.
例如:select * from student cross join score;

2.16、内连接

sql 复制代码
--内连接 inner join
select *|字段列表 from 左表 [inner] join 右表 on 左表.字段 = 右表.字段 [五子句];

数据在左表中存在,同时在右表中又有对应的匹配的结果才会被保存. 如果没有匹配上,数据没有意义不会保存.
通常就是两张表中存在相同的某个字段.(项目中通常是关联主键ID) using() 用法连接两表公共字段. 例如:using(ID)
select student.*, teacher.class as t_class, teacher.name as t_name 
from student join teacher on student.class = teacher.class;

2.17、左外连接

sql 复制代码
-- 左外连接 left join
  select *|字段列表 from 左表 left [outer] join 右表 on 左表.字段 = 右表.字段 [五子句];
  如果数据不存在,左表记录会出现,而右表为null填充
例如:
select student.*, teacher.class as t_class, teacher.name as t_name 
from student left join teacher on student.class = teacher.class;

2.18、右连接

sql 复制代码
-- 右外连接 right join
  select *|字段列表 from 右表 right [outer] join 左表 on 右表.字段 = 左表.字段 [五子句];
  如果数据不存在,右表记录会出现,而左表为null填充
例如:
select student.*, teacher.class as t_class, teacher.name as t_name 
from student right join teacher on student.class = teacher.class;

2.19、自然连接

sql 复制代码
--自然连接 natural join
自动判断连接条件完成连接.
  --自然内连接 natural inner join
  select *|字段列表 from 左表 natural [inner] join 右表;
  自然内连接其实就是内连接,这里的匹配条件是由系统自动指定.

  --自然外连接 natural outer join
  自然外连接分为自然左外连接和自然右外连接.匹配条件也是由系统自动指定.

  --自然左外连接 natural left join
  select *|字段列表 from 左表 natural left [outer] join 右表;
  
  --自然右外连接 natural right join
  select *|字段列表 from 右表 natural right [outer] join 左表;

2.10、子查询

sql 复制代码
/*子查询*/
子查询(内查询)在主查询(外查询)之前一次执行完成,子查询的结果被主查询使用.
使用子查询需用括号包裹.
select * 
from student 
where score=(select max(score) as max from student);--查询班级最高成绩学生的记录

根据子查询返回值的形式:
1.单一值: 返回单行单列的子查询,也叫标量子查询.
例如:select max(score) as max from student;

2.21、判断exists

sql 复制代码
--exists
--主要作用就是判断后面的select语句有没有查询到数据.结果为true有返回数据,否则就是false.
例如:select exists (select * from student where name ='uzi');--有

3、补充

3.1、三范式

sql 复制代码
/*数据库三范式*/
--建表规范
- 每个表保存一个实体信息
- 每个具有一个ID字段作为主键
- ID主键 + 原子表

--第一范式
字段不能再分,确保每列保持原子性.

--第二范式
满足第一范式的基础上,不能有部分依赖.
消除符合组合主键(A,B)就可以避免部分依赖. 增加单列关键字.

--第三范式
满足第二范式的基础上,不能有传递依赖.
某个字段依赖于主键,而有其他字段依赖于该字段. 这就是传递依赖.
将一个实体信息的数据放在一个表内实现

3.2、视图

视图是一张虚拟表,它表示一张表的部分数据和多张表的综合数据,视图的结构和数据都是建立在基表上.视图仅仅是一个表结构,视图的数据并不在数据库中存储,数据保存在基表中. 一张表可以创建多个视图.

视图作用:简化业务逻辑,对客户端隐藏真实的表结构

sql 复制代码
--创建视图
create [algorithm = undefined | merge | temptable] view 视图名称 [(字段列表)]
as
sql语句

语法解析:

1.视图名必须唯一,同时不能与表重名.

2.指定视图执行的算法,通过algorithm指定.

3.merge: 合并算法,将视图的语句和外层的语句合并后再执行.

4.temptable: 临时表算法,将视图执行的结果生成一张临时表,再执行外层语句.

5.undefined: 未定义型,用哪种算法有MySQL决定,默认算法merge.

6."字段列表"如果存在,数目必须等于select语句检索的列数

sql 复制代码
例如:
create view v_student (v_name,v_score)
as
select name,score from student where score >80;
sql 复制代码
--查看结构
show create view 视图名称

--删除视图
drop view [if exists] 视图名称
注意: 删除视图后,数据库中的数据依然存在.(对当前视图删除)

--修改视图结构 
alter view 视图名称 [(字段列表)]
as
sql语句

3.3、事物

事物:是并发控制的基本单位.事务就是一系列的操作,这些操作要么都执行,要么都不执行.(事务中可以保存多个SQL语句. 这些SQL语句是一个整体. 要么都执行,要么都不执行.)

sql 复制代码
--事务操作
  --开启事务
  start transaction; 或者 begin;
  --提交事务
  commit;
  --回滚事务
  rollback;

start transaction;--开启事物

insert into goods(goods_name,price) values('milk','43');
insert into goods(goods_name,price) values('bread','15');

commit;--提交事物

begin;--开启事物

insert into goods(goods_name,price) values('book','99');

rollback;--回滚事物

事务的特性

  • 原子性: 事务是一个不可分割的工作单位,事务中的操作要么都执行,要么都不执行.
  • 一致性: 事务前后数据的完整性必须保持一致. (事务开始和结束时,外部数据一致. 在整个事务过程中,操作是连续的.)
  • 隔离性: 多个用户并发访问数据库时,一个用户的事务不能被其它用户的事物所干扰,多个并发事务之间的数据要相互隔离.
  • 持久性: 一个事务一旦被提交,它对数据库中的数据改变就是永久性的.

事务的原理

利用InnoDB的自动提交(autocommit)特性完成. 普通的Mysql执行语句后,当前的数据提交操作均可被其它客户端可见.

事务是暂时关闭"自动提交"机制,需要commit提交持久化数据操作.

注意: 修改事务自动提交 set autocommit = 0 | 1 (0:取消自动提交;1:自动提交)--设置为不自动提交,因为Mysql默认自动提交执行.

3.4、用户权限管理

sql 复制代码
/*用户权限管理*/
用户信息表:mysql数据库的下, user表中
--创建用户
create user 用户名[@主机地址] identified by '密码';

例如:create user 'user_one'@'localhost' identified by '1234';--创建一个只能本机访问的用户
create user 'user_two'@'192.168.1.204.%' identified by '1234';--创建一个可以局域网访问的用户
create user 'user_three' identified by '1234';--创建一个可全网访问的用户
select host,user,password from user;--查看user表,host用户名和密码


--重命名用户
rename user 老用户名[@老主机地址] to 新用户名[@新主机地址];

-- 设置密码
set password = password('修改密码'); -- 为当前用户设置密码
set password for 用户名 = password('修改密码'); -- 为指定用户设置密码
例如:set password for 'user_three' = password('123456789'); -- 指定'user_three'用户设置密码

-- 删除用户
drop user 用户名[@主机地址];
例如:drop user 'user_two'@'192.168.1.204.%';

--分配权限给用户
grant 权限列表 on  *|库名 . *|表名  to 用户名[@主机地址] [identified by "用户密码"] [with grant option];

语法解析:
权限列表: all [privileges]: 表示所有权限; delete:允许使用delete; select:允许使用select; update:允许使用update; insert:允许使用insert 等...
 *.* :表示所有库的所有表
库名.表名 :表示某库下面的某表
例如: grant update,insert on *.* to user_one@'localhost' identified by "1234" with grant option;

--刷新权限
flush privileges;

--查看权限
show grants for 用户名[@主机地址];  
show grants for 'user_one'@'localhost';

--查看当前用户权限
show grants;

--撤消权限
revoke 权限列表 on *|库名 . *|表名 from 用户名[@主机地址];
revoke all privileges, grant option from 用户名[@主机地址];-- 撤销所有权限
例如:revoke update on *.* from 'user_one'@'localhost';
相关推荐
苹果醋316 分钟前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行17 分钟前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
hanbarger21 分钟前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
微服务 spring cloud42 分钟前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试
先睡1 小时前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
弗罗里达老大爷1 小时前
Redis
数据库·redis·缓存
仰望大佬0071 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#
学不透java不改名2 小时前
sqlalchemy连接dm8 get_columns BIGINT VARCHAR字段不显示
数据库
一只路过的猫咪2 小时前
thinkphp6使用MongoDB多个数据,聚合查询的坑
数据库·mongodb