数据类型
整型数据
整型数据 | 字节数 | 无符号的取值范围 | 有符号的取值范围 |
---|---|---|---|
TINYINT | 1 | 0~225 | -125~127 |
SMALLINT | 2 | 0-65535 | -32768~32768 |
MEDIUMINT | 3 | 0~16777215 | ··· |
INT | 4 | 0-4294967295 | ··· |
BIGINT | 8 | 0~18446744073709551615 |
浮点型
浮点型数据 | 字节数 |
---|---|
FLOAT | 4 |
DOUBLE | 8 |
定点数型数据 | |
DECIMAL(()M , 2) | M+2 |
日期 时间类型
数据类型 | 字节数 | 取值范围 | 日期格式 | 零值 |
---|---|---|---|---|
YEAR | 1 | 1901~2155 | YYYY | 0000 |
DATE | 4 | 1000-01-01-9999-12-3 | YYYY-MM-DD | 0000-00-00 |
TIME | 3 | -838:59:59-838:59:59 | HH:MM:SS | 00:00:00 |
DATETIME | 8 | 11 | YYYY-MM-DD、HH:MM:SS | 0000-00-00 00:00:00 |
TIMESTAMP(时间戳) | 4 | 1970-01-01 00:00:01~2038-01-19 03:14:07 | YYYY-MM-DD、HH:MM:SS | 0000-00-00 00:00:00 |
字符串型
字符串类型(单位:字节) | 字节状态 | 优点 |
---|---|---|
CHAR((int)Max) | 固定 | 查询快 |
VARCHAR((int)Max) | 动态 | 省空间 |
二进制数据类型
二进制数据类型(单位:长度) | 长度状态 |
---|---|
BINARY((int)Max) | 固定 |
VARBINARY((int)Max) | 动态 |
BINARY类型的长度是固定的,如果长度不足最大长度,后面用“0”对齐,直到指定长度。
大文本数据类型
大文本数据类型 | 存储范围(单位:字节) |
---|---|
TINYTEXT | 0~255字节 |
TEXT | 0~65535字节 |
MEDIUMTEXT | 0~16777215字节 |
LONGTEXT | 0~4294967295字节 |
大数据二进制类型
特殊二进制类型 | 存储范围(单位:字节) |
---|---|
TINYBLOB | 0~255字节 |
BLOB | 0-65535字节 |
MEDIUMBLOB | 0~16777215字节 |
LONGBLOB | 0-4294967295字节 |
枚举型
ENUM枚举型,单选项
ENUM('值1','值2'···'值n')
多选项
SET('值1','值2'···'值n')
DDL操作数据库
DDL (Data Definition Language):数据定义语言,定义数据库对象:库、表、列等
创建数据库
CREATE DATABASE 库名;
CREATE DATABASE IF NOT EXISTS 库名;
CREATE DATABASE 库名 CHARACTER SET 编码方式;
CREATE DATABASE 库名 CHARACTER SET 编码方式 COLLATE 排序规则;
CREATE DATABASE :创建数据库
IF NOT EXISTS :检查是否已存在的状态
CHARACTER SET:设置编码方式
COLLATE :排序规则
查看数据库
查看当前数据库:
SHOW DATABASES;
查看创建的库:
SHOW CREATE DATABASE 库名;
查看当前所选的数据库:
SELECT DATABASE();
修改数据库
ALTER DATABASE 库名;
ALTER DATABASE IF NOT EXISTS 库名;
ALTER DATABASE 库名 CHARACTER SET 编码方式;
ALTER DATABASE 库名 CHARACTER SET 编码方式 COLLATE 排序规则;
ALTER DATABASE :修改数据库
IF NOT EXISTS :检查是否已存在的状态
CHARACTER SET :设置编码方式
COLLATE :排序规则
删除数据库
DROP DATABASE 库名;
选择数据库
USE 库名;
DDL表列操作
DDL (Data Definition Language):数据定义语言,定义数据库对象:库、表、列等
创建表
CREATE TABLE 表名(
字段名1 数据类型 [完整性约束条件] [COMMENT '注释内容'],
字段名2 数据类型 [完整性约束条件] [COMMENT '注释内容'],
·······
字段名n 数据类型 [完整性约束条件] [COMMENT '注释内容'],
[完整性约束条件](字段1,字段2,·····,字段n)
)[编码集设置];
编码集设置:
CHARACTER SET 字符集名 [校对规则]
校对规则:
COLLATE 校对名
查看表
查看指定表字段结构:
DESC 表名;
查看当前数据库所有表:
SHOW TABLES;
查看表的详细结构:
SHOW CREATE TABLE 表名;
修改表
修改表名
RENAME TABLE 表名 to 新表名;
ALTER TABLE 表名 RENAME 新表名;
增加字段
ALTER TABLE 表名 ADD 字段名 数据类型;
字段 修改 与 顺序
ALTER TABLE 表名 MODIFY 字段名 数据类型 [更改字段循序 | 完整性约束条件] [COMMENT '内容'];
更改字段循序:
FIRST | (AFTER 字段名2)
FIRST:指定字段为表的第一个
AFTER:指定字段插入字段2的后面
修改字段名
ALTER TABLE 表名 CHANGE 字段名 新字段名 新字段类型;
修改表字符集
ALTER TABLE 表名 CHARACTER SET 字符集类型;
删除字段
ALTER TABLE 表名 DROP 字段名;
删除表
DROP TABLE 表名;
索引
索引的目的在于提高查询效率,与我们查字典所用的目录是一个道理
索引创建
建表时创建索引:
CREATE TABLE 表名(
字段名1 数据类型 [完整性约束条件],
字段名2 数据类型 [完整性约束条件],
·····
字段名n 数据类型
[UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY
[索引名] (字段名1 [(长度)]) [ASC | DESC])
)[存储引擎];
UNIQUE: 可选参数,表示唯一性约束
FULLTEXT:可选参数,表示全文约束
SPATIAL: 可选参数,表示空间约束
INDEX 和 KEY:用来表示字段的索引,二者选一即可
索引名:可选参数,表示创建的索引的名称
字段名1:指定索引对应字段的名称
长度:可选参数,用于表示索引的长度
ASC 和 DESC:可选参数,其中,ASC表示升序排列,DESC表示降序排列
单列索引
在表中单个字段上创建索引,它可以是普通索引、唯一索引或者全文素引, 只要保证该索引只对应表中一个字段即可。
INDEX 索引名 (字段名1[,字段名2…]名);
CREATE INDEX 索引名 ON 表名 (字段名1[,字段名2…]);
ALTER TABLE 表名 ADD INDEX 索引名 (字段名1[,字段名2…]);
唯一索引 (UNIQUE )
使字段的值必须是唯一的
UNIQUE INDEX 索引名 (字段名 (ASC | DESC));
CREATE UNIQUE INDEX 索引名 ON 表名 (字段名);
ALTER TABLE 表名 ADD UNIQUE INDEX 索引名 (字段名);
全文索引 (FULLTEXT)
只能创建在CHAR、VARCHAR或TEXT类型的字段上,现在只有MyISAM存储引擎支持全文索引
FULLTEXT INDEX 索引名 (字段名);
CREATE FULLTEXT INDEX 索引名 ON 表名 (字段名);
ALTER TABLE 表名 ADD FULLTEXT INDEX 索引名 (字段名);
注意: 后面需存储引擎(ENGINE =MyISAM)
空间索引 (SPATIAL)
只能创建在空间数据类型的字段上。MySQL中的空间数据类型有4种,分别是LGEOMETRY、POINT、 LINESTRING和POLYGON,空间索引只能在存储引擎为MyISAM的表中创建
SPATIAL INDEX 索引名 (字段名);
CREATE SPATIAL INDEX 索引名 ON 表名 (字段名);
ALTER TABLE 表名 ADD SPATIAL INDEX 索引名 (字段名);
注意: 后面需存储引擎(ENGINE =MyISAM)
索引删除
ALTER TABLE 表名 DROP INDEX 索引名;
DROP INDEX 索引名 ON 表名;
DML数据操作
DML (Data Manipulation Language):数据操作语言,定义数据库记录(数据)增删改 的操作
插入数据
一条数据添加
INSERT INTO 表名 [(字段名1 [,字段名2. . .])] VALUES(值1 [,值2. . .]);
多条数据添加
INSERT INTO 表名 [(字段名)] VALUES (字段值1),(字段值2)…;
注意:
- 插入字段与它的数据类型位置是一一对应的
- 数据类型对应的值,字段值是非数值,则两侧必须添加单引号
- null设置为空
- 数据的大小应在字段的数据类型规定范围内
- 如果要插入所有字段数据时可以省写字段,但必须按表中字段顺序写值
- 尽可能避免字段数据值写入的是
null
更改数据
更改单表数据
UPDATE 表名 SET 字段名1 = 字段值1 [,字段名2 = 值2…] [WHERE 条件表达式];
更改多表数据
UPDATE 表名1 , 表名2 SET {修改字段值,可跨表修改} [WHERE 条件表达式];
注意:
- 逻辑运算符有: and(并且)、or(或者)、not(取非)
- 如果更改字段无条件表达式,则指定全部该字段的值一致
删除数据
DELETE FROM 表名 [WHERE 条件表达式];
TRUNCATE TABLE 表名;
多表删除
DELETE {表名1,表名2…} FROM {表名1,表名2…} [WHERE 条件表达式];
注意:
- 如果无条件表达式,则删除全部数据
- DELETE删除可找回
- TRUNCATE删除不可找回,类似格式化数据,执行快
- 不能删除某列的值(可修改数据值置NULL)
- 多表删除 建议WHERE过滤他们字段的关系
- 多表中的每张表需要逗号分隔
DCL安全访问
DCL (Data Control Language)︰数据控制语言,用来定义访问权限和安全级别
创建用户
CREATE USER 用户名@指定ip IDENTIFIED BY 密码;
CREATE USER 用户名@’%’ IDENTIFIED BY 密码;
指定ip / 任意ip 可登录
授权用户
GRANT 权限1[,权限2…权限n] ON 库名.* TO 用户名@指定ip;
GRANT ALL ON *
.*
TO 用户名@指定ip;
指定权限 / 所有权限 用户授权
(指定权限自行查询)
查询权限
SHOW GRANTS FOR 用户名@指定IP;
SHOW GRANTS FOR 用户名@‘%’;
查询指定 / 查询所有 IP的权限情况
撤销权限
REVOKE 权限1[,权限2…权限n] ON 库名.* FROM 用户名@指定IP;
删除用户
DROP USER 用户名@指定IP
DQL数据查询
DQL(Data Query Language):数据查询语言,用来查询记录(数据)查询
数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端
查询返回的结果集是一张虚拟表
SELECT的语法结构:
SELECT (* | {字段名1 [别名][,字段名2[别名]····,字段名n[别名]]} ) FROM 表名 [可选参数];
SELECT * FROM 表名;
可选参数:
[WHERE 条件表达式];
[GROUP BY 字段名 [HAVING 条件表达式2]] ;
[ORDER BY 字段名 [ASC | DESC]];
[LIMIT [OFFSET] (int)记录数];
别名:代替字段名
DISTINCT: 过滤表字段中重复的值(数据),如果指定是多个字段,而且指定的字段值相同,则过滤重复的值!!!
WHERE: 指定查询条件
GROUP BY: 将查询结果按指定字段进行分组
HAVING: 对分组后的结果进行过滤
ORDER BY: 将查询结果按指定字段进行排序,排列方式有参数ASC(升序)、DESC(降序)控制,默认为ASC(升序)
LIMIT: 限制查询结果的数量,后面有可有两个参数,
OFFSET: 表示偏移量,如果偏移量为0则从第一条开始,。不指定参数1,其默认值为0。
记录数: 表示返回查询记录的条数
代码示例
# 学生表
CREATE TABLE stu (
sid CHAR(6),
sname VARCHAR(50),age INT,
gender VARCHAR(50)
);
# 添加数据
INSERT INTO stu VALUES('S_1001', 'liuYi',35, 'male');
INSERT INTO stu VALUES('S_1002', 'chenEr',15, 'female');
INSERT INTO stu VALUES('S_1003','zhangSan',95, 'male');
INSERT INTO stu VALUES('S_1004', 'liSi', 65, 'female');
INSERT INTO stu VALUES('S_1005', 'wangWu', 55, 'male');
INSERT INTO stu VALUES('S_1006', 'zhaoLiu',75, 'female');
INSERT INTO stu VALUES('S_1007' , 'sunQi',25, 'male');
INSERT INTO stu VALUES('S_1008', 'zhouBa', 45, 'female');
INSERT INTO stu VALUES('S_1009', 'wuJiu',85, 'male');
INSERT INTO stu VALUES('S_1010', 'zhengShi',5, 'female');
INSERT INTO stu VALUES('S_1011','xxx',NULL,NULL);
INSERT INTO stu VALUES('S_1010', 'zhengShi',5, 'female');
# 雇员表
CREATE TABLE emp2(
empno int,
ename VARCHAR(50),
job VARCHAR(50),
mgr INT,
hiredate DATE,sal DECIMAL(7,2),
comm decimal(7,2),
deptno int
);
# 添加数据
INSERT INTO emp2 values(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp2 values(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp2 values(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp2 values(7566,'JONES', 'MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp2 values(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO emp2 values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO emp2 values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO emp2 values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO emp2 values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp2 values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO emp2 values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
# 部门表
CREATE TABLE dept(
deptno int,
dname varchar(14),
loc varchar(13)
);
# 添加数据
INSERT INTO dept values(10, 'ACCOUNTING','NEW YORK');
INSERT INTO dept values(20,'RESEARCH','DALLAS');
INSERT INTO dept values(30,'SALES','CHICAGO');
INSERT INTO dept values(40,'OPERATIONS','BOSTON');
普通查询
条件查询 (WHERE)
··· WHERE (条件表达式);
# 查询 age大于等于25
SELECT * FROM stu WHERE age>=25;
# 查询 age大于等于25 指定显示 sname
SELECT sname FROM stu WHERE age>=25;
# 查询 指定gender值非male
SELECT * FROM stu WHERE gender!='male';
SELECT * FROM stu WHERE gender<>'male';
SELECT * FROM stu WHERE NOT gender='male';
指定查询 (IN)
查指定字段
··· WHERE 字段名 [NOT] IN (值1,值2,···);
# 查询 指定sid
SELECT * FROM stu WHERE sid IN ('S_1011' , 'S_1004');
# 查询 指定sid
SELECT * FROM stu WHERE sid NOT IN ('S_1011' , 'S_1004');
范围查询 (BETWEEN AND)
查指定字段的范围值
··· WHERE 字段名 [NOT] BETWEEN (int)值1 AND (int)值2;
# 查询 指定age 12 - 28的范围
SELECT * FROM stu WHERE age BETWEEN 12 AND 28;
# 查询 指定age 非12 - 28的范围
SELECT * FROM stu WHERE age NOT BETWEEN 12 AND 28;
查询字段名的值1和值2的范围,前提2值必须大于1值
空值查询 (NULL)
查字段NULL值
··· WHERE 字段名 IS [NOT] NULL;
# 查询 age为空的
SELECT * FROM stu WHERE age IS NULL;
# 查询 gender不为空的
SELECT * FROM stu WHERE gender IS NOT NULL;
过滤查询 (DISTINCT )
过滤重复字段
SELECT DISTINCT * | {字段1,字段2...字段n} FROM 表名 [···];
# 查询表中不重复的字段
SELECT DISTINCT * FROM stu;
模糊查询 (LIKE)
寻找匹配的字符串
··· WHERE 字段名 [NOT] LIKE '匹配字符串%_';
# 查询 sname 前缀有字符 l
SELECT * FROM stu WHERE sname LIKE 'l%';
# 查询 sname 第5个字符为 S
SELECT * FROM stu WHERE sname LIKE '_____S%';
注意:
%
任意0 - n个字符
_
一个字符,通配符(未知数)
\
进行转义
\%
为%
多条件查询 (AND)
(交集)连接两个或者多个查询条件
··· WHERE 条件表达式1 [AND 条件表达式2 [··· AND 条件表达式n]];
#查询 age>16 && age<28
SELECT * FROM stu WHERE age>16 AND age<28;
#查询 age>16 && age<28 且不能有 25
SELECT * FROM stu WHERE age>16 AND age<28 AND age != 25;
多条件查询 (OR)
(并集)记录满足任意一个条件即被查出
··· WHERE 条件表达式1 [OR 条件表达式2 [··· OR 条件表达式n]];
# 查询 age<16 || age>28
SELECT * FROM stu WHERE age<16 OR age>28;
# 查询 age<16 || age>28 且不能有 5
SELECT * FROM stu WHERE age != 5 AND age<16 OR age>28;
OR和AND一起用的情况:
AND的优先级高于OR,因此当两者在一起使用时,应该先运算AND两边的条件表达式,再运算OR两边的条件表达式
高级查询
聚合函数
记数函数 (COUNT)
统计不为null的记录条数
SELECT COUNT((*) | (字段名))
FROM 表名 [···];
# 查询 emp2表 总记录数
SELECT COUNT(*) FROM emp2 ;
# 查询 emp2表 comm记录数
SELECT COUNT(comm) FROM emp2 ;
求和函数 (SUM)
求出表中某个字段所有值的总和
SELECT SUM(字段名1)[,SUM(字段名2)...,SUM(字段名n)]
FROM 表名 [···];
# 查询 emp2表 sal字段总和
SELECT SUM(sal) FROM emp2;
# 查询 emp2表 sal+comm字段 总和(IFNULL(comm , 0) 如果字段值为NULL 则至为0)
SELECT SUM(sal+ IFNULL(comm , 0) ) FROM emp2;
平均值函数 (AVG)
求出某个字段所有值的平均值
SELECT AVG(字段名1)[,AVG(字段名2)...,AVG(字段名n)]
FROM 表名 [···];
# 查询 emp2表 sal字段平均值
SELECT AVG(sal) FROM emp2;
最大值函数 (MAX)
用于求出某个字段的最大值,语法格式:
SELECT MAX(字段名1)[,MAX(字段名2)...,MAX(字段名n)]
FROM 表名 [···];
# 查询 emp2表 mgr字段最大值
SELECT MAX(mgr) FROM emp2;
最小值函数 (MIN)
用于求出某个字段的最小值,语法格式:
SELECT MIN(字段名1)[,MIN(字段名2)...,MIN(字段名n)]
FROM 表名 [···];
# 查询 emp2表 mgr字段最小值
SELECT MIN(mgr) FROM emp2;
顺序查询 (ORDER BY)
对查询结果进行排序,语法格式:
SELECT * | {字段1,字段2...字段n} FROM 表名
ORDER BY 字段名1 [ASC | DESC] [,字段名2 [ASC| DESC]...,字段名n [ASC | DESC]];
# 查询 排序 emp2 表的 mgr(降序)
SELECT * FROM emp2 ORDER BY mgr DESC;
# 查询 排序 emp2表 的 先排序mar ,相同值的情况排序sal (默认升序)
SELECT * FROM emp2 ORDER BY mgr , sal ;
ORDER BY:指定字段进行排序
SELECT:指定查询的字段
ASC升序(默认)、DESC降序
注意:指定字段升序排列时,某条字段值为NULL,则这条记录会在第一条显示,因NULL值被认为是最小值
分组查询 (GROUP BY)
对字段值进行分组查询
SELECT 字段名1 | [···] FROM 表名
GROUP BY 字段名1,字段2,···[HAVING 条件表达式 | ···];
# 查询 emp2表 以daptno字段分组 进行sal求和
SELECT deptno , SUM(sal) FROM emp2 GROUP BY deptno;
# 查询 emp2表 以daptno字段分组 每个dapthon分组的记录数 并排序
SELECT deptno , COUNT(*) FROM emp2 GROUP BY deptno ORDER BY deptno;
# 查询 emp2表 以daptno字段分组 deptno值为30 过滤
SELECT deptno , SUM(sal) FROM emp2 GROUP BY deptno HAVING deptno != 30;
# 查询 emp2表 以daptno字段分组 mgr值小于7800 过滤
SELECT deptno , COUNT(*) FROM emp2 WHERE mgr>7800 GROUP BY deptno;
注意:
- GROUP BY后面的字段 是指定字段进行分组
- 聚合函数一起使用
- 查询过滤使用
HAVING
并非WHERE
- HAVING不能单独出现,只能存在GROUP BY后面
- 非指定字段分组不能显示字段
如:(指定字段分组是deptno字段,但不能显示empno字段)
SELECT empno , SUM(sal) FROM emp2 GROUP BY deptno; - 指定分组的字段可进行排序
WHERE和HAVING区别
WHERE语句:分组前进行过滤,不能使用聚合函数
HAVING语句:分组后进行过滤,可使用聚合函数
限制查询 (LIMIT)
限制查询结果的数量
SELECT 字段名1[,字段名2,...字段n] FROM 表名
LIMIT [(int)偏移量,](int)显示数;
# 查询 emp2表 sal最小5个
SELECT * FROM emp2 ORDER BY sal LIMIT 0 , 5;
# 查询 emp2表 sal最大5个
SELECT * FROM emp2 ORDER BY sal DESC LIMIT 0 , 5;
批量分页查询的情况
如果有大量数据比如:10页,每页有10条 ,共有100条!
第一页0,第二页10,第三页20····第九页90
pagelndex 页码数、pagesize 每页显示的条数
LIMIT (pageindex-1)*pagesize , pagesize;
别名
在查询数据时,可以为表和字段取别名,这个别名可以代替其指定的表和字段。
表别名
可以为表取一个别名,用这个别名来代替表的名称。别名格式:
SELECT (* | 字段) FROM 表名 别名 [...];
AS:用于指定表名的别名,它可以省略不写。
字段别名
为字段取一个别名,用这个别名来代替表的名称。别名格式:
SELECT (* | 字段名1 [别名][,字段名2[别名]····,字段名n[别名]]) FROM 表名 [...];
# 或者:
SELECT (* | 字段名1 [AS 别名][,字段名2[AS 别名]····,字段名n[AS 别名]]) FROM 表名 [...];
多表关系
多对一
在多对一的表关系中,应将外键建在多的一方
多对多
为了实现数据表多对多的关系,需要定义第三方中间表来保存两个关系表的外键
一对一
一对一的对应关系中,需要分清主从关系,通常在从表中建立外键
表创建及测试调用例子 复制粘贴即可
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for category
-- ----------------------------
DROP TABLE IF EXISTS `category`;
CREATE TABLE `category` (
`cid` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`cname` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of category
-- ----------------------------
INSERT INTO `category` VALUES ('c001', '电器');
INSERT INTO `category` VALUES ('c002', '服饰');
INSERT INTO `category` VALUES ('c003', '化妆品');
INSERT INTO `category` VALUES ('c004', '书籍');
-- ----------------------------
-- Table structure for class
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
`classid` int(0) NOT NULL AUTO_INCREMENT,
`classname` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`classid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of class
-- ----------------------------
INSERT INTO `class` VALUES (1, '红龙班');
INSERT INTO `class` VALUES (2, '卫冕班');
INSERT INTO `class` VALUES (3, '神州班');
INSERT INTO `class` VALUES (4, '航天班');
-- ----------------------------
-- Table structure for orderitem
-- ----------------------------
DROP TABLE IF EXISTS `orderitem`;
CREATE TABLE `orderitem` (
`oid` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`pid` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of orderitem
-- ----------------------------
-- ----------------------------
-- Table structure for orders
-- ----------------------------
DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders` (
`oid` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`totalprice` double NULL DEFAULT NULL,
`uid` int(0) NULL DEFAULT NULL,
PRIMARY KEY (`oid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of orders
-- ----------------------------
-- ----------------------------
-- Table structure for products
-- ----------------------------
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
`pid` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`price` double NULL DEFAULT NULL,
`category_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`pid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of products
-- ----------------------------
INSERT INTO `products` VALUES ('p001', '联\r\n想', 5000, 'c001');
INSERT INTO `products` VALUES ('p002', '海\r\n尔', 3000, 'c001');
INSERT INTO `products` VALUES ('p003', '雷\r\n神', 5000, 'c001');
INSERT INTO `products` VALUES ('p004', 'JACK\r\nJONES', 800, 'c002');
INSERT INTO `products` VALUES ('p005', '真维\r\n斯', 200, 'c002');
INSERT INTO `products` VALUES ('p006', '花花公\r\n子', 440, 'c002');
INSERT INTO `products` VALUES ('p007', '劲\r\n霸', 2000, 'c002');
INSERT INTO `products` VALUES ('p008', '香奈\r\n儿', 800, 'c003');
INSERT INTO `products` VALUES ('p009', '相宜本\r\n草', 200, 'c003');
INSERT INTO `products` VALUES ('p010', '梅明\r\n子', 200, NULL);
-- ----------------------------
-- Table structure for scores
-- ----------------------------
DROP TABLE IF EXISTS `scores`;
CREATE TABLE `scores` (
`sid` int(0) NOT NULL AUTO_INCREMENT,
`score` int(0) NULL DEFAULT NULL,
`subjectid` int(0) NULL DEFAULT NULL,
`studentid` int(0) NULL DEFAULT NULL,
PRIMARY KEY (`sid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of scores
-- ----------------------------
INSERT INTO `scores` VALUES (1, 43, 1, 1);
INSERT INTO `scores` VALUES (2, 100, 2, 1);
INSERT INTO `scores` VALUES (3, 54, 3, 1);
INSERT INTO `scores` VALUES (4, 34, 1, 2);
INSERT INTO `scores` VALUES (5, 52, 2, 2);
INSERT INTO `scores` VALUES (6, 32, 3, 2);
INSERT INTO `scores` VALUES (7, 41, 1, 3);
INSERT INTO `scores` VALUES (8, 86, 3, 3);
INSERT INTO `scores` VALUES (9, 98, 2, 3);
INSERT INTO `scores` VALUES (10, 78, 3, 4);
INSERT INTO `scores` VALUES (11, 76, 2, 4);
INSERT INTO `scores` VALUES (12, 54, 1, 4);
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`studentid` int(0) NOT NULL AUTO_INCREMENT,
`studentname` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`password` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`sex` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`classid` int(0) NULL DEFAULT NULL,
`test` int(0) NULL DEFAULT NULL,
PRIMARY KEY (`studentid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '黑猫', '111111', '女', 1, 10);
INSERT INTO `student` VALUES (2, '大鲸', '2222', '男', 3, 20);
INSERT INTO `student` VALUES (3, '白兔', '3333', '女', 3, 30);
INSERT INTO `student` VALUES (4, '柏竹', '4444', '男', NULL, 40);
INSERT INTO `student` VALUES (5, '棕熊', '5555', '男', 5, 50);
INSERT INTO `student` VALUES (6, '智乃', '6666', '女', 3, 60);
INSERT INTO `student` VALUES (7, '蕾姆', '7777', '女', 2, 70);
INSERT INTO `student` VALUES (8, '艾米', '8888', '女', 1, 80);
INSERT INTO `student` VALUES (9, '纱雾', '9999', '女', 2, 90);
-- ----------------------------
-- Table structure for subject
-- ----------------------------
DROP TABLE IF EXISTS `subject`;
CREATE TABLE `subject` (
`subjectid` int(0) NOT NULL AUTO_INCREMENT,
`subjectname` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`subjectid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of subject
-- ----------------------------
INSERT INTO `subject` VALUES (1, 'Java');
INSERT INTO `subject` VALUES (2, 'MySQL');
INSERT INTO `subject` VALUES (3, 'HTML');
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`userid` int(0) NULL DEFAULT NULL,
`username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`upass` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of users
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1;
合并结果集 (UNION)
连接查询的过程中,通过添加过滤条件来限制查询结果,使查询结果更加精确(ALL去除重复的记录)
SELECT {
* | 查询字段} FROM 表1 UNION [ALL]
SELECT {
* | 查询字段} FROM 表2;
# 合并两表数据
SELECT studentid,studentname FROM student UNION
SELECT subjectid,subjectname FROM subject;
注意: 合并前提必须将两表的列数和类型一致
内连接 (INNER JOIN)
内连接使用 比较运算符,对两表中指定字段值进行比较,列出与连接条件匹配的数据行 ,字段值符合匹配的进行连接,组合成新的记录(无视不匹配的字段)
SELECT {
* | 查询字段} FROM 表1 INNER JOIN 表2 ON {表1.关系字段 = 表2.关系字段 | WHERE 条件表达式} ;
# 或者(简写)
SELECT {
* | 查询字段} FROM 表1,表2 WHERE 表1.关系字段 = 表2.关系字段;
# 查询 与班关联的学生(已经分配班级的学生)
SELECT * FROM student JOIN class ON student.classid = class.classid;
# 查询花子所有成绩
SELECT subjectname,score
FROM
scores , subject , student
WHERE
scores.subjectid = subject.subjectid
AND scores.studentid = student.studentid
AND student.studentname = '花儿';
# 查询 所有科目的平均值
SELECT subjectname , AVG( score )
FROM
scores JOIN subject
ON scores.subjectid = subject.subjectid
GROUP BY
subjectname;
外连接 (OUTER JOIN)
外连接 弥补了内连接查询不匹配的条件,查出不满足条件的可能
外连接包括: 左连接、右连接
左连接
指定左表的所有记录,所有满足连接条件的记录。如果左表的某条记录在右表中不存在,则在右表中显示为空值
右连接
右连接与左连接正好相反
SELECT {
* | 查询字段} FROM 表1 { LEFT | RIGHT } JOIN 表2 ON 表1.字段 = 表2.字段;
# 左外连接
SELECT 字段 FROM 主表 LEFT JOIN 次表 ON 主表.字段 = 次表.字段;
# 右外连接
SELECT 字段 FROM 主表 RIGHT JOIN 次表 ON 主表.字段 = 次表.字段;
# 左外查询
SELECT * FROM
student LEFT JOIN class
ON student.classid = class.classid;
# 右外查询
SELECT * FROM
student RIGHT JOIN class
ON student.classid = class.classid;
注意: 主表会显示所有字段,空值或不匹配条件的字段均可查询!!!
连接查询(CROSS JOIN)
交叉连接又称 笛卡尔积 ,返回结果的是 被连接的两个表中所有字段行乘积
SELECT {
* | 查询字段} FROM 表1 CROSS JOIN 表2 [WHERE 条件表达式];
# 或者(简写)
SELECT {
* | 查询字段} FROM 表1,表2 [WHERE 条件表达式];
# 将学生与班级交叉查询
SELECT * FROM student CROSS JOIN class;
自然连接(NATURAL JOIN)
特殊的等值连接,前提两表字段属性必须相同,且字段名也要相同,无须添加连接条件,得出的结果是消除重复的字段
SELECT {
* | 查询字段} FROM 表1 NATURAL JOIN 表2;
# 查询学生所在的班级
SELECT * FROM student NATURAL JOIN class;
子查询
子查询是指一个查询语句 嵌套在另一个 查询语句内部的查询
在执行查询语句时,首先会执行子查询中的语句,然后将返回的结果作为外层查询的过滤条件,子查询必须返回是一个字段数据
IN
内层查询语句仅仅返回一个数据字段,数据字段中的值将供外层查询语句进行比较操作
SELECT {
* | 查询字段} FROM 表名1 WHERE 字段 [NOT] IN(SELECT 字段 FROM 表名2 WHERE 条件表达式);
# 查询 三班有多少女生
SELECT studentname FROM student
WHERE
classid IN(SELECT classid FROM class WHERE classid = 3)
AND sex = '女';
# 查询 与‘智乃’同一个班的学生
SELECT studentname FROM student
WHERE
classid IN( SELECT classid FROM student WHERE studentname = '智乃' );
注意: IN 后面子查询返回结果要和IN前的字段匹配
EXISTS
参数可以是任意一个子查询, 这个子查询的作用相当于测试,返回 布尔值 , 如果 TRUE 外层查询才会执行
SELECT {
* | 查询字段} FROM 表名1 WHERE [NOT] EXISTS (SELECT 字段 FROM 表名2 WHERE 条件表达式);
# 测试 两表关系(匹配显示,不匹配不显示)
SELECT
studentid,
studentname
FROM student WHERE
EXISTS ( SELECT * FROM class WHERE class.classid = student.classid );
ANY
满足任意一个条件,子查询返回的字段列表进行比较,将不匹配的过滤
SELECT * FROM 表名 WHERE [NOT] 字段 {比较运算符} ANY(SELECT 字段 FROM 表名);
# 查询 已经分配班级的学生
SELECT classid,studentname FROM student
WHERE
classid = ANY(SELECT classid FROM class);
#或 (结果一样)
SELECT classid,studentname FROM student
WHERE
classid IN( SELECT classid FROM class);
ALL
子查询返回的字段列表结果需同时满足所有内层查询条件,否则查询为空
比较运算符} ALL(SELECT 字段 FROM 表名)
# 查询 test 高于蕾姆的同学
SELECT studentname,test FROM student
WHERE
test > ALL(SELECT test FROM student WHERE studentname = '蕾姆');
# 查询 匹配错班级的同学(数据错乱)
SELECT classid,studentname FROM student
WHERE
classid > ALL(SELECT classid FROM class);
#或 (结果一样)
SELECT classid,studentname FROM student
WHERE
classid NOT IN( SELECT classid FROM class);
比较运算符
ANY 和 ALL 都用到比较运算符,但还可以使用其他运算符
SELECT * FROM 表名 WHERE [NOT] 字段 {比较运算符} (SELECT 字段 FROM 表名)
查询优化
- 避免全表扫描,应先考虑 where 及 order by 涉及的列上建立索引
- 避免 where语句 中的字段进行
null值
判断 - 避免 where语句 中使用
!=
或<
/>
操作符 - 避免 where语句 使用
OR
连接条件 - 谨慎使用
IN
/NOT IN
进行查询,连续数字可使用BETWEEN
范围查询
完整性
保证了数据的有效性和准确性,以防止数据表中插入错误的数据
约束条件 | 说明 |
---|---|
PRIMARY KEY | 主键约束,用于唯一标识对应的记录 |
FOREIGN KEY | 外键约束 |
NOT NULL | 非空约束 |
UNIQUE [KEY] | 唯一性约束 |
DEFAULT | 默认值约束,用于设置字段的默认值 |
AUTO_INCREMENT | 自动增长 |
FOREIGN KEY | 外键约束 |
CHECK | 约束取值范围 |
UNSIGNED | 无符号约束 |
注意: 多个约束需要空格分隔
实体完整性
单字段主键
每表只有一个主键,唯一性,不能NULL,可创建联合主键
字段名 数据类型 PRIMARY KEY[(字段名1,字段名2,···字段名n)];
ALTER TABLE student ADD PRIMARY KEY[(字段名1,字段名2,···字段名n)]
唯一约束
数据不能重复,只能有一次为空
字段名 数据类型 UNIQUE;
字段自动增加
在数据表中,若想为表中插入的新记录自动生成唯一的 ID,可以使用自增约束来实现
字段名 数据类型 AUTO_INCREMENT;
域完整性
数据类型
非空约束
字段的值不能为NULL(空)
字段名 数据类型 NOT NULL;
默认约束
新添数据时,如果未赋值,则自动插入默认值
字段名 数据类型 DEFAULT(默认值);
无符号约束
字段名 数据类型 UNSIGNED;
约束范围
字段名 数据类型 CHECK (字段值>0 and 字段值<=100);
引用完整性
外键约束
外键是指引用另一个表中的一个字段或多个字段。建立、加强两表数据之间的链接
创建表时 定义外键:
# 从表
CREATE TABLE 表名(
字段名1 数据类型 [完整性约束条件],
字段名2 数据类型 [完整性约束条件],
·······
FOREIGN KEY (外键字段) REFERENCES 主表( 主表的 主键 / 唯一 字段 )
);
创建表后 定义外键:
ALTER TABLE 从表 ADD CONSTRAINT 自定义外键名 FOREIGN KEY(从表 外键字段) REFERENCES 主表( 主表的 主键 / 唯一 字段 );
外键删除
根据逻辑的需求,需要解除两个表之间的关联关系时,就需要删除外键约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
注意:
- 主表是被外键引用的字段,且该字段有 主键约束 或 唯一性约束
- 被引用的是 主表,引用 的是 从表,两表是主从关系
- 引入外键后,从表 外键字段 只能插入主表被引用的字段值
- 如果想删除 主表 一条记录,则必须确保 从表外键字段是否引用到主表字段值,确保数据的完整性
- 建立外键的表必须是InnoDB型不能是临时表。因为MySQL中只有InnoDB型的表才支持外键
- 定义外键名时,不能加引号。如: constraint ‘FK_ ID’ 或constraint" FK_ID "都是错误的
函数
数学函数
函数名称 | 作用 |
---|---|
ABS(x) | 返回x的绝对值 |
SQRT(x) | 返回x的非负2次方根 |
MOD(x , y) | 返回x被y除后的余数 |
CEILING(x) | 返回不小于x的最小整数 |
FLOOR(x) | 返回不大于x的最大整数 |
ROUND(x , y) | 对x进行四舍五入操作,小数点后保留y位 |
TRUNCATE(x) | 舍去x中小数点y位后面的的数 |
SIGN(x) | 返回x的符号,-1、0或者1 |
字符串函数
函数名称 | 作用 |
---|---|
LENGTH(str) | 返回字符串str的长度 |
CONCAT(s1 , s2 , …) | 返回一个或者多个字符串连接产生的新的字符串 |
TRIM(str) | 删除字符串两侧的空格 |
REPLACE(str , s1 , s2) | 使用字符串s2替换字符串str中所有的字符串s1 |
SUBSTRING(tr , n , len) | 返回字符串st的子串,起始位置为n,长度为len |
REVERSE(str) | 返回字符串反转后的结果 |
LOCATE(s1 , str) | 返回子串s1在字符串str中的起始位置 |
日期与时间的函数
函数名称 | 作用 |
---|---|
CURDATE() | 获取 系统当前日期 |
CURTIME() | 获取 系统当前时间 |
SYSDATE() | 获取 当前系统日期和时间 |
DATE_ADD(now() , INTERVAL num {时间单位}) | 指定过去或未来时间点(num是对现在的时间进行相加) |
DATEDIFF(d1 , d2) | 计算 两时间 间隔的天数(从0000.1.1开始 n 天后的日期) |
FROM_DAYS(day) | 计算 时间 得出日期 (从0000.1.1开始 n 天后的日期) |
YEAR(d) | 获取 日期年份 |
MONTH(d) | 获取 日期月份 |
DAY(d) | 获取 日期 日 |
条件判断函数
函数名称 | 作用 |
---|---|
IF(expr , v1 , v2) | 如果expr表达式为true返回v1,否则返回v2 |
IFNULL(v1 , v2) | 如果v1不为NULL返回v1,否则返回v2 |
CASE expr WHEN v1 THEN r1 [WHEN v2 THEN r2…] [ELSE m] END | 如果expr值等于v1、v2等,则返回对应位置THEN后面的结果,否则返回ELSE后的结果m |
加密函数
函数名称 | 作用 |
---|---|
MD5(str) | 对字符串 str 进行MD5加密 |
ENCODE(str , pwd stu) | 使用pwd作为密码加密字符串str |
DECODE(str , pwd str) | 使用pwd作为密码解密字符串str |