MySQL数据库基础02 韩顺平 自学笔记

MySQL数据库基础02

  • sql表查询增强
    • 分页查询
    • 分组函数和分组子句
    • 数据分组的总结
  • 多表查询
    • 问题的引出
    • 多表查询的练习
    • 自连接
    • 子查询
      • 子查询当作临时表使用
      • 在多行子查询中使用all操作符
      • 在多行子查询中使用any操作符
    • 多列子查询
  • 子查询练习
    • from子句中使用子查询
  • 表复制
  • 合并查询
  • 外连接
    • 外连接课后习题
  • mysql约束
    • primary key(主键)-基本使用
    • not null的使用
    • unique的使用
    • foreign key(外键)
    • check的使用
    • mysql约束练习
  • 自增长
  • mysql索引
    • 索引的快速入门
    • 索引的原理
    • 索引的类型
    • 索引的使用
      • 课后作业
    • 索引小结

sql表查询增强

SELECT * FROM db_02.`emp`;
SELECT * FROM db_02.`dept`;
SELECT * FROM db_02.`salgrade`;

-- 使用where子句
-- ?如何查找1992.1.1后入职的员工

-- mysql中日期类型可以直接比较
SELECT * FROM db_02.`emp` a
WHERE a.`hiredate` > '1992-01-01';

-- 如何使用like操作符
-- %:表示0到多个字符: 表示单个字符
-- ?如何显示首字符为S的员工姓名和工资
SELECT a.`ename`,a.`sal` FROM db_02.`emp` a
WHERE a.`ename` LIKE 'S%';


-- ?如何显示第3 个字符为大写0的所有员工的姓名和工资
SELECT a.`ename`,a.`sal` FROM db_02.`emp` a
WHERE SUBSTRING(a.`ename`,3,1) = 'O';


SELECT a.`ename`,a.`sal` FROM db_02.`emp` a
WHERE a.`ename` LIKE '__O%';



-- 如何显示没有上级的雇员的情况
SELECT * FROM db_02.`emp` a
WHERE a.`mgr` IS NULL;

-- 查询表结构
DESC db_02.`emp`;
-- 
-- 使用order by子句
-- ?如何按照工资的从低到高的顺序,显示雇员的信息
SELECT * FROM db_02.`emp` a
ORDER BY a.`sal`;

-- ?按照部门号升序而雇员的工资降序排列,显示雇员信息
SELECT * FROM db_02.`emp` a
ORDER BY a.`deptno`, sal DESC;

分页查询

MySQL数据库基础02 韩顺平 自学笔记_第1张图片

#分页查询
-- 1.按雇员的empno号升序取出,每页显示3条记录, 请分别显示第1页,第2页,第3
-- 页
-- 2.基本语法: select ... limit start, rows
-- 表示从start+1行开始取,取出rows行,start从0开始计算
# 第一页
SELECT * FROM db_02.emp a ORDER BY a.`empno`
LIMIT 0,3; 

# 第二页
SELECT * FROM db_02.emp a ORDER BY a.`empno`
LIMIT 3,3; 

# 第三页
SELECT * FROM db_02.emp a ORDER BY a.`empno`
LIMIT 6,3; 

# 第四页
SELECT * FROM db_02.emp a ORDER BY a.`empno`
LIMIT 9,3; 

# 第五页
SELECT * FROM db_02.emp a ORDER BY a.`empno`
LIMIT 12,3; 

-- 推导一个公式
SELECT * FROM db_02.emp a ORDER BY a.`empno`
LIMIT 12,3; 

SELECT * FROM db_02.emp a ORDER BY a.`empno`
LIMIT 每页显示的记录数 * (第几页 - 1),每页显示的记录数; 

-- page.sql
-- 课堂练习题: 3min
-- 按雇员的empno号降序取出,每页显示5条记录。请分别显示第3页,第5页对
-- 应的sq|语句
# 第三页
SELECT * FROM db_02.`emp` a
ORDER BY a.`empno` DESC
LIMIT 10,5;

# 第五页
SELECT * FROM db_02.`emp` a
ORDER BY a.`empno` DESC
LIMIT 20,5;

分组函数和分组子句

MySQL数据库基础02 韩顺平 自学笔记_第2张图片

