安装mysql
首先找到免安装版的mysql包,之后书写一个.ini文件进行初始化配置,可参考csdn网址
MySql的配置——详细教程_二哈喇子!的博客-CSDN博客_配置mysql
在控制台输入mysql直接进入mysql操作界面,首先需要找到mysql的目录,如C:\Users\wei\Desktop\mysql-5.7.26-winx64,后在环境变量中的系统变量添加 变量名:MYSQL_HOME 变量值;C:\Users\wei\Desktop\mysql-5.7.26-winx64,在Path中添加 %MYSQL_HOME%\bin 即可直接输入mysql进行操作mysql数据库。
连接数据库
mysql -u root -p //root为数据库用户名 输入后会提示界面 enter Password: 输入即可进入数据库
创建数据库
mysql> Create database test;//创建以一个名为test的数据库。
删除数据库
mysql> drop database test; //删除名为test的数据库
选择数据库
mysql> use mysql; //要先建立连接才可以选择数据库
创建表格
//创建表格前要选择表格 root@host# mysql -u root -p Enter password:******* mysql> use RUNOOB; Database changed mysql> CREATE TABLE runoob_tbl (runoob_id INT NOT NULL 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; Query OK, 0 rows affected (0.16 sec)
删除表格
//删除表格也要先选择数据库 删除的表必须是数据库中有的表 mysql> use testtable; mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | testtable | +----------------+ 1 row in set (0.00 sec) mysql> drop table testtable;
插入数据
//插入数据也要选择数据库,第一个括号的参数为表项,第二个参数为插入的值 mysql> use testtable; mysql> show runoob_tbl; INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES ("学习 PHP", "菜鸟教程", NOW());
查询数据
//查询表中的所有数据 SELECT * FROM runoob_tbl; //查询表中的部分数据 SELECT runoob_id, runoob_title FROM runoob_tbl;
WHRER子句
//在runoob_tbl表中查询 runoob_author等于 菜鸟教程 的所有信息 SELECT * FROM runoob_tbl WHERE runoob_author='菜鸟教程';
UPDATA更新
//更新runoob_tbl的数据,将表中runoob_id = 3 的 runoob_title 信息改为学习 C++ UPDATE runoob_tbl SET runoob_title='学习 C++' WHERE runoob_id=3;
DELETE 语句
//删除表runoob_tbl 中 runoob_id = 3 的语句 DELETE FROM runoob_tbl WHERE runoob_id=3;
LIKE语句
//查询 SELECT * from runoob_tbl WHERE runoob_author LIKE '%COM'; //当查询的语句具有中文的时候 需要注意编码问题,否则可能会出现查询不到的结果 //可先进行字符转换 转换为utf-8后进行查询 SHOW VARIABLES LIKE 'character_set_%'; SET character_set_database = utf8 ; //字符的使用方法 % 百分号通配符:表示任何字符出现任意次数(可以是0次). _ 下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符. like操作符: LIKE作用是指示mysql后面的搜索模式是利用通配符而不是直接相等匹配进行比较. 如果在使用like操作符时,后面的没有使用通用匹配符效果是和=一致的, SELECT * FROM products WHERE products.prod_name like '1000'; % 通配符使用: 1、匹配以"Li"开头的记录:(包括记录"Li") : SELECT *FROM products WHERE products.prod_name like 'Li%'; 2、匹配包含"Li"的记录(包括记录"Li") : SELECT* FROM products WHERE products.prod_name like '%Li%'; 3、匹配以"Li"结尾的记录(包括记录"Li",不包括记录"Li ",也就是Li后面有空格的记录,这里需要注意) : SELECT * FROM products WHERE products.prod_name like '%Li'; _ 通配符使用: 1、匹配结果为: 像"xLi"这样记录. SELECT FROM products WHERE products.prod_name like '_Li'; 2、匹配结果为: 像"Lixx"这样的记录.(一个下划线只能匹配一个字符,不能多也不能少) SELECT FROM products WHERE products.prod_name like 'Li**'; 注意事项: 注意大小写,在使用模糊匹配时,也就是匹配文本时,mysql是可能区分大小的,也可能是不区分大小写的,这个结果是取决于用户对MySQL的配置方式.如果是区分大小写,那么像liyue这样记录是不能被"Li__"这样的匹配条件匹配的. 注意尾部空格,"%Li"是不能匹配"Li "这样的记录的. 注意NULL,%通配符可以匹配任意字符,但是不能匹配NULL,也就是说 SELECT * FROM products WHERE products.prod_name like '%; 是匹配不到products.prod_name为NULL的的记录.
UNION语句
UNION的主要功能是将两张表要查询的相同的内容合并成一张表,这样输出就是一张表,而不是两张表 MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。 mysql> SELECT * FROM Websites; +----+--------------+---------------------------+-------+---------+ | id | name | url | alexa | country | +----+--------------+---------------------------+-------+---------+ | 1 | Google | https://www.google.cm/ | 1 | USA | | 2 | 淘宝 | https://www.taobao.com/ | 13 | CN | | 3 | 菜鸟教程 | http://www.runoob.com/ | 4689 | CN | | 4 | 微博 | http://weibo.com/ | 20 | CN | | 5 | Facebook | https://www.facebook.com/ | 3 | USA | | 7 | stackoverflow | http://stackoverflow.com/ | 0 | IND | +----+---------------+---------------------------+-------+---------+ mysql> SELECT * FROM apps; +----+------------+-------------------------+---------+ | id | app_name | url | country | +----+------------+-------------------------+---------+ | 1 | QQ APP | http://im.qq.com/ | CN | | 2 | 微博 APP | http://weibo.com/ | CN | | 3 | 淘宝 APP | https://www.taobao.com/ | CN | +----+------------+-------------------------+---------+ 3 rows in set (0.00 sec) //下面的 SQL 语句从 "Websites" 和 "apps" 表中选取所有不同的country(只有不同的值): SELECT country FROM Websites UNION SELECT country FROM apps ORDER BY country; 执行上面语句查询到 country CN IND USA //下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的country(也有重复的值): SELECT country FROM Websites UNION ALL SELECT country FROM apps ORDER BY country; 执行上面语句查询到 country CN CN CN CN CN IND USA USA USA //下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的中国(CN)的数据(也有重复的值): SELECT country, name FROM Websites WHERE country='CN' UNION ALL SELECT country, app_name FROM apps WHERE country='CN' ORDER BY country; 执行上面语句查询的结果是 countrt name CN 淘宝 CN QQ APP CN 菜鸟教程 CN 微博APP Cn 微博
排序
//对runoob_tbl的submission_date查询数据进行升序排序 mysql> SELECT * from runoob_tbl ORDER BY submission_date ASC; //对runoob_tbl的submission_date查询数据进行降序排序 mysql> SELECT * from runoob_tbl ORDER BY submission_date DESC;
GROUP BY语句
GROUP BY 语句根据一个或多个列对结果集进行分组。在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。 //首先插入数据 查询表格 CREATE TABLE employee_tbl ( id INT(11) NOT NULL, NAME CHAR(10) NOT NULL DEFAULT '', DATE DATETIME NOT NULL, signin TINYINT(4) NOT NULL DEFAULT '0' COMMENT '登录次数', PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8; INSERT INTO employee_tbl VALUES ('1', '小明', '2016-04-22 15:25:33', '1'), ('2', '小王', '2016-04-20 15:25:47', '3'), ('3', '小丽', '2016-04-19 15:26:02', '2'), ('4', '小王', '2016-04-07 15:26:14', '4'), ('5', '小明', '2016-04-11 15:26:40', '4'), ('6', '小明', '2016-04-04 15:26:54', '2'); mysql> SELECT * FROM employee_tbl; +----+--------+---------------------+--------+ | id | name | date | signin | +----+--------+---------------------+--------+ | 1 | 小明 | 2016-04-22 15:25:33 | 1 | | 2 | 小王 | 2016-04-20 15:25:47 | 3 | | 3 | 小丽 | 2016-04-19 15:26:02 | 2 | | 4 | 小王 | 2016-04-07 15:26:14 | 4 | | 5 | 小明 | 2016-04-11 15:26:40 | 4 | | 6 | 小明 | 2016-04-04 15:26:54 | 2 | +----+--------+---------------------+--------+ //使用 GROUP BY 语句 将数据表按名字进行分组,并统计每个人有多少条记录: mysql> SELECT name, COUNT(*) FROM employee_tbl GROUP BY name; +--------+----------+ | name | COUNT(*) | +--------+----------+ | 小丽 | 1 | | 小明 | 3 | | 小王 | 2 | +--------+----------+ 使用 WITH ROLLUP WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。 例如我们将以上的数据表按名字进行分组,再统计每个人登录的次数: mysql> SELECT name, SUM(signin) as signin_count FROM employee_tbl GROUP BY name WITH ROLLUP; +--------+--------------+ | name | signin_count | +--------+--------------+ | 小丽 | 2 | | 小明 | 7 | | 小王 | 7 | | NULL | 16 | +--------+--------------+ 其中记录 NULL 表示所有人的登录次数。 我们可以使用 coalesce 来设置一个可以取代 NUll 的名称,coalesce 语法: select coalesce(a,b,c); 参数说明:如果a==null,则选择b;如果b==null,则选择c;如果a!=null,则选择a;如果a b c 都为null ,则返回为null(没意义)。 以下实例中如果名字为空我们使用总数代替: mysql> SELECT coalesce(name, '总数'), SUM(signin) as signin_count FROM employee_tbl GROUP BY name WITH ROLLUP; +--------------------------+--------------+ | coalesce(name, '总数') | signin_count | +--------------------------+--------------+ | 小丽 | 2 | | 小明 | 7 | | 小王 | 7 | | 总数 | 16 | +--------------------------+--------------+
NULL值处理
我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。 为了处理这种情况,MySQL提供了三大运算符: IS NULL:当列的值是 NULL,此运算符返回 true。 IS NOT NULL:当列的值不为 NULL, 运算符返回 true。 <=>:比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。 关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。 在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 NULL,即 NULL = NULL 返回 NULL 。 MySQL 中处理 NULL 使用 IS NULL 和 IS NOT NULL 运算符。 mysql> SELECT * from runoob_test_tbl; +---------------+--------------+ | runoob_author | runoob_count | +---------------+--------------+ | RUNOOB | 20 | | 菜鸟教程 | NULL | | Google | NULL | | FK | 20 | +---------------+--------------+ mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count = NULL; 使用=查询不到数据 mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count IS NULL; +---------------+--------------+ | runoob_author | runoob_count | +---------------+--------------+ | 菜鸟教程 | NULL | | Google | NULL | +---------------+--------------+ mysql> SELECT * from runoob_test_tbl WHERE runoob_count IS NOT NULL; +---------------+--------------+ | runoob_author | runoob_count | +---------------+--------------+ | RUNOOB | 20 | | FK | 20 | +---------------+--------------+
正则表达式
在前面的章节我们已经了解到MySQL可以通过 **LIKE ...%** 来进行模糊匹配。 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 次。 查找name字段中以'st'为开头的所有数据: mysql> SELECT name FROM person_tbl WHERE name REGEXP '^st'; 查找name字段中以'ok'为结尾的所有数据: mysql> SELECT name FROM person_tbl WHERE name REGEXP 'ok$'; 查找name字段中包含'mar'字符串的所有数据: mysql> SELECT name FROM person_tbl WHERE name REGEXP 'mar'; 查找name字段中以元音字符开头或以'ok'字符串结尾的所有数据: mysql> SELECT name FROM person_tbl WHERE name REGEXP '^[aeiou]|ok$';
MYSQL 事务
事务主要用于处理一致性操作,如转账,第一步是从你这边扣钱,第二部是对方增加钱,如果这两步有任意一步出现问题都需要进行回滚,保持数据的一致性,可以通过SAVEPOINT保存回滚节点,这样回滚时事件就是返回到保存到SAVEPOINT中去。回滚一般是值回滚到begin语句。
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
-
在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
-
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
-
事务用来管理 insert,update,delete 语句
一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
-
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
-
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
-
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
-
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。
事务控制语句:
-
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 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT来实现
-
BEGIN 开始一个事务
-
ROLLBACK 事务回滚
-
COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式:
-
SET AUTOCOMMIT=0 禁止自动提交
-
SET AUTOCOMMIT=1 开启自动提交
mysql> use RUNOOB; Database changed mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb; mysql> select * from runoob_transaction_test; Empty set (0.01 sec) mysql> begin; # 开始事务 Query OK, 0 rows affected (0.00 sec) mysql> insert into runoob_transaction_test value(5); Query OK, 1 rows affected (0.01 sec) mysql> insert into runoob_transaction_test value(6); Query OK, 1 rows affected (0.00 sec) mysql> commit; # 提交事务 Query OK, 0 rows affected (0.01 sec) mysql> select * from runoob_transaction_test; +------+ | id | +------+ | 5 | | 6 | +------+ 2 rows in set (0.01 sec) mysql> begin; # 开始事务 Query OK, 0 rows affected (0.00 sec) mysql> insert into runoob_transaction_test values(7); Query OK, 1 rows affected (0.00 sec) mysql> rollback; # 回滚 Query OK, 0 rows affected (0.00 sec) mysql> select * from runoob_transaction_test; # 因为回滚所以数据没有插入 +------+ | id | +------+ | 5 | | 6 | +------+ //设置SAVEPOINT, 回滚的时候可以选择SAVEPOINT的地方,可以设置多个SAVEPOINT,如果两个SAVEPOINT相同,则回滚的时候会选择最近的一个回滚。 BEGIN; INSERT INTO runoob_transaction_test VALUE(7); INSERT INTO runoob_transaction_test VALUE(8); SAVEPOINT savepoint_name; INSERT INTO runoob_transaction_test VALUE(7); INSERT INTO runoob_transaction_test VALUE(8); ROLLBACK TO savepoint_name; RELEASE SAVEPOINT savepoint_name; // 删除指定保留点
MYSQL ALTER命令
当我们需要修改数据表名或者修改数据表字段时,就需要使用到MySQL ALTER命令。 CREATE TABLE testalter_tbl( i INT, c CHAR(1) ); mysql> SHOW COLUMNS FROM testalter_tbl; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | i | int(11) | YES | | NULL | | | c | char(1) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 删除,添加或修改表字段 如下命令使用了 ALTER 命令及 DROP 子句来删除以上创建表的 i 字段: mysql> ALTER TABLE testalter_tbl DROP i; | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | i | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 如果数据表中只剩余一个字段则无法使用DROP来删除字段。 MySQL 中使用 ADD 子句来向数据表中添加列,如下实例在表 testalter_tbl 中添加 i 字段,并定义数据类型: mysql> ALTER TABLE testalter_tbl ADD i INT; mysql> SHOW COLUMNS FROM testalter_tbl; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | c | char(1) | YES | | NULL | | | i | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 如果你需要指定新增字段的位置,可以使用MySQL提供的关键字 FIRST (设定位第一列), AFTER 字段名(设定位于某个字段之后)。 尝试以下 ALTER TABLE 语句, 在执行成功后,使用 SHOW COLUMNS 查看表结构的变化: ALTER TABLE testalter_tbl DROP i; ALTER TABLE testalter_tbl ADD i INT FIRST; ALTER TABLE testalter_tbl DROP i; ALTER TABLE testalter_tbl ADD i INT AFTER c; ADD i INT FIRST;则加在第一的位置 ADD i INT AFTER c;加在字段为c的后面 修改字段类型及名称 把字段 c 的类型从 CHAR(1) 改为 CHAR(10),可以执行以下命令: mysql> ALTER TABLE testalter_tbl MODIFY c CHAR(10); 使用 CHANGE 子句, 语法有很大的不同。 在 CHANGE 关键字之后,紧跟着的是你要修改的字段名,然后指定新字段名及类型。尝试如下实例: mysql> ALTER TABLE testalter_tbl CHANGE i j BIGINT; mysql> ALTER TABLE testalter_tbl CHANGE j j INT; ALTER TABLE 对 Null 值和默认值的影响 如果你不设置默认值,MySQL会自动设置该字段默认为 NULL。 当你修改字段时,你可以指定是否包含值或者是否设置默认值。 以下实例,指定字段 j 为 NOT NULL 且默认值为100 。 mysql> ALTER TABLE testalter_tbl MODIFY j BIGINT NOT NULL DEFAULT 100; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | c | char(1) | YES | | NULL | | | j | BIGINT(20) | YES | | 100 | | +-------+---------+------+-----+---------+-------+ 修改字段默认值 你可以使用 ALTER 来修改字段的默认值,尝试以下实例: mysql> ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000; mysql> SHOW COLUMNS FROM testalter_tbl; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | c | char(1) | YES | | NULL | | | i | int(11) | YES | | 1000 | | +-------+---------+------+-----+---------+-------+ 你也可以使用 ALTER 命令及 DROP子句来删除字段的默认值,如下实例: mysql> ALTER TABLE testalter_tbl ALTER i DROP DEFAULT; mysql> SHOW COLUMNS FROM testalter_tbl; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | c | char(1) | YES | | NULL | | | i | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 修改数据表类型 可以使用 ALTER 命令及 TYPE 子句来完成。尝试以下实例,我们将表 testalter_tbl 的类型修改为 MYISAM mysql> ALTER TABLE testalter_tbl ENGINE = MYISAM; 修改表的名称 如果需要修改数据表的名称,可以在 ALTER TABLE 语句中使用 RENAME 子句来实现。 尝试以下实例将数据表 testalter_tbl 重命名为 alter_tbl: mysql> ALTER TABLE testalter_tbl RENAME TO alter_tbl;
MYSQL 索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
建立索引会占用磁盘空间的索引文件。
普通索引
这是最基本的索引,它没有任何限制。它有以下几种创建方式: CREATE INDEX indexName ON table_name (column_name); 如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。 修改表结构(添加索引) ALTER table tableName ADD INDEX indexName(columnName); 创建表的时候直接指定 CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX indexName(username(16)) ); 删除索引的语法 DROP INDEX indexName ON mytable;
唯一索引
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式: 创建索引 CREATE UNIQUE INDEX indexName ON mytable(username(length)); 修改表结构 ALTER table mytable ADD UNIQUE indexName(username(length)); 创建表的时候直接指定 CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE indexName(username(length)) );
使用ALTER添加和删除索引
有四种方式来添加数据表的索引: ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。 ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。 ALTER TABLE tbl_name ADD INDEX index_name (column_list):添加普通索引,索引值可出现多次。 ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。 以下实例为在表中添加索引。 mysql> ALTER TABLE testalter_tbl ADD INDEX (c); 你还可以在 ALTER 命令中使用 DROP 子句来删除索引。尝试以下实例删除索引: mysql> ALTER TABLE testalter_tbl DROP INDEX c;
使用ALTER添加和删除主键
主键作用于列上(可以一个列或多个列联合主键),添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下: mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL; mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i); 你也可以使用 ALTER 命令删除主键: mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY; 删除主键时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。
显示索引信息
你可以使用 SHOW INDEX 命令来列出表中的相关的索引信息。可以通过添加 \G 来格式化输出信息。 mysql> SHOW INDEX FROM table_name\G
索引的使用
索引设置之后通过Select即可使用索引进行查询,但使用索引时可能会出现索引失效的情况。 在user_test表上创建一个组合索引 ALTER TABLE user_test ADD INDEX index_user(user_name , city , age); 可以使用到索引排序的案例 SELECT user_name, city, age FROM user_test ORDER BY user_name; SELECT user_name, city, age FROM user_test ORDER BY user_name, city; SELECT user_name, city, age FROM user_test ORDER BY user_name DESC, city DESC; SELECT user_name, city, age FROM user_test WHERE user_name = 'feinik' ORDER BY city; 注:第4条sql语句比较特殊一点,如果where查询条件为索引列的第一列,且为常量条件,那么也可以使用到索引。 无法使用索引排序的案例 sex不在索引列中 SELECT user_name, city, age FROM user_test ORDER BY user_name, sex; 排序列的方向不一致 SELECT user_name, city, age FROM user_test ORDER BY user_name ASC, city DESC; 所要查询的字段列sex没有包含在索引列中 SELECT user_name, city, age, sex FROM user_test ORDER BY user_name; where查询条件后的user_name为范围查询,所以无法使用到索引的其他列 SELECT user_name, city, age FROM user_test WHERE user_name LIKE 'feinik%' ORDER BY city;
MYSQL 临时表
MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。
临时表在MySQL 3.23版本中添加,如果你的MySQL版本低于 3.23版本就无法使用MySQL的临时表。不过现在一般很少有再使用这么低版本的MySQL数据库服务了。
MySQL临时表只在当前连接可见,如果你使用PHP脚本来创建MySQL临时表,那每当PHP脚本执行完成后,该临时表也会自动销毁。
如果你使用了其他MySQL客户端程序连接MySQL数据库服务器来创建临时表,那么只有在关闭客户端程序时才会销毁临时表,当然你也可以手动销毁。
CREATE TEMPORARY TABLE SalesSummary ( 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 ); INSERT INTO SalesSummary (product_name, total_sales, avg_unit_price, total_units_sold) VALUES ('cucumber', 100.25, 90, 2); mysql> SELECT * FROM SalesSummary; +--------------+-------------+----------------+------------------+ | product_name | total_sales | avg_unit_price | total_units_sold | +--------------+-------------+----------------+------------------+ | cucumber | 100.25 | 90.00 | 2 | +--------------+-------------+----------------+------------------+ 当你使用 SHOW TABLES命令显示数据表列表时,你将无法看到 SalesSummary表。 如果你退出当前MySQL会话,再使用 SELECT命令来读取原先创建的临时表数据,那你会发现数据库中没有该表的存在,因为在你退出时该临时表已经被销毁了。 默认情况下,当你断开与数据库的连接后,临时表就会自动被销毁。当然你也可以在当前MySQL会话使用 DROP TABLE 命令来手动删除临时表。 以下是手动删除临时表的实例: mysql> DROP TABLE SalesSummary; mysql> SELECT * FROM SalesSummary; ERROR 1146: Table 'RUNOOB.SalesSummary' doesn't exist
MYSQL 复制表
如果我们需要完全的复制MySQL的数据表,包括表的结构,索引,默认值等。 如果仅仅使用CREATE TABLE ... SELECT 命令,是无法实现的。
本章节将为大家介绍如何完整的复制MySQL数据表,步骤如下:
-
使用 SHOW CREATE TABLE 命令获取创建数据表(CREATE TABLE) 语句,该语句包含了原数据表的结构,索引等。
-
复制以下命令显示的SQL语句,修改数据表名,并执行SQL语句,通过以上命令 将完全的复制数据表结构。
-
如果你想复制表的内容,你就可以使用 INSERT INTO ... SELECT 语句来实现。
//想要复制一个表包括表结构,索引,默认值等信息,需要先查看建表语句 步骤一: SHOW CREATE TABLE runoob_tbl; *************************** 1. row *************************** Table: runoob_tbl 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 AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 步骤二: //之后根据表结构创建一个相同的表结构 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; 步骤三: INSERT INTO clone_tbl (runoob_id,runoob_title, runoob_author,submission_date) SELECT runoob_id,runoob_title,runoob_author,submission_date FROM runoob_tbl; 执行以上步骤后,会完整的复制表的内容,包括表结构及表数据。 还要第二种方法也可以进行对表的结构,索引,默认值等信息进行复制 CREATE TABLE targetTable LIKE runoob_tbl; INSERT INTO targetTable SELECT * FROM runoob_tbl;
MYSQL 元数据
你可能想知道MySQL以下三种信息:
-
查询结果信息: SELECT, UPDATE 或 DELETE语句影响的记录数。
-
数据库和数据表的信息: 包含了数据库及数据表的结构信息。
-
MySQL服务器信息: 包含了数据库服务器的当前状态,版本号等。
在MySQL的命令提示符中,我们可以很容易的获取以上服务器信息。 但如果使用Perl或PHP等脚本语言,你就需要调用特定的接口函数来获取。
在C++中获取这些数据可以通过 int mysql_query(MYSQL *mysql, const char *query) ;来执行语句进行查询通过MYSQL_RES *mysql_store_result(MYSQL *mysql);来获取数据集。
获取查询语句影响的记录数 在PHP中,你可以使用 mysqli_affected_rows( ) 函数来获取查询语句影响的记录数。 $result_id = mysqli_query ($conn_id, $query); # 如果查询失败返回 $count = ($result_id ? mysqli_affected_rows ($conn_id) : 0); print ("$count 条数据被影响\n"); 数据库和数据表列表 你可以很容易的在MySQL服务器中获取数据库和数据表列表。 如果你没有足够的权限,结果将返回 null。 你也可以使用 SHOW TABLES 或 SHOW DATABASES 语句来获取数据库和数据表列表。 获取服务器元数据 以下命令语句可以在 MySQL 的命令提示符使用,也可以在脚本中 使用,如PHP脚本。 命令 描述 SELECT VERSION( ) 服务器版本信息 SELECT DATABASE( ) 当前数据库名 (或者返回空) SELECT USER( ) 当前用户名 SHOW STATUS 服务器状态 SHOW VARIABLES 服务器配置变量
MYSQL 序列使用
MySQL 序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。
使用 AUTO_INCREMENT MySQL 中最简单使用序列的方法就是使用 MySQL AUTO_INCREMENT 来定义序列。 #创建表格 CREATE TABLE insect ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id), NAME VARCHAR(30) NOT NULL, # type of insect DATE DATE NOT NULL, # date collected origin VARCHAR(30) NOT NULL # where collected ); #插入数据 INSERT INTO insect (id,NAME,DATE,origin) VALUES (NULL,'housefly','2001-09-10','kitchen'), (NULL,'millipede','2001-09-10','driveway'), (NULL,'grasshopper','2001-09-10','front yard'); #查看数据 SELECT * FROM insect ORDER BY id; +----+-------------+------------+------------+ | id | name | date | origin | +----+-------------+------------+------------+ | 1 | housefly | 2001-09-10 | kitchen | | 2 | millipede | 2001-09-10 | driveway | | 3 | grasshopper | 2001-09-10 | front yard | +----+-------------+------------+------------+
获取AUTO_INCREMENT值
#在MySQL的客户端中你可以使用 SQL中的LAST_INSERT_ID()函数来获取最后的插入表中的自增列的值。 SELECT LAST_INSERT_ID(); +-----------------+ LAST_INSERT_ID() +-----------------+ 1 如果一次性执行三条插入语句,LAST_INSERT_ID()的值是第一个插入的数据,而不是最后一个,故id为1,而不是3
重置序列
如果你删除了数据表中的多条记录,并希望对剩下数据的AUTO_INCREMENT列进行重新排列,那么你可以通过删除自增的列,然后重新添加来实现。 不过该操作要非常小心,如果在删除的同时又有新记录添加,有可能会出现数据混乱。 ALTER TABLE insect ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (id);
设置序列的开始值
CREATE TABLE insect ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id), name VARCHAR(30) NOT NULL, date DATE NOT NULL, origin VARCHAR(30) NOT NULL )engine=innodb auto_increment=100 charset=utf8; 或者你也可以在表创建成功后,通过以下语句来实现: ALTER TABLE insect AUTO_INCREMENT = 100;
MYSQL 处理重复数据
有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据。
防止表中出现重复数据
你可以在 MySQL 数据表中设置指定的字段为 PRIMARY KEY(主键) 或者 UNIQUE(唯一) 索引来保证数据的唯一性。
CREATE TABLE person_tbl ( first_name CHAR(20), last_name CHAR(20), sex CHAR(10) ); 如果你想设置表中字段 first_name,last_name 数据不能重复,你可以设置双主键模式来设置数据的唯一性, 如果你设置了双主键,那么那个键的默认值不能为 NULL,可设置为 NOT NULL。如下所示: CREATE TABLE person_tbl ( first_name CHAR(20) NOT NULL, last_name CHAR(20) NOT NULL, sex CHAR(10), PRIMARY KEY (last_name, first_name) ); 如果我们设置了唯一索引,那么在插入重复数据时,SQL 语句将无法执行成功,并抛出错 INSERT IGNORE INTO 与 INSERT INTO 的区别就是 INSERT IGNORE INTO 会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。 以下实例使用了 INSERT IGNORE INTO,执行后不会出错,也不会向数据表中插入重复数据: INSERT IGNORE INTO person_tbl (last_name, first_name) VALUES( 'Jay', 'Thomas'); Query OK, 1 row affected (0.00 sec) INSERT IGNORE INTO person_tbl (last_name, first_name) VALUES( 'Jay', 'Thomas'); Query OK, 0 rows affected (0.00 sec) INSERT IGNORE INTO 当插入数据时,在设置了记录的唯一性后,如果插入重复数据,将不返回错误,只以警告形式返回。 而 REPLACE INTO 如果存在 primary 或 unique 相同的记录,则先删除掉。再插入新记录。 另一种设置数据的唯一性方法是添加一个 UNIQUE 索引,如下所示: CREATE TABLE person_tbl ( first_name CHAR(20) NOT NULL, last_name CHAR(20) NOT NULL, sex CHAR(10), UNIQUE (last_name, first_name) );
统计重复数据
CREATE TABLE person_tbl2 ( first_name CHAR(20) NOT NULL, last_name CHAR(20) NOT NULL, sex CHAR(10) ); INSERT IGNORE INTO person_tbl2 (last_name, first_name) VALUES( 'Jay', 'Thomas'); INSERT IGNORE INTO person_tbl2 (last_name, first_name) VALUES( 'Jay', 'Thomas'); INSERT IGNORE INTO person_tbl2 (last_name, first_name) VALUES( 'Sam', 'Thomas'); INSERT IGNORE INTO person_tbl2 (last_name, first_name) VALUES( 'Sam', 'Thomas'); INSERT IGNORE INTO person_tbl2 (last_name, first_name) VALUES( 'Sam', 'Thomas'); 以下我们将统计表中 first_name 和 last_name的重复记录数: SELECT COUNT(*) as repetitions, last_name, first_name FROM person_tbl2 GROUP BY last_name, first_name HAVING repetitions > 1; +----+-------------+------------+ | repetitions | last_name | first_name | +----+-------------+------------+ | 2 | Jay | Thomas | | 3 | Sam | Thomas | +----+-------------+------------+
删除重复数据
#可以通过GROUP BY来把相同的数据删除,后新建表格重命名操作实现删除重复数据 CREATE TABLE tmp SELECT last_name, first_name, sex FROM person_tbl2 GROUP BY last_name, first_name, sex; DROP TABLE person_tbl; ALTER TABLE tmp RENAME TO person_tbl; #如果想要将表的引擎及编码格式等信息全部复制 应该先show CREATE TABLE 表名; #根据建表格式来新建表,在select将数据插入新建的表之中 #也可以在数据表中添加 INDEX(索引) 和 PRIMAY KEY(主键)这种简单的方法来删除表中的重复记录 ALTER IGNORE TABLE person_tbl ADD PRIMARY KEY (last_name, first_name); 笔记 #先按照要查询出现重复数据的列,进行分组查询。count > 1 代表出现 2 次或 2 次以上 /*查询重复数据*/ select serialnum,cdate,count(*) as count from m_8_customer_temp_20180820bak group by serialnum,cdate having count>1 and cdate>='2018-08-20 00:00:00';
MYSQL及SQL注入
如果您通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL注入安全的问题。
本章节将为大家介绍如何防止SQL注入,并通过脚本来过滤SQL中注入的字符。
所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。
#以下实例中,输入的用户名必须为字母、数字及下划线的组合,且用户名长度为 8 到 20 个字符之间: if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) { $result = mysqli_query($conn, "SELECT * FROM users WHERE username=$matches[0]"); } else { echo "username 输入异常"; }
在PHP中的 mysqli_query() 是不允许执行多个 SQL 语句的,但是在 SQLite 和 PostgreSQL 是可以同时执行多条SQL语句的,所以我们对这些用户的数据需要进行严格的验证。
防止SQL注入,我们需要注意以下几个要点:
-
1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。
-
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
-
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
-
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
-
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
-
6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。
防止MYSQL注入
#在脚本语言,如Perl和PHP你可以对用户输入的数据进行转义从而来防止SQL注入。 #PHP的MySQL扩展提供了mysqli_real_escape_string()函数来转义特殊的输入字符。 if (get_magic_quotes_gpc()) { $name = stripslashes($name); } $name = mysqli_real_escape_string($conn, $name); mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");
like语句中的注入
#like查询时,如果用户输入的值有"_"和"%",则会出现这种情况:用户本来只是想查询"abcd_",查询结果中却 #有"abcd_"、"abcde"、"abcdf"等等;用户要查询"30%"(注:百分之三十)时也会出现问题。 #在PHP脚本中我们可以使用addcslashes()函数来处理以上情况,如下实例: $sub = addcslashes(mysqli_real_escape_string($conn, "%something_"), "%_"); // $sub == \%something\_ mysqli_query($conn, "SELECT * FROM messages WHERE subject LIKE '{$sub}%'");
MYSQL 导出数据
配置导出路径
#想要导出文件,首先应该先配置导出路径,如果为配置导出路径则会出现错误。 #先查看文件导出路径 SHOW VARIABLES LIKE '%secure%'; #查看secure_file_priv是否是NULL,如果是NULL则需要进行配置。 #打开mysql安装路径,找到.ini文件,在最下面加入 [mysqld] secure_file_priv="C:/Users/wei/Desktop/" SHOW VARIABLES LIKE '%secure%'; #则可以看到secure_file_priv配置的路径 #配置后需要进行重启MySQL服务才能生效。
MySQL中你可以使用SELECT...INTO OUTFILE语句来简单的导出数据到文本文件上。
使用select ...into outfile语句导出数据
#以下实例中我们将数据表 runoob_tbl 数据导出到 /tmp/runoob.txt 文件中: SELECT * FROM runoob_tbl INTO OUTFILE 'C:/Users/wei/Desktop/test.txt'; #你可以通过命令选项来设置数据输出的指定格式,以下实例为导出 CSV 格式: SELECT * FROM runoob_tbl INTO OUTFILE 'C:/Users/wei/Desktop/test.txt' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\r\n'; #查看txt文件内容如下 "1","学习 C++","菜鸟教程","2022-05-15" "2","学习python","菜鸟教程","2022-05-15" "3","学习C#","菜鸟教程","2022-05-15" "4","我的测试","菜鸟教程","2022-05-20" "5","你的测试","菜鸟教程","2022-05-20"
mysql导入数据
MySQL命令导入
使用 mysql 命令导入语法格式为:
mysql -u用户名 -p密码 < 要导入的数据库数据(runoob.sql) # mysql -uroot -p123456 < runoob.sql
source命令导入
mysql> create database abc; # 创建数据库 mysql> use abc; # 使用已创建的数据库 mysql> set names utf8; # 设置编码 mysql> source C:/Users/wei/Desktop/est.sql; # 导入备份数据库 #注意一下导入的路径一定要是/ 否则可能会根据转义字符发生错误。