2.MySQL数据库基本操作

思考:SQL是一种编程语言,那是不是意味着学习起来非常复杂呢?数据库内部有数据库、数据表、字段以及相应的数据,是不是内容会非常多呢?

引入:SQL是针对关系型数据库的高级的非过程化编程语言,是一种近乎自然语言的编程语言,因此从学习角度来讲是非常简单的。另外根据数据库的实际应用,我们将基础SQL学习分成对应的三类,内容也不多:

  • 库操作:针对数据库的管理
  • 表操作:针对数据表(字段)的管理
  • 数据操作:针对表中数据的管理

总结:SQL的学习本质是要掌握数据库的基础指令操作,因此学习本身难度不大,相对编程语言有各种对应的业务逻辑而言,SQL指令基本是固定的,因此要学习的量也不会太大。


思考:SQL是一种编程语言,那是不是也像PHP一样有一些语法规则呢?

引入:任何一种编程语言都有其固定的语法规则和结构,作为指令式的SQL语言,虽然语法简单,但是也有其自身的规则。

一、SQL语法规则

定义:SQL语法规则就是指服务器DBMS需要客户端提供指定规范的代码,SQL的语法规则比较简单

  1. 语法环境:SQL执行必须是在客户端与服务端建立联系(登录验证通过进入MySQL环境)之后才能被执行的,因此必须在进入MySQL服务端之后,客户端才能给服务端发送指令
  2. 代码执行:SQL的执行是服务器自动判定执行,而判定的标准就是检测到语句结束符。
  3. SQL代码是顺序逐行执行的。
  4. 语句结束符:SQL的语句结束符分为三种:
  • 英文分号(;):与其他语言语句结束符一样
  • \g:与分号的效果一样
  • \G:数据结果以行为单位的纵向展示
mysql> select host,user,authentication_string from mysql.user;

mysql> select host,user,authentication_string from mysql.user\g

mysql> select host,user,authentication_string from mysql.user\G
  1. SQL指令关键字不区分大小写
mysql> select host,user,authentication_string from mysql.user;
#最终执行没有区别
mysql> SELECT host,user,authentication_string FROM mysql.user;
  1. 注释:SQL中也有注释,分为行注释和块注释:
  • 行注释:#和(--空格),表示后面的所有内容都是注释
  • 块注释:和其他编程语言一样,使用/*块注释内容*/
mysql> -- 这是注释(注意--后有空格)
mysql> #这也是注释
mysql>
mysql> /*
   /*> 注释从这里开始
   /*> 注释还没结束,>前面的/*表示在等待对应的结束
   /*> */
mysql>

总结:因为SQL的语法特性,每次执行的SQL基本都是一条,在发送SQL指令的时候可以没有语句结束符,系统不会执行,但是会一直等待语句结束符的出现,才会组织前面的所有内容进行语法检查然后执行。


二、SQL库操作【掌握】

思考:客户端登录数据库服务端之后,什么都看不到,如何知道服务器里有什么东西呢?

引入:客户端登录数据库其实本质就是数据库管理系统DBMS在和客户端进行响应,DMBS管理的最粗单元就是数据库(DB)。默认的,数据库在安装后是有自己的核心数据库的,只是需要特定的SQL指令才能看到。

1.查看数据库【掌握】

定义:查看数据库,即将系统已经存在的数据库显示出来。在SQL操作中,分两种情况查看数据库:一是查看所有数据库,二是查看匹配数据库

  1. 查看所有数据库:show databases;
mysql> show databases;        
+--------------------+
| Database           |    #名字:当前表只有一个字段名字叫Database
+--------------------+
| information_schema |    #第一个数据库
| mysql              |    #第二个数据库
| performance_schema |    
| sys                |    #默认四个数据库
+--------------------+
4 rows in set (0.00 sec)  #说明:4行数据(括号内表示用时,单位秒)

注意:版本不同数据库的内部结构不同,5.7以前的mysql数据库都有一个空数据库test给用户使用的

  1. 查看部分数据库:使用匹配方式匹配相近数据库,语法结构为:show databases like 'pattern';
  • 占位符_(下划线):匹配固定位置单个字符,_a,可以是Aa\aa\sa,但不能是aaa

  • 占位符%(百分号):匹配多个字符,%a,可以是任何以a结尾的字符

  • 为了解决实际需求,_和%可以同时无限制使用

mysql> show databases like '_a'; #下划线匹配

mysql> show databases like '%a'; #模糊匹配
  1. 数据库创建是有SQL指令完成的,可以通过指令查看数据库创建的指令:show create database 数据库名字;
mysql> show create database mysql;

总结:通过show databases指令可以实现查看全部或者匹配部分数据库。在实际工作中,当项目数据库较少时使用查看全部,如果项目数据库非常多,那么可以使用匹配模式来筛选要查看的数据库。如果想了解一下数据库的详细信息,可以通过show create database 数据库名字来实现。


