MySQL约束及索引

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 在特定的数据库引擎下才有,mylsam快速定位数据

1.索引分类

1.主键索引 (primary key)

唯一标识,主键不可重复,只能有一个列作为主键

2.唯一索引 (unique key)

避免重复的列出现,唯一索引可以重复,多个列都可以标识位 唯一索引

3.常规索引(key/index)

默认的,index,key关键字来设置

4.全文索引(fullText)

在特定的数据库引擎下才有,mylsam
快速定位数据

5.基础语法

在这里插入图片描述

2.建表测试

CREATE TABLE `app_user` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT '' COMMENT '用户昵称',
`email` varchar(50) NOT NULL COMMENT '用户邮箱',
`phone` varchar(20) DEFAULT '' COMMENT '手机号',
`gender` tinyint(4) unsigned DEFAULT '0' COMMENT '性别(0:男;1:女)',
`password` varchar(100) NOT NULL COMMENT '密码',
`age` tinyint(4) DEFAULT '0' COMMENT '年龄',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='app用户表'

批量插入数据:100w

DROP FUNCTION IF EXISTS mock_data;
DELIMITER $$
CREATE FUNCTION mock_data()
RETURNS INT
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i < num DO
  INSERT INTO app_user(`name`, `email`, `phone`, `gender`, `password`, `age`)
   VALUES(CONCAT('用户', i), '24736743@qq.com', CONCAT('18', FLOOR(RAND()*(999999999-100000000)+100000000)),FLOOR(RAND()*2),UUID(), FLOOR(RAND()*100));
  SET i = i + 1;
END WHILE;
RETURN i;
END;
SELECT mock_data();

索引效率测试

无索引

SELECT * FROM app_user WHERE name = '用户9999'; -- 查看耗时
SELECT * FROM app_user WHERE name = '用户9999';
SELECT * FROM app_user WHERE name = '用户9999';

mysql> EXPLAIN SELECT * FROM app_user WHERE name = '用户9999'\G
*************************** 1. row ***************************
          id: 1
select_type: SIMPLE
       table: app_user
  partitions: NULL
        type: ALL
possible_keys: NULL
        key: NULL
    key_len: NULL
        ref: NULL
        rows: 992759
    filtered: 10.00
      Extra: Using where
1 row in set, 1 warning (0.00 sec)

创建索引

CREATE INDEX idx_app_user_name ON app_user(name);

测试普通索引

mysql> EXPLAIN SELECT * FROM app_user WHERE name = '用户9999'\G
*************************** 1. row ***************************
          id: 1
select_type: SIMPLE
       table: app_user
  partitions: NULL
        type: ref
possible_keys: idx_app_user_name
        key: idx_app_user_name
    key_len: 203
        ref: const
        rows: 1
    filtered: 100.00
      Extra: NULL
1 row in set, 1 warning (0.00 sec)

mysql> SELECT * FROM app_user WHERE name = '用户9999';
1 row in set (0.00 sec)

mysql> SELECT * FROM app_user WHERE name = '用户9999';
1 row in set (0.00 sec)

mysql> SELECT * FROM app_user WHERE name = '用户9999';
1 row in set (0.00 sec)

3.索引准则

索引不是越多越好

不要对经常变动的数据加索引

小数据量的表建议不要加索引

索引一般应加在查找条件的字段

约束

1.外键概念

外键:给关联字段创建关联就是添加外键,简单来说外键就是被约束条件

切记:作为外键一定要和关联主键的数据类型保持一致

--记录老师的数据表

CREATE TABLE Teachers(

id TINYINT PRIMARY KEY auto_increment,

name VARCHAR (20),

age INT,

gender boolean

);

--给老师添加数据

INSERT INTO Teachers (name,age,gender) VALUES ("Lily",12,0),

("Linta",14,0),

("Zahi",22,0),

("Paul",20,1),

("Jeans",21,1);

--创建学生的表