-- (1)显示每种岗位的雇员总数、平均工资。
SELECT 
  a.`job`,
  SUM(1) zs,
  AVG(a.`sal`) 
FROM
  db_02.`emp` a 
GROUP BY a.`job` ;

SELECT * FROM db_02.`emp` a;

-- (2)显示雇员总数,以及获得补助的雇员数。
SELECT 
  COUNT(*) gyzs,
  (SELECT 
    COUNT(*) 
  FROM
    db_02.`emp` a 
  WHERE a.`comm` IS NOT NULL) bzgys 
FROM
  db_02.`emp` a ;
  
  SELECT COUNT(*) gyzs,COUNT(a.`comm`) FROM db_02.`emp` a;
  -- 统计没有获得补助的人数
  SELECT COUNT(*) gyzs,COUNT(IF(a.`comm` IS NULL,1,NULL)) FROM db_02.`emp` a;
  
  SELECT COUNT(*) - COUNT(a.comm) FROM db_02.`emp` a;


-- (3)显示管理者的总人数。
SELECT COUNT(DISTINCT a.`mgr`) FROM db_02.`emp` a;

-- (4)显示雇员工资的最大差额。
SELECT MAX(a.`sal`) - MIN(a.sal) FROM db_02.`emp` a

数据分组的总结

MySQL数据库基础02 韩顺平 自学笔记_第3张图片

-- 统计各个部门的平均工资,平且大于1000,并且平均工资降序排列
-- 取出前2行数据
SELECT 
  a.`deptno`,
  b.`dname`,
  ROUND(AVG(a.`sal`),2) avg_sal 
FROM
  db_02.`emp` a,
  db_02.`dept` b 
WHERE a.`deptno` = b.`deptno`
GROUP BY a.`deptno`,b.`dname` 
HAVING avg_sal > 1000 
ORDER BY avg_sal DESC 
LIMIT 0,2;

多表查询

问题的引出

MySQL数据库基础02 韩顺平 自学笔记_第4张图片

多表查询的练习

MySQL数据库基础02 韩顺平 自学笔记_第5张图片
直接拼接查询两张表的结果(笛卡尔集)
MySQL数据库基础02 韩顺平 自学笔记_第6张图片

#多表查询
SELECT * FROM db_02.`emp`;
SELECT * FROM db_02.`dept`;
SELECT * FROM db_02.`salgrade`;
-- ?显示雇 员名,雇员工资及所在部门的名字[笛卡尔集]
SELECT 
  a.`ename`,
  a.`sal`,
  b.`dname` ,
  a.`deptno`
FROM
  db_02.`emp` a,
  db_02.`dept` b 
WHERE a.`deptno` = b.`deptno` ;

-- 老韩小技巧:多表查询的条件不能少于表的个数-1,否则会出现笛卡尔集


-- ?如何显示部门号为10的部门名、员工名和工资

SELECT 
  b.`dname`,
  a.`ename`,
  a.`sal`,
  a.`deptno` 
FROM
  db_02.`emp` a,
  db_02.`dept` b 
WHERE b.`deptno` = 10
AND a.`deptno` = b.`deptno`;

DESC  db_02.`emp`;
DESC db_02.`dept`;
 
  -- ?显示各个员工的姓名,工资,及其工资的级别
SELECT 
  a.ename,
  a.sal,
  b.`grade` 
FROM
  db_02.`emp` a,
  db_02.`salgrade` b 
  WHERE a.`sal`BETWEEN b.`losal` AND b.`hisal`;

-- 学员练习:显示雇员名,雇员工资及所在部门的名字,并按
-- 部门排序[降序排].

SELECT 
  a.`ename`,
  a.`sal`,
  b.`dname` 
FROM
  db_02.`emp` a,
  db_02.`dept` b 
WHERE a.`deptno` = b.`deptno` 
ORDER BY b.`dname` DESC ;

自连接

MySQL数据库基础02 韩顺平 自学笔记_第7张图片

# 自连接
# 显示公司员工和他的上级的名字
SELECT 
  a.`ename`,
  a.`empno`,
  a.`mgr`,
  b.`ename` sjxm,
  b.`empno` sj 
FROM
  db_02.`emp` a,
  db_02.`emp` b 
WHERE a.`mgr` = b.`empno` ;


SELECT * FROM db_02.`emp`;

