- 连接数据库:
mysql -uusername -ppassword;
- 运行sql脚本:
source 脚本文件名.sql
- 显示所有数据库:
show databases;
- 选择数据库:
use databasename;
- 显示数据库内的表:
show tables;
- 显示该表的字段信息:
show column from tablename; 可以用describe语句代替 describe tablename
- MySQL查询
使用distinct关键字,只返回不同的值。 不能部分使用 DISTINCT, DISTINCT 关键字应用于所有列而 不仅是前置它的列。如果给出 SELECT DISTINCT vend_id, prod_price ,除非指定的两个列都不同,否则所有行都将被 检索出来。
- 限制返回结果
使用Limit关键字,
select prod_name from products Limit 5;
查询结果将不多于5行。
为得出下一个5行,可指定要检索的开始行和行数
select prod_name from products Limit 5,5;
表示从第5行开始的5行;
MySQL5 开始支持,LIMIT 4 OFFSET 3 意为从行3开始取4行,就像 LIMIT 3, 4 一样。
- 搜索结果排序:
使用order by 关键字进行搜索结果的排序,如果需要对多个字段进行排序,可以使用“,”连接符。
select prod_name,prod_price from poducts order by prod_price,prod_name;
先使用价格排序,当价格相同时,在根据名称排序;
指定排序方向,desc降序,asc(Ascending),不过升序排序没有意义,因为mysql排序默认是升序排序
tips:使用 ORDER BY 和 LIMIT 的组合,能够找出一个列中最高或最低的值。 select prod_price from
products order by prod_price desc limit 1;
- 空值检查
关键字:is null
select prod_name from products where prod_price is null;
- like通配符过滤;
- “%”通配符指任意字符出现的次数,
- “_”通配符指匹配单个字符
- 正则表达式匹配
关键字REGEXP,
基本字符匹配:
select prod_name from products where prod_name REGEXP '1000' ORDER BY prod_name
进行or匹配:
select prod_name from products where prod_name REGEXP '1000|2000' ORDER BY prod_name
匹配几个字符之一:
select prod_name from products where prod_name REGEXP '[123]Tom' ORDER BY prod_name
匹配非几个字符之一:
select prod_name from products where prod_name REGEXP '[^123]Tom' ORDER BY prod_name
匹配范围:
select prod_name from products where prod_name REGEXP '[1-5]Tom' ORDER BY prod_name
匹配特殊字符:
select prod_name from products where prod_name REGEXP '\\.' ORDER BY prod_name 其中"\\"是用来转义的
重复元字符
- “* ”表示 0个或多个匹配
- “+” 表示 1个或多个匹配(等于{1,})
- “?” 表示0个或1个匹配(等于{0,1})
- {n} 指定数目的匹配
- {n,} 不少于指定数目的匹配
{n,m} 匹配数目的范围(m不超过255)
创建计算字段:
在设计报表时,由于需要引用到不同字段的值,所以需要拼接用到的不同字段,可以使用mysql的concat()方法:
select concat(Rtrim(vend_name),'(',RTrim(vend_country),')') as vend_title from vendors order by vend_name;
RTrim()指去掉右边的空格
在sql中执行算术计算,包括加减乘除
select prod_id, quantity,item_price, quantity*item_price as expendered_price from orderitems where order_num=20005;
- 汇总数据,共五个聚集函数
AVG() 在avg()中还可以加入distinct关键字进行非重复值的过滤,avg(distinct column_name)
count() count(*)对表中所有数目进行计算,不管表列中包含的是空值Null,还是非空值。count(column), 对特定列中具有值的行进行计数,忽略NULL 值。
max()
min()
sum()
- 分组查询,关键字group by,having
select vend_id,count(*) as num_prods from products group by vend_id;
- having用于过滤分组
事实上,目前为止所学过的所有类型的 WHERE 子句都可以用 HAVING 来替代。唯一的差别是WHERE 过滤行,而 HAVING 过滤分组。
原理: HAVING 和 WHERE 的差别 这里有另一种理解方法, WHERE 在数据 分组前进行过滤, HAVING
在数据分组后进行过滤。这是一个重 要的区别, WHERE 排除的行不包括在分组中。这可能会改变计 算值,从而影响 HAVING
子句中基于这些值过滤掉的分组。
order by 放在group by 的后面,即order by放在查询语句的末尾
- 组合查询:关键字union
可用 UNION 操作符来组合数条SQL查询。利用 UNION ,可给出多条SELECT 语句,将它们的结果组合成单个结果集。
select vend_id,prod_id,prod_price from products where prod_price<=5 union select vend_id,prod_id,prod_price from products where vend_id in ('1001','1002')
表插入数据,可以使用insert select,即从其他表中查询数据直接插入新的表中,省去了先查找,再插入的步骤。
- 删除表数据:
delete from customers where cust_id = 10006;
更快的删除 如果想从表中删除所有行,不要使用 DELETE 。
可使用 TRUNCATE TABLE 语句,它完成相同的工作,但速度更
快( TRUNCATE 实际是删除原来的表并重新创建一个表,而不
是逐行删除表中的数据)。
创建表中需要指定数据库引擎,常见的引擎有如下几个:
以下是几个需要知道的引擎:
- InnoDB 是一个可靠的事务处理引擎(参见第26章),它不支持全文 本搜索;
- MEMORY 在功能等同于 MyISAM ,但由于数据存储在内存(不是磁盘) 中,速度很快(特别适合于临时表);
- MyISAM 是一个性能极高的引擎,它支持全文本搜索(参见第18章), 但不支持事务处理。
修改表 alter table
- 删除表
drop table customers2
- 重命名表
rename table customers to customers2
创建:create view
查看:show create view viewname查看创建的视图
删除:drop view viewname
更新:可以先用DROP再用CREATE,也可以直接用CREATE ORREPLACE VIEW。如果要更新的视图不存在,则第 2 条更新语句会创
建一个视图;如果要更新的视图存在,则第 2 条更新语句会替换原有视图。
tips:
create view productcustomers as select cust_name,cust_contact,prod_id from customers,orders,orderitems where customers.cust_id = orders.cust_id and orderitems.order_num = orders.order_num;
视图极大地简化了复杂SQL语句的使用。利用视图,可一次性编写基础的SQL,然后根据需要多次使用。
- 存储过程:
定义:存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件,虽然它们的作用不仅限于批处理。
keys: 默认的MySQL语句分隔符为 ; (正如你已经在迄今为止所使用的MySQL语句中所看到的那样)。 mysql
命令行实用程序也使用 ; 作为语句分隔符。如果命令行实用程序要解释存储过程自身内的 ; 字符,则它们最终不会成为存储过程的成分,这会使
存储过程中的SQL出现句法错误。解决办法是临时更改命令行实用程序的语句分隔符,如下所示:
DELIMITER //
create procedure productpricing() BEGIN select avg(prod_price) as priceaverage from products;
END //
DELIMITER ;
其中, DELIMITER // 告诉命令行实用程序使用 // 作为新的语句结束分隔符,可以看到标志存储过程结束的 END 定义为 END
// 而不是 END; 。这样,存储过程体内的 ; 仍然保持不动,并且正确地传递给数据库引擎。最后,为恢复为原来的语句分隔符可使用 DELIMITER ; 。
除 \ 符号外,任何字符都可以用作语句分隔符。
删除存储过程
DROP PROCEDURE productpricing if exists;
带参数的存储过程:
DELIMITER //
create procedure productpricing( out p1 decimal(8,2), out ph decimal(8,2), out pa decimal(8,2) ) BEGIN SELECT MIN(prod_price) into p1 FROM PRODUCTS;
SELECT MAX(prod_price)
into ph from products;
select Avg(prod_price)
into pa from products;
END //
DELIMITER ;
关键字 OUT 指出相应的参数用来从存储过程传出一个值(返回给调用者)。MySQL支持 IN (传递给存储过程)、 OUT (从存储过程传出,如这里所用)和 INOUT (对存储过程传入和传出)类型的参数。存储过程的代码位于 BEGIN 和 END 语句内。如前所见,它们是一系列SELECT 语句,用来检索值,然后保存到相应的变量(通过指定 INTO 关键字)。
调用时,使用CALL productpricing(@pricelow,@pricehigh,@priceaverage)
由于此存储过程要求3个参数,因此必须正好传递3个参数,不多也不少。所以,这条 CALL 语句给出3个参数。它们是存储过程将保存结果的3个变量的名字。
所有MySQL变量都必须以 @ 开始。
查看存储过程:
show create procedure producename;
- 游标:
定义:游标(cursor)是一个存储在MySQL服务器上的数据库查询,它不是一条 SELECT 语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。
只能用于存储过程 不像多数DBMS,MySQL游标只能用于存储过程(和函数)。
创建游标:
DELIMITER //
create procedure processorders() BEGIN DECLARE ordernumbers CURSOR FOR SELECT order_num from orders;
END //
DELIMITER ;
- 触发器:
MySQL语句在需要时被执行,存储过程也是如此。但是,如果你想要某条语句(或某些语句)在事件发生时自动执行,怎么办呢?
这就要用到触发器了,触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句
- DELETE;
- INSERT;
- UPDATE;
仅支持表 只有表才支持触发器,视图不支持(临时表也不支持)。
触发器按每个表每个事件每次地定义,每个表每个事件每次只允许一个触发器。因此,每个表最多支持6个触发器(每条 INSERT 、 UPDATE
和 DELETE 的之前和之后)。
在创建触发器时,需要给出4条信息:
- 唯一的触发器名;
- 触发器关联的表;
- 触发器应该响应的活动( DELETE 、 INSERT 或 UPDATE );
- 触发器何时执行(处理之前或之后)。
创建触发器:
DELIMITER //
create trigger neworder after insert on orders for each row insert into log_table(newId, time) value(new.order_num, now());
//
DELIMITER ;
此代码创建一个名为 neworder 的触发器,它按照 AFTER INSERTON orders 执行。在插入一个新订单到 orders 表时,MySQL生成一个新订单号并保存到 order_num 中。触发器从 NEW. order_num 取得这个值并返回它。此触发器必须按照 AFTER INSERT 执行,因为在 BEFOREINSERT 语句执行之前,新 order_num 还没有生成。对于 orders 的每次插入使用这个触发器将在日志表中保存一行记录;
ps:这里使用create trigger neworder after insert on orders for each row
select new.order_num;
一直报错:not allowed to return a result set from a trigger
查询后没别的办法,就改成上面那种写法了,先创造上面的日志表:
测试一下这个触发器:
insert into orders(order_date, cust_id) values(now(),10001);
- 事务处理
MySQL支持几种基本的数据库引擎。正如本章所述,并非所有引擎都支持明确的事务处理管理。 MyISAM 和 InnoDB 是两种最常使用的引擎。前者不支持明确的事务处理管理,而后者支持。commit 提交
- 作用:
利用事务处理,可以保证一组操作不会中途停止,它们或者作为整体执行,或者完全不执行(除非明确指示)。如果没有错误发生,整组语句提交给(写到)数据库表。如果发生错误,则进行回退(撤销)以恢复数据库到某个已知且安全的状态。
哪些语句可以回退?rollback 事务处理用来管理 INSERT 、 UPDATE 和DELETE 语句。你不能回退 SELECT
语句。(这样做也没有什么意义。)你不能回退 CREATE 或 DROP
操作。事务处理块中可以使用这两条语句,但如果你执行回退,它们不会被撤销。
- 设置保留点
简单的 ROLLBACK 和 COMMIT 语句就可以写入或撤销整个事务处理。但是,只是对简单的事务处理才能这样做,更复杂的事务处理可能需要部分提交或回退。
为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符。这样,如果需要回退,可以回退到某个占位符。这些占位符称为保留点。
为了创建占位符,可如下使用 SAVEPOINT语句:
savepoint delete1;
每个保留点都取标识它的唯一名字,以便在回退时,MySQL知道要
回退到何处。为了回退到本例给出的保留点,可如下进行:
rollback to delete1;
- 安全管理
MySQL用户账号和信息存储在名为 mysql 的MySQL数据库中。
use mysql;
select user from user;
创建用户 create user ben identified by 'root'
删除用户 drop user ben;
新创建的用户能登陆数据库,但是看不到数据。权限为usage,即无任何权限
使用 show grants fro ben;
查看该用户的权限。
- 分配权限:
grant select on crashcourse.* to ben;
此时再查看ben的权限,就多了一行了。
GRANT 的反操作为 REVOKE ,用它来撤销特定的权限。下面举一个例子:
revoke select on crashcourse.* from ben;
- 更改密码:
set password for ben = Password('newpassword');
SET PASSWORD 更新用户口令。新口令必须传递到 Password() 函数进行加密。
在不指定用户名时, SET PASSWORD 更新当前登录用户的口令。
另外,数据库文件可以在网站上下载:
链接