赞
踩
介绍几个数据库的概念
SQL语言分类
DBMS可分为两类
MySQL版本
MySQL工具
mysql -u 登录名 -p 端口号 -h 主机名 -P 密码 # 默认的可以省略
选择数据库
USE 数据库名称
了解数据库和表
- SHOW DATABASES # 返回可用数据库的一个列表
- SHOW TABLES # 返回当前选择的数据库内可用表的列表
- SHOW COLUMNS FROM 表名 # 显示指定表的所有列信息
SQL语句不区分大小写,可以对关键字使用大写,对表名和列使用小写
SELECT * FROM admin_user LIMIT 2 OFFSET 1
ORDER BY :A 被视为与 a 相同
- -- LIMIT 与 ORDER BY 语句顺序不能改变
- SELECT * FROM admin_user ORDER BY username LIMIT 1
比较 NULL < ' '(空格) 总是在 '' (空字符串)前 < 数字 < 中文
SELECT * FROM admin_user ORDER BY email asc
1简单使用
SELECT * FROM admin_user WHERE username = 'ADMIN' ORDER BY username LIMIT 2
2 使用以下语句期望可以将为 NULL 的值查出来,但实际不可以
SELECT * FROM admin_user WHERE gender != 0
3 使用 NULL 时需要注意,它只能使用 IS / IS NOT 来过滤
- SELECT * FROM admin_user WHERE IFNULL(gender,0) = 0
- SELECT * FROM admin_user WHERE IFNULL(gender,0) != 1
4 注意空格,= ‘’ 或者 = ‘ ’ 可以匹配带空格或不带空格的非 NULL 值
1 AND 比 OR 的优先级高
SELECT * FROM admin_user WHERE username = 'admin' or username = 'string' and gender = 0
以上语句实际为
SELECT * FROM admin_user WHERE username = 'admin' or ( username = 'string' and gender = 0 )
2 IN操作符一般比OR操作符清单执行更快
LIKE ,LIKE 'admin' 可以匹配到等于 ‘admin’ 的记录
1 不区分大小写
SELECT * FROM admin_user WHERE username LIKE 'ad%'
2 注意尾空格 LIKE ‘%min’ 不能匹配末尾有空格的 `admin `
3 注意 NULL,LIKE '%' 不能匹配 NULL
SELECT * FROM admin_user WHERE email LIKE '%'
注意:
REGEXP 与 LIKE '%内容%' 一样。不区分大小写,可以使用 REGEXP BINARY 'JetPack .000' 区别大小写
1 与 LIKE '%内容%' 一样
SELECT * FROM admin_user WHERE username REGEXP 'adm'
2 字符类
3 匹配多个实例
SELECT * FROM admin_user WHERE username REGEXP '[[:alnum:]]{7}' -- 可以匹配不少于 7 个的字符串
4 定位符
^ 的双重用途:在集合中(用[和]定义),用它来否定该集合,否则,用来指串的开始处。
SELECT * FROM admin_user WHERE username REGEXP '^string' -- 匹配 string 开头的
5 使用如下语句返回 0 或 1 验证是否匹配
SELECT 'hello' REGEXP 'hello'
函数没有SQL的可移植性强,不赞成使用特殊实现的功能
TRIM() 去掉空格
SELECT TRIM(' abc ') -- abc
LEFT() 返回串左边的几个字符串,小于 0.5 时为空,进行四舍五入
- SELECT LEFT("abc",2) -- ab
- SELECT LEFT(1234,-1) -- 返回空字符串
- SELECT LEFT(1234,1.5) -- 12
- SELECT LEFT(1234,1.4) -- 1
RIGHT() 返回串右边的几个字符,小于 0.5 时为空,进行四舍五入
- SELECT RIGHT('123',1) -- 3
- SELECT RIGHT('123',0) -- 空字符串
LOCATE() 是否匹配
SELECT LOCATE(username,'admin'),username FROM admin_user
LOWER() 转为小写
SELECT LOWER('ACd') -- acd
UPPER() 转为大写
SELECT UPPER('abc') -- ABC
SOUNDEX() 返回 SOUNDEX 值,一种语音算法
SELECT SOUNDEX("abc") -- A120
SUBSTR() 返回子字符串,从 1 开始
- SELECT SUBSTR(123 FROM 1 FOR 4) -- 123
- SELECT SUBSTR(123 FROM 0 FOR 4) -- 空
- SELECT NOW(); -- 2020-03-23 08:28:05
- SELECT CURRENT_DATE; -- 2020-03-23
- SELECT CURRENT_TIME; -- 08:26:54
- SELECT DATE(NOW()); -- 2020-03-23
- SELECT YEAR(NOW()); -- 2020
- SELECT MONTH(NOW()); -- 3 当前是 2020-03-23
- SELECT DAY(NOW()); -- 23
- SELECT HOUR('2020-01-05 00:00:01'); -- 0
- SELECT MINUTE('2020-01-05 00:0:01'); -- 0
- SELECT SECOND('2020-01-05 00:00:01'); -- 1
- SELECT DAYOFWEEK(NOW()) -- 2 当前是周一,周日是 1
- -- 日期运算,两者可接受参数较多:SECOND MINUTE HOUR DAY WEEK MONTH YEAR 等
- SELECT ADDDATE(NOW(),INTERVAL 1 YEAR);
- SELECT DATE_ADD(NOW(),INTERVAL 1 YEAR);
- -- 当前时间加几秒
- SELECT ADDTIME('2020-01-05 00:00:01',6) -- 2020-01-05 00:00:07
- -- 日期差
- SELECT DATEDIFF('2020-01-05','2020-01-06'); -- -1 前面减后面的