思考:MySQL系统自带数据库了,是不是在开发的过程中,就可以直接使用这些数据库来储存项目数据呢?

引入:系统内部的数据库是用于数据库管理工作的,不适合存放用户项目数据,如果用户要使用数据库,需要根据项目来创建对应的数据库。

2.创建数据库【掌握】

定义:创建数据库,就是通过对应的SQL指令实现在数据库服务器中增加对应的数据库信息。

  1. 创建数据库:create database 数据库名字;
mysql> create database my_database;
Query OK, 1 row affected (0.09 sec)    #Query OK表示指令正确执行

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| my_database        |                 #查看到创建的数据库
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.04 sec)
  1. 数据库命名规范
  • 数据库名字由字母、数字和下划线组成
  • 数据库不强制要求数字不能开头(但是不建议)
  • 数据库命名应当见名知意(与项目对应)
  • 数据库多单词数据库命名建议使用下划线法
  • 数据库名字如果使用到了SQL内部关键字或者保留字应该使用反引号包裹(数字键1左边对应的英文状态``,但是不建议使用冲突关键字作为名字
mysql> create database create;
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 'create' at line 1
#错误解析:Mysql不会提示具体错误信息,只会提示在哪一块出现错误,需要开发人员自己寻找错误
mysql>
mysql> create database `create`;    #使用反引号``后可以实现
Query OK, 1 row affected (0.00 sec)
  1. 数据库创建过程中可以指定数据库字符集:create database 数据库名字 charset 字符集;
mysql> create database my_project charset utf8;
Query OK, 1 row affected (0.00 sec)
#指定字符集为utf8,注意mysql中utf-8用utf8表示(不允许使用中划线-)

注意:指定字符集的效果是数据库中的默认数据按照当前字符集来存储,但是实际数据存储的话以更小的字符集为准(数据表字符集);数据库如果不指定字符集,那么默认使用DBMS对应的字符集。

  1. 数据库创建指令执行成功后,不只是会在查看时看到对应数据库,会在MySQL指定的存储数据的目录data下看到一个对应名字的文件夹
创建数据库效果.png

总结:数据库创建是通过create database指令实现,是项目实施的第一条有效指令。在创建数据库的时候通常会根据项目来设定字符集(目前项目基本都是使用utf8),但是要注意utf8不能写成utf-8。


思考:如果在创建数据库的时候弄错了名字或者字符集什么的后期可以改吗?

引入:MySQL数据库在5版本以前允许数据库名字修改,但是在5以后不允许修改名字了,不过可以修改默认字符集。

3.修改数据库字符集【了解】

定义:修改数据库字符集,就是让数据库中其他结构(数据表)能够使用对应的默认字符集。

  1. 修改数据库字符集:alter database 数据库名字 charset 新字符集;
mysql> alter database my_project charset gbk;
Query OK, 1 row affected (0.04 sec)

  1. 数据库字符集的修改是针对以后在数据库创建的结构的默认字符集,不会修改已经存在的数据表对应的字符集

总结:数据库字符集的修改目的是为了让后续创建的数据表能够使用新的默认字符集,但是不能改变已经存在的数据表和表中的数据。实际上在开发过程中,数据库的字符集通常在开始就会根据实际项目需求设定好,不会随意改变。


思考:如果数据库不想要了,或者已经有新的代替了,该如何让数据库消失呢?

引入:让数据库消失在开发中属于伪命题,通常不会轻易就让数据库消失,这样会带来数据的损失。但是如果在开发环境中或者真的要终结某个项目,那么也可以实现数据库删除。

4.删除数据库【了解】

定义:删除数据库,即让数据库在MySQL服务器端不存在

  1. 删除数据库:drop database 数据库名字;
mysql> drop database my_project;
Query OK, 0 rows affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| create             |
| my_database        |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)
  1. 数据库删除会直接清空该数据库内的所有内容,而且不可找回,因此一定要慎重(操作之前先做安全备份)
  2. 数据库的删除只允许一次删除一个,不能删除多个
mysql> drop database my_database,`create`;
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 '`create`' at line 1
  1. 数据库的删除不只是在系统环境中看不到对应的数据库名字,对应data目录下的数据库名字文件夹也会被清空
删除数据库效果.png

总结:数据库的删除是一种非常谨慎的操作,因为一旦删除就不可恢复。在生产环境中进行删除操作非常恐怖,一定不要执行,如果确定要执行,势必要拿到上级的明确指令甚至责任文件,而且在操作的时候也一定要事先备份。


三、数据表(字段)操作【掌握】

思考:目前已经知道如何创建属于用户项目的数据库,那么数据是否可以直接存放到数据库里呢?

引入:数据库是数据存储的大容器,数据库本身不能存放数据,必须依赖数据表才能存储数据。

1.创建数据表【掌握】

定义:创建数据表,即在数据库中创建更小的数据存储的结构。数据表是一个二维结构表,不只是有关表自身结构,而且还与字段是一体的。因此所有数据表的操作就意味着有数据字段的操作。

  1. 创建数据表语法结构
