前面我们已经知道怎么来创建表了,接下来就来对创建的表进行一些基本操作。
这里先将上次创建的表删除掉:
sqlmysql> use test; Database changed mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | student | +----------------+ 1 row in set (0.00 sec) mysql> drop table if exists student; Query OK, 0 rows affected (0.03 sec)
在test数据库里新建一个student表:
sqlmysql> create table student( -> id int comment '序列号', -> name varchar(20) comment '学生名', -> Chinese decimal(3,1) comment '语文成绩', -> Math decimal(3,1) comment '数学成绩', -> English decimal(3,1) comment '英语成绩' -> ); Query OK, 0 rows affected (0.06 sec)
接下来就针对该表进行增删改查的操作~
目录
♫新增
♪单行数据插入
新增操作是指对表增添数据:
语法:insert into 表名 values(类型1的数据,类型2的数据,类型3的数据...);
sqlmysql> insert into student values(1,'student1',99,94,93); Query OK, 1 row affected (0.42 sec)
注:
①.into也可以省略不写
②.插入的数据必须和定义表的列数及顺序一致
♪查看默认编码
上面我们就将student1学生的数据插入到student表里了,但如果我们插入的名字是中文名就有可能会报错:
sqlmysql> insert into student values(1,'张三',99,94,93); ERROR 1366 (HY000): Incorrect string value: '\xD0\xA1\xC3\xF7' for column 'name' at row 1
这是因为我们在创建test数据库的时候没有手动指定字符集,此时字符集就会是配置文件(my.ini)里的字符集,而配置文件的字符集如果没有修改过默认是latin1。
我们可以通过**show variables like "%character%";**语句来查看当前MySQL的数据库编码:
sqlmysql> show variables like "%character%"; +--------------------------+---------------------------------------------------------+ | Variable_name | Value | +--------------------------+---------------------------------------------------------+ | character_set_client | gbk | | character_set_connection | gbk | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | gbk | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.7\share\charsets\ | +--------------------------+---------------------------------------------------------+ 8 rows in set, 1 warning (0.00 sec)
其中,character_set_client为客户端编码方式,character_set_connection为建立连接使用的编码,character_set_database数据库的编码,character_set_results结果集的编码,character_set_server数据库服务器的编码。可以看到此时数据库的编码为latin1,所以我们需要在创建数据库时手动指定字符集或者通过修改配置文件的字符集来使接下来创建的数据库都支持中文。
♪修改配置文件
手动指定字符集我们都会了,下面就来改一改配置文件里的默认字符集吧~
找到并打开my.ini文件,将里面的default-character-set和character-set-server改为如下:
注:修改配置文件前最好备份一份修改前的,以防改错了能改回之前的。
修改完重启MySQL之后再去查询数据库编码可以发现默认字符集已经改为utf8了:
sqlmysql> show variables like"%character%"; +--------------------------+---------------------------------------------------------+ | Variable_name | Value | +--------------------------+---------------------------------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.7\share\charsets\ | +--------------------------+---------------------------------------------------------+ 8 rows in set, 1 warning (0.02 sec)
这样,之后创建的数据库即使不手动指定字符集也能支持中文了,我们删掉之前的test库,并重新创建一个student表插入中文学生名的数据:
sqlmysql> drop database if exists test; Query OK, 1 row affected (0.09 sec) mysql> create database if not exists test; Query OK, 1 row affected (0.00 sec) mysql> use test; Database changed mysql> create table student( -> id int comment '序列号', -> name varchar(20) comment '学生名', -> Chinese decimal(3,1) comment '语文成绩', -> Math decimal(3,1) comment '数学成绩', -> English decimal(3,1) comment '英语成绩' -> ); Query OK, 0 rows affected (0.07 sec) mysql> insert into student values(1,"张三",88,93,89); Query OK, 1 row affected (0.02 sec)
♪指定列插入
插入操作还可以指定列插入:
语法:insert into 表名(列名1,列名2,列名3...) values(列名1的数据,列名2的数据,列名3的数据...);
sqlmysql> insert into student(id,name) values(2,"李四"); Query OK, 1 row affected (0.09 sec)
这样就可以只插入部分数据,其余列则就是默认值。
♪多行数据插入
如果觉得一条一条插入太麻烦,还可以一次插入多条数据:
语法:insert into 表名 values(类型1的数据,类型2的数据,类型3的数据...),(类型1的数据,类型2的数据,类型3的数据...),(类型1的数据,类型2的数据,类型3的数据...)...;
sqlmysql> insert into student values(3,"王五",97,77,82),(4,"赵六",87,67,65),(5,"小七",88,77,82); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0
注:MySQL是一个客户端服务器,每次请求和相应都会有时间开销,数据库服务器把数据存储在硬盘上(硬盘的读取和写入速度慢),每进行一次sql都会开启一个事务,故一次插入多条数据往往比多次插入一条数据效率要高。
♫查询
♪全列查询
新增数据后,我们就可以通过查询操作查看我们插入的数据了:
语法:select * from 表名;
sqlmysql> select * from student; +------+--------+---------+------+---------+ | id | name | Chinese | Math | English | +------+--------+---------+------+---------+ | 1 | 张三 | 88.0 | 93.0 | 89.0 | | 2 | 李四 | NULL | NULL | NULL | | 3 | 王五 | 97.0 | 77.0 | 82.0 | | 4 | 赵六 | 87.0 | 67.0 | 65.0 | | 5 | 小七 | 88.0 | 77.0 | 82.0 | +------+--------+---------+------+---------+ 5 rows in set (0.01 sec)
注:当数据量很大时不介意使用全列查询,容易把硬盘IO和网络带宽吃满。
♪指定列查询
相比于全列查询,指定列查询的数据量就要小很多:
语法:select 列名1,列名2,列名3... from 表名;
sqlmysql> select id,name,Chinese from student; +------+--------+---------+ | id | name | Chinese | +------+--------+---------+ | 1 | 张三 | 88.0 | | 2 | 李四 | NULL | | 3 | 王五 | 97.0 | | 4 | 赵六 | 87.0 | | 5 | 小七 | 88.0 | +------+--------+---------+ 5 rows in set (0.00 sec)
♪表达式查询
还可以指定表达式进行查询:
语法:select 表达式1,表达式2,表达式3... from student;
sqlmysql> select id,name,10 from student; +------+--------+----+ | id | name | 10 | +------+--------+----+ | 1 | 张三 | 10 | | 2 | 李四 | 10 | | 3 | 王五 | 10 | | 4 | 赵六 | 10 | | 5 | 小七 | 10 | +------+--------+----+ 5 rows in set (0.00 sec) mysql> select id,name,Chinese+10 from student; +------+--------+------------+ | id | name | Chinese+10 | +------+--------+------------+ | 1 | 张三 | 98.0 | | 2 | 李四 | NULL | | 3 | 王五 | 107.0 | | 4 | 赵六 | 97.0 | | 5 | 小七 | 98.0 | +------+--------+------------+ 5 rows in set (0.01 sec) mysql> select id, name,Chinese+Math+English from student; +------+--------+----------------------+ | id | name | Chinese+Math+English | +------+--------+----------------------+ | 1 | 张三 | 270.0 | | 2 | 李四 | NULL | | 3 | 王五 | 256.0 | | 4 | 赵六 | 219.0 | | 5 | 小七 | 247.0 | +------+--------+----------------------+ 5 rows in set (0.00 sec)
注:根据表达式查询返回的是一个临时表,并不会改变原来表的数据
♪表达式查询
如果觉得表达式太长,还可以为表达式取个别名,这样返回的结果集中就会以该别名作为该列的名称:
语法:select 表达式 as 别名 from student;
sqlmysql> select id,name,Chinese+Math+English as total from student; +------+--------+-------+ | id | name | total | +------+--------+-------+ | 1 | 张三 | 270.0 | | 2 | 李四 | NULL | | 3 | 王五 | 256.0 | | 4 | 赵六 | 219.0 | | 5 | 小七 | 247.0 | +------+--------+-------+ 5 rows in set (0.00 sec)
注:as也可以省略不写
♪去重查询
还可以通过distnct对某一列进行去重操作:
语法:select distance 列名 from 表名;
sqlmysql> select distinct Chinese from student; +---------+ | Chinese | +---------+ | 88.0 | | NULL | | 97.0 | | 87.0 | +---------+ 4 rows in set (0.01 sec)
注:distnct后面如果跟n列,那么只会对n列都重复的进行去重操作。
♪排序查询
也可以通过order by对查询结果进行排序:
语法:select 列名 from 表名 order by 列名 asc/desc;(asc为升序,desc为降序,不写时默认为asc)
sqlmysql> select id,name,Chinese from student order by Chinese asc; +------+--------+---------+ | id | name | Chinese | +------+--------+---------+ | 2 | 李四 | NULL | | 4 | 赵六 | 87.0 | | 1 | 张三 | 88.0 | | 5 | 小七 | 88.0 | | 3 | 王五 | 97.0 | +------+--------+---------+ 5 rows in set (0.40 sec)
注:
①.NULL比任何值都小。
②.没有 order by 子句的查询,返回的顺序是未定义的。
③.也可以使用表达式及别名排序(如:mysql> select name,Chinese+Math+English as total from student order by total;)。
④.还可以对多个字段进行排序,排序优先级随书写顺序(如:mysql> select name from student order by Chinese desc,Math,English;(先根据语文成绩排序,语文成绩相同再根据数学成绩排序,数学成绩相同再根据英语成绩排序))。
MySQL还可以根据指定的条件进行查询,不过条件查询需要用到运算符,这里我们还是先了解下MySQL里的运算符~
♪运算符
♩比较运算符
|-------------------|------------------------------------------------------|
| 运算符 | 描述 |
| >,>=,<,<= | 大于,大于等于,小于,小于等于 |
| = | 等于, NULL 不安全,例如 NULL = NULL 的结果是 NULL |
| <=> | 等于, NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1) |
| !=,<> | 不等于 |
| between a1 and a2 | 范围匹配, [a1, a2] ,如果 a1 <= value <= a2, 返回 TRUE(1) |
| in (option, ...) | 如果是 option 中的任意一个,返回 TRUE(1) |
| IS NULL | 是 NULL |
| IS NOT NULL | 不是 NULL |
| like | 模糊匹配。 % 表示任意多个(包括 0 个)任意字符; _ 表示任意一个字 符 |注:<=>可以比较两列都为NULL的情况,而IS NULL只能判断一个是否为NULL
♩逻辑运算符
|---------|--------------------------------|
| 运算符 | 描述 |
| and | 多个条件必须都为 TRUE(1) ,结果才是 TRUE(1) |
| or | 任意一个条件为 TRUE(1), 结果为 TRUE(1) |
| not | 条件为 TRUE(1) ,结果为 FALSE(0) |注:and 的优先级高于 or
♪条件查询
对特定条件的数据进行查询也可以降低查询的数据量:
语法:select 列名 from 表名 where 查询条件;
sqlmysql> select id,name,Chinese from student where Chinese<=90; +------+--------+---------+ | id | name | Chinese | +------+--------+---------+ | 1 | 张三 | 88.0 | | 4 | 赵六 | 87.0 | | 5 | 小七 | 88.0 | +------+--------+---------+ 3 rows in set (0.00 sec) mysql> select id,name from student where name like '%五'; +------+--------+ | id | name | +------+--------+ | 3 | 王五 | +------+--------+ 1 row in set (0.02 sec) mysql> select id,name,Chinese from student where Chinese between 88 and 99; +------+--------+---------+ | id | name | Chinese | +------+--------+---------+ | 1 | 张三 | 88.0 | | 3 | 王五 | 97.0 | | 5 | 小七 | 88.0 | +------+--------+---------+ 3 rows in set (0.00 sec) mysql> select id,name,Chinese,Math from student where Chinese>85 and Math>85; +------+--------+---------+------+ | id | name | Chinese | Math | +------+--------+---------+------+ | 1 | 张三 | 88.0 | 93.0 | +------+--------+---------+------+ 1 row in set (0.00 sec) mysql> select id,name,Chinese+Math+English as total from student where Chinese+Math+English is not null;-- where后面不能用别名 +------+--------+-------+ | id | name | total | +------+--------+-------+ | 1 | 张三 | 270.0 | | 3 | 王五 | 256.0 | | 4 | 赵六 | 219.0 | | 5 | 小七 | 247.0 | +------+--------+-------+ 4 rows in set (0.00 sec)
注:条件查询where后面不能用别名
♪限制查询
使用where虽然可以限制查询内容,但仍然不知道查询到的数据量有多少,而limit就可以强制限制查询的行数:
语法:select 列名 from 表名 limit 行数;
sqlmysql> select * from student limit 3; +------+--------+---------+------+---------+ | id | name | Chinese | Math | English | +------+--------+---------+------+---------+ | 1 | 张三 | 88.0 | 93.0 | 89.0 | | 2 | 李四 | NULL | NULL | NULL | | 3 | 王五 | 97.0 | 77.0 | 82.0 | +------+--------+---------+------+---------+ 3 rows in set (0.00 sec)
♪分页查询
当查询结果的数量较大时,我们需要将其分页显示,以方便用户查看和管理,MySQL中可以通过limit 和offset(limit限制行数,offset设置开始查询的行(0为第一行))来实现分页查询:
语法:select 列名 from 表名 limit 行数 offset 第n行;
sqlmysql> select * from student limit 2 offset 0; +------+--------+---------+------+---------+ | id | name | Chinese | Math | English | +------+--------+---------+------+---------+ | 1 | 张三 | 88.0 | 93.0 | 89.0 | | 2 | 李四 | NULL | NULL | NULL | +------+--------+---------+------+---------+ 2 rows in set (0.00 sec) mysql> select * from student limit 2 offset 2; +------+--------+---------+------+---------+ | id | name | Chinese | Math | English | +------+--------+---------+------+---------+ | 3 | 王五 | 97.0 | 77.0 | 82.0 | | 4 | 赵六 | 87.0 | 67.0 | 65.0 | +------+--------+---------+------+---------+ 2 rows in set (0.00 sec) mysql> select *from student limit 2 offset 4; +------+--------+---------+------+---------+ | id | name | Chinese | Math | English | +------+--------+---------+------+---------+ | 5 | 小七 | 88.0 | 77.0 | 82.0 | +------+--------+---------+------+---------+ 1 row in set (0.00 sec)
注:分页查询也可以写成**select 列名 from 表名 limit 第n行,行数;**的形式
了解完这些基础的查询操作后,我们再来看看如何修改已添加的数据。
♫修改
通过update关键字可以对指定条件的列修改指定内容:
语法:update 表名 set 列名 = 值 指定条件;
sql-- 将张三的语文成绩改为90 mysql> update student set Chinese = 90 where name = "张三"; Query OK, 1 row affected (0.19 sec) Rows matched: 1 Changed: 1 Warnings: 0 -- 将语文成绩倒数的2个学生的语文成绩改为90 mysql> update student set Chinese = 90 order by Chinese limit 2; Query OK, 2 rows affected (0.00 sec) Rows matched: 2 Changed: 2 Warnings: 0
MySQL还支持一次修改多列数据:
语法:update 表名 set 列名1=值1,列名2=值2,列名3=值3.. 指定条件;
sql-- 将张三的语文成绩,数学成绩,英语成绩都改为90 mysql> update student set Chinese=90,Math=90,English=90 where name="张三"; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0
注:修改时若不加上指定条件,则会将表里所有行的数据都进行修改
最后来看下删除操作~
♫删除
删除操作是指将表中不需要的数据移除掉:
语法:delete from 表名 指定条件;
sql-- 删除学生名为张三的数据 mysql> delete from student where name="张三"; Query OK, 1 row affected (0.01 sec) -- 删除语文成绩最后两名的学生数据 mysql> delete from student order by Chinese limit 2; Query OK, 2 rows affected (0.00 sec)
注:删除操作如果没有添加指定条件同样会把表里所有数据都删了