本节复习mysql的基础知识,这部分会较详细的复习,因为mysql在日常开发中起到的作用非常大
1, mysql 新增用户 insert into user (host, user, password, select_priv, insert_priv, update_priv) values ('localhost', 'guest', password('root'), 'Y', 'Y', 'Y')
其中的password('root')是对密码进行加密,然后存储
增加完用户后同时要进行 flush privileges 进行重新载入索引表,这样才能起作用
2,mysql命令新增用户的方法: GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON TUTORIALS.* TO 'zara'@'localgost' IDENTIFIED BY 'zara123'
3,常用的mysql管理命令
use 数据库名 选库
show databases 列出mysql数据库管理系统的数据库列表
show tables 显示指定数据库的所有表
show columns from 数据表 显示数据表的属性,属性类型,主键信息,是否为null, 默认值等其他信息
show index from 数据表 展示数据表的详细索引信息,包括primary key 主键
show tables status
4,PHP 提供了函数 mysqli_select_db 来选取一个数据库。函数在执行成功后返回 TRUE ,否则返回 FALSE 。mysqli_select_db(connection,dbname);
5,数值类型
6,日期与时间类型
7,字符串类型
8,在我们执行完 SELECT 语句后,释放游标内存是一个很好的习惯。可以通过 PHP 函数 mysqli_free_result() 来实现内存的释放。
9,MySQL 的 WHERE 子句的字符串比较是不区分大小写的。 你可以使用 BINARY 关键字来设定 WHERE 子句的字符串比较是区分大小写的。
mysql> SELECT * from runoob_tbl WHERE BINARY runoob_author='runoob.com'; Empty set (0.01 sec) mysql> SELECT * from runoob_tbl WHERE BINARY runoob_author='RUNOOB.COM'; +-----------+---------------+---------------+-----------------+ | runoob_id | runoob_title | runoob_author | submission_date | +-----------+---------------+---------------+-----------------+ | 3 | JAVA 教程 | RUNOOB.COM | 2016-05-06 | | 4 | 学习 Python | RUNOOB.COM | 2016-03-06 | +-----------+---------------+---------------+-----------------+ 2 rows in set (0.01 sec)
10,select country from A union select country from B UNION 不能用于列出两个表中所有的country。如果一些网站和APP来自同一个国家,每个国家只会列出一次。UNION 只会选取不同的值。请使用 UNION ALL 来选取重复的值!
若要列出所有的值,包括重复的,可以使用union all select country from A union all select country from B
11, group by 可以根据一个列或者多个列对结果进行分组,在分组的列上可以使用count, sum avg 进行计算
使用 with rollup 可以实现在分组统计数据基础上再进行相同的统计
select name, SUM(singin) as sing_count from employee_tb1 group by name with rollup
其中null 中的值为所有人的所有次数,可以使用coalesce 来设置一个可以取代null的名称,coalesce的语法;
select coalesce(a,b,c); 如果a==null,则选择b;如果b==null,则选择c;如果a!=null,则选择a;如果a b c 都为null ,则返回为null(没意义)。
将sql 改为 select coalesce(name,'总数'), SUM(singin) as sing_count from employee_tb1 group by name with rollup
12, having having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。
eg: select region sum(pop), sum(area) from A group by region having sum(area) >100000
以下是having和where的区别:
Select city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
作用的对象不同。WHERE 子句作用于表和视图,HAVING 子句作用于组。
WHERE 在分组和聚集计算之前选取输入行(因此,它控制哪些行进入聚集计算), 而 HAVING 在分组和聚集之后选取分组的行。因此,WHERE
子句不能包含聚集函数; 因为 试图用聚集函数判断那些行输入给聚集运算是没有意义的。 相反,HAVING
子句总是包含聚集函数。(严格说来,你可以写不使用聚集的 HAVING 子句, 但这样做只是白费 劲。同样的条件可以更有效地用于 WHERE
阶段。)
13,mysql 多表联查的时候需要使用到了join 包括inner join, left join, rignt join
INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。
RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。
14, 连表查询实例
inner join 内连接查询:
获取A表与B表中runoob_id一样的列的runoob_id和runoob_author
select a.runoob_id, a.runoob_author, b.runoob_count from A a inner join B b on a.runoob_id = b.runoob_id
图解:
left join
MySQL left join 与 join 有所不同。 MySQL LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据。
select a.runoob_id, a.runoob_author,b.runoob_count from A a left join B b on a.runoob_author = b.runoob_author
以上实例中使用了 LEFT JOIN,该语句会读取左边的数据表 A 的所有选取的字段数据,即便在右侧表 B 中 没有对应的 runoob_author 字段值。
图解:
right join
MySQL RIGHT JOIN 会读取右边数据表的全部数据,即便左边边表无对应数据。
select a.runoob_id, a.runoob_author,b.runoob_count from A a right join B b on a.runoob_author = b.runoob_author
与left相反,主要以右侧表为主
15,在mysql 中使用正则表达式进行匹配
eg: select name from person_tb1 where name REGEXP '^st' 取出以st开头的符合条件的列
16, 事务
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
事务用来管理 insert,update,delete 语句
一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
17,事务的原子性:一组事务,要么成功;要么撤回。稳定性 :有非法数据(外键约束之类),事务撤回。隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit 选项 决定什么时候吧事务保存到日志里。
在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。
18, 事务的控制语句:
BEGIN或START TRANSACTION;显式地开启一个事务;
COMMIT;也可以使用COMMIT WORK,不过二者是等价的。COMMIT会提交事务,并使已对数据库进行的所有修改称为永久性的;
ROLLBACK;有可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
SAVEPOINT identifier;SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;
RELEASE SAVEPOINT identifier;删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
ROLLBACK TO identifier;把事务回滚到标记点;
SET TRANSACTION;用来设置事务的隔离级别。InnoDB存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。
19,mysql 的事务处理主要有两种方法
用 BEGIN, ROLLBACK, COMMIT来实现 BEGIN 开始一个事务 ROLLBACK 事务回滚 COMMIT 事务确认
直接用 SET 来改变 MySQL 的自动提交模式: SET AUTOCOMMIT=0 禁止自动提交 SET AUTOCOMMIT=1 开启自动提交
20,在php 中使用事务的时候,默认mysql是开启自动提交的,因此需要设置不自动提交 mysqli_query($conn, "SET AUTOCOMMIT=0");
21,Alert 当我们需要修改数据表名或者修改数据表字段时,就需要使用到MySQL ALTER命令。
22,索引:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。
23,mysql 临时表 MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。即,当php执行完后,在执行中生成的临时表会删除
创建实例;
24,复制表 如果我们需要完全的复制MySQL的数据表,包括表的结构,索引,默认值等。 如果仅仅使用CREATE TABLE ... SELECT 命令,是无法实现的。
因此使用如下步骤,复制完整的数据表:
使用 SHOW CREATE TABLE 命令获取创建数据表(CREATE TABLE) 语句,该语句包含了原数据表的结构,索引等。
复制以上命令显示的AQL语句,修改表名,并执行sql语句,通过以上语句可以完全的复制数据表结构
若想复制表的内容可以使用insert into table ....select 语句来实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1,显示表结构 mysql> SHOW CREATE TABLE runoob_tbl G; *************************** 1. row *************************** Table: runoob_tbl Create Table: CREATE TABLE `runoob_tbl` ( `runoob_id` int(11) NOT NULL auto_increment, `runoob_title` varchar(100) NOT NULL default '', `runoob_author` varchar(40) NOT NULL default '', `submission_date` date default NULL, PRIMARY KEY (`runoob_id`), UNIQUE KEY `AUTHOR_INDEX` (`runoob_author`) ) ENGINE=InnoDB 2,修改SQL语句,并执行 mysql> CREATE TABLE `clone_tbl` ( -> `runoob_id` int(11) NOT NULL auto_increment, -> `runoob_title` varchar(100) NOT NULL default '', -> `runoob_author` varchar(40) NOT NULL default '', -> `submission_date` date default NULL, -> PRIMARY KEY (`runoob_id`), -> UNIQUE KEY `AUTHOR_INDEX` (`runoob_author`) -> ) ENGINE=InnoDB; 3,将数据拷贝到复制表 mysql> INSERT INTO clone_tbl (runoob_id, -> runoob_title, -> runoob_author, -> submission_date) -> SELECT runoob_id,runoob_title, -> runoob_author,submission_date -> FROM runoob_tbl;
25,mysql 元数据 在PHP中,你可以使用 mysqli_affected_rows( ) 函数来获取查询语句影响的记录数。
获取服务器的元数据
26,Mysql 序列使用
MySQL序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。
MySQL中最简单使用序列的方法就是使用 MySQL AUTO_INCREMENT 来定义列。
获取auto_increment 的值, 在php中使用mysql_inser_id() 来获取最后一个自增列的值
重置序列: 如果你删除了数据表中的多条记录,并希望对剩下数据的AUTO_INCREMENT列进行重新排列,那么你可以通过删除自增的列,然后重新添加来实现。 不过该操作要 非常小心,如果在删除的同时又有新记录添加,有可能会出现数据混乱。
设置序列的开始值: 一般情况下序列的开始值为1,但如果你需要指定一个开始值100,那我们可以通过以下语句来实现:
或者你也可以在表创建成功后,通过以下语句来实现: ALTER TABLE t AUTO_INCREMENT = 100;
27,mysql 处理重复数据
INSERT IGNORE INTO与INSERT INTO的区别就是INSERT IGNORE会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。
统计重复数据: 使用group by 分组及having筛选进行查找 select count(*) as repetitions, last_name, first_name from person group by last_name, first_name having repitions > 1
过滤重复数据:如果你需要读取不重复的数据可以在 SELECT 语句中使用 DISTINCT 关键字来过滤重复数据。
28,SQL注入:
防止SQL注入,我们需要注意以下几个要点:
1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用 MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。
29,防止sql注入,可以进行对特殊含义字符转义
PHP的MySQL扩展提供了mysqli_real_escape_string()函数来转义特殊的输入字符。
30,Like 语句的注入
like查询时,如果用户输入的值有"_"和"%",则会出现这种情况:用户本来只是想查询"abcd_",查询结果中却有"abcd_"、"abcde"、"abcdf"等等;用户要查询"30%"(注:百分之三十)时也会出现问题。在PHP脚本中我们可以使用addcslashes()函数来处理以上情况
31,Mysql 数据导出
1,MySQL中你可以使用SELECT...INTO OUTFILE语句来简单的导出数据到文本文件上。
eg: 1>,导出到文本文件txt中 select * from runoob_tb1 into outfile '/tmp/a.txt'
2>,也可以通过命令选项来设置数据输出的指定个数,例如导出csv文件
select * from passwd into outfile './tmp/a.txt' fields terminated by ',' enclosed by '"' lines terminated by ' '
3>,下面例子中导出的文件各值使用逗号进行分割,可以被许多程序利用
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY ' ' FROM test_table;
32,select ...into outfile 具有的属性
LOAD DATA INFILE是SELECT ... INTO OUTFILE的逆操作,SELECT句法。为了将一个数据库的数据写入一个文件,使用SELECT ... INTO OUTFILE,为了将文件读回数据库,使用LOAD DATA INFILE。
SELECT...INTO OUTFILE 'file_name'形式的SELECT可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有FILE权限,才能使用此语法。
输出不能是一个已存在的文件。防止文件数据被篡改。
你需要有一个登陆服务器的账号来检索文件。否则 SELECT ... INTO OUTFILE 不会起任何作用。
在UNIX中,该文件被创建后是可读的,权限由MySQL服务器所拥有。这意味着,虽然你就可以读取该文件,但可能无法将其删除。
33,mysqldump 导出表作为原始数据
mysqldump是mysql用于转存储数据库的实用程序。它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE TABLE INSERT等。
使用mysqldump导出数据需要使用 --tab 选项来指定导出文件指定的目录,该目标必须是可写的。
mysqldump -u root -p --no-create-info --tab=/tmp RUNOOB runoob_tbl
导出sql格式的数据到指定文件
mysqldump -u root -p RUNOOB runoob_tbl > dump.txt
导出整个数据库的数据
mysqldump -u root -p RUNOOB > database_dump.txt
备份所有数据库,可以使用以下命令:
mysqldump -u root -p --all-databases > database_dump.txt
将数据导入到远程服务器:
需要确保两台服务器是相通的,可以相互访问的
mysqldump -u root -p database_name | mysql -h other-host.com database_name
34,Mysql 导入数据
MySQL中可以使用两种简单的方式来导入MySQL导出的数据。
1>,使用LOAD DATA导入数据
MySQL 中提供了LOAD DATA INFILE语句来插入数据。 以下实例中将从当前目录中读取文件 dump.txt ,将该文件中的数据插入到当前数据库的 mytbl 表中。
LOAD DATA LOCAL INFILE 'dump.txt' INTO TABLE mytbl; 如果指定LOCAL关键词,则表明从客户主机上按路径读取文件。如果没有指定,则文件在服务器上按路径读取文件。
2>, 使用mysqlimport 导入数据
mysqlimport客户端提供了LOAD DATA INFILEQL语句的一个命令行接口。mysqlimport的大多数选项直接对应LOAD DATA INFILE子句。
从文件 dump.txt 中将数据导入到 mytbl 数据表中, 可以使用以下命令: mysqlimport -u root -p --local database_name dump.txt
mysqlimport命令可以指定选项来设置指定格式,命令语句格式如下:mysqlimport -u root -p --local --fields-terminated-by=":" --lines-terminated-by=" " database_name dump.txt
mysqlimport 语句中使用 --columns 选项来设置列的顺序: mysqlimport -u root -p --local --columns=b,c,a database_name dump.txt