1. MySQL基础
    1. 系统特性
      1. 支持大型的数据库。可以处理拥有上千万条记录的大型数据库
      2. 提供TCP/IP、ODBC和JDBC等多种数据库连接途径。
      3. 使用C和C++编写
    2. 存储引擎
      1. 支持多种存储引擎。,常见的有MyISAM、InnoDB、BDB、Memory 、Merge、Federated、Cluster/NDB、CSV、BlackHole、EXAMPLE
      2. MyISAM Mysql5.5之前的默认数据库引擎,最为常用。拥有较高的存储和查询速度,但不支持事务,使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。 非事务安全性,锁的粒度是表级,支持全文索引,表保存为文件形式,适合跨平台数据转移,索引文件和数据文件是分离的。
        1. MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。
        2. 非聚集索引
      3. InnoDB 事务 型数据库的首选引擎,支持ACID事务,支持行级锁定,适合执行大量的插入和更新操作, MySQL 5.5起成为默认数据库引擎,使用B+Tree作为索引结构 食物安全性,支持行级锁定,不支持全文索引,更安全,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。
        1. 聚集索引
        2. InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
        3. 与MYISAM不同,InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。
          1. 因此,不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。
          2. 还有,用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。
      4. BDB 源自Berkeley DB,事务型数据库的另一种选择,支持COMMIT和ROLLBACK等其他事务特性
      5. Memory 所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。并且其内容会在Mysql重新启动时丢失。 它非常适合存储临时数据的临时表,默认采用哈希索引
      6. Merge 将一定数量的MyISAM表联合而成一个整体,在超大规模数据存储时很有用
      7. Archive 非常适合存储大量的独立的,作为历史记录的数据。因为它们不经常被读取。Archive拥有高效的插入速度,但其对查询的支持相对较差
      8. Federated将不同的Mysql服务器联合起来,逻辑上组成一个完整的数据库。非常适合分布式应用,并不存放数据
      9. Cluster/NDB高冗余的存储引擎,用多台数据机器联合提供服务以提高整体性能和安全性。适合数据量大,安全和性能要求高的应用
      10. CSV: 逻辑上由逗号分割数据的存储引擎。 它会在数据库子目录里为每个数据表创建一个.CSV文件。这是一种普通文本文件,每个数据行占用一个文本行。CSV存储引擎不支持索引。
      11. BlackHole :黑洞引擎,写入的任何数据都会消失,一般用于记录binlog做复制的中继
      12. *** EXAMPLE存储引擎是一个不做任何事情的存根引擎。它的目的是作为MySQL源代码中的一个例子,用来演示如何开始编写一个新存储引擎。同样,它的主要兴趣是对开发者。EXAMPLE存储引擎不支持编索引。另外,Mysql的存储引擎接口定义良好。有兴趣的开发者可以通过阅读文档编写自己的存储引擎。
    3. 应用架构
      1. 单点(Single),适合小规模应用
      2. 复制(Replication),适合中小规模应用
      3. 集群(Cluster),适合大规模应用
    4. 应用环境
      1. 一个稳定免费的网站系统的总体配置
        1. “LAMP“组合
          1. Linux作为操作系统,Apache和Nginx作为Web服务器,MySQL作为数据库,PHP/Perl/Python作为服务器端脚本解释器
    5. 索引功能
      1. 作用
        1. 主要是为最经常查询和最经常排序的数据列建立索引
        2. 索引可以加快数据检索操作,缺点是会使数据修改操作变慢(每修改数据记录,索引就要刷新一次),解决缺点的方法有:使用DELAY_KEY_WRITE,使得对索引的刷新等所有记录插入/修改完毕后再进行,适用于需要把许多新纪录插入某个数据表的场合。
        3. 索引会在硬盘占用相当大空间
      2. 类别
        1. 普通索引
          1. 唯一任务是加快对数据的访问速度
          2. 允许被索引的数据列包含重复的值
        2. 唯一索引 UNIQUE
          1. 不允许被索引的数据列包含重复的值,即某个数据列将只包含彼此各不相同的值
          2. 唯一索引可以保证数据记录的唯一性,主要是为了避免数据出现重复
        3. 主索引 PRIMARY
          1. 为主键字段创建的索引
        4. 外键索引 FOREIGN
          1. 定义一个内部索引来帮助自己以最有效率的方式去管理和使用 外键约束条件(为了某个外键字段定义的)。
        5. 复合索引 例如INDEX(columnA,columnB)
          1. 索引覆盖多个数据列
          2. 这种用法仅适用于在复合索引中排列在前的数据列组合。比如说,INDEX(A,B,C)可以当做A或(A,B)的索引来使用,但不能当做B、C或(B,C)的索引来使用。
        6. 全文索引 FULLTEXT(columnA,columnB)
          1. 生成这种类型的索引时,MySQL将把在文本中出现的所有单词创建为一份清单,查询操作将根据这份清单去检索有关的数据记录。
          2. 创建全文索引的命令:ALERT TABLE tablename ADD FULLTEXT(columnA,lolumnB)
          3. 查询命令:SELECT * FROM tablename WHERE MATCH(columnA,lolumnB) AGAINST('word1','word2','word3') 作用:上面这条命令将把column1和column2字段里有word1、word2和word3 的数据记录全部查询出来。
      3. 长度
        1. 索引长度必须小于这个字段的最大字符个数
        2. 限定索引长度的好处是可以生成一个尺寸比较小、检索速度却比较快的索引文件
      4. 其他
        1. 在不确定给哪些数据列创建索引时,可以使用EXPLAIN SELECT,给一条普通的SELECT命令加一个EXPLAIN关键字作为前缀,MySQL将不是去执行那条SELECT命令,而是去对它进行分析。MySQL将以表格的形式把查询的执行过程和用到的索引等信息列出来。
    6. 基础操作
      1. 管理MySQL的命令
        1. use 数据库名
          1. 选择要操作的Mysql数据库,使用该命令后所有Mysql命令都只针对该数据库。
        2. SHOW DATABASES
          1. 列出 MySQL 数据库管理系统的数据库列表。
        3. SHOW TABLES
          1. 显示指定数据库的所有表,使用该命令前需要使用 use 命令来选择要操作的数据库。
        4. SHOW COLUMNS FROM 数据表
          1. 显示数据表的属性,属性类型,主键信息 ,是否为 NULL,默认值等其他信息。
        5. SHOW INDEX FROM 数据表
          1. 显示数据表的详细索引信息,包括PRIMARY KEY(主键)。
        6. SHOW TABLE STATUS FROM 数据表 LIKE ‘模式%’\G
          1. 该命令将输出Mysql数据库管理系统的性能及统计信息。
          2. mysql> SHOW TABLE STATUS FROM RUNOOB; # 显示数据库 RUNOOB 中所有表的信息
          3. mysql> SHOW TABLE STATUS from RUNOOB LIKE 'runoob%'; # 表名以runoob开头的表的信息
          4. mysql> SHOW TABLE STATUS from RUNOOB LIKE 'runoob%'\G; # 加上 \G,查询结果按列打印
        7. ALTER命令
          1. ALTER TABLE testalter_tbl DROP i;
          2. 删除表的 i 字段
          3. mysql> ALTER TABLE testalter_tbl ADD i INT;
          4. 在表 testalter_tbl 的末尾添加 i 字段,并定义数据类型
          5. ALTER TABLE testalter_tbl ADD i INT FIRST;
          6. FIRST (设定位第一列)
          7. ALTER TABLE testalter_tbl ADD i INT AFTER c;
          8. AFTER 字段名(设定位于某个字段之后)
          9. 注意:想重置数据表字段的位置就需要先使用 DROP 删除字段然后使用 ADD 来添加字段并设置位置。
          10. ALTER TABLE testalter_tbl MODIFY c CHAR(10);
          11. 修改字段类型
          12. ALTER TABLE testalter_tbl CHANGE i j BIGINT;
          13. 修改字段类型和名称。在 CHANGE 关键字之后,紧跟着的是你要修改的字段名,然后指定新字段名及类型。
          14. ALTER TABLE testalter_tbl RENAME TO alter_tbl;
          15. 将数据表 testalter_tbl 重命名为 alter_tbl
          16. ALTER TABLE testalter_tbl MODIFY j BIGINT NOT NULL DEFAULT 100;
          17. 指定字段 j 为 NOT NULL 且默认值为100
          18. ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;
          19. 使用 ALTER 来修改字段的默认值为1000
          20. ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
          21. 删除字段的默认值
      2. php中的MySQL函数
        1. mysql_connect($dbhost,$dbuser,$dbpass)
        2. mysql_select_db('数据库名')
        3. mysql_query($sql,$conn)
        4. mysql_fetch_array($retval,MYSQL_ASSOC)
        5. mysql_fetch_assoc($retval)
        6. mysql_fetch_array($retval,MYSQL_NUM)
        7. mysql_free_result($retval)
        8. mysql_close($conn)
        9. mysql_affected_rows ($conn_id)
          1. 获取查询语句影响的记录数
        10. mysql_insert_id ()
          1. 获取执行的插入SQL语句中 AUTO_INCREMENT列的值
      3. MySQL中的join
        1. (INNER) JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
        2. LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。
        3. RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。
      4. NULL 值处理
        1. IS NULL: 当列的值是NULL,此运算符返回true。
        2. IS NOT NULL: 当列的值不为NULL, 运算符返回true。
        3. <=>: 比较操作符(不同于=运算符),当比较的的两个值为NULL时返回true。
      5. 正则表达式
        1. 使用 LIKE ...% 来进行模糊匹配
        2. 使用REGEXP进行正则表达式匹配
          1. ^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。
          2. $ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。
          3. . 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
          4. [...] 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
          5. [^...] 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
          6. p1|p2|p3 匹配 p1 或 p2 或 p3。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
          7. * 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
          8. + 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
          9. {n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
          10. {n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。
      6. 事务
        1. 注意:在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务
        2. 事务必须满足ACID四个条件
        3. PHP中使用事务
          1. mysql_query("SET AUTOCOMMIT=0");//设置为不自动提交,因为MYSQL默认立即执行
          2. mysql_query("BEGIN");//开始事务定义
          3. mysql_query("ROLLBACK");//判断当执行失败时回滚
          4. mysql_query("COMMIT");//执行事务
      7. 临时表
        1. 作用:保持一些临时数据,临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。
      8. 复制表(克隆)
        1. 步骤: 1.show create table 2.create table 3.insert into ...select ...from..
      9. 序列使用
        1. 由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现
        2. 实现方法
          1. 使用AUTO_INCREMENT 来定义列
          2. AUTO_INCREMENT = 100
          3. 一般情况下序列的开始值为1,前面的语句用于指定一个开始值100
      10. 处理重复数据
        1. 防止表中出现重复数据
          1. 设置指定的字段为 PRIMARY KEY(主键) 或者 UNIQUE(唯一) 索引来保证数据的唯一性
          2. INSERT INTO
          3. INSERT IGNORE INTO
          4. 忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就返回警告,然后跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。
          5. INSERT REPLACE INTO
          6. 如果存在primary 或 unique相同的记录,则先删除掉。再插入新记录。
        2. 过滤重复数据
          1. select distinct
          2. group by
        3. 删除重复数据
          1. 重建新表代替旧表,使用group by
          2. 在数据表中添加 INDEX(索引) 和 PRIMAY KEY(主键)
      11. SQL注入
        1. 定义:通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
        2. 防止SQL注入
          1. 1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。
          2. 2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
          3. 3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
          4. 4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
          5. 5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
          6. 6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky, 网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。
          7. PHP的MySQL扩展
          8. 提供了mysql_real_escape_string()函数来转义特殊的输入字符
          9. addcslashes() 函数在指定的字符前添加反斜杠。
      12. 导出数据
        1. SELECT...INTO OUTFILE 'file_name'
          1. 把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有FILE权限
        2. 导出SQL格式的数据
          1. mysqldump是mysql用于转存储数据库的实用程序。它主要产生一个SQL脚本, 其中包含从头重新创建数据库所必需的命令CREATE TABLE INSERT等。
          2. $ mysqldump -u root -p RUNOOB > database_dump.txt
          3. 导出整个数据库的数据
          4. $ mysqldump -u root -p --all-databases > database_dump.txt
          5. 备份所有数据库
        3. 导入
          1. $ mysql -u root -p database_name < dump.txt
          2. 将备份的数据库导入到MySQL服务器已经创建的数据库中
      13. 导出数据
        1. LOAD DATA LOCAL INFILE 'dump.txt' INTO TABLE mytbl;
          1. 将从当前目录中读取文件 dump.txt ,将该文件中的数据插入到 当前数据库的 mytbl 表中。
          2.  如果指定LOCAL关键词,则表明从客户主机上按路径读取文件。 如果没有指定,则文件在服务器上按路径读取文件。
        2. $ mysqlimport -u root -p --local database_name dump.txt
          1. mysqlimport客户端提供了LOAD DATA INFILEQL语句的一个命令行接口。 mysqlimport的大多数选项直接对应LOAD DATA INFILE子句。
  2. MySQL优化
    1. 结构优化
      1. 索引优化
    2. 查询优化