CREATE TABLE Students(

id INT PRIMARY KEY auto_increment,

name VARCHAR(20),

Teacher_id TINYINT,

FOREIGN KEY (Teacher_id) REFERENCES Teachers(id)

)ENGINE=INNODB;

--给学生添加数据

INSERT INTO Students (name,Teacher_id) VALUES ("ViewIn1",2),

("ViewIn2",4),

("ViewIn3",1),

("ViewIn4",3),

("ViewIn5",2),

("ViewIn6",3),

("ViewIn7",2),

("ViewIn8",4);

以上就是给Students的Teacher_id绑定外键为Teachers的id,这样就能将每一个学生与老师对应起来

2.关联约束

其中,Teacher是母表,Students是子表,无法单独删除母表中的字段,因为被子表约束了

要删除母表中的字段,必须将该字段的约束解除,即子表的外键不再对应该字段

因此可以选择修改作为外键的数据,来删除母表的某字段

比如要删除字段1,将Students中id=4和id=6(原本对应母表id=3)的Teacher_id值设置为4

—>这样子表中就没有与母表id=3的字段有关联了

update Students set Teacher_id=4 where id=4 or id=6;

—>之后再删除母表id=3的字段就不受影响了

delete from Teachers where id=3;

—>此时插入一个学生,绑定外键为3就会报错

INSERT INTO Students (name,Teacher_id) values ("ZaHuw",3);

3.添加与删除外键

给现成的表加外键

例:给Students创建一个外键,取名为aaa,外键字段为Teacher_id,将该外键关联到表Teachers的id字段

ALTER TABLE Students ADD CONSTRAINT aaa

FOREIGN KEY(Teacher_id)

REFERENCES Teachers(id);

2)删除已有的外键

ALTER TABLE Students drop foreign key aaa;

4.集联删除

设置集联删除:这样就不会被限制删除了;

如果删除了外键的字段,那它对应的外键也会跟着被删除;

如果删除了母表的字段,它对应的子表字段也会跟着被删除。

CREATE TABLE Students3(

id INT PRIMARY KEY auto_increment,

name VARCHAR(20),

Teacher_id TINYINT,

FOREIGN KEY (Teacher_id) REFERENCES Teachers(id) on DELETE CASCADE

)ENGINE=INNODB;

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
13天前
|
关系型数据库 MySQL 索引
mysql 分析5语句的优化--索引添加删除
mysql 分析5语句的优化--索引添加删除
12 0
|
19天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
|
25天前
|
存储 自然语言处理 关系型数据库
ElasticSearch索引 和MySQL索引那个更高效实用那个更合适
ElasticSearch索引 和MySQL索引那个更高效实用那个更合适
37 0
|
25天前
|
SQL 存储 关系型数据库
MySQL not exists 真的不走索引么
MySQL not exists 真的不走索引么
24 0
|
13天前
|
SQL 缓存 关系型数据库
mysql性能优化-慢查询分析、优化索引和配置
mysql性能优化-慢查询分析、优化索引和配置
79 1
|
19天前
|
SQL 关系型数据库 MySQL
轻松入门MySQL:深入学习数据库表管理,创建、修改、约束、建议与性能优化(3)
轻松入门MySQL:深入学习数据库表管理,创建、修改、约束、建议与性能优化(3)
|
19天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
19天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
19天前
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
|
10天前
|
存储 关系型数据库 MySQL
【MySQL实战笔记】 04 | 深入浅出索引(上)-02
【4月更文挑战第9天】InnoDB数据库使用B+树作为索引模型,其中主键索引的叶子节点存储完整行数据,非主键索引则存储主键值。主键查询只需搜索一棵树,而非主键查询需两次搜索,因此推荐使用主键查询以提高效率。在插入新值时,B+树需要维护有序性,可能导致数据页分裂影响性能。自增主键在插入时可避免数据挪动和页分裂,且占用存储空间小,通常更为理想。然而,如果场景仅需唯一索引,可直接设为主键以减少查询步骤。
13 1
【MySQL实战笔记】 04 | 深入浅出索引(上)-02