create table 表名(
字段名 字段类型 [字段属性],        #每个字段有对应的英文逗号“,”分隔
字段名 字段类型 [字段属性],        #字段属性并非强制要求
...          
字段名 字段类型 [字段属性]         #最后一个字段名不需要逗号结束          
)[表选项];                        #表选项可有可无,都有默认值
  • 表名:描述表内数据的关键字,由数字、字母和下划线组成(不建议使用数字开头);如果使用关键字或者保留字作为表名应该使用反引号``;表名字在同一个数据库下不能重复
  • 字段名字:二维表列名字,描述该列数据的关键字;同一表内字段名字不能重复
  • 字段类型:MySQL为了方便数据的规范,对每列数据都强制规定数据的类型
  • 表选项:表的额外规范,包括存储引擎(默认InnoDB)、字符集(默认数据库字符集)和校对集(默认数据库对应校对集)

注意:表是一种多行结构,因此不建议直接使用CMD控制台输入指令,应该先在文本中写好指令,然后复制到CMD下去运行

mysql> create table my_table(
    -> name varchar(10),     #name为字段名,varchar(10)表示最长10个字符
    -> age int               #age为字段名,int表示整形
    -> );
ERROR 1046 (3D000): No database selected #错误,没有选择数据库
mysql>
  1. 数据表是依附于数据库存在的,也就是说数据表必须属于某个指定的数据库,而不能直接在DMBS下创建对应的数据库。要指定表对应的数据库有两种方式:
  • 直接在数据表名字前绑定数据库:create table 数据库.数据表名字 ...
mysql> create table my_database.my_table( #指定数据表my_table放到数据库my_database下
    -> name varchar(10),
    -> age int
    -> );
Query OK, 0 rows affected (0.36 sec)

  • 进入到某个具体数据库环境:use 数据库名字;
mysql> use my_database;    #进入my_database,后续的操作默认都是在my_database里面
Database changed
mysql>
mysql> create table my_student(
    -> name varchar(10),
    -> number varchar(10),
    -> age int
    -> );
Query OK, 0 rows affected (0.70 sec)

  1. 表选项1:存储引擎,数据存储的方式,默认是InnoDB(5以前是MyIsam)。存储引擎的语法结构为:engine [=] InnoDB/Myisam
mysql> create table my_engine1(
    -> name varchar(10)
    -> )engine InnoDB;
Query OK, 0 rows affected (0.77 sec)

mysql> create table my_engine2(
    -> name varchar(10)
    -> )engine = MyIsam;
Query OK, 0 rows affected (0.08 sec)

注意:存储引擎InnoDB和MyIsam的差别不仅仅是在数据处理上,在数据存储结构方面也有区别:InnoDB会创建一个结构和一个数据、索引文件(5.7.2后存在);MyIsam会创建三个文件:结构、数据和索引

InnoDB和MyIsam存储引擎.png

  1. 表选项2:字符集,表中数据指定的字符集,默认是所属数据库的字符集。字符集的语法为:[default] charset [=] 字符集
mysql> create table my_charset1(
    -> name varchar(10)
    -> )default charset = utf8;
Query OK, 0 rows affected (0.31 sec)

mysql> create table my_charsete2(
    -> name varchar(10)
    -> )charset gbk;
Query OK, 0 rows affected (0.29 sec)

  1. 表选项中的存储引擎和字符集没有顺序关系,可以同时存在
mysql> create table my_engine_charset1(
    -> name varchar(10)
    -> )charset utf8 engine = Innodb;
Query OK, 0 rows affected (0.29 sec)

mysql> create table my_engine_charset2(
    -> name varchar(20)
    -> )engine = Myisam default charset = utf8;
Query OK, 0 rows affected (0.10 sec)

  1. 创建表的特殊方式:有的时候可以使用一种“偷懒”的方式来创建表,这种方式就是通过已经创建好的表来实现。MySQL中提供了两种简单方式:
  • 使用SQL指令创建仿照已经存在的表创建新表:create table 表名 like [数据库名.]旧表名;

    mysql> use create; #进入到create数据库环境
    Database changed
    
    mysql> create table my_table_new like my_database.my_table;
    Query OK, 0 rows affected (0.73 sec)
    
  • 可以直接复制MyIsam结构表的三个文件到另外的数据库:MyIsam表是独立空间,可以移动有效;而InnoDB是非独立空间直接移动是无法生效的
MyIsam结构复制.png
  1. 练习:创建一张学生表和一张专业表,学生表包含字段有:学生姓名、性别、年龄、学号、联系方式、专业、家庭住址,专业表包含字段有:专业名称、专业编号、所属学院。然后思考一下两个表之间是否有联系