子查询

MySQL数据库基础02 韩顺平 自学笔记_第8张图片

# 显示与SMITH同一部门的所有员工
SELECT * FROM db_02.`emp`;
# 1.先查询SMITH的部门编号
# 2.把select语句当作子查询来使用
SELECT 
  * 
FROM
  db_02.`emp` b 
WHERE b.`deptno` IN 
  (SELECT 
    a.`deptno` 
  FROM
    db_02.`emp` a
    WHERE a.`ename` = 'SMITH') ;

# 如何查询和部门10的工作相同的雇员名字、
# 岗位、工资、部门号但是不含10本身

# 1.查询10号部门有哪些工作岗位
# 2.把1.的查询结果当作子查询使用

SELECT 
  b.`ename`,
  b.`job`,
  b.`sal`,
  b.`deptno` 
FROM
  db_02.`emp` b 
WHERE b.`job` IN 
  (SELECT 
    DISTINCT a.`job` 
  FROM
    db_02.`emp` a 
  WHERE a.`deptno` = 10) 
  AND b.`deptno` <> 10 ;

子查询当作临时表使用

MySQL数据库基础02 韩顺平 自学笔记_第9张图片

# 查询ecshop中各个类别中,价格最高的商品
-- 1.查询需要的字段
SELECT 
  a.goods_id,
  a.cat_id,
  a.goods_name,
  a.shop_price
FROM
  ecs_goods a ;
  
  DESC ecs_goods;
  -- 2.查询各个类别的最大价值的商品
SELECT 
  a.cat_id,
  MAX(a.shop_price) 
FROM
  ecs_goods a 
GROUP BY a.cat_id ;

-- 3.把2者组合一下
SELECT 
  c.goods_id,
  c.cat_id,
  c.goods_name,
  c.shop_price 
FROM
  ecs_goods c,
  (SELECT 
    a.cat_id,
    MAX(a.shop_price) max_price 
  FROM
    ecs_goods a 
  GROUP BY a.cat_id) b 
WHERE c.cat_id = b.cat_id 
  AND b.max_price = c.shop_price ;

在多行子查询中使用all操作符

MySQL数据库基础02 韩顺平 自学笔记_第10张图片

# 如何显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号
# 方法一:直接求30部门最高的工资,然后比最高工资高的员工信息即可
SELECT 
  c.`ename`,
  c.`sal`,
  c.`deptno` 
FROM
  db_02.`emp` c,
  (SELECT 
    MAX(a.`sal`) maxsal 
  FROM
    db_02.`emp` a 
  WHERE a.`deptno` = 30) b 
WHERE c.sal > b.maxsal ;

## 方法二 使用all
SELECT 
  b.`ename`,
  b.`sal`,
  b.`deptno` 
FROM
  db_02.`emp` b 
WHERE b.`sal` > ALL 
  (SELECT 
    a.sal 
  FROM
    db_02.`emp` a 
  WHERE a.`deptno` = 30) ;

在多行子查询中使用any操作符

MySQL数据库基础02 韩顺平 自学笔记_第11张图片

#如何显示工资比部门30的其中一个员工的工资高的员工的姓名、
#工资和部门号
-- 方法一:比最低的高即可

SELECT 
  b.ename,
  b.`sal`,
  b.`deptno` 
FROM
  db_02.`emp` b 
WHERE b.`sal` > 
  (SELECT 
    MIN(a.`sal`) 
  FROM
    db_02.`emp` a
    WHERE a.`deptno` = 30);
    
 -- 方法2:使用any
 SELECT 
  b.ename,
  b.`sal`,
  b.`deptno` 
FROM
  db_02.`emp` b 
WHERE b.`sal` > ANY
  (SELECT a.`sal`
  FROM
    db_02.`emp` a
    WHERE a.`deptno` = 30);

多列子查询

MySQL数据库基础02 韩顺平 自学笔记_第12张图片

# 查询与smith的部门和岗位完全相同的所有雇员(并且不含smith本人)
SELECT * FROM db_02.`emp` b
WHERE (b.`deptno`,b.`job`) =
(SELECT a.`deptno`,a.`job` FROM db_02.`emp` a
WHERE a.`ename` = 'SMITH')
AND b.`ename` <> 'SMITH';