SELECT COUNT(gender) FROM admin_user -- 只计算不为 null 的行数
WITH ROLLUP 计算汇总和
SELECT username,COUNT(*) FROM admin_user GROUP BY username WITH ROLLUP
ORDER BY 可以对分组后的别名进行排序
SELECT gender,AVG(gender) FROM admin_user GROUP BY gender ORDER BY gender DESC
select 子句顺序
SELECT * FROM admin_user, admin_role
- SELECT user_id , username FROM admin_user
- UNION
- SELECT user_id , username FROM admin_user
- ORDER BY user_id
如果以上语句的列顺序或列名不一致,将出现一个笛卡尔乘积的结果;
只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句。
并( UNION) 或复合查询(compound query),使用场景
注意事项:
UNION ALL 不会对结果进行去重,它完成 WHERE 子句完成不了的工作,比如查询两条一样的数据?
并非所有引擎都支持全文本搜索。两个最常使用的引擎为MyISAM和InnoDB,前者支持全文本搜索,而后者不支持。
启用全文本搜索支持 FULLTEXT、ENGINE = MYISAM ,FULLTEXT可以索引多个列
- CREATE TABLE productnotes (
- note_id INT NOT NULL AUTO_INCREMENT,
- prod_id CHAR ( 10 ) NOT NULL,
- note_date datetime NOT NULL,
- note_text text NULL,
- PRIMARY KEY ( note_id ),
- FULLTEXT ( note_text )
- ) ENGINE = MYISAM
进行全文本搜索,Match() 指定被搜索的列, Against() 指定要使用的搜索表达式
- SELECT note_text FROM productnotes
- WHERE match ( note_text ) against ( 'food' )
- -- 与 like '%food%' 作用相同
什么是等级?
Match()和Against()的结果是具有等级的,等级由MySQL根据行中词的数目、唯一词的数目、整个索引中词的总数以及包含该词的行的数目计算出来
- SELECT note_text, match ( note_text ) against ( 'food' ) as rank
- FROM productnotes
使用查询扩展
- SELECT note_text FROM productnotes
- WHERE MATCH ( note_text ) AGAINST ( 'anvils' WITH QUERY EXPANSION)
布尔文本搜索
- SELECT note_text FROM productnotes
- WHERE MATCH ( note_text ) AGAINST ( 'food -ROP*' IN BOOLEAN MODE)
不安全的插入,高度依赖于表中列的定义次序
INSERT INTO productnotes VALUES ( NULL, 'a1', NOW( ), 'hello ' )
安全但是繁琐,给出了列名,并且省略了不需要的列
- INSERT INTO productnotes(note_id,prod_id,note_date)
- VALUES ( NULL, 'a1', NOW( ) )
使用 LOW_PRIORITY 指示 MySQL 降低 INSERT 语句的优先级,先执行 SELECT,提高性能。同样适用于 UPDATE/DELETE
- INSERT LOW_PRIORITY INTO productnotes(prod_id,note_date,note_text)
- VALUES ('a2', NOW( ), 'hello ' )
多个 insert 语句使用封号隔开
- INSERT LOW_PRIORITY INTO productnotes(prod_id,note_date,note_text)
- VALUES ('a2', NOW( ), 'hello' );
- INSERT LOW_PRIORITY INTO productnotes(prod_id,note_date,note_text)
- VALUES ('a3', NOW( ), 'home' );
VALUES 后边多个括号的值用逗号隔开。效率高。
- INSERT INTO productnotes ( prod_id, note_date, note_text )
- VALUE
- ( 'a1', NOW( ), 'year' ),
- ( 'b1', NOW( ), 'month' )
注意:VALUE 是 VALUES 的 synonym 没有区别。
- INSERT SELECT
-
- INSERT INTO productnotes ( prod_id, note_date, note_text )
- SELECT prod_id,note_date,note_text FROM productnotes
更新表中的特定行,添加 WHERE 子句
- UPDATE productnotes SET note_text = 'update hello', prod_id = 520
- WHERE note_id = '3'
更新表中的所有行,不加 WHERE 子句
IGNORE 关键字,发生错误仍然继续更新
UPDATE IGNORE tablename ..
从表中删除特定的行
DELETE FROM productnotes WHERE note_id = 1
从表中删除所有行
使用 TRUNCATE TABLE 提高效率,实际是直接删除原来的表再新建一个。不能有 where 子句
TRUNCATE TABLE productnotes
注意事项:
- CREATE TABLE user
- (
- id INT NOT NULL AUTO_INCREMENT comment '用户id',
- name CHAR ( 50 ) NOT NULL,
- sex int DEFAULT 0,
- PRIMARY KEY ( id )
- ) ENGINE = INNODB;
使用ALTER TABLE要极为小心,应该在进行改动前做一个完整的备份
- ALTER TABLE `user` ADD address VARCHAR ( 255 );
- ALTER TABLE `user` DROP address;
- ALTER TABLE `user` CHANGE name username VARCHAR ( 100 ); -- 修改列名与类型
- ALTER TABLE `user` MODIFY username VARCHAR(255) comment '用户名称'; -- 修改列属性
永久删除表,小心点啊
DROP TABLE test
可以同时修改多个
RENAME TABLE `user` TO my_user ,tablename to newtablename;
- CREATE VIEW vw_user AS
- SELECT * FROM `user`
使用存储过程比使用多条SQL语句要快
不带参数的存储过程
- CREATE PROCEDURE `pro_user`()
- BEGIN
- SELECT * FROM `user`;
- END;
-
- CALL pro_user -- 使用
使用命令行需注意:
如果命令行实用程序要解释存储过程自身内的;字符,则它们最终不会成为存储过程的成分,这会使存储过程中的SQL出现句法错误。解决办法是临时更改命令行实用程序的语句分隔符,如下所示:
DELIMITER // 告诉命令行实用程序使用//作为新的语句结束分隔符,可以看到标志存储过程结束的END定义为END// 而不是END;。 除\符号外,任何字符都可以用作语句分隔符
- DELIMITER //
- CREATE PROCEDURE `pro_user`()
- BEGIN
- SELECT * FROM `user`;
- END //
- DELIMITER;
列出了查询结果
CALL pro_user
- DROP PROCEDURE pro_user
- DROP PROCEDURE IF EXISTS pro_user -- 仅存在时删除,防止报错
OUT 获取返回结果,只能是单列,想要获取结果集就不要使用 OUT参数。
注意:参数使用 id 时无法使用呢??不要和字段名一样
- CREATE PROCEDURE pro_user ( OUT outid INT)
- BEGIN
- SELECT MAX( id ) INTO outid FROM `user`;
- END;
-
-
- CALL pro_user ( @outid);
- SELECT @outid as id;
如果没有返回值 OUT ,但是有多个查询,会输出第一个的查询结果
- DROP PROCEDURE IF EXISTS pro_user;
- CREATE PROCEDURE pro_user ( in inname VARCHAR ( 255 ) )
- BEGIN
- SELECT * FROM `user`;
- SELECT * FROM `user` WHERE `name` = inname;
- END;
- -- 使用
- CALL pro_user ( 'ewjlf' );
IN 向存储过程中传入参数,
注意:传入参数也不能使用 id,不要和字段名一样
- DROP PROCEDURE IF EXISTS pro_user;
- CREATE PROCEDURE pro_user ( OUT outname VARCHAR ( 255 ), IN inid INT )
- BEGIN
- SELECT `name` INTO outname FROM `user` WHERE id = inid;
- END;
- DROP PROCEDURE IF EXISTS pro_user;
-
- CREATE PROCEDURE pro_user ( IN inid INT ) COMMENT '用户的存储过程'
- BEGIN
- -- 声明变量
- DECLARE username VARCHAR(255);
- DECLARE test int;
- -- INTO 的位置可以是末尾
- SELECT `name` FROM `user` WHERE id = inid INTO username;
- -- if 语句
- IF LENGTH( username ) > 0 THEN
- SELECT '存在';
- ELSE
- SELECT '不存在';
- END IF;
- END;
-
- -- 显示所有存储过程,也可以在后面加 like '存储过程名称' 这个查询条件
- SHOW procedure STATUS