总结

  1. 创建数据表是通过create table关键字创建

  2. 因为表和字段不分家,而字段在MySQL中又是必须指定类型的,所以表、字段名和字段类型是一起存在的

  3. 创建数据库表必须指定数据库,因为表属于数据库管理

  4. 表选项部分如果在数据库设定好的前提下,不是特别业务需求,不用额外的管理。


思考:创建表的时候表名是不能在一个数据库中重复存在的,那么如何查看表名在数据库中已经使用过了呢?

引入:首先在系统开发中,创建结构的SQL指令应该是要在外部文档创建的,其次在进行表格创建的时候,系统会自动告知表名是否已经存在,也不会出现什么大问题。但是我们可以通过查看数据库中的表来避免这种错误。

2.查看数据表【掌握】

定义:数据表的存在是与字段和类型一体的,因此查看表的情况相对来说种类比较多,可以是查看表名也可以是查看表结构

  1. 查看全部已存在表:show tables; #进入数据库环境
mysql> show tables;
+-----------------------+
| Tables_in_my_database |
+-----------------------+
| my_charset1           |
| my_charsete2          |
| my_engine1            |
| my_engine2            |
| my_engine_charset1    |
| my_engine_charset2    |
| my_student            |
| my_table              |
+-----------------------+
8 rows in set (0.00 sec)
  1. 查看部分匹配表名:show tables like 'pattern';

    匹配模式也是‘_’单个字符匹配和‘%’多个字符模糊匹配

mysql> show tables like 'my_charset_'; 
#注意my后面的下划线会匹配所有单个字符包括下划线本身
+-------------------------------------+
| Tables_in_my_database (my_charset_) |
+-------------------------------------+
| my_charset1                         |
+-------------------------------------+
1 row in set (0.00 sec)

mysql> show tables like 'my_e%';       
#匹配所有my开头后跟一个字符,然后接e字符,后无限匹配
+-------------------------------+
| Tables_in_my_database (my_e%) |
+-------------------------------+
| my_engine1                    |
| my_engine2                    |
| my_engine_charset1            |
| my_engine_charset2            |
+-------------------------------+
4 rows in set (0.00 sec)
  1. 查看表结构,就是显示表中所有的字段细信息等:desc/describe/[show columns from] 表名;
mysql> desc my_table;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> describe my_table;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> show columns from my_table;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

#Field表示字段名
#Type表示字段类型
#NULL表示字段是否允许为空(属性)
#key表示字段的索引
#Default表示字段的默认值(属性)
#Extra表示额外属性(属性)
  1. 查看表创建语句,可以方便看出表的结构信息以及表选项控制:show create table 表名;
