- 创建数据库:CREATE DATABASE 数据库名字
CREATE DATABASE runoob ;
- 删除数据库:DROP DATABASE 数据库名字
DROP DATABASE runoob;
- 选择数据库:user 数据库
USE runoob;
- 创建数据表:CREATE TABLE 数据表名字(行名 类似,…)
- NOT NULL:规定字段不能是NULL
- AUTO_INCREMENT:定义为自增属性
- PRIMARY KEY:定义列为主键
- ENGINE:设置存储引擎
- CHARSET:设置编码
CREATE TABLE IF NOT EXISTS 'runoob_table1'(
'runoob_id' INT UNSIGNED AUTO_INCREMENT,
'runoob_title' VARCHAR(100) NOT NULL,
`runoob_author` VARCHAR(40) NOT NULL,
`submission_date` DATE,
PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
- 删除数据表:DROP TABLE table_name
DROP TABLE ‘runoob_table1’;
- 插入数据:INSERT INTO 数据表名字(属性名1,属性名2,…,属性名n)
VALUES
(值1,值2,…,值n)
INSERT INTO runoob_table1
(runoob_title,runoob_author,runoob_date)
VALUES
('学习PHP','菜鸟教程',NOW());
- 查询数据SELECT
查询语法:
SELECT 属性名1,属性名2,…
FROM 表名
[WHERE 条件]
[LIMIT N][OFFSET M]
WHERE语句包含任何条件
LIMIT属性用来设定返回的记录数
OFFSET语句指定SELECT语句开始查询的数据偏移量,默认情况下偏移量为0
SELECT *
FROM runoob_table1;
- WHERE子句
- 可以在WHERE语句中指定任何条件
- 可以用AND 和 OR 指定一个或者多个条件
- WHERE子句也可以用在DELETE 和 UPDATE子句
操作符 | 描述 |
---|---|
= | 等号,检测两个值是否相等,相等就返回true |
<> | 不等于,检测两个值不相等就返回true |
!= | 不等于,检测两个值不相等就返回true |
< | 小于号,左边值小于右边值就返回true |
> | 大于号,左边值大于右边值就返回true |
>= | 大于等于,左边值大于等于右边值就返回true |
<= | 小于等于,左边值小于等于右边值就返回true |
SELECT *
FROM runoob_table
WHERE runoob_author='菜鸟教程';
- 修改数据表数据UPDATE
修改数据表数据语法:
UPDATE 数据表名 SET 属性名1=值1,属性名2=值2,…
[WHERE 条件]
UPDATE runoob_table
SET runoob_title='学习C++'
WHERE runoob_id=3;
- 从数据表删除数据
删除的语法:
DELETE FROM 数据表名
WHERE 条件
- 如果没有指定WHERE子句,那么数据表中的所有数据都会被删除
- 可以在单个表中一次性删除数据
DELETE FROM runoob_table1
WHERE runoob_id = 3;
- LIKE子句
举例,假设我们需要runoob_author字段包含’COM’字符的所有记录,我们就需要在WHERE子句中使用LIKE。
LIKE子句中用%表示任意字符,如果没有使用%那么效果与=一样。
语法:
SELECT 属性名1,属性名2,…
FROM 数据表名
WHERE 属性名1 LIKE 某一情况 [AND [OR] 属性名2 = 值1]
SELECT runoob_id, runoob_title
FROM runoob
WHERE runoob_author LIKE '%COM';
- 连接操作符UNION
语法格式:
SELECT 属性名1,属性名2,…
FROM 数据表1
[WHERE 条件1]
UNION [ALL|DISTINCT]
SELECT 属性名1,属性名2,…
FROM 数据表2
[WHERE 条件2]
- DISTINCT:可选,删除结果集中重复的数据。默认情况下 UNION 操作符已经删除了重复数据,所以 DISTINCT 修饰符对结果没啥影响。
- ALL:可选,返回所有结果集,包含重复数据。
SELECT contury
FROM Websites
UNION
SELECT contury
FROM apps
ORDER BY contury;
带有WHERE子句的例子
SELECT contury
FROM Websites
WHERE contury='CN'
UNION ALL
SELECT contury
FROM apps
WHERE contury='EN'
- 对结果进行排序ORDER BY
如果我们需要对结果进行排序,我们可以使用ORDER BY子句。默认情况下按照升序排列。
语法:
SELECT 属性名1,属性名2,…
FROM 数据表1
ORDER BY 属性名1,属性名2 [ASC[DESC]];
SELECT *
FROM runoob
ORDER BY author DESC;
- 对结果进行分组GROUP
对结果根据一个或多个列进行分组,在分组上我们可以使用COUNT,SUM,AVG等函数。
语法:
SELECT 属性名,函数名(属性名)
FROM 表名
WHERE 条件
GROUP BY 属性名
SELECT name,COUNT(*)
FROM runoob
GROUP BY name
在分组统计数据的基础上再进行相同的统计(SUM,AVG,COUNT),就可以加上with rollup,作用是在分组统计的基础上,还会加上一行显示函数的结果。
举例子:
假设数据表
id | name | age |
---|---|---|
1 | A | 21 |
2 | B | 22 |
3 | C | 23 |
4 | D | 21 |
5 | E | 22 |
如果SQL语句是
SELECT COUNT(*),age
FROM table
GROUP BY age;
那么显示结果是
COUNT(*) | age |
---|---|
2 | 21 |
2 | 22 |
1 | 23 |
但是如果SLQ语句是
SELECT COUNT(*) ,age
FROM table
GROUP BY age WITH ROLLUP;
那么结果是
COUNT(*) | age |
---|---|
2 | 21 |
2 | 22 |
1 | 23 |
5 | NULL |
其中NULL那一行就是显示函数的汇总结果
- MySQL中的连接
分类 | 用处 |
---|---|
INNER JOIN(内连接或等值连接) | 获取两个表中字段匹配关系的记录。 |
LEFT JOIN(左连接) | 获取左表所有数据,即使右表没有对应的匹配记录 |
RIGHT JOIN(右连接) | 获取右表所有数据,即使左表没有对应的匹配记录 |
假设有两个表如下,表1名为author_count,表2名为title_author
author | count |
---|---|
菜鸟教程 | 10 |
RUNOOB.COM | 20 |
22 |
id | title | author | date |
---|---|---|---|
1 | 学习PHP | 菜鸟教程 | 2017-04-12 |
2 | 学习C++ | 菜鸟教程 | 2017-04-12 |
3 | 学习Java | RUNOOB.COM | 2015-05-01 |
4 | 学习Python | RUNOOB.COM | 2016-03-06 |
5 | 学习C | FK | 2017-04-05 |
使用了以下的SQL语句
SELECT a.author,a.count
FROM author_count a INNER JOIN title_author b ON a.author=b.author
结果如下表
a.author | a.count |
---|---|
菜鸟教程 | 10 |
菜鸟教程 | 10 |
RUNOOB.COM | 20 |
RUNOOB.COM | 20 |
如果使用了以下SQL语句
SELECT b.author,b.id,a.count
FROM title_author b LEFT JOIN author_count a ON a.author = b.author
结果如下表
b.author | b.id | a.count |
---|---|---|
菜鸟教程 | 1 | 10 |
菜鸟教程 | 2 | 10 |
RUNOOB.COM | 3 | 20 |
RUNOOB.COM | 4 | 20 |
FK | 5 | NULL |
因为是 title_author LEFT JOIN author_count 所以在左边的表二的所有数据都要保留,但是在表一中没有的FK那一行中的count应该是NULL。
如果使用以下SQL语句
SELECT b.id,b.author,a.count
FROM title_author b RIGHT JOIN author_count a ON a.author = b.author
结果如下表
b.id | b.author | a.count |
---|---|---|
1 | 菜鸟教程 | 10 |
2 | 菜鸟教程 | 10 |
3 | RUNOOB.COM | 20 |
4 | RUNOOB.COM | 20 |
NULL | NULL | 22 |
上表的结果中应该注意,在author_count中最后一行的author是Google,但是结果却是NULL,是因为在SELECT语句中选择的是b.author也就是title_author中的author。
- MySQL中的NULL处理
为了处理NULL值,SQL中有三种运算符
- IS NULL:当列的值是NULL,这个表达式返回true
- IS NOT NULL :当列的值不是NULL,这个表达式返回true
- <=>:比较操作符,当比较的两个值为NULL则返回true
SELECT *
FROM author_title
WHERE count IS NULL;
- MySQL的正则表达式
MySQL中使用 REGEXP 操作符来进行正则表达式匹配。
模式 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。 |
. | 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式 |
[…] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^…] | 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3。例如,‘z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
举例子
想要找出名字以"st"开头的所有名字
SELECT name
FROM student
WHERE name REGEXP '^st';
想要找到名字以"er"结尾的所有名字
SELECT name
FROM student
WHERE name REGEXP 'er$';
想要找到名字里面有"as"并且后面接任意一个字符的所有名字
SELECT name
FROM student
WHERE name REGEXP 'as.';
想要找到名字里面以"a"或者"b"开头并且以"wq"结尾的所有名字
SELECT name
FROM student
WHERE name REGEXP '^[a|b]wq$';
- MySQL事务
- MySQL中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
- 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
- 事务用来管理 insert,update,delete 语句
事务一般满足4个条件:原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
- 原子性:一个事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间某个环节。
- 一致性:在事务开始之前和事务结束之后,数据库的完整性没有被破坏。这表示写入的资料必须符合所有的预设规则。
- 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力。
- 持久性:事务处理结束之后,对数据的修改是永久的,即便发生故障也不会丢失。
事务控制语句: - 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。
MySQL的事务处理主要有两种方法
- 用 BEGIN, ROLLBACK, COMMIT来实现
- BEGIN 开始一个事务
- ROLLBACK 事务回滚
- COMMIT 事务确认
- 直接用 SET 来改变 MySQL 的自动提交模式
- SET AUTOCOMMIT=0 禁止自动提交
- SET AUTOCOMMIT=1 开启自动提交
- MySQL中的ALTER语句
当我们需要修改数据表名或者修改数据表字段时用ALTER
以下SQL语句可以删除table_one数据表中名为name的字段
ALTER TABLE table_one DROP name;
以下SQL语句可以在table_one数据表中增加名为number的字段并规定了数据类型。
ALTER TABLE table_one ADD number INT;
如果在增加数据表的字段时想要规定字段的位置,可以使用FIRST等
ALTER TABLE table_one ADD number INT FIRST;
ALTER TABLE table_one ADD number INT AFTER name;
FIRST和AFTER关键字只占用ADD子句,如果需要更改字段位置,就需要先DROP再ADD。
如果需要修改字段类型或名称,可以在ALTER命令中使用MODIFY或CHANGE子句。
举例子:
把字段 name 的类型从 CHAR(1) 改为 CHAR(10),可以执行以下命令
ALTER TABLE table_one MODIFY name CHAR(10);
使用 CHANGE 子句, 语法有很大的不同。 在 CHANGE 关键字之后,紧跟着的是你要修改的字段名,然后指定新字段名及类型。
ALTER TABLE table_one CHANGE number number BIGINT;
ALTER TABLE table_one CHANGE number new_number INT;
当你修改字段时,你可以指定是否包含值或者是否设置默认值。
举例子指定字段number为NOT NULL并且默认值为100
ALTER TABLE table_one
MODIFY number BIGINT NOT NULL DEFAULT 100;
修改字段的默认值
ALTER TABLE table_one ALTER number SET DEFAULT 1000;
也可以用ALTER中的DROP子句删除字段默认值
ALTER TABLE table_one ALTER number DROP DEFAULT;
修改数据表类型,可以使用ALTER命令以及TYPE子句来完成。
举例子我们将表 table_one 的类型修改为 MYISAM :
ALTER TABLE table_one ENGINE = MYISAM;
如果需要修改数据表的名称,可以在 ALTER TABLE 语句中使用 RENAME 子句来实现。
举例子把数据表table_one改名为table_two
ALTER TABLE table_one RENAME TO table_two;
- MySQL的索引
索引可以大大提高MySQL的检索速度。
索引分为单列索引和组合索引
单列索引就是一个索引只包含单个列,一个表可以有多个单列索引。
组合索引就是一个索引包含多个列。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上索引也是一张表,该表保存了主键和索引字段,并指向实体表的记录。
索引的缺点:虽然索引大大提高了查询速度,但是同时却会降低更新表的速度,如对表进行INSERT、UPDATE、DELETE。因为更新表时MySQL不仅要保存数据,还要保存索引文件。
建立索引还会占用磁盘空间的索引文件
- 普通索引:这是最基本的索引,他没有任何限制。
- 创建索引:
如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。CREATE INDEX indexName ON mytable(username(length));
- 在修改表结构的时候添加索引:
ALTER TABLE tableName ADD INDEX indexName(columnName);
- 在创建表的时候直接指定索引 :
CREATE TABLE table_name( id INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [index_name] (username(length)) );
- 删除索引的语法:
DROP INDEX [indexName] ON table_name;
- 创建索引:
- 唯一索引
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:- 创建索引
CREATE UNIQUE INDEX index_name ON table_name(username(length)) ;
- 修改表的结构
ALTER table table_name ADD UNIQUE [index_name] (username(length))
- 创建表的时候直接指定
CREATE TABLE table_name( id INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [index_name] (username(length)) );
- 创建索引
- 使用ALTER命令添加和删除索引
- ALTER TABLE table_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。
- ALTER TABLE table_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。
- ALTER TABLE table_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。
- ALTER TABLE table_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。
- 显示索引
SHOW INDEX FROM table_name;
- MySQL临时表
MySQL临时表保存一些临时数据非常有用。临时表只在当前连接可见,当关闭连接时,MySQL会自动删除表并释放所有空间。- 创建临时表
CREATE TEMPORARY TABLE table_name( product_name VARCHAR(50) NOT NULL, total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00, avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00, total_units_sold INT UNSIGNED NOT NULL DEFAULT 0 );
- 删除临时表
默认情况下,当你断开与数据库连接时,临时表就会自动断开连接。当然也可以手动删除临时表。DROP TABLE tem_table_name;
- 创建临时表
- 复制表
如果我们需要完全复制MySQL数据表,包括表的结构,索引,默认值等,仅仅使用CREATE TABLE … SELECT命令是无法实现的。
复制表需要以下的步骤:- 使用 SHOW CREATE TABLE 命令获取创建数据表(CREATE TABLE) 语句,该语句包含了原数据表的结构,索引等。
- 复制以下命令显示的SQL语句,修改数据表名,并执行SQL语句,通过以上命令 将完全的复制数据表结构。
- 如果你想复制表的内容,你就可以使用 INSERT INTO … SELECT 语句来实现。
步骤一
SHOW CREATE TABLE runoob_tbl;
得到的结果假设是
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
那么步骤二是
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;
那么在步骤二之后得到的就是一个没有数据的克隆表
步骤三
INSERT INTO clone_tbl (runoob_id,
runoob_title,
runoob_author,
submission_date)
SELECT runoob_id,runoob_title,
runoob_author,submission_date
FROM runoob_tbl;
- 元数据
你可能想知道以下三种信息
- 查询结果信息: SELECT, UPDATE 或 DELETE语句影响的记录数。
- 数据库和数据表的信息: 包含了数据库及数据表的结构信息。
- MySQL服务器信息: 包含了数据库服务器的当前状态,版本号等。
命令 | 描述 |
---|---|
SELECT VERSION( ) | 服务器版本信息 |
SELECT DATABASE( ) | 当前数据库名 (或者返回空) |
SELECT USER( ) | 当前用户名 |
SHOW STATUS | 服务器状态 |
SHOW VARIABLES | 服务器配置变量 |
- MySQL序列使用
MySQL序列是一组整数:1,2,3,…由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。
- 使用AUTO_INCREMENT
使用序列最简单的方法就是使用AUTO_INCREMENT来定义列
在以下的table_name中的id无需指定值可以实现自动增长。CREATE TABLE table_name( id INT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id), name VARCHAR(30) NOT NULL, date DATE NOT NULL, origin VARCHAR(30) NOT NULL );
- 获取AUTO_INCREMENT的值
在MySQL的客户端中你可以使用 SQL中的LAST_INSERT_ID( ) 函数来获取最后的插入表中的自增列的值。 - 重置序列
如果你删除了数据表中的多条记录,并希望对剩下数据的AUTO_INCREMENT列进行重新排列,那么你可以通过删除自增的列,然后重新添加来实现。 不过该操作要非常小心,如果在删除的同时又有新记录添加,有可能会出现数据混乱。操作如下所示:
ALTER TABLE insect DROP id; #先删除自增的列
ALTER TABLE insect
ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (id); #再增加自增的列
- 设置序列的开始值
一般情况下序列的开始值为1,但如果你需要指定一个开始值100,那我们可以通过以下语句来实现:
CREATE TABLE insect(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id),
name VARCHAR(30) NOT NULL,
date DATE NOT NULL,
rigin VARCHAR(30) NOT NULL
)engine=innodb auto_increment=100 charset=utf8;;
也可以在表创建成功之后,通过以下语句实现
ALTER TABLE t AUTO_INCREMENT = 100;
- MySQL处理重复数据
- 防止表中出现重复数据
MySQL数据表中设置指定的字段为 PRIMARY KEY(主键) 或者 UNIQUE(唯一) 索引来保证数据的唯一性。
如果想要设置字段中first_name和last_name不能重复,那么我们可以设置为双主键模式,设置为双主键那么默认值不能为NULL,可设置为NOT NULL。CREATE TABLE table_name( first_name CHAR(20) NOT NULL, last_name CHAR(20) NOT NULL, sex CHAR(10), PRIMARY KEY(last_name,first_name) );
- 我们可以使用INSERT IGNORE INTO
INSERT IGNORE 会忽略数据库中已经存在的数据,如果数据库没有数据,就插入数据,如果有数据,就保留数据库中已经存在的数据。也就是INSERT IGNORE 不会插入重复的数据,并且执行的时候不会报错 - 我们还可以使用REPLACE INTO
REPLACE INTO 中如果存在primary或者unique的相同记录,则会先删除,再插入新记录 - 同上面那个例子,如果想要first_name和last_name不重复,那么可以设置一个UNIQUE索引。
CREATE TABLE table_name( first_name CHAR(20) NOT NULL, last_name CHAR(20) NOT NULL, sex CHAR(10), UNIQUE (first_name,last_name) );
- 统计重复数据
假设上面的例子,统计first_name和last_name的重复数SELECT COUNT(*) as repetitions,last_name,first_name FROM table_name GROUP BY last_name,first_name HAVING repetitions>1;
- 过滤重复数据
如果需要过滤掉重复的数据,可以在SELECT语句中加上DISTINCT关键词来过滤数据。
也可以用GROUP BY 来过滤重复数据SELECT DISTINCT first_name,last_name FROM table_name;
SELECT first_name,last_name FROM table_name GROUP BY (first_name,last_name);
- 删除重复数据
也可以在数据表中添加索引和主键来删除表中的记录CREATE TABLE new_table SELECT first_name,last_name,sex FROM table_name GROUP BY (first_name,last_name,sex); DROP TABLE table_name; ALTER TABLE new_table RENAME TO table_name;
ALTER IGNORE TABLE table_name ADD PRIMARY KEY(last_name,first_name);
- SQL和SQL注入
所谓的SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或网页请求的查询字符,最终达到欺骗服务器执行恶意的SQL命令。我们需要对用户数据进行过滤处理。
为了防止SQL注入我们需要注意以下几点:- 永远不要信任用户的输入。
- 永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
- 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
- 不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
- 应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
- 导出数据
SELECT * FROM table_name INTO OUTFILE '/tmp/runoob.txt';
以上从菜鸟教程上总结的SQL基础,有不对欢迎指正