SHOW CREATE PROCEDURE pro_user
参考:https://www.jb51.net/article/55019.htm##1
查看是否允许自定义函数,OFF 不允许
show variables like '%func%';
set global log_bin_trust_function_creators=1 -- 临时开启自定义函数功能
CREATE FUNCTION <函数名> ( [ <参数1> <类型1> [ , <参数2> <类型2>] ] … )
RETURNS <类型>
<函数主体>
- DROP FUNCTION IF EXISTS fun_user; -- 删除
- CREATE FUNCTION fun_user(userid int) -- 创建
- RETURNS varchar(255) -- 注意返回值是 RETURNS,有个 S
- BEGIN
- DECLARE username VARCHAR(255);
- DECLARE result VARCHAR(255);
-
- SELECT `name` FROM `user` WHERE id = userid INTO username;
- -- if 语句
- IF LENGTH( username ) > 0 THEN
- SELECT '存在' into result;
- ELSE
- SELECT '不存在' INTO result;
- END IF;
- RETURN result;
- END;
-
- SELECT fun_user(22);

检查,与存储过程的使用方式一样
- SHOW CREATE FUNCTION fun_user;
- SHOW FUNCTION STATUS;
MySQL游标只能用于存储过程(和函数)
游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改
http://c.biancheng.net/view/2600.html
只支持 6 中触发器语句
begin | insert | update | delete |
end | insert | update | delete |
创建触发器
CREATE <触发器名> < BEFORE | AFTER >
<INSERT | UPDATE | DELETE >
ON <表名> FOR EACH Row <触发器主体>
可以引用 NEW 和 OLD 指代被操作前后的记录
- CREATE TRIGGER before_insert BEFORE INSERT on user
- FOR EACH ROW SET New.sex = 5;
事务用来管理 INSERT、UPDATE、DELETE。
不能回退 SELECT、CREATE、DROP ,它们可以存在事务块中,但不可以撤销
隐含事务关闭 当COMMIT或ROLLBACK语句执行后,事务会自动关闭(将来的更改会隐含提交)。
保留点越多越好 可以灵活回退
释放保留点:ROLLBACK 或 COMMIT 后自动释放。MySQL 5 后可以使用 RELEASE SAVEPOINT 释放。
更改默认提交行为 SET autocommit = 0 设置为不自动提交,只在当前连接生效
- START TRANSACTION;
- SELECT * FROM `user`;
- DELETE FROM `user` WHERE ID = 19
- SAVEPOINT U20;
- DELETE FROM `user` WHERE ID= 20
- ROLLBACK TO U20;
- COMMIT/ROLLBACK;
字符集和校对可以在系统管理安装、创建数据库、表、列的时候指定。
也可以在 select 语句中指定校对,实现想要的排序方式,或者是针对 GROUP BY、HAVING、聚集函数、别名
字符串可以使用 Cast() Convert() 转换字符集
- SHOW CHARACTER SET; -- 显示可用的字符集、描述和默认校对
- SHOW COLLATION; -- 显示所有可用校对,以及适用的字符集
- SHOW VARIABLES LIKE 'character%'; -- 查看字符集
- SHOW VARIABLES LIKE 'collation%'; -- 查看校对
root 拥有对整个 MySQL 服务器的完全控制,只有在绝对需要时使用 root 用户
查看所有用户 存放在 mysql 这数据库的 user 表中
SELECT * from mysql.`user`
创建用户 最好使用 CREATE USER,不推荐使用 INSERT 直接操作 USER 表 ,也可以使用 GRANT
- CREATE USER test IDENTIFIED BY '123' -- 创建用户,口令自动被加密
- RENAME USER test TO test1; -- 重命名,仅 MySQL 5 后支持
删除用户 MySQL 5 之后会删除用户账号及相关权限。之前只删除用户账号,所以需要先用 REVOKE 删除相关权限
DROP USER test1;
设置权限
- SHOW GRANTS FOR test; -- 显示拥有的权限
- GRANT SELECT ON cloud.* TO test; -- 授予 cloud 数据库所有表上的只读权限
- REVOKE SELECT ON cloud.* FROM test; -- 撤销权限
授权范围包括
注意:在使用 GRANT 和 REVOKE 时,用户账号必须存在,但对所涉及的对象没有这个要求。这允许管理员在创建数据库和表之前设计和实现安全措施。
这样做的副作用是,当某个数据库或表被删除时(用DROP语句),相关的访问权限仍然存在。而且,如果将来重新创建该数据库或表,这些权限仍然起作用。
更改口令
- SET PASSWORD FOR test = PASSWORD('443'); -- 修改指定用户的密码,必须使用 PASSWORD() 函数加密
- SET PASSWORD = PASSWORD('443'); -- 修改当前登录用户的口令
参考《MySQL 必知必会》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。