CHAPTER 第3章 MySQL数据库和表 可以将数据库看作一个存储数据对象的容器,这些对象包括表、视图、触发器、存储过程 等。其中,表是最基本的数据对象,是存放数据的实体。实际应用中,必须首先创建数据库, 然后才能建立表及其他数据对象。 3.1 MySQL数据库 3.1.1 创建数据库 使用CREATEDATABASE 或CREATESCHEMA命令可以创建数据库,其语法格式为: CREATE {DATABASE|SCHEMA} [IF NOT EXISTS]数据库名 [选项 ...] 选项: [DEFAULT]CHARACTER SET 字符集 |[DEFAULT]COLLATE 校对规则名 说明: ● IFNOTEXISTS———在创建数据库前进行判断,只有该数据库目前尚不存在时才执 行CREATEDATABASE操作。用此选项可以避免出现数据库已经存在而再新建 的错误。 ● DEFAULT———指定默认值。 ● 字符集———指定数据库采用的字符集。 ● COLLATE———指定字符集的校对规则。字符集和校对规则的概念参考附录D。 【例3.1】 创建学生成绩数据库xscj。 mysql>create database xscj 如果已经创建了数据库,如mytest,重复创建时系统会提示数据库已经存在,不能再创建。 系统显示错误信息,如图3.1所示。使用IFNOTEXISTS选项从句可不显示错误信息。 图3.1 错误信息提示 26 MySQL教程(第2版) 创建了数据库之后使用USE命令可指定当前数据库,其语法格式为: USE 数据库名; 例如,指定当前数据库为学生成绩数据库(xscj): mysql>use xscj 说明:这个语句也可以用来从一个数据库“跳转”到另一个数据库,在用CREATE DATABASE 语句创建了数据库之后,该数据库不会自动成为当前数据库,需要用这条USE语 句来指定。 注意:在MySQL中,每一条SQL语句都以分号“;”作为结束标志。 3.1.2 修改数据库 数据库创建后,如果需要修改数据库的参数,可以使用ALTERDATABASE 命令,其语法 格式为: ALTER {DATABASE |SCHEMA} [数据库名] 选项 ... 选项: [DEFAULT]CHARACTER SET 字符集名 | [DEFAULT]COLLATE 校对规则名 说明:ALTERDATABASE 用于更改数据库的全局特性,这些特性存储在数据库目录中 的db.opt文件中。用户必须有对数据库进行修改的权限,才可以使用ALTERDATABASE。 修改数据库的选项与创建数据库相同,功能不再重复说明。如果语句中数据库名称忽略,则修 改当前(默认)数据库。 【例3.2】 修改学生成绩数据库(xscj)默认字符集和校对规则。 输入命令如图3.2所示。 图3.2 执行命令 3.1.3 删除数据库 已经创建的数据库需要删除,可使用DROPDATABASE 命令,其语法格式为: DROP DATABASE [IF EXISTS]数据库名 还可以使用IFEXISTS子句,避免删除不存在的数据库时出现MySQL错误信息。 注意:这个命令必须小心使用,因为它将删除指定的整个数据库,该数据库的所有表(包 第3章 MySQL数据库和表 27 括其中的数据)也将永久删除。 3.2 MySQL表 在数据库创建后,就应该创建表,因为表是数据库存放数据的对象实体。没有表,数据库 中其他数据对象就都没有意义。要查看数据库中有哪些表,可以使用SHOW TABLES命令。 3.2.1 创建表 1.全新创建 从头创建一个全新的表,可使用CREATETABLE命令,其语法格式为: CREATE [TEMPORARY]TABLE [IF NOT EXISTS]表名 [([列定义] ...|[表索引定义])] [表选项][select 语句]; 说明: ● TEMPORARY———表示用CREATE命令新建的表为临时表。不加该关键字创建 的表称为持久表。在数据库中持久表一旦创建将一直存在,多个用户或多个应用程 序可以同时使用持久表。有时需要临时存放数据,如临时存储复杂的SELECT语句 的结果。此后可能要重复地使用这个结果,但该结果又不需永久保存,这时可使用 临时表。用户可像操作持久表一样操作临时表。只不过临时表的生命周期较短,而 且只对创建它的用户可见,当断开与该数据库的连接时,MySQL会自动删除它。 ● IFNOTEXISTS———在创建表前加上一个判断,只有该表目前尚不存在时才执行 CREATETABLE操作。用此选项可避免出现表已经存在无法再新建的错误。 ● 列定义———包括列名、数据类型,可能还有一个空值声明和一个完整性约束。 ● 表索引项定义———主要定义表的索引、主键、外键等,具体定义参见第5章。 ● select语句———用于在一个已有表的基础上创建表。 (1)“列定义”格式为: 列名 type [NOT NULL|NULL][DEFAULT 默认值] [AUTO_INCREMENT][UNIQUE [KEY]|[PRIMARY]KEY] [COMMENT 'string'][参照定义] 其中: ● 列名———必须符合标识符规则,长度不能超过64个字符,而且在表中要唯一。如果 为MySQL保留字,必须用单引号括起来。 ● type———列的数据类型,有的数据类型需要指明长度n,并用括号括起来,MySQL支 持的数据类型见附录C。 ● AUTO_INCREMENT———设置自增属性,只有整型列才能设置此属性。当插入 NULL值或0到一个AUTO_INCREMENT 列中时,列被设置为value+1,这里 value是此前表中该列的最大值。AUTO_INCREMENT 顺序从1开始。每个表只 28 MySQL教程(第2版) 能有一个AUTO_INCREMENT列,并且它必须被索引。 ● NOTNULL|NULL———指定该列是否允许为空。如果不指定,则默认为NULL。 ● DEFAULT 默认值———为列指定默认值,默认值必须为一个常数。其中,BLOB和 TEXT列不能被赋予默认值。如果没有为列指定默认值,MySQL自动地分配一个。 如果列可以取NULL值,默认值就是NULL。如果列被声明为NOT NULL,默认 值取决于列类型: ◆ 对于没有声明AUTO_INCREMENT 属性的数字类型,默认值是0。对于一个 AUTO_INCREMENT列,默认值是在顺序中的下一个值。 ◆ 对于除TIMESTAMP以外的日期和时间类型,默认值是该类型适当的“零”值。 对于表中第一个TIMESTAMP列,默认值是当前的日期和时间。 ◆ 对于除ENUM 的字符串类型,默认值是空字符串。对于ENUM,默认值是第一 个枚举值。 ● UNIQUEKEY|PRIMARYKEY:PRIMARYKEY和UNIQUEKEY都表示字段 中的值是唯一的。PRIMARYKEY表示设置为主键,一个表只能定义一个主键,主 键一定要为NOTNULL。 ● COMMENTs'tring':对于列的描述,string是描述的内容。 ● 参照定义:指定参照的表和列,具体定义将在5.3节中介绍。 type定义如下: TINYINT[(length)][UNSIGNED][ZEROFILL] |SMALLINT[(length)][UNSIGNED][ZEROFILL] |MEDIUMINT[(length)][UNSIGNED][ZEROFILL] |INT[(length)][UNSIGNED][ZEROFILL] |INTEGER[(length)][UNSIGNED][ZEROFILL] |BIGINT[(length)][UNSIGNED][ZEROFILL] |REAL[(length,decimals)][UNSIGNED][ZEROFILL] |DOUBLE[(length,decimals)][UNSIGNED][ZEROFILL] |FLOAT[(length,decimals)][UNSIGNED][ZEROFILL] |DECIMAL(length,decimals) [UNSIGNED][ZEROFILL] |NUMERIC(length,decimals) [UNSIGNED][ZEROFILL] |BIT[M] |DATE |TIME |TIMESTAMP |DATETIME |CHAR(length) [BINARY|ASCII|UNICODE] |VARCHAR(length) [BINARY] |TINYBLOB |BLOB |MEDIUMBLOB |LONGBLOB 第3章 MySQL数据库和表 29 |TINYTEXT [BINARY] |TEXT [BINARY] |MEDIUMTEXT [BINARY] |LONGTEXT [BINARY] |ENUM(value1,value2,value3,...) |SET(value1,value2,value3,...) |spatial_type 说明:在字符数据类型和数值数据类型之后,MySQL允许指定一个数据类型选项来改 变数据类型的属性和功能。 对于字符数据类型,MySQL 支持两种数据类型选项:CHARACTER SET 和 COLLATE。如果要区分字符的大小写,可以在字符类型后面加上BINGARY。 对于除BIT 以外的数值数据类型,MySQL 允许添加一个或多个数据类型选项。 UNSIGNED:不允许负值。ZEROFILL:当插入的值长度小于字段设定的长度时,剩余部 分用0填补。 spatial_type是空间类型数据,本书不讨论。 (2)“表选项”定义如下: {ENGINE|TYPE}=engine_name /*存储引擎*/ |AUTO_INCREMENT=value /*初始值*/ |AVG_ROW_LENGTH=value /*表的平均行长度*/ |[DEFAULT]CHARACTER SET 字符集名[COLLATE 校对规则名] /*默认字符集和校对*/ |CHECKSUM={0|1} /*设置1 表示求校验和*/ |COMMENT='string' /*注释*/ |CONNECTION='connect_string' /*连接字符串*/ |MAX_ROWS=value /*行的最大数*/ |MIN_ROWS=value /*列的最小数*/ |PACK_KEYS={0|1|DEFAULT} |PASSWORD='string' /*对.frm 文件加密*/ |DELAY_KEY_WRITE={0|1} /*对关键字的更新*/ |ROW_FORMAT={DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} /*定义各行应如何储存*/ |UNION=(表名[,表名]...) /*表示哪个表应该合并*/ |INSERT_METHOD={NO|FIRST|LAST} /*是否执行INSERT 语句*/ |DATA DIRECTORY='absolute path to directory' /*数据文件的路径*/ |INDEX DIRECTORY='absolute path to directory' /*索引的路径*/ 说明:表中大多数的选项涉及的是表数据如何存储及存储在何处。多数情况下,不必 指定表选项。ENGINE选项是定义表的存储引擎。 【例3.3】 在学生成绩数据库(xscj)中也创建一个学生情况表,表名为xs。 输入以下命令: 30 MySQL教程(第2版) USE xscj CREATE TABLE xs ( 学号 char(6) not null primary key, 姓名char(8) not null, 专业名char(10) null, 性别tinyint(1) not null default 1, 出生日期date not null, 总学分tinyint(1) null, 照片blob null, 备注text null ) engine=innodb; 在上面的例子里,每个字段都包含附加约束或修饰符,这些可用来增加对所输入数据的 约束。primarykey表示将“学号”字段定义为主键。default1表示“性别”的默认值为1。 engine=innodb表示采用的存储引擎是InnoDB,InnoDB是MySQL在Windows平台默认 的存储引擎,所以engine=innodb也可以省略。 然后,用showtables命令显示xscj数据库中产生了学生(xs)表,用describexs命令可 以显示xs表的结构,如图3.3所示。 图3.3 学生(xs)表结构 2.复制现成的表 除了全新创建外,用户也可直接复制数据库中已有表的结构和数据,用这种方式构建一 个表,十分方便、快捷,其语法格式为: CREATE [TEMPORARY]TABLE [IF NOT EXISTS]表名 [( ) LIKE 已有表名[]] |[AS ( 表达式)]; 第3章 MySQL数据库和表 31 说明: ● 使用LIKE关键字创建一个与已有表名相同结构的新表,列名、数据类型、空指定和 索引也将复制,但是表的内容不会复制,因此创建的新表是一个空表。 ● 使用AS关键字可以复制表的内容,但索引和完整性约束是不会复制的。表达式是 复制内容部分,例如可以是一条SELECT语句。 【例3.4】 在mytest数据库中,用复制的方式创建一个名为user_copy1的表,表结构 直接取自user表;再创建一个名为user_copy2的表,其结构和内容(数据)都取自user表。 (1)创建user_copy1表: USE mytest CREATE TABLE user_copy1 LIKE user; (2)创建user_copy2表: CREATE TABLE user_copy2 AS (select*from user); 执行过程及结果,如图3.4所示。 图3.4 用复制的方式创建表 查询user_copy1表中没有记录,而user_copy2表中包含user表中所有记录,如图3.5 所示。 3.2.2 修改表 1.修改表结构 ALTERTABLE用于更改原有表的结构。例如,可以增加(删减)列、创建(取消)索引、 更改原有列的类型、重新命名列或表,还可以更改表的评注和表的类型。其语法格式为: ALTER [IGNORE]TABLE 表名 选项... 选项: 32 MySQL教程(第2版) 图3.5 查询表记录 ADD [COLUMN]列定义[FIRST|AFTER 列名] /*添加列*/ |ALTER [COLUMN]列名{SET DEFAULT literal|DROP DEFAULT} /*修改默认值*/ |CHANGE [COLUMN]列名 原列名[FIRST|AFTER 列名] /*列名重定义*/ |MODIFY [COLUMN]列定义[FIRST|AFTER 列名] /*修改列数据类型*/ |DROP [COLUMN]列名/*删除列*/ |RENAME [TO]新表名/*重命名该表*/ |ORDER BY 列名/*排序*/ |CONVERT TO CHARACTER SET 字符集名[COLLATE 校对规则名] /*将字符集转换为二进制*/ |[DEFAULT]CHARACTER SET 字符集名[COLLATE 校对规则名] /*修改默认字符集*/ |表选项 |列或表中索引项的增、删、改(详细见第5 章) 说明: ● IGNORE———是MySQL相对于标准SQL的扩展。若在修改后的新表中存在重复 关键字,如果没有指定IGNORE,当重复关键字错误发生时操作失败。如果指定了 IGNORE,则对于有重复关键字的行只使用第一行,其他有冲突的行被删除。 ● ADD[COLUMN]子句———向表中增加新列。例如,在表user中增加新的一列a: user mytest alter table user add column a tinyint null; ● FIRST|AFTER 列名———表示在某列的前或后添加,不指定则添加到最后。 ● ALTER [COLUMN]子句———修改表中指定列的默认值。 ● CHANGE [COLUMN]子句———修改列的名称。重命名时,需给定旧的列名和新的 列名称和数据类型。例如,要把一个INTEGER列的名称从a变更到b: alter table user change a b integer; ● MODIFY [COLUMN]子句———修改指定列的数据类型。例如,要把一个列的数据 类型改为BIGINT: alter table user modify b bigint not null; 第3章 MySQL数据库和表 33 注意:若表中该列所存数据的数据类型与将要修改的列的类型冲突,则发生错误。例 如,原来CHAR类型的列要修改成INT类型,而原来列值中有字符型数据,则无法修改。 ● DROP子句———从表中删除列或约束。 ● RENAME子句———修改该表的表名。例如,将表user_copy1改名为use1: alter table user_copy1 rename to usera; ● ORDERBY子句———用于在创建新表时,让各行按一定的顺序排列。注意,在插入 和删除后,表不会仍保持此顺序。在对表做了大的改动后,通过使用此选项可提高 查询效率。在有些情况下,如果表按列排序,对于MySQL来说,排序可能会更简单。 ● 表选项———修改表选项,具体定义与CREATETABLE语句中一样。 可以在一个ALTERTABLE语句里写入多个ADD、ALTER、DROP和CHANGE子 句,中间用逗号分开。这是MySQL相对于标准SQL的扩展,在标准SQL中,每个ALTER TABLE语句中的每个子句只允许使用一次。 【例3.5】 在xscj数据库的xs表中,增加“奖学金等级”一列,并将表中的“姓名”列 删除。 user xscj alter table xs add 奖学金等级tinyint null, drop column 姓名; 执行后,xs表的结构如图3.6所示。 图3.6 修改后的xs表结构 为了在后面演示表记录操作的方便,此处完成后要及时地将xs表改回原样,语句如下: alter table xs add 姓名char(8) not null after 学号, drop column 奖学金等级; 这样,xs表结构就又恢复原状了。 34 MySQL教程(第2版) 2.更改表名 除了上面的ALTERTABLE命令外,还可以直接用RENAMETABLE语句来更改表 的名字,其语法格式为: RENAME TABLE 老表名TO 新表名... 【例3.6】 将mytest数据库usera表重命名为user1,user_copy2表重命名为user2。 rename table usera to user1,user_copy2 to user2; 3.2.3 删除表 需要删除一个表时可以使用DROPTABLE语句,其语法格式为: DROP [TEMPORARY]TABLE [IF EXISTS]表名... 说明:这个命令将表的描述、表的完整性约束、索引及和表相关的权限等一并删除。 【例3.7】 删除表uesra。 drop table if exists usera; 3.2.4 表结构特点 在使用工具或SQL语句创建表之前,先要确定表的名字、所包含的列名、列的数据类型 及长度、是否可为空值、默认值情况、是否要使用及何时使用约束、默认设置或规则及所需索 引、哪些列是主键、哪些列是外键等,这些构成表的结构。 1.空值概念 空值通常表示未知、不可用或将在以后添加的数据。若一个列允许为空值,则向表中输 入记录值时可不为该列给出具体值;而一个列若不允许为空值,则在输入时必须给出该列的 具体值。 注意:表的关键字不允许为空值。空值不能与数值数据0或字符类型的空字符混为一 谈。任意两个空值都不相等。 2.列的标志属性 对任何表都可创建包含系统所生成序号值的一个标志列,该序号值唯一标志表中的一 列,可以作为键值。每个表只能有一个列设置为标志属性,该列只能是decimal、int、 numeric、smallint、bigint或tinyint数据类型。定义标志属性时,可指定其种子(即起始) 值、增量值,二者的默认值均为1。系统自动更新标志列值,标志列值不允许空值。 3.隐含地改变列类型 在下列情况下,MySQL隐含地改变在一个CREATETABLE语句中给出的一个列类 型(这也可能在ALTERTABLE语句上出现)。 (1)长度小于4的varchar被改变为char。 (2)如果在一个表中的任何列有可变长度,结果使整个行是变长的。因此,如果一张表 第3章 MySQL数据库和表 35 包含任何变长的列(varchar、text或Blob),所有大于三个字符的char列被改变为varchar 列。这在任何方面都不影响用户如何使用列。在MySQL中这种改变可以节省空间并且使 表操作更加快捷。 (3)timestamp的显示尺寸必须是偶数且在2~14内。如果指定0显示尺寸或比14 大,尺寸被强制为14。从1~13的奇数值尺寸被强制为下一个更大的偶数。 (4)不能在一个timestamp列中存储一个NULL,将它设为NULL默认为当前的日期 和时间。 如果想要知道MySQL是否使用了除指定的以外的一种列类型,在创建表之后,使用一 个DESCRIBE语句即可。DESCRIBE语句将在3.4节详细介绍。 3.3 MySQL表记录操作 创建数据库和表后,需要对表中的数据(记录)进行操作,包括插入、修改和删除操作,可 以通过SQL语句操作表记录,也可以用第2章介绍的各种MySQL界面工具来操作。与界 面操作相比,通过SQL语句操作更为灵活,功能更强大。 3.3.1 插入记录 一旦创建了数据库和表,下一步就是向表里插入数据记录。通过INSERT 或 REPLACE语句可以向表中插入一行或多行记录。 1.插入新记录 向表中插入全新的记录用INSERT语句,其语法格式为: INSERT [LOW_PRIORITY|DELAYED|HIGH_PRIORITY][IGNORE] [INTO]表名[(列名,...)] VALUES ({expr|DEFAULT},...),(...),... |SET 列名={expr|DEFAULT}, ... [ON DUPLICATE KEY UPDATE 列名=expr, ... ] 说明: ● 列名———需要插入数据的列名。如果要给全部列插入数据,列名可以省略。如果只 给表的部分列插入数据,需要指定这些列。对于没有指出的列,它们的值根据列默 认值或有关属性来确定,MySQL处理的原则是: ① 具有IDENTITY属性的列,系统生成序号值来唯一标志列。 ② 具有默认值的列,其值为默认值。 ③ 没有默认值的列,若允许为空值,则其值为空值;若不允许为空值,则出错。 ④ 类型为timestamp的列,系统自动赋值。 ● VALUES子句———包含各列需要插入的数据清单,数据的顺序要与列的顺序相对 应。若表名后不给出列名,则在VALUES子句中要给出每一列(除IDENTITY 和 timestamp类型的列)的值,如果列值为空,则值必须置为NULL,否则会出错。 VALUES子句中的值: 36 MySQL教程(第2版) ①expr———可以是一个常量、变量或一个表达式,也可以是空值NULL,其值的数据 类型要与列的数据类型一致。例如,列的数据类型为int,插入的数据是'aaa'就会出 错。当数据为字符型时要加单引号。 ② DEFAULT———指定为该列的默认值。前提是该列原先已经指定了默认值。 如果列清单和VALUES 清单都为空,则INSERT会创建一行,每个列都设置成默认值。 INSERT语句支持下列修饰符: ● LOW_PRIORITY———可以使用在INSERT、DELETE和UPDATE 等操作中,当原有 客户端正在读取数据时,延迟操作的执行,直到没有其他客户端从表中读取为止。 ● DELAYED———若使用此关键字,则服务器会把待插入的行放到一个缓冲器中,而发 送INSERTDELAYED语句的客户端会继续运行。如果表正在被使用,则服务器会 保留这些行。当表空闲时,服务器开始插入行,并定期检查是否有新的读取请求(仅 适用于MyISAM、MEMORY和ARCHIVE表)。 ● HIGH_PRIORITY———可以使用在SELECT和INSERT操作中,使操作优先执行。 ● IGNORE———使用此关键字,在执行语句时出现的错误就会被当作警告处理。 ● ON DUPLICATE KEY UPDATE———使用此选项插入行后,若导致UNIQUE KEY或PRIMARYKEY出现重复值,则根据UPDATE后的语句修改旧行(使用此 选项时DELAYED被忽略)。 ● SET子句———用于给列指定值,使用SET 子句时表名的后面省略列名。要插入数 据的列名在SET子句中指定,列名为指定列名,等号后面为指定数据,未指定的列, 列值为默认值。 从INSERT的语法格式可以看到,使用INSERT 语句可以向表中插入一行记录,也可 以插入多行记录,插入的行可以给出每列的值,也可只给出部分列的值,还可以向表中插入 其他表的数据。 【例3.8】 向学生成绩数据库(xscj)的表xs(表中列包括学号、姓名、专业名、性别、出生 日期、总学分、照片、备注)中插入如下一行: 081101,王林,计算机,1,1994-02-10,50,NULL,NULL 使用下列语句: use xscj insert into xs values('081101', '王林', '计算机', 1, '1994-02-10', 50, null, null); 若表xs中专业的默认值为“计算机”,照片、备注默认值为NULL,插入数据也可以使用 如下命令: insert into xs (学号, 姓名, 性别, 出生日期, 总学分) values('081101', '王林', 1, '1994-02-10', 50); 与下面这个命令的效果相同: 第3章 MySQL数据库和表 37 insert into xs values('081101', '王林', default, 1, '1994-02-10', 50, null, null); 当然,也可以使用SET子句来实现: insert into xs set 学号='081101', 姓名='王林', 专业= default, 性别= 1, 出生日期= '1994- 02- 10', 总学分=50; 执行结果如图3.7所示。 图3.7 修改后的xs表记录 注意:若原有行中存在PRIMARYKEY或UNIQUEKEY,而插入的数据行中含有与 原有行中PRIMARYKEY或UNIQUEKEY相同的列值,则INSERT语句无法插入此行。 要插入这行数据需要使用REPLACE语句,它的用法与INSERT语句基本相同。 2.从已有表中插入新记录 使用INSERTINTO…SELECT…,可以快速地从一个或多个已有的表记录向表中插 入多个行,其语法格式为: INSERT [LOW_PRIORITY|HIGH_PRIORITY][IGNORE] [INTO]表名[(列名,...)] SELECT 语句 [ON DUPLICATE KEY UPDATE 列名=expr, ...] 说明:SELECT语句中返回的是一个查询到的结果集,INSERT 语句将这个结果集插 入到指定表中,但结果集中每行数据的字段数、字段的数据类型要与被操作的表完全一致。 有关SELECT语句会在第7章具体介绍。 【例3.9】 将mytest数据库user表记录插入到user1表中。 user mytest insert into user1 select*from user; 命令执行前后的效果如图3.8所示。 3.替换旧记录 REPLACE语句可以在插入数据之前将与新记录冲突的旧记录删除,从而使新记录能 够替换旧记录,正常插入。REPLACE语句格式与INSERT相同。 【例3.10】 若上例中的记录行已经插入,其中学号为主键(PRIMARY KEY),现在想 再插入下列一行记录: 38 MySQL教程(第2版) 图3.8 插入前后user1表记录 081101,刘华,通信工程,1,1995-03-08,48,NULL,NULL 若直接使用INSERT语句,会产生如图3.9所示的错误。 图3.9 错误提示 使用REPLACE语句,则可以成功插入,如图3.10所示。 图3.10 成功插入 4.插入图片 MySQL还支持图片的插入,图片一般可以以路径的形式来存储,即插入图片可以采用插 入图片的存储路径的方式。当然也可以直接插入图片本身,只要用LOAD_FILE函数即可。 【例3.11】 向xs表中插入一行记录: 081102,程明,计算机,1,1995-02-01,50,picture.jpg,NULL 设照片路径为D:\IMAGE\picture.jpg。使用如下语句: insert into xs values('081102', '程明', '计算机', 1, '1995- 02- 01', 50, ' D:\IMAGE\ picture. jpg', null); 也可使用以下语句直接存储图片本身: insert into xs values('081102', '程明', '计算机', 1, '1995-02-01', 50, load_file('D:\ IMAGE\ picture.jpg'), null); 执行结果如图3.11所示。 第3章 MySQL数据库和表 39 图3.11 例3.11执行结果 3.3.2 修改记录 要修改表中的一行记录,使用UPDATE语句,UPDATE可用来修改一个表,也可以修 改多个表。 1.修改单个表 使用UPDATE修改单个表的语法格式为: UPDATE [LOW_PRIORITY][IGNORE]表名 SET 列名1=expr1 [, 列名2=expr2 ...] [WHERE 条件] [ORDER BY ...] [LIMIT row_count] 说明: ● 若语句中不设定WHERE子句,则更新所有行。列名1、列名2……为要修改列,列 值为expr,expr可以是常量、变量、列名或表达式。可以同时修改所在数据行的多个 列值,中间用逗号隔开。 ● WHERE子句———指定的删除记录条件。如果省略WHERE子句则删除该表的所 有行。 ● ORDERBY 子句———各行按照子句中指定的顺序进行删除,此子句只在与 LIMIT联用时才起作用。子句ORDERBY 和LIMIT的具体定义将在第7章中 介绍。 ● LIMIT子句———用于告知服务器,在控制命令被返回到客户端前,被删除的行的最 大值。 【例3.12】 将学生成绩数据库(xscj)的学生(xs)表中的所有学生的总学分都增加10。 将姓名为“刘华”的学生的备注填写为“辅修计算机专业”,学号改为081250。 update xs set 总学分=总学分+10; update xs set 学号='081250' , 备注='辅修计算机专业' where 姓名='刘华'; select 学号, 姓名, 总学分, 备注from xs; 40 MySQL教程(第2版) 图3.12 例3.12执行结果 执行结果如图3.12所示。 这样,可以发现表中所有学生的总学分已经都 增加了10,姓名为“刘华”的学生的备注填写为“辅 修计算机专业”,学号也改成了081250。 2.修改多个表 使用UPDATE修改多个表的语法格式为: UPDATE [LOW_PRIORITY][IGNORE]表名,表名... SET 列名1=expr1 [, 列名2=expr2 ...] [WHERE 条件] 【例3.13】 mytest数据库表user和表user2中都有两个字段:idint(11)、password varchar(10),其中id为主键。当表user中id值与user2中id值相同时,将表user中对应 的password值修改为11111111,将表user2中对应的password值改为22222222。 user mytest update user, user2 set user.password='11111111', user2.password='22222222' where user.id=user2.id; 修改后的结果如图3.13所示。 图3.13 同时修改两个表 3.3.3 删除记录 DELETE语句或TRUNCATETABLE语句可以用于删除表中的一行或多行记录。 1.删除满足条件的行 使用DELETE语句删除表中满足条件的记录行。 从单个表中删除的语法格式为: DELETE [LOW_PRIORITY][QUICK][IGNORE]FROM 表名 [WHERE 条件] [ORDER BY ...] [LIMIT row_count] 说明: ● QUICK修饰符———可以加快部分种类的删除操作的速度。 ● FROM 子句———用于说明从何处删除数据,表名为要删除数据的表名。 第3章 MySQL数据库和表 41 ● WHERE子句———指定的删除记录条件。如果省略WHERE子句则删除该表的所有行。 ● ORDERBY子句———各行按照子句中指定的顺序进行删除,此子句只在与LIMIT 联用时才起作用。ORDERBY子句和LIMIT子句的具体定义,将在第4章MySQL 数据库查询语句中介绍。 ● LIMIT子句———用于告知服务器,在控制命令被返回到客户端前,被删除的行的最 大值。 【例3.14】 删除mytest数据库中user2表“周何骏”记录。 use mytest delete from person where username='周何骏'; 或 delete from xs where id=2; 2.从多个表中删除行 删除操作若要在多个表中进行,其语法格式为: DELETE [LOW_PRIORITY][QUICK][IGNORE]表名[.*][, 表名[.*]...] FROM table_references [WHERE where_definition] 或 DELETE [LOW_PRIORITY][QUICK][IGNORE] FROM 表名[.*][, 表名[.*]...] USING table_references [WHERE where_definition] 说明:对于第一种语法格式,只删除列于FROM 子句之前的表中对应的行;对于第二 种语法格式,只删除列于FROM 子句之中(在USING 子句之前)的表中对应的行。作用 是,可以同时删除多个表中的行,并使用其他的表进行搜索。 【例3.15】 删除user1中id值等于user的id值的所有行以及user2中id值等于user 的id值的所有行。使用如下语句: DELETE user1, user2 FROM user1, user2, user WHERE user1.id=user.id AND user2.id=user.id; 执行结果如图3.14所示。 3.清除表数据 使用TRUNCATETABLE语句将删除指定表中的所有数据,因此也称其为清除表数 据语句,其语法格式为: 42 MySQL教程(第2版) 图3.14 例3.15执行结果 TRUNCATE TABLE 表名 说明:由于TRUNCATETABLE语句将删除表中的所有数据,且无法恢复,因此使用 时必须十分小心! TRUNCATETABLE在功能上与不带WHERE子句的DELETE语句(如DELETE FROM XS)相同,二者均删除表中的全部行。但TRUNCATETABLE 比DELETE 速度 快,且使用的系统和事务日志资源少。DELETE 语句每次删除一行,并在事务日志中为所 删除的每行记录一项。而TRUNCATETABLE通过释放存储表数据所用的数据页来删除 数据,并且只在事务日志中记录页的释放。使用TRUNCATE TABLE,AUTO _ INCREMENT计数器被重新设置为该列的初始值。 对于参与了索引和视图的表,不能使用TRUNCATE TABLE 删除数据,而应使用 DELETE语句。 3.4 MySQL数据库信息显示 在使用MySQL时,经常需要查看数据库本身的一些信息,如系统中已有哪些数据库、 某数据库中已建立了哪几张表、某个表的结构等,通常使用SHOW 和DESCRIBE这两个语 句来显示这些常用信息,在以后的学习中也会经常用到它们。 1.SHOW 语句 SHOWtables或SHOWtablesfromdatabase_name:显示当前数据库中所有表的 名称。 SHOWdatabases:显示MySQL中所有数据库的名称。 SHOWcolumnsfromtable_namefrom database_name 或SHOW columnsfrom database_name.table_name:显示表中列的名称。 SHOWgrantsforuser_name:显示一个用户的权限,显示结果类似于grant命令。 SHOWindexfromtable_name:显示表的索引。 SHOWstatus:显示一些系统特定资源的信息,如正在运行的线程数量。 SHOWvariables:显示系统变量的名称和值。 第3章 MySQL数据库和表 43 SHOWprocesslist:显示系统中正在运行的所有进程,即当前正在执行的查询。大多 数用户可查看自己的进程,如果拥有process权限,还可查看所有人的进程,包括密码。 SHOWtablestatus:显示当前使用或者指定的database中的每个表的信息。信息包 括表类型和表的最新更新时间。 SHOWprivileges:显示服务器所支持的不同权限。 SHOW createdatabasedatabase_name: 显示创建某一个数据库的CREATE DATABASE语句。 SHOWcreatetabletable_name:显示创建一个表的CREATETABLE语句。 SHOWevents:显示所有事件的列表。 SHOWinnodbstatus:显示innoDB存储引擎的状态。 SHOWlogs:显示BDB存储引擎的日志。 SHOW warnings:显示最后一个执行的语句所产生的错误、警告和通知。 SHOWerrors:只显示最后一个执行语句所产生的错误。 SHOW [storage]engines:显示安装后的可用存储引擎和默认引擎。 SHOWprocedurestatus:显示数据库中所有存储过程基本信息,包括所属数据库、存 储过程名称、创建时间等。 SHOWcreateproceduresp_name:显示某一个存储过程的详细信息。 2.DESCRIBE语句 DESCRIBE语句用于显示表中各列的信息,结果与SHOWcolumns…from…语句相 同。其语法格式为: {DESCRIBE|DESC} 表名[列名|wild ] 说明: ● DESC是DESCRIBE的简写,二者用法相同。 ● 列名可以是一个列名称,或一个包含%和_通配符的字符串,用于获得对于带有与字 符串相匹配的名称的各列的输出。没有必要在引号中包含字符串,除非其中包含空 格或其他特殊字符。 【例3.16】 用DESCRIBE语句查看xscj数据库xs表的列的信息。 use xscj describe xs; 执行结果如图3.15所示。 图3.15 例3.16执行结果 44 MySQL教程(第2版) 【例3.17】 查看xs表学号列的信息。 use xscj desc xs 学号; 执行结果如图3.16所示。 图3.16 例3.17执行结果 习题3 1.写出创建产品销售数据库cpxs及其中表的语句,库中所包含的表如下。 产品表:产品编号,产品名称,价格,库存量。 销售商表:客户编号,客户名称,地区,负责人,电话。 产品销售表:销售日期,产品编号,客户编号,数量,销售额。 要求:全部使用本章所讲的命令行方式创建,不要借助界面工具。 2.简要说明空值的概念及其作用。 3.写出命令行语句,对cpxs数据库的产品表进行如下操作。 (1)插入如下记录: 0001 空调 3000 200 0203 冰箱2500 100 0301 彩电2800 50 0421 微波炉1500 50 (2)将产品表中每种产品的价格打8折。 (3)将产品表中价格打8折后低于50元的产品记录删除。