提交学习笔记专用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

528 lines
16 KiB

  1. # 10.29MySQL学习笔记
  2. ## 1.分类
  3. - DDL: 数据定义语言,用来定义数据库对象(数据库、表、字段)
  4. - DML: 数据操作语言,用来对数据库表中的数据进行增删改
  5. - DQL: 数据查询语言,用来查询数据库中表的记录
  6. - DCL: 数据控制语言,用来创建数据库用户、控制数据库的控制权限
  7. ## 2.数据库操作
  8. ### 2.1查看数据库
  9. ```java
  10. # 查看所有的数据库
  11. mysql> SHOW DATABASES;
  12. ```
  13. ## 3.表操作(DDL)
  14. DDL是对表的结构进行操作
  15. ### 3.1数据类型
  16. #### 3.1.1 数值
  17. | 类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
  18. | ------------ | --------------------------------- | --------------------------------------------- | --------------------------- | ---------------------------------------- |
  19. | INT | 4 字节 | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) | 大整数值 |
  20. | DOUBLE | 8 字节 | (-1.797E+308,-2.22E-308) | (0,2.22E-308,1.797E+308) | 双精度浮点数值 |
  21. | DOUBLE(M,D) | 8个字节,M表示长度,D表示小数位数 | 同上,受M和D的约束 DOUBLE(5,2) -999.99-999.99 | 同上,受M和D的约束 | 双精度浮点数值 |
  22. | DECIMAL(M,D) | DECIMAL(M,D) | 依赖于M和D的值,M最大值为65 | 依赖于M和D的值,M最大值为65 | 小数值,和钱相关,不会出现精度缺失的问题 |
  23. #### 3.1.2字符串
  24. | 类型 | 大小 | 用途 |
  25. | --------------------------- | ------------ | ----------------------------- |
  26. | CHAR | 0-255字符 | 定长字符串CHAR(10)10个字符 |
  27. | VARCHAR | 0-65535 字节 | 变长字符串VARCHAR(10)10个字符 |
  28. | BLOB(binary large object) | 0-65535字节 | 二进制形式的长文本数据 |
  29. | TEXT | 0-65535字节 | 长文本数据 |
  30. #### 3.1.3、日期时间类型
  31. | 类型 | 大小 | 范围 | 格式 | 用途 |
  32. | --------- | :--- | ------------------------------------------------------------ | ------------------- | ------------------------ |
  33. | DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
  34. | TIME | 3 | '-838:59:59'/'838:59:59' | HH:MM:SS | 时间值或持续时间 |
  35. | YEAR | 1 | 1901/2155 | YYYY | 年份值 |
  36. | DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
  37. | TIMESTAMP | 4 | 1970-01-01 00:00:00/2038 结束时间是第 **2147483647** 秒北京时间 **2038-1-19 11:14:07**,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 |
  38. ### 3.2创建表
  39. ```sql
  40. CREATE TABLE [IF NOT EXISTS] 表名(
  41. 列名 数据类型 [约束],
  42. 列名 数据类型 [约束],
  43. 列名 数据类型 [约束] //最后一列的末尾不加逗号
  44. )[CHARSET=utf8]; //可根据需要指定表的字符编码集
  45. ```
  46. ### 3.3查看表
  47. ```sql
  48. # 查看当前数据库中所有表名称
  49. SHOW TABLES;
  50. # 查看指定表的创建语句
  51. SHOW CREATE TABLE 表名;
  52. # 查看表结构
  53. DESC 表名;
  54. ```
  55. ### 3.4修改表
  56. ```sql
  57. # 添加列
  58. ALTER TABLE 表名 ADD (
  59. 列名 列类型,
  60. 列名 列类型
  61. )
  62. # 修改列类型(如果被修改的列已存在数据,那么新的类型可能会影响到已存在数据), 修改表中的某列时,也要写全列的名字,数据类型,约束
  63. ALTER TABLE 表名 MODIFY 列名 列类型;
  64. # 修改列名, 在给定列新名称时,要指定列的类型和约束
  65. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型;
  66. # 删除列, 删除列时,每次只能删除一列
  67. ALTER TABLE 表名 DROP 列名;
  68. # 修改表名称
  69. ALTER TABLE 原表名 RENAME TO 新表名;
  70. ALTER TABLE 原表名 RENAME 新表名;
  71. ```
  72. ### 3.5删除表
  73. ```sql
  74. DROP TABLE 表名;
  75. ```
  76. ## 4.DML
  77. DML就是对表的内容进行操作
  78. ### 4.1插入
  79. 基本格式:
  80. ```sql
  81. INSERT INTO 表名(列名1, 列名2, ...) VALUES(列值1, 列值2, ...);
  82. 或者
  83. INSERT INTO 表名 VALUES(列值1, 列值2, ...);
  84. ```
  85. ### 4.2修改
  86. ```sql
  87. # WHERE条件是可选的, 如果没有条件, 就修改所有记录, 多数时候我们都加上WHERE条件
  88. UPDATE 表名 SET 列名1=列值1, 列名2=列值2, ...[WHERE 条件]
  89. ```
  90. ### 4.3删除
  91. ```sql
  92. # WHERE条件是可选的, 如果没有条件, 就删除所有记录, 多数时候我们都加上WHERE条件
  93. DELETE FROM 表名 [WHERE 条件];
  94. ```
  95. ### 4.4约束
  96. #### 4.4.1主键约束
  97. ```sql
  98. # 创建表时指定主键
  99. CREATE TABLE 表名(
  100. 列名 数据类型 PRIMARY KEY,
  101. 列名 数据类型,
  102. 列名 数据类型
  103. );
  104. # 创建表时指定主键
  105. CREATE TABLE 表名(
  106. 列名 数据类型,
  107. 列名 数据类型,
  108. 列名 数据类型,
  109. PRIMARY KEY(设置为主键的列名)
  110. );
  111. # 修改表时指定主键
  112. ALTER TABLE 表名 ADD PRIMARY KEY(列名);
  113. ALTER TABLE 表名 MODIFY 列名 列类型 PRIMARY KEY;
  114. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型 PRIMARY KEY;
  115. # 删除主键
  116. ALTER TABLE 表名 DROP PRIMARY KEY;
  117. ```
  118. 主键自增长:
  119. ```sql
  120. # 创建表时指定主键
  121. CREATE TABLE 表名(
  122. 列名 数据类型 PRIMARY KEY AUTO_INCREMENT,
  123. 列名 数据类型,
  124. 列名 数据类型
  125. );
  126. # 修改表时设置主键自增长
  127. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型 PRIMARY KEY AUTO_INCREMENT;
  128. ALTER TABLE 表名 MODIFY 列名 列类型 PRIMARY KEY AUTO_INCREMENT;
  129. # 修改表时删除主键自增长
  130. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型;
  131. ```
  132. #### 4.4.2唯一约束
  133. ```sql
  134. # 创建表时指定唯一约束
  135. CREATE TABLE 表名(
  136. 列名 数据类型 UNIQUE,
  137. 列名 数据类型,
  138. 列名 数据类型
  139. );
  140. # 修改表时设置唯一约束
  141. ALTER TABLE 表名 MODIFY 列名 列类型 UNIQUE;
  142. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型 UNIQUE;
  143. # 删除唯一约束
  144. ALTER TABLE 表名 DROP INDEX name;
  145. ```
  146. #### 4.4.3非空约束
  147. ```sql
  148. # 创建表时指定非空约束
  149. CREATE TABLE 表名(
  150. 列名 数据类型 NOT NULL,
  151. 列名 数据类型,
  152. 列名 数据类型
  153. );
  154. # 修改表时设置非空约束
  155. ALTER TABLE 表名 MODIFY 列名 列类型 NOT NULL;
  156. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型 NOT NULL;
  157. # 删除非空约束
  158. ALTER TABLE 表名 MODIFY 列名 列类型;
  159. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型;
  160. ```
  161. #### 4.4.4默认值
  162. ```sql
  163. # 创建表时指定默认值
  164. CREATE TABLE 表名(
  165. 列名 数据类型 DEFAULT 默认值,
  166. 列名 数据类型,
  167. 列名 数据类型
  168. );
  169. # 修改表时设置默认值
  170. ALTER TABLE 表名 MODIFY 列名 列类型 DEFAULT 默认值;
  171. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型 DEFAULT 默认值;
  172. # 删除默认值
  173. ALTER TABLE 表名 MODIFY 列名 列类型;
  174. ALTER TABLE 表名 CHANGE 原列名 新列名 列类型;
  175. ```
  176. #### 4.4.5外键约束
  177. ## 5.DQL
  178. 查询操作:所有操作中使用最频繁
  179. ### 5.1单表查询
  180. ```sql
  181. # 查询指定列
  182. SELECT 列1 [, 列2, ...列N] FROM 表名;
  183. #去重查询
  184. SELECT DISTINCT 列1 [, 列2, ...列N] FROM 表名;
  185. ```
  186. ### 5.2列运算
  187. ```sql
  188. # 列可以进行加、减、乘、除运算
  189. 如:SELECT ename, sal*1.5 FROM emp;
  190. # 格式:列名 AS 别名
  191. # AS也可以省略,格式:列名 别名
  192. # 查询所有员工的姓名和总工资(工资加奖金, 如果奖金为NULL则按照奖金为0进行运算)
  193. SELECT ename AS '姓名', sal+IFNULL(comm, 0) AS '总工资' FROM emp;
  194. SELECT ename '姓名', sal+IFNULL(comm, 0) '总工资' FROM emp;
  195. # 除了可以给列起别名,也可以给表起别名,在多表查询中会使用到为表起别名
  196. ```
  197. ### 5.3条件查询
  198. 主要使用where连接
  199. ```sql
  200. # 查询部门编号为20的所有员工的信息
  201. SELECT * FROM emp WHERE deptno=20
  202. # 查询工种为工程师的所有员工的信息
  203. SELECT * FROM emp WHERE job='工程师'
  204. # 查询有奖金的所有员工的信息
  205. SELECT * FROM emp WHERE comm IS NOT NULL and comm <> 0;
  206. SELECT * FROM emp WHERE comm IS NOT NULL and comm != 0;
  207. ```
  208. ### 5.4模糊查询
  209. > "_"匹配一个任意字符,只匹配一个字符而不是多个
  210. >
  211. > "%"匹配0~N个任意字符
  212. >
  213. > 模糊查询需要使用运算符:LIKE
  214. ```sql
  215. # 查询姓“周”的所有员工的信息
  216. SELECT * FROM emp WHERE ename LIKE '周%';
  217. # 查询姓名中包含“杰”的所有员工的信息
  218. SELECT * FROM emp WHERE ename LIKE '%杰%';
  219. # 查询姓“周”并且姓名只有三个字的所有员工的信息
  220. SELECT * FROM emp WHERE ename LIKE '周__';
  221. ```
  222. ### 5.5排序
  223. > 对查询的结果进行排序
  224. >
  225. > 排序分成升序(ASC)和降序(DESC),可以使用多列作为排序条件
  226. >
  227. > 排序使用关键字ORDER BY
  228. ```sql
  229. # 排序
  230. # 规则:列名 升序/降序
  231. SELECT 列1, 列2, 列3 FROM 表名 WHERE 条件 ORDER BY 规则1, 规则2,....,规则n 
  232. # 查询所有员工信息,按照工号升序排列
  233. SELECT * FROM emp ORDER BY empno ASC;
  234. # 如果是升序,ASC可以省略
  235. SELECT * FROM emp ORDER BY empno;
  236. 多个排序规则就按顺序执行
  237. SELECT * FROM emp ORDER BY sal ASC, empno DESC;
  238. ```
  239. ### 5.6聚合函数
  240. > | 函数 | 功能 |
  241. > | ----- | -------- |
  242. > | COUNT | 计算个数 |
  243. > | MAX | 最大值 |
  244. > | MIN | 最小值 |
  245. > | AVG | 平均值 |
  246. > | SUM | 和 |
  247. 例如:
  248. ```sql
  249. # 查询公司员工个数
  250. SELECT count(1) FROM emp;
  251. SELECT count(*) FROM emp;
  252. # 查询公司最高工资
  253. SELECT MAX(sal) FROM emp;
  254. # 查询公司最低工资
  255. SELECT MIN(sal) FROM emp;
  256. # 查询公司所有员工工资和
  257. SELECT SUM(sal) FROM emp;
  258. # 查询公司员工工资的平均值
  259. SELECT AVG(sal) FROM emp;
  260. ```
  261. ### 5.7分组查询
  262. >主要使用GROUP BY关键字
  263. 例如:
  264. ```sql
  265. # 查询每个工种的平均工资
  266. SELECT job, AVG(sal) FROM emp GROUP BY job;
  267. # 查询每个工种的员工数量
  268. SELECT job, COUNT(1) FROM emp GROUP BY job;
  269. ```
  270. 分组查询设置条件的话,分组前的条件使用where,分组后的条件使用having
  271. ```sql
  272. # 查询工资大于15000的员工的工种,以及工种的平均工资
  273. SELECT job, AVG(sal) FROM emp WHERE sal>15000 GROUP BY job;
  274. # 查询工资大于15000的员工的工种,以及工种的平均工资,只显示超过两人的工种
  275. SELECT job, AVG(sal) FROM emp WHERE sal>15000 GROUP BY job HAVING COUNT(*)>=2;
  276. ```
  277. ### 5.8Limit子句
  278. >主要用于分页查询
  279. ```sql
  280. # 语法
  281. SELECT 列名 FROM 表名 LIMIT 起始行,查询行数;
  282. # 查询员工表中前五名员工的所有信息
  283. # 起始行是从 0 开始,代表了第一行
  284. SELECT * FROM emp LIMIT 0, 5;
  285. #查询员工表中从第4条开始,查询10行
  286. SELECT * FROM emp LIMIT 3,10;
  287. ```
  288. ### 5.9 多表查询
  289. #### 5.9.1合并结果集
  290. > 合并结果集就是把两个select语句的查询结果合并到一起,结果集就是一个表格。
  291. >
  292. > 要求:被合并的两个结果:列数必须相同。
  293. ```sql
  294. # UNION:去除重复记录
  295. SELECT * FROM t1 UNION SELECT * FROM t2;
  296. # UNION ALL:不去除重复记录
  297. SELECT * FROM t1 UNION ALL SELECT * FROM t2;
  298. ```
  299. #### 5.9.2内连接
  300. ```sql
  301. # 方式1(MySQL特有,不符合SQL标准)
  302. SELECT 列名 FROM 表1, 表2 WHERE 表1.列名 条件运算符 表2.列名 [AND 条件];
  303. # 方式2(符合SQL标准)
  304. SELECT 列名 FROM 表1 INNER JOIN 表2 ON 表1.列名 条件运算符 表2.列名 [WHERE 条件];
  305. ```
  306. ```
  307. # 列出员工的姓名和部门名称
  308. SELECT e.ename, d.dname FROM emp e, dept d WHERE e.deptno=d.deptno;
  309. SELECT e.ename, d.dname FROM emp e INNER JOIN dept d ON e.deptno=d.deptno;
  310. ```
  311. > 上面的查询只能查询出拥有部门的员工和拥有员工的部门,没有部门的员工和没有员工的部门是查询不到的。如果要将所有的员工和部门都查询出来需要使用外连接。
  312. #### 5.9.3外连接
  313. > 结果集中包含主表所有数据行,如果主表的某行在从表中没有匹配行时,则从表的选择列为NULL值。
  314. ##### 5.9.3.1左外链接
  315. > 左外连接是以左表为主表,去关联右表(从表),**结果集中包含主表所有数据行**,如果主表的某行在从表中没有匹配行时,则从表的选择列为NULL值。
  316. ```sql
  317. # 语法
  318. SELECT 列名 FROM 左表 LEFT [OUTER] JOIN 右表 ON 左表.列名 条件运算符 右表.列名 [WHERE 条件];
  319. # 列出员工的姓名和部门名称, 包括没有部门的员工
  320. SELECT e.ename, d.dname FROM emp e LEFT JOIN dept d ON e.deptno=d.deptno;
  321. # 列出员工的姓名和部门名称, 包括没有员工的部门
  322. SELECT e.ename, d.dname FROM dept d LEFT JOIN emp e ON e.deptno=d.deptno;
  323. ```
  324. ##### 5.9.3.2右外连接
  325. > 右外连接是以右表为主表,去关联左表(从表),**结果集中包含主表所有数据行**,如果主表的某行在从表中没有匹配行时,则从表的选择列为NULL值。
  326. ```sql
  327. # 语法
  328. SELECT 列名 FROM 左表 RIGHT [OUTER] JOIN 右表 ON 左表.列名 条件运算符 右表.列名 [WHERE 条件];
  329. # 列出员工的姓名和部门名称, 包括没有员工的部门
  330. SELECT e.ename, d.dname FROM emp e RIGHT JOIN dept d ON e.deptno=d.deptno;
  331. # 列出员工的姓名和部门名称, 包括没有部门的员工
  332. SELECT e.ename, d.dname FROM dept d RIGHT JOIN emp e ON e.deptno=d.deptno;
  333. ```
  334. ##### 5.9.3.3 全外连接
  335. > 完全连接左表和右表中所有行,当某行数据在另一个表中没有匹配时,则另一个表的选择列值为NULL。
  336. ```sql
  337. # 语法
  338. SELECT 列名 FROM 左表 FULL [OUTER] JOIN 右表 ON 左表.列名 条件运算符 右表.列名 [WHERE 条件]
  339. ```
  340. > MySQL不支持这种语法,可以使用合并结果集进行模拟全外连接。
  341. ```sql
  342. SELECT e.ename, d.dname FROM emp e LEFT JOIN dept d ON e.deptno=d.deptno
  343. UNION
  344. SELECT e.ename, d.dname FROM emp e RIGHT JOIN dept d ON e.deptno=d.deptno;
  345. ```
  346. ### 5.10子查询
  347. > 子查询出现的位置:
  348. >
  349. > - WHERE后,作为条件的一部分;
  350. > - FROM后,作为被查询的一条表。
  351. #### 5.10.1列子查询
  352. ```sql
  353. SELECT id,stu_id,`name`,(SELECT `class_name`FROM t_class WHERE id = class_id ) class_name,class_id,sex,birthday FROM t_student LIMIT 10;
  354. ```
  355. #### 5.10.2表子查询
  356. ```sql
  357. SELECT id,stu_id,`name`,pinyin,sex,birthday FROM (SELECT *FROM t_student WHERE sex = '女')t1;
  358. ```
  359. #### 5.10.3where之后
  360. ```sql
  361. -- 等号(不等号)子查询 要求子查询结果必须是一行一列
  362. SELECT id,stu_id,`name`,pinyin,sex,birthday FROM t_student
  363. WHERE class_id = (SELECT id FROM t_class WHERE class_name = '080503-JAVA');
  364. SELECT id,stu_id,`name`,pinyin,sex,birthday FROM t_student
  365. WHERE class_id != (SELECT id FROM t_class WHERE class_name = '080503-JAVA');
  366. -- 大于号子查询,小于号子查询
  367. SELECT id,stu_id,`name`,pinyin,sex,birthday,class_id FROM t_student
  368. WHERE class_id > ALL(SELECT id FROM t_class WHERE class_name LIKE '%JAVA%');
  369. SELECT id,stu_id,`name`,pinyin,sex,birthday,class_id FROM t_student
  370. WHERE class_id > ANY(SELECT id FROM t_class WHERE class_name = '080503-JAVA');
  371. -- 4.in 和not in 子查询
  372. SELECT id,stu_id,`name`,pinyin,sex,birthday,class_id FROM t_student WHERE id in(1,2,3);
  373. SELECT id,stu_id,`name`,pinyin,sex,birthday,class_id FROM t_student
  374. WHERE id in(SELECT id FROM t_class WHERE class_name LIKE '%JAVA%');
  375. ```
  376. #### 5.10.4exists
  377. ```sql
  378. SELECT id,stu_id,`name`,pinyin,sex,birthday,class_id FROM t_student
  379. WHERE EXISTS(SELECT id From t_class WHERE class_name LIKE '%JAVA%')
  380. ```