一、索引
1、索引的定义
对数据库中表的一列或者多列的值进行排序的一种结构(MySQL中索引用Btree方式)
2、索引的优点
加快数据的检索速度
3、索引的缺点
a、需动态维护,占用系统资源,降低数据维护速度
b、占用物理存储空间
4、索引对比
a、运行 insert.py 文件(参见附录1),插入100万条记录(终端窗口)
python3 insert.py
b、开启性能分析(mysql环境)
set profiling=1;
备注 :show variables like "profiling";
c、执行查询语句
select name from t1 where name="lucy99999";
d、查看性能分析结果
show profiles;
e、给name字段创建索引
create index name on t1(name);
f、执行查询语句
select name from t1 where name="lucy88888";
g、查看性能分析结果
show profiles;
h、关闭性能分析
set profiling = 0;
5、索引类型
普通索引(index),唯一索引(unique),主键索引(primary key)&&自增长属性(auto_increment),外键(foreign key)
二、索引类型
1、普通索引(index)
a、使用规则
1)一个表中可以有多个index字段
2)字段的值可以重复,也可以为NULL
3)经常把做查询条件的字段设置为index字段
4)index字段的key标志位:MUL
b、创建
1)创建表时创建index语法:index(字段名),
create table t4(
id int,
name varchar(20),
index(id),
index(name)
);
desc t4;
2)在已有表中添加索引字段
语法:create index 索引名 on 表名(字段名);
# 索引名一般和字段名一样,也可以自己定义索引名
alter table t4 add score tinyint;
create index score on t4(score);
desc t4;
c、查看普通索引
1)desc 表名; --> 查看KEY标志位MUL
2)show index from 表名\G;
show index from t4;
show index from t4\G;
d、删除
drop index 索引名 on 表名;
注意:删除普通索引只能一个一个删除
drop index name on t4;
drop index score on t3;
2、唯一索引(unique)
a、使用规则
1)一个表中可以有多个unique字段2)unique字段的值 不允许重复,可以为空值NULL
3)unique的KEY表中是 :UNI
b、创建(基本等同index创建)
1)创建表unique(字段名),
create table t5(
id int,
name varchar(20),
unique(id),
unique(name)
);
2)已有表
create unique index 索引名 on 表名(字段名);
# 索引名一般和字段名一样,也可以自己定义索引名
alter table t5 add name varchar(10);
create unique index name_index on t5(name);
c、查看、删除同普通索引
desc 表名;show index from 表名;
drop index 索引名 on 表名;
注:
Non_unique: 0 --> 唯一索引
Non_unique: 1 --> 普通索引
3、主键索引(primary key)&&自增长属性(auto_increment)
a、使用规则
1)一个表中只能有一个主键字段
2)对应字段的值不允许重复 且 不能为空值NULL
3)主键字段的KEY标志位:PRI
4)把表中能够唯一标识一条记录的字段设置为主键,通常把表中记录编号id的字段设置为主键
b、创建主键(PRI)
1)创建表时
格式1:字段名 数据类型 primary key auto_increment,
create table t6(
id int primary key auto_increment,
name varchar(10)
);
格式2:primary key(id),
create table t7(
id int auto_increment,
name varchar(10),
primary key(id)
);
2)已有表
I、在已有表中添加主键
alter table 表名 add primary key(字段名) ;
II、在已有表中添加自增长属性
alter table 表名 modify 字段名 数据类型 auto_increment;
注:字段名的数据类型可以重新指定
create table t8(
id int,
name varchar(10)
);
alter table t8 add primary key(id);
alter table t8 modify id bigint auto_increment;
c、删除主键
1)删除自增长属性
alter table 表名 modify id 数据类型;
2)删除主键
alter table 表名 drop primary key;
d、指定自增长属性起始值
1)创建表(创建时就指定起始值)
create table 表名(
id int primary key auto_increment,
... ...
)auto_increment=10000;
2)已有表(自增长属性必须已存在,才能添加起始值)
alter table 表名 auto_increment=10000;
alter table t8 auto_increment=1000;
4、外键(foreign key)
a、定义
让当前表字段值从另一个表范围内选择b、语法格式
foreign key(参考字段名)references 主表(被参考字段名)
on delete 级联动作
on update 级联动作
c、使用规则
1)两张表被参考字段(主表)和参考字段(从表)数据类型要一致2)主表被参考字段 :主键
d、级联动作
1)cascade 数据级联更新当主表删除级联时,从表会级联更新
当主表更新被参考字段的值时,从表会级联更新
2)restrict 默认
当删除主表记录时,如果从表中有相管理记录则不允许主表删除
更新同理
3)set null
当主表删除记录时,从表中相关联记录的参考字段值自动设置为NULL
更新同理
4)no action
on delete no action on update no action
同 restrict,都是立即检查外键限制
e、示例
学号 | 姓名 | 班级 | 金额 |
---|---|---|---|
1 | 唐伯虎 | AID1 | 10 |
2 | 点秋香 | AID1 | 8 |
学号 | 姓名 | 金额 |
---|---|---|
1 | 唐伯虎 | 10 |
2 | 点秋香 | 8 |
#主表:jftab
create table jftab(
id int primary key,
name varchar(20),
class char(7),
money int
)character set utf8;
insert into jftab values
(1,"唐伯虎","AID1",10),
(2,"点秋香","AID1",8);
#从表:bjtab
create table bjtab(
stu_id int,
name varchar(20),
money int,
foreign key(stu_id) references jftab(id)
on delete cascade
on update cascade)character set utf8;
insert into bjtab values
(1,"唐伯虎",10),
(2,"点秋香",8);
g、删除外键
alter table 表名 drop foreign key 外键名;注:
外键名的查看方式:show create table 表名;
h、在已有表中添加外键
## 会受到表中原有数据的限制alter table 表名 add foreign key(参考字段名)
references 主表(被参考字段名)
on delete 级联动作
on update 级联动作;
二、多表查询
1、select 字段名列表 from 表1,表2;
相当于笛卡尔积(不加where)
表1中所有字段分别和表2的第一个字段匹配,然后表1中所有字段分别和表2的下一个字段匹配,...
2、select 字段名列表 from 表1,表2 where 条件;
等同于连接查询中的内连接(inner join)
# 通过附录2创建表,然后查询
a、显示 省、市详细信息
select sheng.s_name,city.c_name from sheng,city
where sheng.s_id=city.cfather_id;
b、显示 省、市、县详细信息
select sheng.s_name,city.c_name,xian.x_name from sheng,city,xian
where sheng.s_id=city.cfather_id and city.c_id=xian.xfather_id;
三、连接查询
1、内连接
从表中删除与其他被连接的表中没有匹配到的行(只显示匹配到的行)
语法格式select 字段名列表 from 表1
inner join 表2 on 条件
inner join 表3 on 条件;
1、显示 省、市详细信息
select sheng.s_name,city.c_name from sheng
inner join city on sheng.s_id=city.cfather_id;
2、显示 省、市、县详细信息
select sheng.s_name,city.c_name,xian.x_name from sheng
inner join city on sheng.s_id=city.cfather_id
inner join xian on city.c_id=xian.xfather_id;
2、外连接
a、左连接
以左表为主显示查询结果
语法格式select 字段名列表 from 表1
left join 表2 on 条件;
a.以省表为主(省全部显示),显示省、市详细信息
select sheng.s_name,city.c_name from sheng
left join city on sheng.s_id=city.cfather_id;
b.以县表为主(县全部显示),显示省、市、区详细信息
select sheng.s_name,city.c_name,xian.x_name from sheng
left join city on sheng.s_id=city.cfather_id
left join xian on city.c_id=xian.xfather_id;
c.以市表为主(市全部显示),显示省、市、区详细信息
select sheng.s_name,city.c_name,xian.x_name from sheng
right join city on sheng.s_id=city.cfather_id
left join xian on city.c_id=xian.xfather_id;
b、右连接
用法同左连接,以右表为主显示查询结果四、附录1:insert.py 文件
import pymysql
db = pymysql.connect("localhost","root","123456")
cursor = db.cursor()
cursor.execute("create database indexdb;")
cursor.execute("use indexdb;")
cursor.execute("create table t1(id int,name char(20));")
n = 1
name="lucy"
while n <= 2000000:
cursor.execute("insert into t1 values('%s','%s')" % (n,name+str(n)))
# n = int(n)
n += 1
db.commit()
cursor.close()
db.close()
五、附录2:创建省、市、区表
create table sheng(
id int primary key auto_increment,
s_id int,
s_name varchar(15)
)default charset=utf8;
insert into sheng values
(1, 130000, '河北省'),
(2, 140000, '陕西省'),
(3, 150000, '四川省'),
(4, 160000, '广东省'),
(5, 170000, '山东省'),
(6, 180000, '湖北省'),
(7, 190000, '河南省'),
(8, 200000, '海南省'),
(9, 200001, '云南省'),
(10,200002,'山西省');
create table city(
id int primary key auto_increment,
c_id int,
c_name varchar(15),
cfather_id int
)default charset=utf8;
insert into city values
(1, 131100, '石家庄市', 130000),
(2, 131101, '沧州市', 130000),
(3, 131102, '廊坊市', 130000),
(4, 131103, '西安市', 140000),
(5, 131104, '成都市', 150000),
(6, 131105, '重庆市', 150000),
(7, 131106, '广州市', 160000),
(8, 131107, '济南市', 170000),
(9, 131108, '武汉市', 180000),
(10,131109, '郑州市', 190000),
(11,131110, '北京市', 320000),
(12,131111, '天津市', 320000),
(13,131112, '上海市', 320000),
(14,131113, '哈尔滨', 320001),
(15,131114, '雄安新区', 320002);
create table xian(
id int primary key auto_increment,
x_id int,
x_name varchar(15),
xfather_id int
)default charset=utf8;
insert into xian values
(1, 132100, '正定县', 131100),
(2, 132102, '浦东新区', 131112),
(3, 132103, '武昌区', 131108),
(4, 132104, '哈哈', 131115),
(5, 132105, '安新县', 131114),
(6, 132106, '容城县', 131114),
(7, 132107, '雄县', 131114),
(8, 132108, '嘎嘎', 131115);