数据库-MySQL

本文介绍了MySQL数据库的基础知识,包括数据类型的选择、数据库的增删改查、索引的创建和使用、建表约束的种类以及数据库的三大设计范式。重点讨论了索引的作用、类型和创建时机,以及事务的特性及其隔离性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2021.08.15

1. MySQL数据类型和选择

(1)数值

(2)日期/时间

(3)字符串类型

 举例:

CREATE TABLE IF NOT EXISTS `runoob_tbl`(
   `runoob_id` INT UNSIGNED AUTO_INCREMENT,
   `runoob_title` VARCHAR(100) NOT NULL,
   `runoob_author` VARCHAR(40) NOT NULL,
   `submission_date` DATE,
   PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

数据类型选择:

日期:选择按照格式

数值/字符串:按照大小

2.0 数据库的增删改查

insert into 表名 (key1,key2) values('1', '2');
delete from 表名 where 条件;
update 表名 set 字段='1' where 条件;
select * from 表名 where 条件;

2.5 MySQL索引

创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

索引的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。

2.5.1 Mysql索引类型

主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE。

2.5.2 索引种类

  • 普通索引(index):仅加速查询

  • 唯一索引(unique):加速查询 + 列值唯一(可以有null)

  • 主键索引(primary key):加速查询 + 列值唯一(不可以有null)+ 表中只有一个

  • 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并

  • 全文索引(FULLTEXT):对文本的内容进行分词,进行搜索

--创建普通索引
CREATE INDEX index_name ON table_name(col_name);
--创建唯一索引
CREATE UNIQUE INDEX index_name ON table_name(col_name);
--创建普通组合索引
CREATE INDEX index_name ON table_name(col_name_1,col_name_2);
--创建唯一组合索引
CREATE UNIQUE INDEX index_name ON table_name(col_name_1,col_name_2);

 --查看索引
show index from table_name;

补充:

  • 索引合并,使用多个单列索引组合搜索
  • 覆盖索引,select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖

2.5.3 创建索引的时机

在WHERE和JOIN中出现的列需要建立索引,但也不完全如此,因为MySQL只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE才会使用索引

因为在以通配符%和_开头作查询时,MySQL不会使用索引

SELECT t.Name FROM t 
LEFT JOIN m ON t.Name=m.username 
WHERE m.age=20 AND m.city= '郑州';
--此时就需要对city和age建立索引,由于m表的userame也出现在了JOIN子句中,也有对它建立索引的必要。

2.5.4 命中索引

--like  '%xx'     
select * from tb1 where name like  '%cn' ;
-- 使用函数
select * from tb1 where reverse(name) =  'wupeiqi' ;
-- or 
select * from tb1 where nid = 1  or  email =  'seven@live.com' ;

--特别的:当 or 条件中有未建立索引的列才失效,以下会走索引
select * from tb1 where nid = 1  or  name =  'seven' ;
select * from tb1 where nid = 1  or  email =  'seven@live.com'  and  name =  'alex' 

--类型不一致
--如果列是字符串类型,传入条件是必须用引号引起来,不然...
select * from tb1 where name = 999;
- !=    select * from tb1 where name !=  'alex'

特别的:如果是主键,则还是会走索引
select * from tb1 where nid != 123
- >    select * from tb1 where name >  'alex'     

特别的:如果是主键或索引是整数类型,则还是会走索引
select * from tb1 where nid > 123
 select * from tb1 where num > 123- order by    select email from tb1 order by name desc;

当根据索引排序时候,选择的映射如果不是索引,则不走索引

特别的:如果对主键排序,则还是走索引:
select * from tb1 order by nid desc; - 组合索引最左前缀

--如果组合索引为:(name,email)
-- name  and  email:使用索引
-- name:使用索引
-- email:不使用索引


-- LIMIT分页
--下一页
SELECT * FROM table_name WHERE id in (SELECT id FROM table_name WHERE id > max_id LIMIT 10);
--上一页
SELECT * FROM table_name WHERE id in (SELECT id FROM table_name WHERE id < min_id ORDER BY id DESC LIMIT 10);
--当前页之后的某一页
SELECT * FROM table_name WHERE id in (SELECT id FROM (SELECT id FROM (SELECT id FROM table_name WHERE id < min_id ORDER BY id desc LIMIT (页数差*10)) AS N ORDER BY N.id ASC LIMIT 10) AS P ORDER BY P.id ASC);
--当前页之前的某一页
SELECT * FROM table_name WHERE id in (SELECT id FROM (SELECT id FROM (SELECT id FROM table_name WHERE id > max_id LIMIT (页数差*10)) AS N ORDER BY N.id DESC LIMIT 10) AS P) ORDER BY id ASC;

3. MySQL建表约束(Constraints

共7种:primary key、unique、auto increasement、not null、default、foreign、check

(1.1)主键约束(primary key)-单个主键

唯一确定一张表中的一条记录,使得字段不重复且不为空null。

create table user(
id int primary key,
name varchar(20)
);

——修改表结构,添加主键add

——修改表结构,删除主键drop

——修改表结构,添加主键modify

create table user4(
id int,
name varchar(20)
)

alter table user4 add primary key(id);
alter table user4 drop primary key;
alter table user4 modify id int primary key;

(1.2)主键约束(primary key)-联合主键

多个联合的主键值同时不重复就可以。联合起来唯一;任何一个字段都不能为空null。

create table user2(
id int,
name varchar(20),
password varchar(20),
primary key(id,name)
);

(2)唯一约束(unique)-单个/联合

约束修饰的字段的值不可重复,可为null

unique(a,b):两个键在一起不重复

create table user5(
id in,
name varchar(20) unique
);

create table user5(
id in,
name varchar(20),
unique(name)
);


alter table user6 add unique(name);
alter table user6 modify name varchar(20) unique;
alter table user6 drop index name;

总结:

1、建表的时候添加约束

2、使用alter .. add .. 或者 alter .. modify .. 进行添加

3、使用alter .. drop .. 进行删除

 (3)自增约束(auto_increment)

管控字段,值自动递增

create table user3(
id int primary key auto_increment,
name varchar(20)
);

(4)非空约束(Not Null 大小写皆可)

修饰的字段不能为空 null

create table user8(
id int,
name varchar(20) NOT NULL
);

(5)默认约束(default)

当插入字段值时,如果没有传值,就会使用默认值

 create table user8(
id int,
name varchar(10),
age int default 10
);

(6)外键约束(foreign)

涉及两个表:父表、子表(或 主表、副表)

1、主表中没有的数据值,副表中不可以使用存在

2、主表中的记录被副表引用,是不可以删除的

-- 班级
create table class(
id int primary key,
name varchar(20)
);


-- 学生
create table student(
id int primary key,
name varchar(20),
class_id int,
foreign key(class_id) references class(id)
);

(7)CHECK - 保证列中的值符合指定的条件

3. 数据库的三大设计范式

3.1 第一范式(1NF)-拆字段

数据表中的所有字段都是不可分割的原子值

范式:设计的越详细,对于某些实际操作可能更好,但不一定都是好处。

address拆字段为country、Provence、city、area

3.2 第二范式(2NF)-拆表

必须满足第一范式的前提下,第二范式要求除主键外的每一列必须完全依赖于主键

如果出现不完全依赖,只可能是联合主键的情况。

 3.3 第三范式(3NF)-拆表

必须满足第二范式的前提下,第三范式要求除主键外的其他列之间不能有传递依赖关系。

 4. mysql的查询

--查询
select * from user;
select id, name, age from user;
--去重 distinct
select distinct name from user;
--区间 between或者运算符
select * from user where score between 60 and 80;
select * from user where score > 60 and score < 80;
--字段值 或者关系 in
select * from user where score in(50,60,80);
--字段 或者关系 or
select * from user where score id > 10 or sex="female";
--排序 降序desc 升序asc(默认,可不写)
select * from user order by id desc;
select * from user order by id asc;
select * from user order by id asc,score desc; --优先以id排序,其次是score
--统计 count
select count(*) from user where class='1';
--最值 最高max 最低min
select * from user where score=(select max(score) from class);
--取有限条数 limit n,m(指从第n条开始取m条数据)
select * from user order by desc limit 0,1;
--平均值 avg()
--分组 group by
select id, avg(score) from user where id = 1;
select id, avg(score) from user group by id;
--先分组后加条件用having,先加条件后分组用where
--模糊匹配 like
select class,avg(score),count(*) from user 
group by class
having count(class) >= 2 
and class like '3%';
--多表查询 =(共同字段建立联系)
select uid,name,class from user,class
where user.uid = class.uid;
select uid,name,class,score from user,class,score
where user.uid = class.uid and user.course = score.course
--获取年份 year()内置函数
--子查询 in(子查询)
select * from user where year(birthday) in (selecet * from user where uid > 10)


B站P33-P56未看



5. MySQL事务

5.1 事务定义和作用

mysql中,事务是一个最小的不可分割的工作单元。事务能够保证一个业务的完整性 

多条SQL语句,要求要么同时成功,要么同时失败,否则会数据前后出现不一致。

5.2 控制事务commit_rollback

(1)MySQL默认事务开启(即可自动提交commit)

事务开启commit:作用是执行一个SQL时,效果会立即体现且不能回滚(自动提交和手动提交)

事务回滚rollback:撤销SQL语句执行效果,提供一个反悔的机会

1表示事务开启,0表示事务关闭。

(2)关闭MySQL的自动提交事务(set autocommit=0),当前事务在提交时结束

需要手动提交数据(commit;),提交前可回滚,提交后不可回滚(rollback;)

 

 回滚成功:

 回滚失败:

 

(3)语句手动开启一个事务 (begin; 或  start transaction;)

 5.3 事务的特征(ACID)

A  atomicity 原子性:事务是最小的工作单元,不可再分割。同时成功或者同时失败

C consistency 一致性:事务在执行前后,数据的完整性保持不变(例:原本的外键约束在进行事务成功后不会损坏)

I isolation 隔离性:事务1和事务2之间具有隔离性

D durability 持久性:事务一旦结束(commit 或 rollback),就不可以返回

 5.4 事务的隔离性

查看数据库的隔离级别 

 修改数据库的隔离级别  

 

(1)read uncommitted; 读未提交的(默认隔离级别)

如果有事务A和事务B,A事务对数据进行操作,操作过程中事务没有被提交时,事务B可以看见A操作的结果。会出现“脏读”,实际开发不允许出现。

“脏读”:一个事务读到了另一个事务没有提交的数据。

(2)read committed; 读已提交的

虽然只能读到另一个事务提交的数据,但还会出现“不可重复读”现象

“不可重复读”现象:读取同一个表的数据,发现前后不一致的问题

(3)repeatable read; 可重复读

“幻读”:事务A和事务B同时操作一张表,事务A提交的数据,不能被事务B读到,就会造成幻读。

(4)serializable; 串行化

当表被事务A操作的时候,其他事务里面的写操作不可以进行。即进入排队状态(串行化),事务A提交完成后,其他事物的写操作才会执行(在没有等待超时的情况)

总结:

性能正向排序(即隔离级别倒序):

read uncommitted(啥问题都出现,脏读) > read committed(不可重复读) > repetable read(mysql默认隔离级别,幻读) > serializable(性能差)

1-4 章节:B站学习视频

2.5 章节:什么是索引?Mysql目前主要的几种索引类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值