# 查询与ALLEN的部门和岗位完全相同的所有雇员(并且不含ALLEN本人)
SELECT * FROM db_02.`emp` b
WHERE (b.`deptno`,b.`job`) =
(SELECT a.`deptno`,a.`job` FROM db_02.`emp` a
WHERE a.`ename` = 'ALLEN')
AND b.`ename` <> 'ALLEN';


# 请查询和宋江数学、英语、语文成绩完全相同的学生
SELECT 
  * 
FROM
  db_02.`student` a 
WHERE (
    a.`chinese`,
    a.`english`,
    a.`math`
  ) = 
  (SELECT 
    b.`chinese`,
    b.`english`,
    b.`math` 
  FROM
    db_02.`student` b
    WHERE b.`name` = '宋江');
    

子查询练习

from子句中使用子查询

MySQL数据库基础02 韩顺平 自学笔记_第13张图片

# from子句中使用子查询
# 查找每个部门工资高于本部门平均工资的人的个人资料
SELECT 
  b.* 
FROM
  db_02.emp b,
  (SELECT 
    AVG(a.`sal`) avg_sal,
    a.`deptno` 
  FROM
    db_02.emp a 
  GROUP BY a.`deptno`) c 
WHERE b.`sal` > c.avg_sal 
  AND b.`deptno` = c.deptno ;

MySQL数据库基础02 韩顺平 自学笔记_第14张图片

# 查找每个部门工资最高的人的详细资料
SELECT b.* FROM db_02.emp b,(
SELECT MAX(a.`sal`) max_sal,a.`deptno` FROM db_02.emp a
GROUP BY a.`deptno`) c
WHERE b.`sal` = c.max_sal
AND b.`deptno` = c.deptno;

MySQL数据库基础02 韩顺平 自学笔记_第15张图片

# 显示每个部门的信息(包括部门名称、部门编号、部门地址)和人员数量
SELECT 
  a.`dname`,
  a.`deptno`,
  a.`loc`,
  c.rs 
FROM
  db_02.`dept` a,
  (SELECT 
    b.deptno,
    COUNT(*) rs 
  FROM
    db_02.`emp` b 
  GROUP BY b.deptno) c 
WHERE a.`deptno` = c.deptno ;

表复制

MySQL数据库基础02 韩顺平 自学笔记_第16张图片

# 表复制
CREATE TABLE my_table01
(id INT,
NAME VARCHAR(32),
sal DOUBLE,
job VARCHAR(32),
deptno INT);

DESC my_table01;

-- 演示自我复制
-- 1.先把emp表记录复制到my_table01中
INSERT INTO my_table01
(id,NAME,sal,job,deptno)
SELECT empno,ename,sal,job,deptno
FROM db_02.`emp`;

SELECT COUNT(*) FROM db_02.`my_table01`;

-- 2.自我复制
INSERT INTO my_table01
SELECT * FROM my_table01;

-- 3.删除一张表的重读记录
-- (1).先创建一张表my_table02
-- (2).让my_table02有重复记录
# 让db_02.`my_table02`表结构与emp表结构相同,但是不填充数据
CREATE TABLE db_02.`my_table02` LIKE emp;
DESC db_02.`my_table02`;

SELECT * FROM db_02.`my_table02`; -- 0

INSERT INTO db_02.`my_table02`
SELECT * FROM db_02.`emp`;

SELECT * FROM db_02.`my_table02`; -- 13

INSERT INTO db_02.`my_table02`
SELECT * FROM db_02.`emp`;

SELECT * FROM db_02.`my_table02`; -- 26

-- (3)考虑去重
-- (3).1先创建一张临时表,表结构与重复表结构一致
CREATE TABLE db_02.temp LIKE db_02.`emp`;

-- (3).2把my_table02的记录通过distinct关键字处理后把记录复制到my_temp
INSERT INTO db_02.temp
SELECT DISTINCT * FROM db_02.`my_table02`;

SELECT * FROM db_02.temp;
-- (3).3把temp记录复制到my_table02中
DELETE FROM db_02.`my_table02`;

INSERT INTO db_02.`my_table02`
SELECT * FROM db_02.`temp`;

-- (3).4 删除临时表
DROP TABLE db_02.`temp`;

合并查询

