MySQL学习笔记
SQL和MySQL
SQL:结构化查询语言(Structured Query Language)
MySQL:一种DBMS(数据库管理系统),优点:简单、性能、免费、可信
虽然可以不使用主键,但是为了便于开发和管理我们应该总是定义主键
并且应遵循下列规则:
MySQL强制:
- 任意两行都不具有相同的主键值;
- 每个行都必须有一个主键值(NOT NULL);
好的习惯:
- 不更新主键列中的值;
- 不重用主键列中的值;
- 不在主键列中使用可能会更改的值;
不要用MySQL保留的关键字命名表和列。
MySQL命令
虽然没有规定大小写,但是将SQL关键字大写,将列名和表名等小写更加易于阅读和调试。
db_name:库名
tbl_name:表名
col_name:列名
查看信息
命令行登录MySQL:mysql -u username -p password -h server -P port
默认端口:3306
选择数据库:USE db_name;
(必须先用USE打开数据库才能读取其中的数据。)
查看版本:SELECT VERSION();
查看所有数据库:SHOW DATABASES;
查看数据库内所有的表:SHOW TABLES;快捷方式:DESC tbl_name;
查看表中的列:SHOW COLUMNS FROM tbl_name;
(包含字段名、数据类型、是否为NULL、键信息、默认值及其他信息)
(使用HELP SHOW查看可以SHOW的语句)
更改分隔符:DELIMITER //
数据检索
简单检索
检索单个列:SELECT col_name FROM tbl_name;
检索多个列:SELECT col_name1, col_name2 ... FROM tbl_name;
检索所有列:SELECT * FROM tbl_name;
(除非确实需要表中的每个列,否则最好不要使用*通配符,会降低性能)
筛除重复数据:SELECT DISTINCT col_name FROM tbl_name;
限制返回结果个数:SELECT col_name FROM tbl_name LIMIT x;(返回x条数据)
SELECT col_name FROM tbl_name LIMIT x,y;(返回x+1开始的y条数据)
排序检索
按某个列排序:SELECT col_name FROM tbl_name ORDER BY col_name;
多列排序:SELECT col_name1, col_name2 FROM tbl_name ORDER BY col_name1, col_name2;
(MySQL默认升序排列,加上DESC可降序排列)
过滤数据
按条件搜索:SELECT col_name FROM tbl_name WHERE id = 1;
SELECT col_name FROM tbl_name WHERE id BETWEEN a AND b;
(1、考虑到性能原因,最好在数据库层进行数据筛选和过滤而不是在应用层进行
2、ORDER BY要在WHERE子句后面,否则会报错
3、匹配时默认不区分大小写
4、检查空值时用 IS NULL)
WHERE子句操作符:
操作符 | 说明 |
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
BETWEEN | 在制定的两个值之间 |
AND操作符:SELECT col_name1 FROM tbl_name WHERE col_name2 = x AND col_name3 = y;(返回同时满足两个条件的数据,多个条件之间以AND连接)
OR操作符:SELECT col_name1 FROM tbl_name WHERE col_name2 = x OR col_name3 = y;(只要满足一个条件就返回,多个条件之间以OR连接)
(涉及顺序问题时用括号括起来的优先运算,否则按顺序运算)
IN操作符:SELECT col_name FROM tbl_name WHERE id IN (x,y,z);
(IN的优点:
1、语法清楚直观
2、计算顺序容易管理
3、比OR执行更快
4、可以嵌套其他SELECT语句)
NOT操作符:否定WHERE后面的条件,返回不满足条件的数据
通配符过滤:
- 百分号(%)通配符:SELECT col_name FROM tbl_name WHERE col_name LIKE 'x%';('x%':以x开头的任意字符;'%x':以x结尾的任意字符;'%x%':包含x的任意字符。通配符无法匹配NULL值)
- 下划线(_)通配符:用途与%一样,不过只匹配单个字符;
正则表达式过滤:将LIKE替换为REGEXP
聚集函数:
函数 | 说明 |
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
分组检索
创建分组:SELECT col_name FROM tbl_name GROUP BY col_name;
(要在GROUP BY中用SELECT中相同的条件,并且SELECT语句中的每个列都必须在GROUP BY子句中给出;GROUP BY必须在WHERE之后,ORDER BY之前)
过滤分组:SELECT col_name, COUNT(*) FROM tbl_name GROUP BY col_name HAVING COUNT(*) >= n;
WHERE+HAVING:SELECT col_name1, COUNT(*) AS c FROM tbl_name WHERE col_name2 > a GROUP BY col_name1 HAVING COUNT(*) > b;
(一般在使用GROUP BY子句时应该也给出ORDER BY子句,)
SELECT 子句顺序:SELECT - FROM - WHERE - GROUP BY - ORDER BY - LIMIT
子查询
查询的嵌套:对于能嵌套的子查询数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询。
相关子查询(完全限定的列名):表名和列名之间用"."隔开用于区分不同表之间相同的列名,如:tbl_name1.col_name = tbl_name2.col_name(在tbl_name1和tbl_name2这两个不同的表中都有col_name这个字段)
组合查询
- UNION必须由两条或以上SELECT语句组成,语句之间用UNION分隔
- UNION中每个查询都要包含相同的列、表达式、聚集函数(顺序不必相同)
- 列数据类型必须兼容,类型不必完全相同,但必须是DBMS可以转换的类型
- UNION默认会自动去除重复的数据,如果不想去除可以用UNION ALL
- UNION中只能在最后一个SELECT后使用一个ORDER BY语句,不允许使用多条ORDER BY子句
联结表
不要联结不必要的表,联结的表越多,性能下降越厉害。
内联结:SELECT * FROM tbl_name1, tbl_name2 WHERE tbl_name1.col_name = tbl_name2.colname;
SELECT * FROM tbl_name1 INNER JOIN tbl_name2 ON tbl_name1.col_name = tbl_name2.colname;
(上面两个结果一样,形式不同)
左联结:LEFT JOIN
右联结:RIGHT JOIN
(左联结返回左标所有的记录和右表中符合条件的记录,记录数和左标中的记录数相同,右联结则相反)
数据操作
插入数据
基本语法:INSERT INTO tbl_name(col1,col2,col3) VALUES(val1,val2,val3);
(如果列被定义为允许NULL或者有默认值,则在INSERT时可以不写该列)
插入多行:INSERT INTO tbl_name(col1,col2,col3) VALUES(val1,val2,val3), (val4,val5,val6);
(单条INSERT语句比多条INSERT快)
更新数据
UPDATE语句的组成:
1、要更新的表
2、列名和它们的新值
3、确定要更新行的过滤条件
基本语法:UPDATE tbl_name SET col_name1 = 'value' WHERE col_name2 = n;
更新多列:UPDATE tbl_name SET col_name1 = 'value1', col_name2 = 'value2' WHERE col_name3 = n;
删除数据
基本语法:DELETE FROM tbl_name WHERE col_name = x;
(TRUNCATE TABLE语句可以清空一张表中的数据)
创建表
基本语法:CREATE TABLE tbl_name
(
col1 int NOT NULL AUTO_INCREMENT,
col2 char(50) NOT NULL,
col3 char(50) NOT NULL DEFAULT n,
col4 char(50) NULL
)ENGINE=InnoDB;
(AUTO_INCREMENT 自增长,每个表只允许有一个
SELECT last_insert_id()可以获得最后一个自增长的ID)
更新表
基本语法:
- 增加一个列:ALTER TABLE tbl_name ADD col CHAR(20);
- 删除一个列:ALTER TABLE tbl_name DROP COLUMN col_name;
- 定义外键:ALTER TABLE tbl_name ADD CONSTRAINT fk_tbl_name FOREIGN KEY (col_name) REFERENCES tbl_name(col_name);
- 重命名表:RENAME TABLE tbl_name TO new_tbl_name;
删除表
语法:DROP TABLE tbl_name;
事务
事务处理
MyISAM不支持事务,InnoDB支持事务,这就是为什么一般项目中用InnoDB比较多的原因。
术语:
- 事务(transaction)
- 回退(rollback)
- 提交(commit)
- 保留点(savepoint)
控制事务处理
标识事务的开始:START TRANSACTION;
撤销MySQL语句:ROLLBACK;
(事务处理用来管理INSERT/UPDATE/ELETE语句,无法回退SELECT语句,也无法回退CREATE或DROP操作)
提交事务:COMMIT
(普通操作时数据库会自动提交,但在事务操作中需要显式地使用COMMIT来提交)
保留点:SAVEPOINT sp_name;
ROLLBACK TO sp_name;
(就像存档点一样,事务发生回滚时退到这个地方,执行一条ROLLBACK或COMMIT后自动释放保留点,也可以用RELEASE SAVEPOINT手动释放)
设置自动提交:SET autocommit = true/false;
(针对每个连接而不是服务器)
其他知识
视图
视图就是把一些复杂的查询封装起来以便其他SELECT语句调用,视图不是数据,而是一些SQL语句的集合。
使用视图的好处:
- 重用SQL语句
- 简化复杂的SQL操作
- 保护数据
- 更改数据格式和表示
视图的规则和限制:
- 视图必须唯一命名
- 数目没有限制
- 创建视图需要权限
- 视图可以嵌套
- ORDER BY可以用在视图中
- 视图不能索引
- 可以和表一起使用
使用方法:
- 创建:CREATE VIEW view_name;
- 查看:SHOW CREATE VIEW view_name;
- 删除:DROP VIEW view_name;
- 更新视图:先DROP再CREATE或者用CREATE OR REPLACE VIEW;
(一般应该将视图用于检索(SELECT),而不用于更新(INSERT/UPDATE/DELETE))
存储过程
就像函数一样,难以维护,一般不用
游标
只能用于存储过程,难以维护,一般不用
触发器
触发器是MySQL响应DELETE/INSERT/UPDATE语句而自动执行的一条MySQL语句。