SQL语言定义了这么几种操作数据库的能力:
DDL:Data Definition Language
DDL允许用户定义数据,也就是创建表、删除表、修改表结构这些操作。通常,DDL由数据库管理员执行。
DML:Data Manipulation Language
DML为用户提供添加、删除、更新数据的能力,这些是应用程序对数据库的日常操作。
DQL:Data Query Language
DQL允许用户查询数据,这也是通常最频繁的数据库日常操作。
选取主键的一个基本原则是:不使用任何业务相关的字段作为主键。
因此,身份证号、手机号、邮箱地址这些看上去可以唯一的字段,均不可用作主键。
外键
索引
联合索引
投影查询
排序
聚合查询
如果我们要统计一张表的数据量,例如,想查询students表一共有多少条记录,难道必须用SELECT * FROM
students查出来然后再数一数有多少行吗?对于统计总数、平均数这类计算,SQL提供了专门的聚合函数,使用聚合函数进行查询,就是聚合查询,它可以快速获得结果。
仍然以查询students表一共有多少条记录为例,我们可以使用SQL内置的COUNT()函数查询:
SELECT COUNT(*) FROM students;
mysql> select * from employee_tbl order by singin DESC,id;
+----+--------+---------------------+--------+
| id | name | date | singin |
+----+--------+---------------------+--------+
| 4 | 小王 | 2016-04-07 15:26:14 | 4 |
| 5 | 小明 | 2016-04-11 15:26:40 | 4 |
| 2 | 小王 | 2016-04-20 15:25:47 | 3 |
| 3 | 小丽 | 2016-04-19 15:26:02 | 2 |
| 6 | 小明 | 2016-04-04 15:26:54 | 2 |
| 1 | 小明 | 2016-04-22 15:25:33 | 1 |
+----+--------+---------------------+--------+
mysql> select sum(id) from employee_tbl where singin = 4;
+---------+
| sum(id) |
+---------+
| 9 |
+---------+
分组
如果我们要统计一班的学生数量,我们知道,可以用SELECT COUNT(*) num FROM students WHERE class_id = 1;。如果要继续统计二班、三班的学生数量,难道必须不断修改WHERE条件来执行SELECT语句吗?
对于聚合查询,SQL还提供了“分组聚合”的功能。我们观察下面的聚合查询:
执行这个查询,COUNT()的结果不再是一个,而是3个,这是因为,GROUP BY子句指定了按class_id分组,因此,执行该SELECT语句时,会把class_id相同的列先分组,再分别计算,因此,得到了3行结果。
但是这3行结果分别是哪三个班级的,不好看出来,所以我们可以把class_id列也放入结果集中:
JOIN查询需要先确定主表,然后把另一个表的数据“附加”到结果集上;
INNER JOIN是最常用的一种JOIN查询,它的语法是SELECT … FROM <表1> INNER JOIN <表2> ON <条件…>;
JOIN查询仍然可以使用WHERE条件和ORDER BY排序。
现在问题来了,存放班级名称的name列存储在classes表中,只有根据students表的class_id,找到classes表对应的行,再取出name列,就可以获得班级名称。
这时,连接查询就派上了用场。我们先使用最常用的一种内连接——INNER JOIN来实现:
sql 中 ALTER 和 UPDATE 的区别
alter 是DDL语句,是修改数据库中对象(表,数据库,视图。。)的语句。
如需在表中添加列,请使用下面的语法:
ALTER TABLE table_name
ADD column_name datatype
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
ALTER TABLE table_name
DROP COLUMN column_name
要改变表中列的数据类型,请使用下面的语法:
ALTER TABLE table_name
MODIFY COLUMN column_name datatype
update是DML语句,是修改表中数据的语句。
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
举例子
mysql> alter table apps add time int;
Query OK, 0 rows affected (0.17 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from apps;
+----+-----------+---------+------+
| id | app_name | country | time |
+----+-----------+---------+------+
| 1 | QQ APP | CN | NULL |
| 2 | 微博APP | CN | NULL |
| 3 | 淘宝APP | CN | NULL |
| 4 | 抖音APP | AA | NULL |
+----+-----------+---------+------+
4 rows in set (0.00 sec)
mysql> alter table apps drop time;
Query OK, 0 rows affected (0.16 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc apps;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| app_name | varchar(40) | NO | | NULL | |
| country | varchar(40) | NO | MUL | NULL | |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
UPDATE students SET name='小牛', score=77 WHERE id>=5 AND id<=7;
-- 查询并观察结果:
SELECT * FROM students;
UPDATE students SET score=score+10 WHERE score<80;
-- 查询并观察结果:
SELECT * FROM students;
如果WHERE条件没有匹配到任何记录,UPDATE语句不会报错,也不会有任何记录被更新。例如:
-- 更新id=999的记录
update student set score=100 where id=999;
#
修改表就比较复杂。如果要给students表新增一列birth,使用:
ALTER TABLE students ADD COLUMN birth VARCHAR(10) NOT NULL;
要修改birth列,例如把列名改为birthday,类型改为VARCHAR(20):
ALTER TABLE students CHANGE COLUMN birth birthday VARCHAR(20) NOT NULL;
要删除列,使用:
ALTER TABLE students DROP COLUMN birthday;
DELETE语句的基本语法是:
DELETE FROM <表名> WHERE …;
例如,我们想删除students表中id=1的记录,就需要这么写:
– 删除id=1的记录
DELETE FROM students WHERE id=1;
如果WHERE条件没有匹配到任何记录,DELETE语句不会报错,也不会有任何记录被删除
实用SQL语句
插入或替换
如果我们希望插入一条新记录(INSERT),但如果记录已经存在,就先删除原记录,再插入新记录。此时,可以使用REPLACE语句,这样就不必先查询,再决定是否先删除再插入:
REPLACE INTO students (id, class_id, name, gender, score) VALUES (1, 1, '小明', 'F', 99);
若id=1的记录不存在,REPLACE语句将插入新记录,否则,当前id=1的记录将被删除,然后再插入新记录。
快照
如果想要对一个表进行快照,即复制一份当前表的数据到一个新表,可以结合CREATE TABLE和SELECT:
– 对class_id=1的记录进行快照,并存储为新表students_of_class1:
CREATE TABLE students_of_class1 SELECT * FROM students WHERE class_id=1;
新创建的表结构和SELECT使用的表结构完全一致。
写入查询结果集
如果查询结果集需要写入到表中,可以结合INSERT和SELECT,将SELECT语句的结果集直接插入到指定表中。
例如,创建一个统计成绩的表statistics,记录各班的平均成绩:
查询user表的索引主键
mysql> show index from user;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| user | 0 | PRIMARY | 1 | Host | A | NULL | NULL | NULL | | BTREE | | |
| user | 0 | PRIMARY | 2 | User | A | 8 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
查询user表有哪些列
mysql> show columns from user;
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
。。。。。。。。
SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern'] \G: 注意是数据库
该命令将输出Mysql数据库管理系统的性能及统计信息。
mysql> SHOW TABLE STATUS FROM RUNOOB; # 显示数据库 RUNOOB 中所有表的信息
mysql> SHOW TABLE STATUS from RUNOOB LIKE 'runoob%'; # 表名以runoob开头的表的信息
mysql> SHOW TABLE STATUS from RUNOOB LIKE 'runoob%'\G; # 加上 \G,查询结果按列打印
创建表
CREATE TABLE table_name (column_name column_type);
mysql> use test;
Database changed
mysql>
mysql> show tables;
Empty set (0.00 sec)
mysql> CREATE TABLE test_tbl(
-> test_id int not null auto_increment,
-> test_title varchar(100) not null,
-> test_author varchar(40) not null,
-> submission_date DATE,
-> primary key(test_id)
-> )engine=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)
#
实例解析:
如果你不想字段为 NULL 可以设置字段的属性为 NOT NULL, 在操作数据库时如果输入该字段的数据为NULL ,就会报错。
AUTO_INCREMENT定义列为自增的属性,一般用于主键,数值会自动加1。
PRIMARY KEY关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号分隔。
ENGINE 设置存储引擎,CHARSET 设置编码。
##
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test_tbl |
+----------------+
1 row in set (0.00 sec)
mysql> select * from test_tbl
-> ;
Empty set (0.00 sec)
mysql> show columns from test_tbl; ####等同于desc test_tbl;
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| test_id | int(11) | NO | PRI | NULL | auto_increment |
| test_title | varchar(100) | NO | | NULL | |
| test_author | varchar(40) | NO | | NULL | |
| submission_date | date | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
MySQL 插入数据
语法 以下为向MySQL数据表插入数据通用的 INSERT INTO SQL语法:
INSERT INTO table_name ( field1, field2,…fieldN )
VALUES
( value1, value2,…valueN );
mysql> insert into test_tbl
-> (test_title,test_author,submission_date)
-> values
-> ("数据库",'swj',now());
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from test_tbl;
+---------+------------+-------------+-----------------+
| test_id | test_title | test_author | submission_date |
+---------+------------+-------------+-----------------+
| 1 | 数据库 | swj | 2021-08-24 |
+---------+------------+-------------+-----------------+
1 row in set (0.00 sec)
mysql> insert into test_tbl (test_title,test_author,submission_date) values ('k8s','swj','2021-01-011');
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_tbl;
+---------+------------+-------------+-----------------+
| test_id | test_title | test_author | submission_date |
+---------+------------+-------------+-----------------+
| 1 | 数据库 | swj | 2021-08-24 |
| 2 | k8s | swj | 2021-01-11 |
+---------+------------+-------------+-----------------+
2 rows in set (0.00 sec)
在以上实例中,我们并没有提供 runoob_id 的数据,因为该字段我们在创建表的时候已经设置它为 AUTO_INCREMENT(自动增加)属性。 所以,该字段会自动递增而不需要我们去设置。实例中 NOW() 是一个 MySQL 函数,该函数返回日期和时间。
MySQL 查询数据
SELECT column_name,column_name
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
查询语句中你可以使用一个或者多个表,表之间使用逗号(,)分割,并使用WHERE语句来设定查询条件。 SELECT
命令可以读取一条或者多条记录。 你可以使用星号(*)来代替其他字段,SELECT语句会返回表的所有字段数据 你可以使用 WHERE语句来包含任何条件。 你可以使用 LIMIT 属性来设定返回的记录数。
你可以通过OFFSET指定SELECT语句开始查询的数据偏移量。默认情况下偏移量为0。
MySQL WHERE 子句
以下是 SQL SELECT 语句使用 WHERE 子句从数据表中读取数据的通用语法:
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
查询语句中你可以使用一个或者多个表,表之间使用逗号, 分割,并使用WHERE语句来设定查询条件。 你可以在 WHERE 子句中指定任何条件。
你可以使用 AND 或者 OR 指定一个或多个条件。 WHERE 子句也可以运用于 SQL 的 DELETE 或者 UPDATE 命令。
WHERE 子句类似于程序语言中的 if 条件,根据 MySQL 表中的字段值来读取指定的数据。
以下为操作符列表,可用于 WHERE 子句中。
下表中实例假定 A 为 10, B 为 20
操作符 描述 实例
= 等号,检测两个值是否相等,如果相等返回true (A = B) 返回false。
<>, != 不等于,检测两个值是否相等,如果不相等返回true (A != B) 返回 true。
大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true (A > B) 返回false。
< 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true (A < B) 返回 true。
>= 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true (A >= B) 返回false。
<= 小于等于号,检测左边的值是否小于或等于右边的值, 如果左边的值小于或等于右边的值返回true (A <= B) 返回 true。
如果我们想在 MySQL 数据表中读取指定的数据,WHERE 子句是非常有用的。
使用主键来作为 WHERE 子句的条件查询是非常快速的。
如果给定的条件在表中没有任何匹配的记录,那么查询不会返回任何数据。
大小写都可以
MySQL UPDATE 更新
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
你可以同时更新一个或多个字段。
你可以在 WHERE 子句中指定任何条件。
你可以在一个单独表中同时更新数据。
mysql> update test_tbl set test_author='zz' where test_id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MySQL DELETE 语句
DELETE FROM table_name [WHERE Clause]
如果没有指定 WHERE 子句,MySQL 表中的所有记录将被删除。
你可以在 WHERE 子句中指定任何条件
您可以在单个表中一次性删除记录。
当你想删除数据表中指定的记录时 WHERE 子句是非常有用的。
MySQL LIKE 子句
WHERE 子句中可以使用等号 = 来设定获取数据的条件,如 “runoob_author = ‘RUNOOB.COM’”。
但是有时候我们需要获取 runoob_author 字段含有 “COM” 字符的所有记录,这时我们就需要在 WHERE 子句中使用 SQL LIKE 子句。
SQL LIKE 子句中使用百分号 %字符来表示任意字符,类似于UNIX或正则表达式中的星号 *。
如果没有使用百分号 %, LIKE 子句与等号 = 的效果是一样的。
SELECT field1, field2,…fieldN
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = ‘somevalue’
MySQL UNION 操作符
描述
MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。
语法
MySQL UNION 操作符语法格式:
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];
给apps表添加一行数据;
MySQL 排序
语法
以下是 SQL SELECT 语句使用 ORDER BY 子句将查询数据排序后再返回数据:
SELECT field1, field2,…fieldN FROM table_name1, table_name2… ORDER
BY field1 [ASC [DESC][默认 ASC]], [field2…] [ASC [DESC][默认 ASC]]
你可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
你可以设定多个字段来排序。
你可以使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。
你可以添加 WHERE…LIKE 子句来设置条件。
注意,上面这个命令的意思是说添加新列到某一列后面。如果想添加到第一列的话,可以用:
alter table TABLE_NAME add column NEW_COLUMN_NAME varchar(255) not null first;
MySQL GROUP BY 语句
GROUP BY 语句根据一个或多个列对结果集进行分组。
在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
mysql 设置外键约束SET FOREIGN_KEY_CHECKS=1
Mysql中如果表和表之间建立的外键约束,则无法删除表及修改表结构
解决方法是在Mysql中取消外键约束: SET FOREIGN_KEY_CHECKS=0;
然后将原来表的数据导出到sql语句,重新创建此表后,再把数据使用sql导入,
然后再设置外键约束: SET FOREIGN_KEY_CHECKS=1;
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 | singin |
+----+--------+---------------------+--------+
| 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 |
+----+--------+---------------------+--------+
6 rows in set (0.01 sec)
mysql> select name,count(*) from employee_tbl group by name;
+--------+----------+
| name | count(*) |
+--------+----------+
| 小丽 | 1 |
| 小明 | 3 |
| 小王 | 2 |
+--------+----------+
mysql> select name,count(*) from employee_tbl where name='小明' group by name;
+--------+----------+
| name | count(*) |
+--------+----------+
| 小明 | 3 |
+--------+----------+
1 row in set (0.00 sec)
使用 WITH ROLLUP
WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。
例如我们将以上的数据表按名字进行分组,再统计每个人登录的次数:
mysql> select name,sum(singin) as singin_count from employee_tbl group by name;
+--------+--------------+
| name | singin_count |
+--------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
+--------+--------------+
3 rows in set (0.00 sec)
mysql> select name,sum(singin) as singin_count from employee_tbl group by name with rollup;
+--------+--------------+
| name | singin_count |
+--------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
| NULL | 16 |
+--------+--------------+
4 rows in set (0.00 sec)
其中记录 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(singin) as singin_count from employee_tbl group by name with rollup;
+-------------------------+--------------+
| coalesce(name,'总数') | singin_count |
+-------------------------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
| 总数 | 16 |
+-------------------------+--------------+
4 rows in set (0.00 sec)
MySQL 连接的使用
在前几章节中,我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据。
本章节我们将向大家介绍如何使用 MySQL 的 JOIN 在两个或多个表中查询数据。
你可以在 SELECT, UPDATE 和 DELETE 语句中使用 Mysql 的 JOIN 来联合多表查询。
JOIN 按照功能大致分为如下三类:
INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。
RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。
MySQL NULL 值处理
我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。
为了处理这种情况,MySQL提供了三大运算符:
IS NULL: 当列的值是 NULL,此运算符返回 true。
IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。
<=>: 比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。
注意:
select * , columnName1+ifnull(columnName2,0) from tableName;
columnName1,columnName2 为 int 型,当 columnName2 中,有值为 null 时,
columnName1+columnName2=null, ifnull(columnName2,0) 把 columnName2 中 null 值转为 0。
mysql> SELECT * from runoob_test_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| RUNOOB | 20 |
| 菜鸟教程 | NULL |
| Google | NULL |
| FK | 20 |
+---------------+--------------+
4 rows in set (0.01 sec)
以下实例中你可以看到 = 和 != 运算符是不起作用的:
mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count = NULL;
Empty set (0.00 sec)
mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count != NULL;
Empty set (0.01 sec)
查找数据表中 runoob_test_tbl 列是否为 NULL,必须使用 IS NULL 和 IS NOT NULL,如下实例:
mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count IS NULL;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鸟教程 | NULL |
| Google | NULL |
+---------------+--------------+
2 rows in set (0.01 sec)
mysql> SELECT * from runoob_test_tbl WHERE runoob_count IS NOT NULL;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| RUNOOB | 20 |
| FK | 20 |
+---------------+--------------+
2 rows in set (0.01 sec)
MySQL 正则表达式
^ 匹配输入字符串的开始位置。
$ 匹配输入字符串的结束位置。
. 匹配除 "\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"。
{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> select * from apps where country regexp '^[aeiou]|n$';
+----+-----------+---------+
| id | app_name | country |
+----+-----------+---------+
| 1 | QQ APP | CN |
| 2 | 微博APP | CN |
| 3 | 淘宝APP | CN |
| 4 | 抖音APP | AA |
+----+-----------+---------+
4 rows in set (0.00 sec)
mysql> select * from apps where country regexp 'a*';
+----+-----------+---------+
| id | app_name | country |
+----+-----------+---------+
| 1 | QQ APP | CN |
| 2 | 微博APP | CN |
| 3 | 淘宝APP | CN |
| 4 | 抖音APP | AA |
+----+-----------+---------+
4 rows in set (0.00 sec)
mysql> select * from apps where country regexp 'a+';
+----+-----------+---------+
| id | app_name | country |
+----+-----------+---------+
| 4 | 抖音APP | AA |
+----+-----------+---------+
1 row in set (0.00 sec)
mysql> select * from apps where country regexp 'aa*';
+----+-----------+---------+
| id | app_name | country |
+----+-----------+---------+
| 4 | 抖音APP | AA |
+----+-----------+---------+
1 row in set (0.00 sec)
MySQL 事务
mysql> use RUNOOB;
Database changed
mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb; # 创建数据表
Query OK, 0 rows affected (0.04 sec)
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 |
+------+
2 rows in set (0.01 sec)
mysql>
MySQL ALTER命令
当我们需要修改数据表名或者修改数据表字段时,就需要使用到MySQL ALTER命令。
mysql> create table testalter_tbl
-> (
-> i INT,
-> c CHAR(1)
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i | int(11) | YES | | NULL | |
| c | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
删除,添加或修改表字段
如下命令使用了 ALTER 命令及 DROP 子句来删除以上创建表的 i 字段:
mysql> ALTER TABLE testalter_tbl DROP i;
如果数据表中只剩余一个字段则无法使用DROP来删除字段。
MySQL 中使用 ADD 子句来向数据表中添加列,如下实例在表 testalter_tbl 中添加 i 字段,并定义数据类型:
mysql> ALTER TABLE testalter_tbl ADD i INT;
执行以上命令后,i 字段会自动添加到数据表字段的末尾。
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c | char(1) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
如果你需要指定新增字段的位置,可以使用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;
FIRST 和 AFTER 关键字可用于 ADD 与 MODIFY 子句,所以如果你想重置数据表字段的位置就需要先使用 DROP 删除字段然后使用 ADD 来添加字段并设置位置。
MySQL ALTER命令
mysql> create table testalter_tbl
-> (
-> i int,
-> c char(1)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> desc testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i | int(11) | YES | | NULL | |
| c | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
#删除i列
mysql> ALTER TABLE testalter_tbl DROP i;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
#添加i列
mysql> ALTER TABLE testalter_tbl ADD i INT;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c | char(1) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE testalter_tbl DROP i;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE testalter_tbl ADD i INT FIRST;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i | int(11) | YES | | NULL | |
| c | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE testalter_tbl DROP i;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE testalter_tbl ADD i INT AFTER c;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c | char(1) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE testalter_tbl MODIFY c CHAR(10);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE testalter_tbl CHANGE i j BIGINT;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| j | bigint(20) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE testalter_tbl CHANGE j j INT;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| j | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE testalter_tbl
-> MODIFY j BIGINT NOT NULL DEFAULT 100;
Query OK, 0 rows affected (0.28 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| j | bigint(20) | NO | | 100 | |
+-------+------------+------+-----+---------+-------+
mysql> alter table testalter_tbl change j i int;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
你可以使用 ALTER 来修改字段的默认值,尝试以下实例:
mysql> alter table testalter_tbl modify i set default 1000;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 1000' at line 1
mysql> alter table testalter_tbl alter i set default 1000;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| i | int(11) | YES | | 1000 | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
此处可以观察alter和modify的区别
ysql> alter table testalter_tbl modify i bigint default 1000; ##modify不用加set!!
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| i | bigint(20) | YES | | 1000 | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
你也可以使用 ALTER 命令及 DROP子句来删除字段的默认值,如下实例:
mysql> alter table testalter_tbl modify i int default 1000;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| i | int(11) | YES | | 1000 | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> alter table testalter_tbl alter i drop default;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc testalter_tbl;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| c | char(10) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
修改数据表类型,可以使用 ALTER 命令及 TYPE 子句来完成。尝试以下实例,我们将表 testalter_tbl 的类型修改为 MYISAM :
注意:查看数据表类型可以使用 SHOW TABLE STATUS 语句。
mysql> alter table testalter_tbl engine=myisam;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show table status like 'testalter_%'\G;
*************************** 1. row ***************************
Name: testalter_tbl
Engine: MyISAM
Version: 10
Row_format: Fixed
Rows: 0
Avg_row_length: 0
Data_length: 0
Max_data_length: 4222124650659839
Index_length: 1024
Data_free: 0
Auto_increment: NULL
Create_time: 2021-08-26 00:09:26
Update_time: 2021-08-26 00:09:26
Check_time: NULL
Collation: latin1_swedish_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)
更改表名
mysql> ALTER TABLE testalter_tbl RENAME TO alter_tbl;
Query OK, 0 rows affected (0.00 sec)
MySQL 索引
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
建立索引会占用磁盘空间的索引文件。
索引学习
例如,对于students表:
id class_id name gender score
1 1 小明 M 90
2 1 小红 F 95
3 1 小军 M 88
如果要经常根据score列进行查询,就可以对score列创建索引:
ALTER TABLE students
ADD INDEX idx_score (score);
使用ADD INDEX idx_score (score)就创建了一个名称为idx_score,使用列score的索引。索引名称是任意的
,索引如果有多列,可以在括号里依次写上,例如:
ALTER TABLE students
ADD INDEX idx_name_score (name, score);
索引的效率取决于索引列的值是否散列,即该列的值如果越互不相同,那么索引效率越高。反过来,如果记录的列存在大量相同的值,
例如gender列,大约一半的记录值是M,另一半是F,因此,对该列创建索引就没有意义。
索引的优点是提高了查询效率,缺点是在插入、更新和删除记录时,需要同时修改索引,因此,索引越多,插入、更新和删除记录的速度就越慢。
对于主键,关系数据库会自动对其创建主键索引。使用主键索引的效率是最高的,因为主键会保证绝对唯一。
唯一索引
在设计关系数据表的时候,看上去唯一的列,例如身份证号、邮箱地址等,因为他们具有业务含义,因此不宜作为主键。
但是,这些列根据业务要求,又具有唯一性约束:即不能出现两条记录存储了同一个身份证号。这个时候,就可以给该列添加一个唯一索引。例如,我们假设students表的name不能重复:
ALTER TABLE students
ADD UNIQUE INDEX uni_name (name);
通过UNIQUE关键字我们就添加了一个唯一索引。
也可以只对某一列添加一个唯一约束而不创建唯一索引:
ALTER TABLE students
ADD CONSTRAINT uni_name UNIQUE (name);
这种情况下,name列没有索引,但仍然具有唯一性保证。
普通索引
创建索引
这是最基本的索引,它没有任何限制。它有以下几种创建方式:
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(length))
);
删除索引的语法
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可能会出现多次 区别就是可以为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
........
创建索引
create index idx1 on table1(col1,col2,col3)
查询
select * from table1 where col1= A and col2= B and col3 = C
组合索引查询的各种场景
组合索引 Index (A, B, C)
下面条件可以用上该组合索引查询:
A>5
A=5 AND B>6
A=5 AND B=6 AND C=7
A=5 AND B=6 AND C IN (2, 3)
下面条件将不能用上组合索引查询:
B>5 ——查询条件不包含组合索引首列字段
B=6 AND C=7 ——理由同上
下面条件将能用上部分组合索引查询(重要! ! ! ! ) :
A>5 AND B=2 ——当范围查询使用第一列, 查询条件仅仅能使
用第一列
A=5 AND B>6 AND C=2 ——范围查询使用第二列, 查询条件仅仅能使用
前二列
A=5 AND B IN (2, 3) AND C=2 ——理由同上
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
);
Query OK, 0 rows affected (0.00 sec)
mysql> 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 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)
当你使用 SHOW TABLES命令显示数据表列表时,你将无法看到 SalesSummary表。
如果你退出当前MySQL会话,再使用 SELECT命令来读取原先创建的临时表数据,
那你会发现数据库中没有该表的存在,因为在你退出时该临时表已经被销毁了。
删除
mysql> DROP TABLE SalesSummary;
mysql> SELECT * FROM SalesSummary;
ERROR 1146: Table 'RUNOOB.SalesSummary' doesn't exist
mysql复制表
使用 SHOW CREATE TABLE 命令获取创建数据表(CREATE TABLE) 语句,该语句包含了原数据表的结构,索引等。
复制以下命令显示的SQL语句,修改数据表名,并执行SQL语句,通过以上命令 将完全的复制数据表结构。
实例
尝试以下实例来复制表 runoob_tbl 。
步骤一:
获取数据表的完整结构。
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
1 row in set (0.00 sec)
ERROR:
No query specified
步骤二:
修改SQL语句的数据表名,并执行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;
Query OK, 0 rows affected (1.80 sec)
步骤三:
执行完第二步骤后,你将在数据库中创建新的克隆表 clone_tbl。 如果你想拷贝数据表的数据你可以使用
INSERT INTO... SELECT 语句来实现。
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;
Query OK, 3 rows affected (0.07 sec)
Records: 3 Duplicates: 0 Warnings: 0
执行以上步骤后,会完整的复制表的内容,包括表结构及表数据。
自己操作的
mysql> show create table apps \G;
*************************** 1. row ***************************
Table: apps
Create Table: CREATE TABLE `apps` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app_name` varchar(40) NOT NULL,
`country` varchar(40) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
ERROR:
No query specified
mysql> CREATE TABLE `apps111` (
-> `id` int(11) NOT NULL AUTO_INCREMENT,
-> `app_name` varchar(40) NOT NULL,
-> `country` varchar(40) NOT NULL,
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
-> ;
Query OK, 0 rows affected (0.01 sec)
mysql> desc apps;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| app_name | varchar(40) | NO | | NULL | |
| country | varchar(40) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> desc apps111;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| app_name | varchar(40) | NO | | NULL | |
| country | varchar(40) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> insert into apps111 (id,
-> app_name,
-> country)
-> select id,app_name,country from apps;
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
注意啦
mysql> insert into apps22 (id,app_name,country)
-> select * from apps;
直接使用这个也可以插入数据
mysql> select * from apps111;
+----+-----------+---------+
| id | app_name | country |
+----+-----------+---------+
| 1 | QQ APP | CN |
| 2 | 微博APP | CN |
| 3 | 淘宝APP | CN |
| 4 | 抖音APP | AA |
+----+-----------+---------+
4 rows in set (0.00 sec)