《MySQL必知必会》读书笔记
一、了解MySQL
1、什么是数据库?
数据库是一种以某种有组织的方式存储的数据集合。
2、模式(schema):关于数据库和表的布局及特性的信息。
3、列:正确的将数据分解为多个列极为重要。通过把它分解开,才有可能利用特定的列对数据进行排序和过滤。
4、主键(primary key):一列,其值能够唯一区分表中每个行,用来表示一个特定的行。应该保证创建的每个表具有一个主键,以便于以后的数据操纵和管理。
5、外键:
6、SQL语句不区分大小写,但是开发人员通常对所有SQL关键字大写,而对所有列和表名使用小写,这样做使代码更易于阅读和调试。
二、使用MySQL
1、连接 mysql -h localhost -u root -p xxxx
2、show命令:
show databases;
use databases;
show tables;
show columns from tablename; ==== describe tablename;
show status; 用于显示广泛的服务器状态信息
show create database databasename;
show create table tablename; 分别用来显示创建特定数据库或表的MySQL语句。
show grants; 用来显示授予用户(所有用户或特定用户)的安全权限
show errors; show warnings; 用来显示服务器错误或警告消息
help show; 显示允许的show语句
MySQL 5支持一个新的Information_schema命令,可用它来获得和过滤模式信息。
三、检索数据
1、select语句:为了检索数据,必须至少给出两条信息--想选择什么,从什么地方选。
select column from tablename; 检索单个列,如果未排序,返回的顺序可能是数据的添加顺序也可能不是。
select column1,column2 from tablename; 检索多个列
select * from tablename; 检索所有列 ,除非你确实需要表中的每个列,否则最好别用*通配符。虽然使用通配符可能会使你自己省事,但检索不需要的列通常会降低检索和应用程序的性能
select distinct column from tablename; 只返回不同值,即剔除重复的数据。distinct 应用于所有列,不仅是前置它的列
select column form tablename limit 5;限制语句,不多于5行。
select column form tablename limit 5,5;限制语句,从第6行开始的5行 ,第一行的行号为0,
有一些情形需要完全限定名,tablename.columnname
2、order by子句排序检索数据:
关系数据库设计理论认为,如果不明确规定排序顺序,则不应该嘉定检索出的数据的顺序有意义。
select column from tablename order by column;用选择的列或非选择的列排序都是合法的。默认升序排列,desc关键字降序,如果多个列排序,desc只应用到直接位于其前面的列名。
select column from tablename order by column1,column2;按多个列排序,先按第一个排序,如果重复则继续按第二个排序。所以,列的顺序选择很重要。
在字典排序中,A被视为与a相同。这是MySQL的默认行为,如果有必要,可以用collation校对字符集改变这种行为。
select * from XXX order by limit 1;可以找到最大值。使用子句的次序不对会产生错误消息。
3、where子句过滤检索数据:
只检索所需要的数据,通常需要指定搜索条件(search crierria),即过滤条件
select column from table where name ='zhangsan' order by ..;过滤条件默认不区分大小写。
where子句包含多种条件操作符:
=, <>, !=, <, <=, >, >=, between 5 and 10,(包括开始和结束)
select column from table where column is null;空值检查
4、组合where子句建立功能更强,更高级的搜索条件:
AND操作符:
select A from table where B=2 and C<>5; 条件交集
OR操作符:
select A from table where B=2 or C<>5; 条件并集
where可以包含任意数目的AND和OR操作,允许两者结合以进行复杂和高级的过滤。但是AND的优先级比OR的优先级高,所以需要使用圆括号来保证计算次序。不要依赖默认的计算次序。
IN操作符:
select A from table where B in (2,4,6) order by ..;
IN操作符用来指定清单时与OR功能相同,但IN还有很多优点:
IN操作符的语法更清楚且更直观;IN操作符计算次序更容易管理;
IN操作符一般比OR清单执行更快;
IN操作符最大的优点是可以包含其他select语句,使得能够更对台地建立where子句。
NOT操作符: not操作符有且只有一个功能,就是否定他之后所跟的任何条件。
Select A from table where B not in (2,4);
MySQL 支持使用 NOT 对 IN 、Between 和 exists 子句取反
5、使用通配符(wildcard)过滤:
搜索模式(search pattern): 由字面值、通配符或两者组合构成的搜索条件。
LIKE操作符(谓词):前面介绍的所有操作都是针对已知值进行过滤的。但是这种过滤方式并不是任何时候都好用。利用通配符可以创建比较特定的数据搜索模式。
百分号(%)通配符: %表示任何字符出现任意次数
select * from table where name like 'zhang%';
select * from table where name like '%ang%';
通过 % 可以组合多种搜索模式;但是 % 不能匹配 NULL值
下划线(_)统配符: _ 只匹配单个字符,不能多也不能少
select * from table where name like '_hang';
使用通配符的技巧:
MySQL通配符很有用,但是这种功能是花费代价的,通配符搜索的处理一般要比前面讨论的其他搜索花费时间更长。所以需要一些技巧
不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
在确实需要使用通配符是,除非绝对有必要,否则不要把他们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
仔细注意通配符的位置,如果放错地方,可能不会反悔想要的数据。
6、用正则表达式进行搜索: 用于匹配特定模式的文本,如电话号码,邮箱等。
REGEXP操作符: regexp 替换立刻的作用
关于正则表达式的内容请参考正则表达式语法。
7、创建计算字段:
计算字段是运行时在select语句内创建的。
使用Concat()函数实现拼接。
select Contact(A, '(',B,')') from table ;
使用别名,别名有时也称为导出列
select Contact(A, '(',B,')') as A(B) from table ;
执行算术计算
select A, B*C as BC from table;
8、使用数据处理函数:
文本处理函数:
Left()、Right()返回串左(右)边的字符
Length() 返回串的长度
Locate()找出串的一个子串
Lower()、Upper()转换大小写
LTrim()、RTrim()去掉左(右)边的空格
Soundex() 返回串的SOUNDEX值,将任何文本串转换为描述其语音表示的字母数字模式的算法。即匹配所有发音类似的值。
SubString()返回子串的字符
日期和时间处理函数:
AddDate() 增加一个日期(天、周等)
AddTime() 增加一个时间(时、分等)
Now()、CurDate()、CurTime() 返回当前的日期和时间、日期部分、时间部分
Date()、Time()、Year()、Month()、Day()、Hour()、Minute()、Second()、返回日期时间的日期部分、时间部分、年、月、日、小时、分钟、秒
DateDiff() 计算两个日期之差
Date_ADD() 高度灵活的日期运算函数
Date_Format() 返回一个格式化的日期或时间串
DayOfWeek() 对于一个日期,返回对应的星期几
数值处理函数:
Abs(), Cos(), Exp(), Mod(), Pi(), Rand(), Sin(), Sqrt(), Tan()
9、汇总数据:
聚集函数:运行在行组上,计算和返回单个值的函数
AVG(), COUNT(), MAX(), MIN(), SUM()
10、分组数据:
where group by having order by;
select from where group by having order by limit;
group by 通常与汇总函数连用。
11、使用子查询:
select * from table where A in (select * from table where xxxx);
对于嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询。注意:列必须匹配。
12、联结表:
外键(foreign key):外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。
联结查询:规定要联结的所有表以及他们如何关联。
select A from table1,table2 where table1.id = table2.id;
笛卡尔积:
内联结:inner join
外联结:左外 left outer join;查询左表中所有记录的右表活动,如所有人的消费记录,没有就显示空
右外 right outer jion;查询右表所有记录的关于左表的情况。
13、组合查询:
UNION关键字:
14、全文本搜索:
MySQL中两个最常使用的引擎:
MyISAM:支持全文本搜索
InnoDB:不支持全文本搜索
一般在创建表时启用全文本搜索: fulltext(column);
在索引之后,使用两个函数Match()和Against()执行全文本搜索,Match()指定被搜索的列,Against指定要使用的搜索表达式。
select column from table where Match(column) Against('模式');
四、插入数据
1、插入完整的行:
insert into tablename values(对应列的次序的值);
这种语法很简单,但并不安全,应该尽量避免使用。编写依赖于特定列次序的SQL语句,如果列发生了变化,有时难免会出问题。
insert into tablename(列的名列表) values(对应的值列表);
虽然麻烦,但即使标的结构改变,该语句仍能正确工作,
2、插入多个行:
insert inte tablename(列的名列表) values(对应的值列表),(对应的值列表);
3、插入检索出的数据:
insert into tableA(列列表) select 列列表 from tableB;
五、更新和删除数据
1、update: 一定要注意确定要更新的条件,一不小心就更新了所有行。
更新表中特定行:
update table set column='value' where id = 1;
如果删除某个列的值,可以set null;
更新表中所有行:
2、delete:一定要仔细,因为稍不注意,就会错误的删除表中的所有行
删除表中特定的行:
delete from tablename where id = 1;
删除表中所有的行:
delete from tablename;
truncate tablename; 这种完成相同的工作,但是效率更高,它是删除原来的表在重新创建一个,而不是一行一行的删除
六、创建表和操纵表
1、创建表:
create table user if not exists
(
id int not null auto_increment,
name varchar(10),
gender char(1) not null default '男',
primary key(id),
foreign key(id) references tableA(id)
)engine=InnoDB;
默认使用 MyISAM引擎,支持全文本搜索
InnoDB引擎,支持事务处理。
引擎类型可以混用,但是外键不能跨引擎
存储引擎:
MySQL可以将数据以不同的技术存储在文件(内存)中,这种技术就成为存储引擎。
每一种存储引擎使用不同的存储机制、索引技巧、锁定水平,最终提供广泛且不同的功能。
2、更新表:
alter table,在理想状态下,当表中存储数据后,该表就不应该在被更新。在表的设计过程中需要花费大量时间来考虑,以便后期不对该表进行大的改动。
alter table add column ; 增加列
alter table drop column; 删除列
alter table modify
alter table 的一种常见用途是定义外键:
alter table tableA add constraint 外键名 foreign key (列名) references tableB (列名);
alter table 要极为小心,应该在进行改动前做一个完整的备份(模式和数据的备份),数据库表的更改不能撤销,如果增加了不需要的列,肯呢过不能删除他们,类似的,如果删除了不应该删除的列,可能会丢失该列中的所有数据。
3、删除表:
drop table tableA; 该语句没有确认,也不能撤销,执行将永久删除该表。
4、重命名表:
rename table tableA to tableB;
七、视图
视图是一个虚拟的表。与包含数据的表不一样,试图只包含使用动态检索数据的查询。即视图中不包含表中应该有的任何列或数据,它包含的是一个SQL查询。
视图的作用:
重用SQL语句。
简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道它的基本查询细节。
使用标的组成部分而不是整个表。
保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限。
更改数据格式和表示。试图可返回与底层表的表示格式不同的数据。
使用视图:
创建视图:create view 视图名 as select 一个联结查询;
查看创建视图的语句:show create view viewname;
删除视图:drop view viewname;
更新视图:create or replace view;
八、使用存储过程
存储过程简单来书,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件。
存储过程的优点:简单、安全、高性能
通过把处理封装在容易使用的单元中,简化复杂的操作。
由于不要求反复建立一系列处理步骤,这保证了数据的完整性。
简化多变动的管理。如果表名、列名或业务逻辑有变化,只需要更改存储过程的代码,使用它的人员甚至不需要知道这些变化。
提高性能。
创建存储过程:
执行存储过程:
九、游标
MySQL游标只能用于存储过程。
创建游标:
打开和关闭游标:
十、使用触发器
触发器是MySQL在响应 insert、update、delete时自动执行的一条语句。
创建触发器:
删除触发器:
使用触发器:
十一、事务处理
事务处理可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行。
相关术语:事务(transaction)、回滚(rollback)、提交(commit)、保留点(savepoint)
控制事务处理:
十二、全球化与本地化
1、字符集和校对顺序:
数据库表被用来存储和检索数据。不同的语言和字符集需要以不同的方式存储和检索。因此,MySQL需要使用不同的字符集,使用不同的排序和检索数据的方法。
字符集:为字母和符号的集合
编码:为某个字符集成员的内部表示
校对:为规定字符如何比较的指令,对 order by 命令的排序结果有重要影响。
show character set; 这条语句显示所有可用的字符集以及每个字符集的描述和默认校对。
show collation; 显示所有可用的校对,以及他们使用的字符集。
确定数据库所用的字符集和校对:
show variables like 'character%';
show variables like 'collation%';
MySQL有六处使用了字符集,分别为:client、connection、database、results、server、system。
client是客户端使用的字符集。
connection是连接数据库的字符集设置类型,如果程序没有指明连接数据库使用的字符集烈性就按照服务器端默认的字符集设置。
database是数据库服务器中某个使用的字符集设定,如果建库是没有指明,将使用服务器安装时指定的字符集设置。
results是数据库给客户端返回时使用的字符集设定,如果没有指明,使用服务器默认的字符集。
server是服务器安装时指定的默认字符集设定。
system是数据库系统使用的字符集设定。
实际上,字符集很少是服务器范围的设置,不同的表,甚至不同的列都可能需要不同的字符集,而且两者都可以在创建表时指定。
create table student(
id int,
name varchar(10) character set gbk collate
)default character set utf8
collate utf8_general_ci;
十三、安全管理
1、访问控制:
用户应该对他们需要的数据有适当的访问权,既不能多也不能少。换句话说,用户不能对过多的数据具有过多的访问权。
使用MySQL Administrator 提供了一个图形界面来管理用户及账号权限。
防止无意识的错误,访问控制的目的不仅仅是防止用户的恶意企图。数据梦魇更为常见的是无意识错误的结果,如打错MySQL语句,在不合适的数据库中操作或其他一些用户错误。通过保证用户不能执行他们不应该执行的语句,访问控制有助于避免这些情况的发生。
不要使用root,应该严肃对待root登录的使用。仅在绝对需要时使用它,不用改在日常的MySQL操作中使用root。
2、管理用户:
MySQL用户账号和信息存储在名为mysql的数据库中。
use mysql;
select user from user;
创建用户账号:
create user 用户名 identified by '密码';
重命名用户账号:
rename user old to new;
删除用户账户:同时删除了所有相关的账号权限。
drop user 用户名;
设置访问权限:在创建用户账号后,必须接着分配访问权限。不然看不到任何数据。
show grants for 用户名@主机名;查看用户权限
grant用法:要授予的权限,被授予访问权限的数据库或表,用户名
grant select on 数据库名.表名 to 用户名;
revoke用法:grant的反操作,用法一样,被撤销的访问权限必须存在。
revoke select on 数据库名.表名 from 用户名;
权限列表:all, alter, create, select, insert,............很多
控制层次: 整个服务器, grant all;
整个数据库, on 数据库名.*;
特定的表, on 数据库名.表名;
特定的列,
特定的存储过程。
简化多次授权:逗号分隔
grant select,insert on database.* to username;
更改口令:使用Password加密
set passward for user = Password('密码');
十四、数据库维护
1、备份数据:(经常备份,各种备份)
使用命令行程序 mysqldump 转储所有数据库内容到某个外部文件。
mysqldump -u root -p 数据库名> e:/backdatabase/备份文件名.sql(txt...).
恢复:mysql -u root -p 数据库名<e:/backdatabase/备份文件名.sql(txt...).
或在数据库内部使用source命令。
使用命令行程序 mysqlhotcopy 从一个数据库复制所有数据。
使用MySQL的 backup table 或 select into outfile 转储所有数据到某外部文件。这两条语句都接受将要创建的文件名,此文件必须不存在,否则会出错。使用 restore table 来复原。
在备份前使用 flush tables 刷新未写数据。
2、进行数据库维护:
analyze table 表名;用来检查表键是否正确。
check table 表名;用来针对许多问题对表进行检查。
如果MyISAM表访问产生不正确和不一致的结果,可能需要 repair table 来修复相应的表。这条语句不应该经常使用,如果经常使用,可能会有更大的问题要解决。
如果从一个表中删除大量数据,应该使用 optimize table 来收回所用的空间,从而优化表的性能。
3、诊断启动问题:
服务器启动问题通常在对MySQL配置或服务器本身进行更改时出现。MySQL在这个问题发生时报告错误,但由于多数MySQL服务器是作为系统进程或服务自启动的,这些消息可能看不到。
在排除系统启动问题是,首先应该尽量用手动启动服务器。MySQL服务器自身通过在命令行执行 mysqld 启动。mysqld命令的参数有:
--help 显示帮助。
--safe-mode 装载减去某些最佳配置的服务器。
--verbose 显示全文本消息(与help联合使用)
--version 显示版本信息然后退出
4、查看日志文件:
MySQL维护管理员依赖的一系列日志文件,主要日志文件有以下几种:
错误日志:它包含启动和关闭问题以及任意关键错误的细节。此日志通常名为 hostname.err, 位于data目录中,此日志名可用 --log-error命令更改。
查询日志:它记录所有MySQL活动,在诊断问题时非常有用。此日志文件可能会很快地变得非常大,因此不应该长期使用它。此日志通常名为hostname.org,位于data目录中,此名字可以用 --log命令更改。
二进制日志:它记录更新过数据的所有语句。此日志通常名为hostname-bin,位于data目录内。此名字可以用--log-bin命令更改。
缓慢查询日志:顾名思义,此日志记录执行缓慢的任何查询。这个日志在确定数据库何处需要优化很有用。此日志通常名为hostname-slow.log,位于data目录中,此名字可以用 --log-slow-queries命令更改.
在使用日志时,可用flush logs语句来刷新和重新开始所有日志文件。
十五、改善性能:
1、MySQL使用一些列的默认设置预先配置的,这些设置开始通常是很好的,但过一段时间后你可能需要调整内存分配、缓冲区大小等。使用show variables; show status; 查看当前设置。
2、MySQL是一个多用户多线程的DBMS,它经常同时执行多个任务。如果这些任务中的某一个执行缓慢,则所有请求都会执行缓慢,如果你遇到显著的性能不良,可使用 show processlist; 显示所有活动进程(以及它们的线程ID和执行时间)。你还可以用 kill 命令终结某个特定的进程。
3、总是有不止一种方法编写同一条select语句。应该试验联结、并、子查询等,找出最佳的方法。
4、使用 explain 语句让MySQL解释他讲如何执行一条select语句。
5、一般来说,存储过程执行得比一条一条地执行其中的各条MySQL语句块。
6、应该总是使用正确的数据类型。
7、绝不要检索比需求还要多的数据。不要使用select *(除非你真正需要每个列)
8、有的操作(包括insert)支持一个可选的 delayed 关键字,如果使用它,将把控制励志返回给调用程序,并且一旦有可能就实际执行该操作。
9、在导入数据时,应该关闭自动提交。你可能还想删除索引(包括 fulltext索引),然后再导入完成后再重建它们。
10、必须索引数据库表以改善数据检索的性能。确定索引什么不是一件微不足道的任务,需要分析使用的select语句以找出重复的 where 和 order by子句。如果一个简单的 where 子句返回结果所花的时间太长,则可以断定其中使用的列就是需要索引的对象。
11、你的select语句中有一系列复杂的 or 条件吗?通过使用多条select语句和连接它们的union语句,你能看到极大的性能改进。
12、索引改善数据检索的性能,但损害数据插入、删除和更新的性能。则对经常需要添加删除数据的表如果不必要的话不要索引它们。
13、like 很慢。一般来说最好使用fulltext而不是like。
14、数据库是不断变化的实体。一组优化良好的表一会儿后可能就面目全非了。由于表的使用和内容的更改,理想的优化和配置也会改变。
15、最重要的规则就是,每条规则在某些条件下都会被打破。