mysql> show create table my_table;
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                     |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| my_table | CREATE TABLE `my_table` (
  `name` varchar(10) DEFAULT NULL,
  `age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.06 sec)
#此创建语句并非用户输入的原始语句,而是被系统加工保存的创建语句

#这种结构查看适合使用\G查看,会更清晰
mysql> show create table my_table\G
*************************** 1. row ***************************
       Table: my_table
Create Table: CREATE TABLE `my_table` (
  `name` varchar(10) DEFAULT NULL,
  `age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

总结

  1. show tables可以实现查看全部表或者匹配部分查看

  2. show create table能够实现表结构的查看,方便我们去了解表的结构并针对其进行相应的调整

  3. desc/describe/show columns from 表名来查看字段数据


思考:表结构查看可以方便我们看原来的设计是否满足需求,如果不满足怎么办?

引入:数据表涉及的内容比较多,包括名字本身和字段以及字段类型(还有字段属性),这块如果前期设计不好的话,后期的确会有一些需要修改的时候。

3.更新数据表【掌握】

定义:更新数据表即根据需求更新表本身以及表内部字段部分的内容

  1. 更新表名,表的名字可以修改:rename table 旧表名 to 新表名;
mysql> show tables;
+-----------------------+
| Tables_in_my_database |
+-----------------------+
| my_charset1           |
| my_charsete2          |        #原表名
| my_engine1            |
| my_engine2            |
| my_engine_charset1    |
| my_engine_charset2    |
| my_student            |
| my_table              |
+-----------------------+
8 rows in set (0.00 sec)

mysql> rename table my_charsete2 to my_charset2; #修改语句
Query OK, 0 rows affected (0.65 sec)

mysql> show tables;
+-----------------------+
| Tables_in_my_database |
+-----------------------+
| my_charset1           |
| my_charset2           |        #新表名
| my_engine1            |
| my_engine2            |
| my_engine_charset1    |
| my_engine_charset2    |
| my_student            |
| my_table              |
+-----------------------+
8 rows in set (0.00 sec)

注意:如果见到有些地方对应的表名是 XXX.表名 不要奇怪,XXX只是显式的指定的数据库名字而已

  1. 更新表选项,即更新表后期对应信息(不建议修改):alter table 表名 表选项修改;
mysql> show create table my_table\G
*************************** 1. row ***************************
       Table: my_table
Create Table: CREATE TABLE `my_table` (
  `name` varchar(10) DEFAULT NULL,
  `age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> #当前表使用的字符集为my_database数据库的默认字符集(数据库也没指定用的DMBS的字符集)
mysql>
mysql> alter table my_table default charset = utf8; #修改表选项
Query OK, 0 rows affected (0.50 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table my_table\G
*************************** 1. row ***************************
       Table: my_table
Create Table: CREATE TABLE `my_table` (
  `name` varchar(10) CHARACTER SET latin1 DEFAULT NULL,
  #细节:原本该字段没有提示字符集,但是在表字符集被改后该字段多出了字符集显示
  #原理:原来表和字段都是采用数据库默认字符集,现在改了表,但是字段不会自动改变
  `age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql>

注意:表选项通常在一开始确定后就不再修改,尤其是当表内已经产生数据后更不要轻易修改(尤其是字符集修改)。

  1. 修改表字段或者属性,这块操作比较复杂,涉及到字段新增、字段修改(名字+属性),字段删除等操作,都是使用alter table 表名操作
  • 增加表字段,本质是增加表的字段名以及字段类型(属性):alter table 表名 add [column] 字段名 字段类型 [属性];
mysql> desc my_table;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> alter table my_table add column number varchar(10);
Query OK, 0 rows affected (0.58 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc my_table;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| name   | varchar(10) | YES  |     | NULL    |       |
| age    | int(11)     | YES  |     | NULL    |       |
| number | varchar(10) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

  • 修改表字段名,也是强制要求必须修改对应的字段类型:alter table 表名 change [column] 旧字段名 新字段名 字段类型 [属性];
mysql> desc my_table;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| name   | varchar(10) | YES  |     | NULL    |       |
| age    | int(11)     | YES  |     | NULL    |       |
| number | varchar(10) | YES  |     | NULL    |       |         #修改前
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> alter table my_table change number school_number varchar(10);
Query OK, 0 rows affected (0.47 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc my_table;
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| name          | varchar(10) | YES  |     | NULL    |       |
| age           | int(11)     | YES  |     | NULL    |       |
| school_number | varchar(10) | YES  |     | NULL    |       |    #修改后
+---------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
  • 修改表字段类型(属性):alter table 表名 modify [column] 字段名 新字段类型 [属性];
mysql> desc my_table;
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| name          | varchar(10) | YES  |     | NULL    |       |
| age           | int(11)     | YES  |     | NULL    |       |
| school_number | varchar(10) | YES  |     | NULL    |       |    #修改前Type为varchar类型
+---------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> alter table my_table modify school_number int;
Query OK, 0 rows affected (0.79 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc my_table;
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| name          | varchar(10) | YES  |     | NULL    |       |
| age           | int(11)     | YES  |     | NULL    |       |
| school_number | int(11)     | YES  |     | NULL    |       |    #修改后Type为int类型
+---------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

注意:change也可以用于修改字段类型和属性(不建议),只需要使用:alter table 表名 change 旧名字 旧名字 字段类型 [属性];

  • 删除表字段:alter table 表名 drop [column] 字段名;
mysql> desc my_table;
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| name          | varchar(10) | YES  |     | NULL    |       |
| age           | int(11)     | YES  |     | NULL    |       |
| school_number | int(11)     | YES  |     | NULL    |       |
+---------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> alter table my_table drop school_number;
Query OK, 0 rows affected (0.63 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc my_table;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
  1. 修改字段位置:字段默认的操作(新增)都是在所有字段最后,我们可以通过位置指令来实现字段放到任意位置(change和modify指令也可以修改位置)
  • first:字段放到第一个位置
mysql> desc my_table;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(10) | YES  |     | NULL    |       |
| age   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> alter table my_table add number varchar(10) first; #放到第一个位置
Query OK, 0 rows affected (0.87 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc my_table;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| number | varchar(10) | YES  |     | NULL    |       |    #原本应该在age后的,现在在第一个位置
| name   | varchar(10) | YES  |     | NULL    |       |
| age    | int(11)     | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
  • after 字段名:放到指定字段名的后面
mysql> desc my_table;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| number | varchar(10) | YES  |     | NULL    |       |
| name   | varchar(10) | YES  |     | NULL    |       |
| age    | int(11)     | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> alter table my_table modify name varchar(10) after age;    #只修改位置,使用modfiy
Query OK, 0 rows affected (1.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc my_table;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| number | varchar(10) | YES  |     | NULL    |       |
| age    | int(11)     | YES  |     | NULL    |       |
| name   | varchar(10) | YES  |     | NULL    |       |            #name字段由原来的age前变到age后
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.07 sec)

注意:drop字段操作会将该字段对应的数据也一并删除,所以请确保安全(操作前备份)

  1. 练习:在已创建的学生表中,增加爱好hobby、高中high_school字段和ID字段(放到第一个),然后修改hign_school为senior_school,并将位置放到hobby前(hobby前一个字段之后),最后删除hobby字段

总结

  1. MySQL为表结构提供了一套容错机制,允许在表创建后对字段进行增删改操作,这些操作主要是考虑到业务变化,之前设定的字段名、字段类型或者属性需要有对应的修改
  2. 我们可以通过rename实现表名修改
  3. 可以通过alter table 表名 add/change/modify/drop实现表中字段的增删改,从而可以全面的维护表结构
  4. 不过,虽然MySQL有这样一套容错机制,但是开发人员还是应该尽量在表创建期间考虑到更多的因素以防止后期对表结构的修改。

思考:如果一张表创建错了,不想要了该怎么办呢?

引入:虽然创建表错误是一件低概率事件,而且是应该尽量避免的事情,但是MySQL也还是提供了一种容错机制,允许用户删除表。

4.数据表删除【掌握】

定义:删除表结构,即将创建表以及表中的数据进行一次性删除。

  1. 删除表结构语法:drop table 表名;
mysql> show tables;
+-----------------------+
| Tables_in_my_database |
+-----------------------+
| my_charset1           |
| my_charset2           |
| my_engine1            |    #执行删除前
| my_engine2            |
| my_engine_charset1    |
| my_engine_charset2    |
| my_student            |
| my_table              |
+-----------------------+
8 rows in set (0.00 sec)

mysql> drop table my_engine1;    #执行删除操作
Query OK, 0 rows affected (0.26 sec)

mysql> show tables;
+-----------------------+
| Tables_in_my_database |    #删除后效果
+-----------------------+
| my_charset1           |
| my_charset2           |
| my_engine2            |
| my_engine_charset1    |
| my_engine_charset2    |
| my_student            |
| my_table              |
+-----------------------+
7 rows in set (0.00 sec)

注意:删除表操作会删除表中所有的数据,因此一定要做好删除前的准备工作(删除确认以及对应数据备份)

  1. 删除表的时候MySQL允许同时删除多张表:drop table 表名1,表名2...;
mysql> show tables;
+-----------------------+
| Tables_in_my_database |
+-----------------------+
| my_charset1           |
| my_charset2           |
| my_engine2            |    #删除前
| my_engine_charset1    |
| my_engine_charset2    |
| my_student            |    #删除前
| my_table              |
+-----------------------+
7 rows in set (0.00 sec)

mysql> drop table my_engine2,my_student;    #一次性删除两张表
Query OK, 0 rows affected (0.27 sec)

mysql> show tables;
+-----------------------+
| Tables_in_my_database |
+-----------------------+
| my_charset1           |
| my_charset2           |
| my_engine_charset1    |
| my_engine_charset2    |
| my_table              |
+-----------------------+
5 rows in set (0.00 sec)
  1. 在项目前期或者备份还原数据的时候,有的时候会特意去删除已经存在的同名数据表,这个时候也会用到删除操作,不过在操作的时候会加上一个判断,保证删除表结构的指令不会被报错:drop table if exists 表名;
mysql> show tables;
+-----------------------+
| Tables_in_my_database |
+-----------------------+
| my_charset1           |
| my_charset2           |
| my_engine_charset1    |
| my_engine_charset2    |
| my_table              |
+-----------------------+
5 rows in set (0.00 sec)

mysql> drop table if exists my_student; #有则删除,没有就跳过
Query OK, 0 rows affected, 1 warning (0.00 sec)
#当前没有执行,因为数据库中没有my_student表

mysql> create table my_student(
    -> name varchar(10),
    -> age int
    -> )charset utf8;
Query OK, 0 rows affected (0.68 sec)

mysql> show tables;
+-----------------------+
| Tables_in_my_database |
+-----------------------+
| my_charset1           |
| my_charset2           |
| my_engine_charset1    |
| my_engine_charset2    |
| my_student            |
| my_table              |
+-----------------------+
6 rows in set (0.00 sec)

注意:drop table if exists 表名如果发现没有删除的表虽然不会做什么,但是会给出一个警告,如果想知道警告内容是什么,可以直接在出现警告后使用: show warnings;命令查看警告信息

mysql> drop table if exists my_student;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+----------------------------------------+
| Level | Code | Message                                |
+-------+------+----------------------------------------+
| Note  | 1051 | Unknown table 'my_database.my_student' |        #明确告知没有my_student表
+-------+------+----------------------------------------+
1 row in set (0.00 sec)

总结:删除表操作能够帮助我们清楚错误的或者已经不用的表,但是这种操作本身具有不安全性,因此需要特别注意被删除的表的安全性质,事先做好保护工作。


四、数据操作【掌握】

思考:数据表已经创建好了,怎样才能把数据放到数据表中去呢?

引入:数据表是数据操作的基本单位,但是实际上数据本身的存储都是以字段为最小存储单位的。往表中存放数据,就是将数据存放到表中每个字段对应的列中。在MySQL中,数据是以插入的方式来实现数据新增的。

1.新增数据【掌握】

定义:新增数据,就是往数据表中对应的空行中填充对应字段所需要的数据。

  1. 新增一条完整数据:对表中对应的一条空白记录处所有字段数据:insert into 表名 values(字段1对应的值1,字段2对应的值2...,字段N对应的值N)
  • 值元素的数量和字段数量要一致
  • 字段的顺序与值的顺序要对应上
  • 字符串数据需要使用引号包裹,可以是单引号和双引号
mysql> desc my_table;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| number | varchar(10) | YES  |     | NULL    |       |
| age    | int(11)     | YES  |     | NULL    |       |
| name   | varchar(10) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.04 sec)

mysql> insert into my_table values('0000000001',20,'Jim');
Query OK, 1 row affected (0.17 sec)
  1. 新增指定字段数据:给表中对应的一条空白记录处指定字段数据:insert into 表名 (字段1,字段2...字段N) values(值1,值2...值N);
  • 值元素的数量要与指定的字段数量一致
  • 值元素的顺序要与指定字段的顺序一致(字段顺序可以不和表字段顺序一致)
  • 没有被选中的其他表字段不能因为没有数据出错
mysql> insert into my_table (name,number) values('Tom','0000000002');
Query OK, 1 row affected (0.11 sec)
  1. 新增多条记录:可以是完整的或者指定字段的多条记录:insert into 表名 [(字段列表)] values(值列表1),(值列表2),...(值列表N);
mysql> insert into my_table values('0000000003',20,'Lily'),
    -> ('0000000004',18,'LiLei'),
    -> ('0000000005',28,'Lycy'); #最后一次分号,表示结束,前面使用逗号“,”分隔
Query OK, 3 rows affected (0.10 sec)
Records: 3  Duplicates: 0  Warnings: 0
  1. 练习:使用多种方式进行数据插入操作,让数据表中数据最少达到10条记录

总结:数据插入是数据操作的第一步,使用insert into 表名 [(字段列表)] values(值列表);方式,可以使用字段列表来进行数据插入,但是通常实际开发会使用全字段数据插入方式。可以每次进行一条数据插入,也可以一次性实现多条数据插入。在数据插入的过程中要保证值列表的顺序与字段的顺序一致,避免出现数据放错位置。


思考:如何确保数据的插入操作是成功的呢?

引入:数据的插入操作本身可以通过执行的反馈判定(受影响的行数),不过数据插入的目的是为了数据的查看,因此可以使用数据查询方式来检验数据。

2.查询数据【掌握】

定义:查询数据,就是通过查询SQL指令,从指定的数据表中,将数据获取出来,以一种二维表的形式展示给用户看

  1. 查看所有数据:select * from 表名; #*号属于通配符,表示匹配所有字段信息
mysql> select * from my_table;

+------------+------+-------+

| number     | age  | name  |

+------------+------+-------+

| 0000000001 |   20 | Jim   |

| 0000000002 | NULL | Tom   |

| 0000000003 |   20 | Lily  |

| 0000000004 |   18 | LiLei |

| 0000000005 |   28 | Lycy  |

+------------+------+-------+

5 rows in set (0.11 sec)

  1. 查看指定字段数据:select 字段名1,字段名2... from 表名;
mysql> select name,number from my_table;
+-------+------------+
| name  | number     |
+-------+------------+
| Jim   | 0000000001 |
| Tom   | 0000000002 |
| Lily  | 0000000003 |
| LiLei | 0000000004 |
| Lycy  | 0000000005 |
+-------+------------+
5 rows in set (0.36 sec)

注意:要查看的字段可以根据自己的需求选择数量以及顺序

  1. 匹配数据查看:在查询数据的时候根据适当的条件筛选数据:select 字段列表/* from 表名 where 条件表达式;
mysql> select * from my_table where age > 20; #查看年龄大于20的数据
+------------+------+------+
| number     | age  | name |
+------------+------+------+
| 0000000005 |   28 | Lycy |
+------------+------+------+
1 row in set (0.08 sec)

总结:查询操作是增删改查操作中最为频繁的一种,利用select 字段列表/* from 表名;可以实现对表中数据的基本查询需求。


思考:数据查看后或者实际业务中需要对数据进行修改的话,该如何操作呢?

引入:数据的更新操作也是可以通过SQL指令来实现的

3.更新数据【掌握】

定义:更新数据,就是根据某些条件(可以没有条件)对指定字段数据进行更新操作。

  1. 更新全部数据的某个字段信息:update 表名 set 字段名 = 新值;
mysql> select * from my_table;
+------------+------+-------+
| number     | age  | name  |
+------------+------+-------+
| 0000000001 |   20 | Jim   |
| 0000000002 | NULL | Tom   |
| 0000000003 |   20 | Lily  |
| 0000000004 |   18 | LiLei |
| 0000000005 |   28 | Lycy  |
+------------+------+-------+
5 rows in set (0.00 sec)

mysql> update my_table set age = 30;    #全部更新
Query OK, 5 rows affected (0.11 sec)
Rows matched: 5  Changed: 5  Warnings: 0

mysql> select * from my_table;
+------------+------+-------+
| number     | age  | name  |
+------------+------+-------+
| 0000000001 |   30 | Jim   |
| 0000000002 |   30 | Tom   |
| 0000000003 |   30 | Lily  |
| 0000000004 |   30 | LiLei |
| 0000000005 |   30 | Lycy  |
+------------+------+-------+
5 rows in set (0.00 sec)

注意:在实际操作中应该尽量避免此类更新,这样的更新会让某些数据变得完全一样,从而失去实际价值。应该根据具体的需求去更新对应的记录。

  1. 根据更新条件实现部分记录更新:update 表名 set 字段 = 新值 where 条件表达式;
mysql> select * from my_table;
+------------+------+-------+
| number     | age  | name  |
+------------+------+-------+
| 0000000001 |   30 | Jim   |
| 0000000002 |   30 | Tom   |
| 0000000003 |   30 | Lily  |
| 0000000004 |   30 | LiLei |
| 0000000005 |   30 | Lycy  |
+------------+------+-------+
5 rows in set (0.00 sec)

mysql> update my_table set age = 50 where name = 'Lily'; #Mysql中“=”号也有比较的意思,没有“==”
Query OK, 1 row affected (0.43 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from my_table;
+------------+------+-------+
| number     | age  | name  |
+------------+------+-------+
| 0000000001 |   30 | Jim   |
| 0000000002 |   30 | Tom   |
| 0000000003 |   50 | Lily  |
| 0000000004 |   30 | LiLei |
| 0000000005 |   30 | Lycy  |
+------------+------+-------+
5 rows in set (0.00 sec)
  1. 可以同时修改多个字段数据:update 表名 set 字段1 = 新值1, 字段2 = 新值2 ... [where 条件表达式];
mysql> select * from my_table;
+------------+------+-------+
| number     | age  | name  |
+------------+------+-------+
| 0000000001 |   30 | Jim   |
| 0000000002 |   30 | Tom   |
| 0000000003 |   50 | Lily  |
| 0000000004 |   30 | LiLei |
| 0000000005 |   30 | Lycy  |
+------------+------+-------+
5 rows in set (0.00 sec)

mysql> update my_table set age = 18,name = 'Jack' where number = '0000000001';
Query OK, 1 row affected (0.37 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from my_table;
+------------+------+-------+
| number     | age  | name  |
+------------+------+-------+
| 0000000001 |   18 | Jack  |
| 0000000002 |   30 | Tom   |
| 0000000003 |   50 | Lily  |
| 0000000004 |   30 | LiLei |
| 0000000005 |   30 | Lycy  |
+------------+------+-------+
5 rows in set (0.00 sec)

总结

  1. 更新数据可以使用update 表名 set 字段=新值 where条件;来实现
  2. 更新过程中可以更新多个字段,也可以更新多条记录
  3. 建议在更新的时候一定要通过条件来限定更新数据的量,除非特殊情况下需要更新全部数据。

思考:数据如果出错了,或者不要了,那么该怎么处理呢?

引入:首先,所有的数据应该都是由业务需求产生的,用户操作记录的。那么如果数据出现错误,也应该是用户来操作解决。数据的删除可以通过SQL删除指令来完成。

4.删除数据【掌握】

引入:删除数据,就是将对应数据所占据的行(多个列)清空还原到空白状态

  1. 删除全部数据:delete from 表名;
mysql> delete from my_charset1;
Query OK, 0 rows affected (0.43 sec)

注意:数据删除通常操作都是逐个删除,真实业务不会出现全部删除

  1. 删除部分条件匹配数据:delete from 表名 where 条件表达式;
mysql> select * from my_table;
+------------+------+-------+
| number     | age  | name  |
+------------+------+-------+
| 0000000001 |   18 | Jack  |
| 0000000002 |   30 | Tom   |
| 0000000003 |   50 | Lily  |
| 0000000004 |   30 | LiLei |
| 0000000005 |   30 | Lycy  |
+------------+------+-------+
5 rows in set (0.00 sec)

mysql> delete from my_table where number = '0000000005';
Query OK, 1 row affected (0.08 sec)

mysql> select * from my_table;
+------------+------+-------+
| number     | age  | name  |
+------------+------+-------+
| 0000000001 |   18 | Jack  |
| 0000000002 |   30 | Tom   |
| 0000000003 |   50 | Lily  |
| 0000000004 |   30 | LiLei |
+------------+------+-------+
4 rows in set (0.00 sec)

总结

  1. 数据删除操作的指令:delete from 表名 where ==条件表达式==;
  2. 该项操作却是最需要注意的。因为数据一旦删除就无法找回,因此在进行数据删除的时候需要特别小心确认再操作。如果涉及到整表数据删除,一定要确保数据删除的确认通知,并且要实现做好安全备份。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容