MySQL数据库基础02 韩顺平 自学笔记_第17张图片

# 合并查询
-- union all 将两条结果合并,不去重(8条)
SELECT a.`ename`,a.`sal`,a.`job` FROM db_02.`emp` a WHERE a.`sal` > 2500 -- 5条
UNION ALL
SELECT b.`ename`,b.`sal`,b.`job` FROM db_02.`emp` b WHERE b.`job` = 'MANAGER'; -- 3条

-- union 将两结果合并去重(6条)
SELECT a.`ename`,a.`sal`,a.`job` FROM db_02.`emp` a WHERE a.`sal` > 2500 -- 5条
UNION
SELECT b.`ename`,b.`sal`,b.`job` FROM db_02.`emp` b WHERE b.`job` = 'MANAGER'; -- 3条

外连接

MySQL数据库基础02 韩顺平 自学笔记_第18张图片
MySQL数据库基础02 韩顺平 自学笔记_第19张图片

# 外连接
## 建立2张表
CREATE TABLE stu (
	id INT,
	`name` VARCHAR(32));
INSERT INTO stu VALUES(1, 'jack'),(2,'tom'),(3, 'kity'),(4, 'nono');
SELECT * FROM stu;

CREATE TABLE exam(
	id INT,
	grade INT);
INSERT INTO exam VALUES(1, 56),(2,76),(11, 8);
SELECT * FROM exam;

-- 左外连接
SELECT * FROM stu LEFT JOIN exam
ON stu.`id` = exam.`id`
ORDER BY stu.id;

-- 右外连接
SELECT * FROM stu RIGHT JOIN exam
ON stu.`id` = exam.`id`
ORDER BY exam.id;

外连接课后习题

MySQL数据库基础02 韩顺平 自学笔记_第20张图片

-- 列出部门名称和这些部门的员工信息(名字和工作),同时列出那些没有员工
-- 的部门名。5min
-- 1.使用左外连接实现
# 左外连接
SELECT 
  a.`dname`,
  b.`ename`,
  b.`job` 
FROM
  db_02.`dept` a LEFT JOIN
  db_02.`emp` b ON
a.`deptno` = b.`deptno` 
ORDER BY a.`dname`;

-- 2.使用右外连接实现

# 右外连接
SELECT 
  a.`ename`,
  a.`job`,
  b.dname 
FROM
  db_02.`emp` a RIGHT JOIN
  db_02.`dept` b ON
a.`deptno` = b.`deptno` 
ORDER BY b.`dname` ;

mysql约束

MySQL数据库基础02 韩顺平 自学笔记_第21张图片

primary key(主键)-基本使用

# 主键
CREATE TABLE t17
(`id` INT PRIMARY KEY, -- 主键
`name` VARCHAR(32),
`email` VARCHAR(32)
);

INSERT INTO t17
VALUES(1,'jack','[email protected]');

INSERT INTO t17
VALUES(2,'tom','[email protected]');

INSERT INTO t17
VALUES(1,'hsp','[email protected]');

# 主键重复
-- 错误代码: 1062
-- Duplicate entry '1' for key 'PRIMARY'

-- 主键使用的细节讨论
-- 1.primary key不能重复而且不能为null。
INSERT INTO t17
VALUES(NULL,'hsp','[email protected]');

-- 错误代码: 1048
-- Column 'id' cannot be null

-- 2.一张表最多只能有一个主键,但可以是复合主键
CREATE TABLE t18
(`id` INT PRIMARY KEY, -- 主键
`name` VARCHAR(32) PRIMARY KEY,
`email` VARCHAR(32)
);

-- 错误代码: 1068
-- Multiple primary key defined


# 解决办法:复合主键 id + name 当作复合主键
CREATE TABLE t18
(`id` INT, -- 主键
`name` VARCHAR(32) ,
`email` VARCHAR(32),
PRIMARY KEY (`id`,`name`) -- 这里是复合主键
) ;

INSERT INTO t18
VALUES(1,'tom','[email protected]');

SELECT * FROM t18;

# 这里可以添加成功
INSERT INTO t18
VALUES(1,'jack','[email protected]');


INSERT INTO t18
VALUES(1,'tom','[email protected]');

-- 错误代码: 1062
-- Duplicate entry '1-tom' for key 'PRIMARY'

