1.概述
表记录的插入使用 insert 关键字,可以添加行到数据库表中,一般分以下几种情况:
- 插入完整的行;
- 插入行的一部分;
- 插入多行;
- 插入某些查询到的结果
当然也可以利用MySql的安全机制,设置某些表或某个用户,禁止使用insert语句,这将在后续安全管理的内容中进行介绍;
2.插入完整的行
基本的insert语句可以支持将完整的行插入到数据表中,它要求指定表名和完整的需要插入的数据,如:
insert into customers
values(
null,
'tom',
'200 Maple Lane',
'Detroit',
'MI',
'90046',
'USA',
null,
null
);
insert 语句只会返回是否成功,不会产生输出;
使用insert 语句插入时,要给定表名,并在values 子句中给出每个列的数据,对应的列必须全部提供值,没有值的列使用 null 值,值的给定顺序要严格按照表中列的顺序给出;
当表中设置了主键自增时,你也可以给定一个 null 值,此时MySql 会对该列进行自动增量,例如上方的插入语句,第一个值给定为null,但查询结果并不为null,而是根据上一条数据自动增量的结果;
这种语法虽然简单,但是应该尽量避免使用,其过于依赖插入时的顺序,当使用sql脚本时,如果表结构发生了变化,则会导致插入的数据次序错误,减弱的脚本的通用性;
我们一般建议更为完整的写法,如:
INSERT INTO customers(
cust_id,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country,
cust_contact,
cust_email)
VALUES(
null,
'tom',
'200 Maple Lane',
'Detroit',
'MI',
'90046',
'USA',
null,
null
);
这样的写法与上面的写法结果并没有什么不同,但是它能保证在表结构发生变化后,也正确将对应的值插入到其应该插入的列中;首先在表名后给出列名,然后根据列名的顺序在values表中依次给出对应的值,此时只要保证值与给出列名的对应顺序关系即可;
2.插入行的一部分
有些时候,我们并不是要插入一个行的完整数据,可能只需要插入一部分数据即可,如:
INSERT INTO customers(
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country,
cust_contact,
cust_email)
VALUES(
'tom',
'200 Maple Lane',
'Detroit',
'MI',
'90046',
'USA',
null,
null
);
因为 cust_id 为主键,且设置了主键自增,所以我们在插入时只需要给定 null 值即可,但是这样也比较繁琐,我们可以直接不给定此字段的值,其字段也会根据表设置的主键自增去自动的设置相应的值;
但是要注意,要省略某些列时,必须符合以下某个条件:
- 该列定义允许为 null;
- 该列在当前表中给定了默认值,这样的话,不给定值就会使用默认值填充;
- 该列为自增字段,不给定值时MySql会协助给定正确的值;
3.插入多行
其实 insert 命令只可以插入一行数据到数据表中,如果想插入多行的话,则需要使用多个 insert 语句,中间使用分号结尾区分,如:
INSERT INTO customers(
cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(
'tom','200 Maple Lane', 'Detroit', 'MI', '90046', 'USA', null, null
);
INSERT INTO customers(
cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(
'tom2','201 Maple Lane', 'Detroit', 'MI', '90047', 'USA', null, null
);
INSERT INTO customers(
cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(
'tom2','202 Maple Lane', 'Detroit', 'MI', '90048', 'USA', null, null
);
或者当插入的列名次序一致时,也可以使用下列的格式,如:
INSERT INTO customers(
cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(
'tom','200 Maple Lane', 'Detroit', 'MI', '90046', 'USA', null, null
),
(
'tom1','201 Maple Lane', 'Detroit', 'MI', '90047', 'USA', null, null
),
(
'tom2','202 Maple Lane', 'Detroit', 'MI', '90048', 'USA', null, null
);
其中单条 insert 语句有多组值,每组值使用圆括号括起来,用逗号分隔;
4.插入检索出的数据
insert 一般用来给表插入一个指定列的数据,但其还存在另一种形式,可以利用它将一条 select 语句的结果插入表中,如果你想将另一张表中的数据合并到当前表中,并不需要每次插入一行来进行手动操作,可以通过 insert select 语句来实现,如:
insert into 想要插入数据的表名(
字段1,
字段2,
字段3)
select
字段1,
字段2,
字段3
from
需要获取数据的表名
在插入时,首先要确保的就是主键的值不能重复,如果值重复,可以在查询数据表的数据时不要查询主键值,在插入时由MySql自动填入;
insert select 语句中的 select 语句也可以包含where子句来进行条件过滤;
5.避免插入限制数据时的错误
在某些时候我们插入一些数据时,可能某些列的数据在表中已经存在,并且此数据进行了一些限制,列入主键,和unique
唯一约束,此时插入相同数据时就会报此数据已存在的错误:
此时我们还可以选择使用replace into
进行数据的插入,此命令会先判断要插入的数据是否与表中已有限制数据产生冲突,如果没有冲突则直接进行数据的插入,如果有冲突会将插入语句变更为更新语句,将已有数据更新为新插入的数据;
6.插入数据时的性能控制
数据库经常被多人使用,在使用时会同时处理多个命令,对于当前存在的命令用什么优先级处理是比较重要的;
insert 语句对于数据库性能的消耗是比较大的,特别是有多个索引需要更新时,对于用户来说,快速获取结果是直观影响其使用体验的,所以我们一般将插入数据的优先级设置为比查询数据的优先级低,此时我们可以在 insert 和 into 之间使用 LOW_PRIORITY 关键字,降低 Insert 语句的优先级;
同样的,此关键字也适用于 update 和 delete 命令;