###############################################################################

第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 
; 
END;


例子:用游标遍历取得表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. ...