-- 3.主键的指定方式 有两种
-- ●直接在字段名后指定:字段名primakry key
CREATE TABLE t19
(`id` INT PRIMARY KEY, -- 主键
`name` VARCHAR(32) ,
`email` VARCHAR(32)
) ;
-- ●在表定义最后写primary key(列名);
CREATE TABLE t20
(`id` INT, 
`name` VARCHAR(32) ,
`email` VARCHAR(32),
 PRIMARY KEY(`id`)-- 主键
) ;


-- 4.使用desc 表名,可以看到primary key的情况.
DESC t20;
-- 5.老师提醒:在实际开发中,每个表往往都会设计一个主键.

not null的使用

MySQL数据库基础02 韩顺平 自学笔记_第22张图片

unique的使用

MySQL数据库基础02 韩顺平 自学笔记_第23张图片

# unique的使用
CREATE TABLE t21
(`id` INT UNIQUE,  -- 表示id列不能够重复
`name` VARCHAR(32) ,
`email` VARCHAR(32)
) ;

INSERT INTO t21
VALUES(1,'jack','[email protected]');

INSERT INTO t21
VALUES(1,'tom','[email protected]');

-- 错误代码: 1062
-- Duplicate entry '1' for key 'id'

-- ●unique 细节(注意): unique.sql
-- 1.如果没有指定 not null ,则unique字段可以有多个null
-- 没有说明not null则可以添加多条记录
INSERT INTO t21
VALUES(NULL,'tom','[email protected]');

INSERT INTO t21
VALUES(NULL,'jerry','[email protected]');

INSERT INTO t21
VALUES(NULL,'kear','[email protected]');

SELECT * FROM t21;

# unique + not null = primary key

-- 2.一张表可以有多个unique字段
CREATE TABLE t22
(`id` INT UNIQUE,  -- 表示id列不能够重复
`name` VARCHAR(32) UNIQUE,
`email` VARCHAR(32)
) ;

DESC t22;

foreign key(外键)


MySQL数据库基础02 韩顺平 自学笔记_第24张图片

# 外键演示
# 创建班级表(主表)
CREATE TABLE class
(id INT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL DEFAULT '');

DESC class;

# 从表
CREATE TABLE classmate
(id INT PRIMARY KEY,
`NAME` VARCHAR(255) NOT NULL DEFAULT '',
classid INT, -- 学生所在班级编号
 FOREIGN KEY (classid) REFERENCES class(id) -- 外键
);

DESC classmate;


INSERT INTO class
VALUES
(100,'Java');

INSERT INTO class
VALUES
(200,'Web');

SELECT * FROM class;

INSERT INTO classmate
VALUES
(1,'tom',100);

SELECT * FROM classmate;

INSERT INTO classmate
VALUES
(2,'tom',200);

# 300号班级不存在
INSERT INTO classmate
VALUES
(3,'Jerry',300);

-- 错误代码: 1452
-- Cannot add or update a child row: a 
-- foreign key constraint fails (`db_02`.`classmate`, CONSTRAINT `classmate_ibfk_1` FOREIGN KEY (`classid`) REFERENCES `class` (`id`))

-- 1.外键指向的表的字段,要求是primary key或者是unique
-- 也就是,外键必须指向主表的primary key 或者 unique字段

-- 2.表的引擎类型是innodb,这样的表才支持外键

-- 3.外键字段的类型要和主键字段的类型一致(长度可以不同)

