###############################################################################
第1~3章:理解SQL、MariaDB入门、让MariaDB运行起来
DBMS-数据库管理系统(Database Management System):
基于共享文件系统的非关系型数据库、基于客户端/服务器的关系型数据库
Mariadb 基于Mysql5的代码库
主键(primary key):主键是数据表的唯一索引,比如学生表里有学号和姓名,姓名可能有重名的,但学号确是唯一的。数据库中必须定义主键。
describe table; --等价于 show columns from tables;
SQL语句中额外的空格,包括换行会被忽视。因此一条语句可以很长也可以分行。
在没有use特定的database下,可以用.来完全限定database和table来访问,如
select user from mysql.user;
注释:
--xxxx; 内嵌注释
# 开头注释;
/* xxxx */ 长注释
###############################################################################
第4章:检索数据
检索:
select 列名,列名 from table;
检索不同列:
distinct
检索限定行数:
limit 1 offset 2 / limit 2,1
###############################################################################
第5章:对检索数据排序
排序:
order by 列名1,列名2 -- 以列名1排序,当列名1相同,以列名2排序。
默认升序,用关键字DESC降序。
默认不区分大小。若要做到区分大小写,要修改列字符集,convert()函数
###############################################################################
第6章 过滤数据
过滤
where 列名=xxxx
字符串用
where 列名=‘’
数字比较>,<,>=,<=,=,!=,between and
特殊的 where 列名 is null
提示:虽然也可以从数据库取出所有数据后,在应用程序过滤数据。但是不提倡,因为用数据库来过滤比较高效,且不需要把所有数据发送给应用程序(浪费带宽)
警告:需要where过滤后才可以排序,否则会语法错误。
###############################################################################
第7章 高级过滤数据
where 配合and,or,not使用,可以用括号指明优先级,还有
where 列名 in (xx,yy)
###############################################################################
第8章 使用通配符过滤
where 列名 like ‘xx%xx%’ : % 匹配任意字符包括空
下划线 匹配一个字符
###############################################################################
第9章 正则表达式搜索
where 列名 REGEXP ‘符号’
符号:|,[],\\,?,[:alnum:],[:digit:],{m,n},^,% 等等
###############################################################################
第10章 创建计算字段
把多列数据拼接在一起Concat
别名as
select Concat(列名,'(',列名)) as 新列名
###############################################################################
第11章 数据操作函数
1. 文本操作函数:
Lower(),RTrim(),SubString(),Soundex()
2. 日期函数:
Date(), Now(),
3. 数值操作函数:
Abs(),
###############################################################################
第12章 数据汇总
AVG()列平均,COUNT()行数,MAX(),MIN(),SUM()
select count(*) as num_items, -- * 包含NULL,count(列名)不包含NULL
min(列名) as xxx,
max(列名) as xxx,
from xxx
###############################################################################
第13章 数据分组
1. group by
# 对user中用户授权的情况进行分组和统计数量
select user,count[*] as user_number
from mysql.user
group by user;
2. having
类似于where, where对数据分组前过滤,having对分组后过滤
###############################################################################
第14章 子查询
1. 在语句里面嵌套
select cust_id
from orders
where order_num in (select order_num
from orderitems
where prod_id = 'TNT2')
2.相关子查询(两个表格之间的统计关系)
select cust_name,
cust_state,
(select count(*)
from orders
where order.cust_id = customers.cust_id) as orders
from customers
order by cust_name;
###############################################################################
第15章 多表连接
关系表:通过外键,在表的一列中包含来自其他表的主键值。
select prod_name,vend_name,prod_price
from vendors,products -- 如果去掉verdors表,
where vendors.vend_id = products.vend_id -- 这里的vendors.vend_id会提示Unkown column,
order by vend_name,prod_name; -- 如果没有where这一行,会输出两个表格行数相乘的数据量
内连接:inner join on, 跟where得到的结果相同
性能考虑:表连接越多,查询性能越低
###############################################################################
第16章 创建高级连接
1. 表别名 as c, 然后可以用c.xxx 来访问列
2. 自连接:在同一个表里面查询,比如在products表中查询出问题的product来自哪个供应商,这个供应商的所有产品
3. 自然连接:
例子:在满足其他列的情况下,得到customers所有的列
select o.order_num, o.order_date, oi.prod_id, oi.quantity,oi.item_price
from customers as c, orders as o, orderitems as oi
where c.cust_id = o.cust_id
and oi.order_num = o.order_num
and prod_id = 'FB';
4. 外连接:对应不上的情况下填NULL,可以左对应或者右对应
select xxx,xxx
from 表名 LEFT/RIGHT OUTER JOIN 表名
on xxx = xxx;
###############################################################################
第17章 联合查询 union
直接在两个查询语句中掺入union,要求相同列数,会默认去重复。也可以用where实现
union all 直接把两次查询合并在一起
###############################################################################
第18章 全文本搜索
select match() against()
不需要完全匹配,可以搜索特定的单词,不区分大小写
create table 时指定FULLTEXT(列名)
rank指定排位,先搜索到的排位高,没有包含单词的排位为0
###############################################################################
第19章 插入数据
insert into 表名(列名,列名)
values('xxxx','xxxx'),
values('xxxx','xxxx')
)
###############################################################################
第20章 更新和删除数据
update 表名
set 列名
where 列名 = xxx;
delete from 表名
where 列名 = xxx
提醒:使用update和delete必须加where,否则会set或者删除表的所有行。
###############################################################################
第21章 创建和操作表
create table 表名
(
列名 数据类型 NULL AUTO_INCREMENT
列名 数据类型 NOT NULL DEFAULT 1
xxxx
)ENGINE=XXX
设置为not null 的列必须指定或加default指定,设置为null的列默认为null
每个表要设置引擎:
(1) InnoDB: 事务安全,不支持全文本搜索
(2) MEMORY: 数据存储在内容中,处理快 -> 适用于临时表
(3) MyISAM: 跟MEMORY类似,支持全文本搜索,不支持事务
(4) ARIA:新的事务安全引擎,支持全文本搜索和重要的崩溃恢复特性
更新表:
(1) 插入一列
alter table if not exists 表名
add 列名 类型
(2) 删除一列
alter table 表名
drop column 列名
(3) 其他(更新列名等)
删除表:
drop table 表名
重命名表:
rename table 表名 to 表名;
外键 :
将一个表格的列的内容约束在另一个表格的列里面。当定义一个表中的列,不在另一个表内容中,就报错。
例子:
ALTER TABLE pc --(表名)
ADD CONSTRAINT fk_cpu_model --(外键名字)
FOREIGN KEY (cpumodel) --cpumode是表pc中的一列
REFERENCES parts(model) -- parts 是表model中的一列
解释:pc中的cpumodel列表必须在parts表格中的model里面
###############################################################################
第22章 视图
视图是一些虚表,将复杂的查询封装起来。
优点:1.重用SQL语句,简化复杂的SQL操作; 2.保证数据安全,只暴露表的一部分 3.改变数据呈现的格式
缺点:视图不包含数据,每次操作都要先执行查询检索,所以一旦比较复杂,性能明显下降。
视图的使用方式跟普通表相同:select,过滤, 如果是增加或更新数据库有一些限制条件
举例:
create view verdorlacation as
select Concat(RTrim(vend_name),'{',RTrim(vend_country),'}') as vend_title --查询语句不需改变
from vendors
order by vend_name;
select * from verdorlacation;
提醒:
并非所有视图都可以更新,更新视图会改变底层的表。
基本上,如果MariaDB不能正确地查询出底层需要更新的数据,就不允许更新
使用了以下操作就不可以更新:分组(使用group by/having), 连接(多个表格), 子查询, 联合union, 聚合函数(max,min等), distinct, 导出计算列
###############################################################################
第23章 存储过程
存储过程是一个可编程的函数,可以看成面向对象编程。预先编译(SQL语句执行是都需要先编译),调用即可。
delimiter //--定界符,防止多个分号造成语句识别错误
create procedure 存储函数名字(
out 输出参数名 数据类型,
in 输入参数名 数据类型
...)
begin
select xxx
into 输出参数名
from xxx;
...
end // --遇到定界符//后执行以上语句
delimiter;
call 存储函数名字(输入参数,@输出参数名); --编译(不输出)
select @输出参数名; --输出结果
例子:同时用 IN, OUT, 接收订单号,返回订单总额
DELIMITER //
CREATE PROCEDURE ordertotal(
IN onnumber INT,
IN taxable BOOLEAN,
OUT ototal DECIMAL(8,2)
)COMMENT 'Obtain order total, optionally adding tax'
BEGIN
DECLARE total DECIMAL(8,2);
DECLARE taxrate INT DEFAULT 6;
SELECT Sum(item_price*quantity)
FROM orderitems
WHERE order_num = onnumber
INTO total;
IF taxable THEN
SELECT total+(total/100*taxrate) INTO total;
END IF;
SELECT total INTO ototal;
END //
DELIMITER ; --这里必须要有空格以恢复,否则下面一直要用// 来结束语句
CALL ordertotal(20005,1,@total);
SELECT @total;
删除存储过程
drop procedure ordertotal
查询存储过程细节
show create procedure ordertotal
存储过程编程还可以用declare定义局部变量、用if语句等
###############################################################################
第24章 游标
游标(Cursor)允许用户逐行访问SQL Server返回的结果集。
允许程序对由查询语句select返回的行集合中的每一行执行相同或不同的操作,而不是对整个行集合执行同一个操作。
游标通常嵌套在存储过程中
create procedure 名字()
BEGIN
DECLARE <游标名>CURSOR
FOR
例子:用游标遍历取得表orders中的order_number给局部变量o,
传入存储过程ordertotal(o,1,t),计算得到t并插入新表ordertotals
DELIMITER //
create procedure processorders()
begin
declare done boolean DEFAULT 0;
declare o int;
declare t decimal(8,2);
declare ordernumbers cursor
FOR
select order_num from orders;
declare continue handler for sqlstate '02000' set done=1;
create table if not exists ordertotals
(order_num int, total decimal(8,2));
open ordernumbers;
repeat
fetch ordernumbers into o;
call ordertotal(o,1,t);
insert into ordertotals(order_num,total)
values (o,t);
until done end repeat;
close ordernumbers;
end //
DELIMITER ;
###############################################################################
第25章 触发器
当对一个表进行delete,insert,update的时候执行触发器,一个触发器只对应一个事件一个表,
触发器不支持视图以及临时表。
create trigger 触发器名 触发时间 触发事件
on 表名
[for each row]
[begin]
pl/sql 语句
[end;]
触发时间:before/after
触发事件:insert/update/delete
表名:数据库触发器所在的表
例子:在表orders发生insert后,orders_log增加一行
create table orders_log(
change_id int not null AUTO_INCREMENT,
changed_on datetime not null,
change_type char(1) not null,
order_num int not null,
primary key (change_id)
)ENGINE=Maria;
DELIMITER //
create trigger neworder after insert on orders
for each row
begin
insert into orders_log(changed_on,change_type,order_num)
values(Now(),'A',new.order_num); --new.order_num获取表orders中新插入的order_num。类似的,也有old的虚表可以使用
end //
DELIMITER ;
###############################################################################
第26章 管理事务处理
事务: Transaction
回滚:Rollback --对insert,update,delete回滚,对select回滚没意义。也不能对create或者drop回滚
提交:Commit --显示执行commit后,执行rollback没有用
保存点:Savepoint
数据库默认是autocommit,只要执行语句,数据库的改变就是永久的。也可以set autocommit=0,就要手动commit
Savepoint 名字;
rollback to 名字; --因此,越多保存点,有利于回滚;
例子:证明对delete回滚
select * from ordertotals;
start Transaction; -- 定义事务处理
delete from ordertotals;
select * from ordertotals;
rollback -- 回滚上面语句直到遇到 start Transaction
select * from ordertotals;
###############################################################################
第27章 全球化和本地化
字符集:show character set;
排序规则:show collation;
###############################################################################
第28章 安全管理
--新建之后usage表示没有任何权限,SHOW grants for test默认是grant usage on *.* to 'test'@'%'
create user username identified by 'password'
授予权限:
grant select on crashcourse.* to username; --给username 赋予查询crashcourse所有表格的权限
revoke select on *.* from username; --取消对所有数据库查询权限
要记得
flush privileges;
修改密码:
set password for username = Password('xxx');
###############################################################################
第29章 数据库维护
执行备份mysqldump之前执行flush tables;
analyze table tablename;
check table tablename,tablename;
可以使用repairtable,但不应该经常使用
日志:
错误日志: hostname.err,包含启动关闭问题
查询日志:hostname.orders_log,记录所有活动,很快变大
二进制日志:hostname-bin,记录更新数据库的所有语句
慢速查询日志:hostname-slow.log, 记录执行速度慢的查询,优化用
###############################################################################
第30章 提升性能
1. 使用推荐/指定的硬件
2. 配置参数:调整内存分配,缓冲区尺寸,show variables; show status;
3. show processlist可以看到活动进程,一个进程慢会影响其他;
4. 优化数据库语句,使用explain解释select语句
5. 通常存储过程比单独的语句执行快
6. 使用正确的数据类型
7. 不要检索超出你需求的数据,少用select *
8. ...