85-实战-单表访问方法
2023-02-28 本文已影响0人
紫荆秋雪_文
一、数据准备
1.1、创建数据库
CREATE TABLE single_table (
id INT NOT NULL AUTO_INCREMENT,
key1 VARCHAR(100),
key2 INT,
key3 VARCHAR(100),
key_part1 VARCHAR(100),
key_part2 VARCHAR(100),
key_part3 VARCHAR(100),
common_field VARCHAR(100),
PRIMARY KEY (id),
KEY idx_key1 (key1),
UNIQUE KEY idx_key2 (key2),
KEY idx_key3 (key3),
KEY idx_key_part(key_part1, key_part2, key_part3)
) Engine=InnoDB CHARSET=utf8;
1.2、创建数据
- 设置MySQL可以创建
函数
# 不加global只是当前窗口有效
SET GLOBAL log_bin_trust_function_creators = 1;
- 创建随机字符串 函数
DELIMITER $
CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255)
BEGIN
DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
DECLARE return_str VARCHAR(255) DEFAULT '';
DECLARE i INT DEFAULT 0;
WHILE i < n
DO
SET return_str = CONCAT(return_str, SUBSTRING(chars_str, FLOOR(1 + RAND() * 52), 1));
SET i = i + 1;
END WHILE;
RETURN return_str;
END $
DELIMITER ;
- 创建随机数字
函数
DELIMITER $
CREATE FUNCTION rand_num(from_num INT, to_num INT) RETURNS INT(11)
BEGIN
DECLARE i INT DEFAULT 0;
SET i = FLOOR(from_num + RAND() * (to_num - from_num + 1));
RETURN i;
END $
DELIMITER ;
- 制造数据的存储过程
DELIMITER $
CREATE PROCEDURE insert_data(start INT, max_num INT)
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0; # 设置手动提交事务
REPEAT
#循环
SET i = i + 1; # 赋值
INSERT INTO single_table (key1, key2, key3, key_part1, key_part2, key_part3, common_field)
VALUES (rand_string(100),
i,
rand_string(100),
rand_string(100),
rand_string(100),
rand_string(100),
rand_string(100));
UNTIL i = max_num
END REPEAT;
COMMIT; # 提交事务
END $
DELIMITER ;
- 创建 10000 条数据
CALL insert_data(1, 10000);
二、访问方法(access method)的概念
2.1、const
2.1.1、使用主键
DESC
SELECT *
FROM single_table
WHERE id = 1438;

2.1.2、使用唯一
的二级索引
DESC
SELECT *
FROM single_table
WHERE key2 = 3841;

2.1.3、使用唯一
的二级索引,但是查询条件为NULL
时
唯一二级索引列并不限制 NULL 值的数量
DESC
SELECT *
FROM single_table
WHERE key2 IS NULL;

2.2、ref
2.2.1、二级索引列值为NULL的情况
不论是普通的
二级索引
,还是唯一二级索引
,它们的索引列对包含NULL值
的数量并不限制,所以我们采用key IS NULL
这种形式的搜索条件最多只能使用ref
的访问方法,而不是const
的访问方法
2.2.2、如果最左边的连续索引列
并不全部是等值
比较的话,它的访问方法
就不能称为ref
了
DESC
SELECT *
FROM single_table
WHERE key_part1 = 'god like'
AND key_part2 > 'legendary';
2.3、ref_or_null
有时候我们不仅想找出某个
二级索引列
的值等于
某个常数
的记录,还想把该列的值为NULL
的记录也找出来
DESC
SELECT *
FROM single_table
WHERE key1 = 'abc'
OR key1 IS NULL;

2.4、range
DESC
SELECT *
FROM single_table
WHERE key2 IN (1438, 6328)
OR (key2 >= 38 AND key2 <= 79);

2.5、index
DESC
SELECT key_part1, key_part2, key_part3
FROM single_table
WHERE key_part2 = 'abc';

小结
由于
key_part2
并不是联合索引idx_key_part
最左索引列,所以我们无法使用ref
或者range
访问方法来执行这个语句。但是这个查询符合下面这两个条件:
- 它的查询列表只有3个列:
key_part1, key_part2, key_part3
,而索引idx_key_part
又包含这三个列 - 搜索条件中只有
key_part2
列。这个列也包含在索引idx_key_part
中