-- 4.外键字段的值,必须在主键字段中出现过,或者为null [前
-- 提是外键字段允许为null
INSERT INTO classmate
VALUES
(3,'Jerry',NULL);

SELECT * FROM classmate;

DESC classmate;-- 外键字段classid允许为空

-- 5.一旦建立主外键的关系,
-- 数据不能随意删除了.
DELETE FROM class 
WHERE id = 100;


-- 错误代码: 1451
-- Cannot delete or update a parent row: a foreign key constraint fails (`db_02`.`classmate`, CONSTRAINT `classmate_ibfk_1` FOREIGN KEY (`classid`) REFERENCES `class` (`id`))

check的使用

MySQL数据库基础02 韩顺平 自学笔记_第25张图片

# check的使用
CREATE TABLE t23
(id INT PRIMARY KEY,
`name` VARCHAR(32),
`sex` CHAR(1) CHECK(sex IN ('男','女')),
`sal` DOUBLE CHECK(sal > 1000 AND sal < 5000)
);
-- mysql 5.7 只做语法提示,不生效
INSERT INTO t23
VALUES
(1,'Jack','未',6000);

SELECT * FROM t23;

mysql约束练习

CREATE DATABASE shop_db 
CHARACTER SET utf8 
COLLATE utf8_bin;

# 商品 主表
CREATE TABLE goods
(`goods_id` INT,
`goods_name` VARCHAR(100),
`unitprice` DOUBLE CHECK(`unitprice` > 1.0 AND `unitprice` < 9999.99),
`category` VARCHAR(20),
`provider` VARCHAR(50),
PRIMARY KEY(`goods_id`)
) ENGINE INNODB;

# 客户 主表
CREATE TABLE customer
(`customer_id` INT PRIMARY KEY,
`name` VARCHAR(100) NOT NULL,
`address` VARCHAR(100),
`email` VARCHAR(50) UNIQUE,
-- `sex` char(1) check(`sex` in ('男','女')),
`sex` ENUM('男','女') NOT NULL CHECK(`sex` IN ('男','女')), -- 枚举
`card_id` INT
)ENGINE INNODB;

# 购买 从表
CREATE TABLE purchase
(`order_id` INT UNSIGNED PRIMARY KEY,
`customer_id` INT, -- 外键
`goods_id` INT, -- 外键
`nums` INT NOT NULL DEFAULT 0,
FOREIGN KEY(`customer_id`) REFERENCES customer(`customer_id`),
FOREIGN KEY(`goods_id`) REFERENCES goods(`goods_id`)
)ENGINE INNODB;

自增长

MySQL数据库基础02 韩顺平 自学笔记_第26张图片
MySQL数据库基础02 韩顺平 自学笔记_第27张图片

# 自增长
CREATE TABLE t24
(`id` INT PRIMARY KEY AUTO_INCREMENT,
`email` VARCHAR(32) NOT NULL DEFAULT '',
`name` VARCHAR(32) NOT NULL DEFAULT '');

DESC t24;

-- 测试自增长
INSERT INTO t24
VALUES(NULL,'[email protected]','jack');

SELECT * FROM t24;

INSERT INTO t24
VALUES(NULL,'[email protected]','tom');

INSERT INTO t24
(`email`,`name`)
VALUES('[email protected]','hsp');

-- 自增长
-- ●自增长使用细节I
-- 1. 一般来说自增长是和primary key配合使用的

-- 2.自增长也可以单独使用[但是需要配合一 个unique]
CREATE TABLE t16
(`id` INT UNIQUE AUTO_INCREMENT,
`email` VARCHAR(32) NOT NULL DEFAULT '',
`name` VARCHAR(32) NOT NULL DEFAULT '');
-- 3.自增长修饰的字段为整数型的(虽然小数也可以但是非常非常
-- 少这样使用


-- 4.自增长默认从1开始,你也可以通过如下命令修改alter table表名auto increment = xxx;
CREATE TABLE t25
(`id` INT PRIMARY KEY AUTO_INCREMENT,
`email` VARCHAR(32) NOT NULL DEFAULT '',
`name` VARCHAR(32) NOT NULL DEFAULT '');
-- 从100开始
ALTER TABLE t25 AUTO_INCREMENT = 100;

INSERT INTO t25
VALUES(NULL,'[email protected]','hsp');

SELECT * FROM t25;.
-- 5.如果添加数据时,给自增长字段指定的值,则以指定的值为准.
-- 一般来说,就按照自增长的规则来添加数据
INSERT INTO t25
VALUES(666,'[email protected]','hsp');

INSERT INTO t25
VALUES(NULL,'[email protected]','hsp');

mysql索引

索引的快速入门

MySQL数据库基础02 韩顺平 自学笔记_第28张图片

-- 没有索引查询,花了5.586秒,生成文件 emp.ibd 大小 524M
SELECT * FROM emp a
WHERE a.empno = 1234567;
-- 创建索引empno_index 之后 emp.ibd 大小 655M 索引本身也有空间
CREATE INDEX empno_index ON emp(empno);

-- 有索引查询,花了0.003s
SELECT * FROM emp a
WHERE a.empno = 1234578;

-- 创建索引后只对创建了索引的列有效,6.360s
SELECT * FROM emp
WHERE ename = 'axJ';

CREATE INDEX ename_index ON emp(ename);

-- 创建索引后只对创建了索引的列有效,0.01s,文件变为827M
SELECT * FROM emp
WHERE ename = 'YcsDQt';

索引的原理

MySQL数据库基础02 韩顺平 自学笔记_第29张图片

索引的类型

MySQL数据库基础02 韩顺平 自学笔记_第30张图片

索引的使用

MySQL数据库基础02 韩顺平 自学笔记_第31张图片

# 创建索引
CREATE TABLE t26
(id INT,
`name` VARCHAR(32));

CREATE TABLE t03
(id INT PRIMARY KEY,
`name` VARCHAR(32));

-- 查询表是否有索引
SHOW INDEX FROM t26;

-- 添加唯一索引
CREATE UNIQUE INDEX id_index ON t26(id);

-- 添加普通索引
CREATE INDEX id_index ON t01(id);

-- 唯一索引和普通索引的选择:如果某列的值是不重复的,则优先考虑UNIQUE
-- 否则采用普通索引

-- 添加普通索引
ALTER TABLE t02 ADD INDEX id_index (id);

-- 添加主键索引
ALTER TABLE t03 ADD PRIMARY KEY (id);

SHOW INDEX FROM t03;

-- 删除索引
SHOW INDEX FROM t26;
DROP INDEX id_index ON t26;

ALTER TABLE t01 DROP INDEX id_index;

SHOW INDEX FROM t01;

-- 删除主键索引
ALTER TABLE t03 DROP PRIMARY KEY;

-- 修改索引(先删除后添加即可)

-- 查询索引
SHOW INDEX FROM t25;
SHOW INDEXES FROM t25;
SHOW KEYS FROM t25;
DESC t25;

课后作业

MySQL数据库基础02 韩顺平 自学笔记_第32张图片

# 课后作业
-- 3种方式创建主键
-- 1.
CREATE TABLE order1
(`id` INT PRIMARY KEY,
`goods_name` VARCHAR(100),
`purchase` VARCHAR(50),
`num` INT);

-- 2.
CREATE TABLE order2
(`id` INT,
`goods_name` VARCHAR(100),
`purchase` VARCHAR(50),
`num` INT,
PRIMARY KEY (id)
);

-- 3.
CREATE TABLE order3
(`id` INT,
`goods_name` VARCHAR(100),
`purchase` VARCHAR(50),
`num` INT
);

ALTER TABLE order3 ADD PRIMARY KEY  (id);

# 建立唯一索引 2种方式
-- 1.
CREATE TABLE menu1
(`id` INT PRIMARY KEY,
`menu_name` VARCHAR(255),
`cook` VARCHAR(50),
`card` VARCHAR(20) UNIQUE,
`price` DOUBLE);

-- 2.
CREATE TABLE menu2
(`id` INT PRIMARY KEY,
`menu_name` VARCHAR(255),
`cook` VARCHAR(50),
`card` VARCHAR(20),
`price` DOUBLE);

CREATE UNIQUE INDEX card_index ON menu2(card);

-- 3.
CREATE TABLE menu3
(`id` INT PRIMARY KEY,
`menu_name` VARCHAR(255),
`cook` VARCHAR(50),
`card` VARCHAR(20),
`price` DOUBLE);

ALTER TABLE menu3 ADD UNIQUE INDEX (card);

MySQL数据库基础02 韩顺平 自学笔记_第33张图片

# 普通索引
CREATE TABLE sportsman1
(`id` INT PRIMARY KEY,
`name` VARCHAR(100),
`hobby` VARCHAR(100));
-- 1.
CREATE INDEX name_index ON sportsman1 (`hobby`);


CREATE TABLE sportsman2
(`id` INT PRIMARY KEY,
`name` VARCHAR(100),
`hobby` VARCHAR(100));
-- 2.
ALTER TABLE sportsman2 ADD INDEX (`hobby`);

SHOW INDEX FROM sportsman2;

索引小结

MySQL数据库基础02 韩顺平 自学笔记_第34张图片

你可能感兴趣的:(数据库,数据库,mysql,sql)