MySQL插入、更新和删除

发布时间:2024年01月12日

一、插入数据

插入有以下几种方式:

  • 插入完整的行;
  • 插入行的一部分;
  • 插入多行;
  • 插入某些查询的结果。

1. 插入完整的行

子插入一个新客户到customers表。

INSERT INTO customers 
VALUES (NULL,
			'Pep E. LaPew',
			'100 Main Street',
			'Los Angeles',
			'CA',
			'90046',
			'USA',
			NULL,
			NULL);

更安全的的方法

INSERT INTO customers(cust_name,
								cust_address,
								cust_city, 
								cust_state, 
								cust_zip, 
								cust_country,
								cust_contact,
								cust_email)
VALUES ('Pep E. LaPew',
			'100 Main Street',
			'Los Angeles',
			'CA',
			'90046',
			'USA',
			NULL,
			NULL);

一般不要使用没有明确给出列的列表的 INSERT语句。使用列的列表能使SQL代码继续发挥作用,即使表结构发生了变化。

不管使用哪种INSERT语法,都必须给出 VALUES的正确数目。如果不提供列名,则必须给每个表列提供一个值。如果提供列名,则必须对每个列出的列给出一个值。如果不这样,将产生一条错误消息,相应的行插入不成功。

省略列

如果表的定义允许,则可以在INSERT操作中省略某些列。省略的列必须满足以下某个条件。

  • 该列定义为允许NULL值(无值或空值)。
  • 在表定义中给出默认值。这表示如果不给出值,将使用默认值。

如果对表中不允许NULL值且没有默认值的列不给出值,则MySQL将产生一条错误消息,并且相应的行插入不成功。

提高整体性能

数据库经常被多个客户访问,对处理什么请求以及用什么次序处理进行管理是MySQL的任务。INSERT操作可能很耗时(特别是有很多索引需要更新时),而且它可能降低等待处理的SELECT语句的性能。

如果数据检索是最重要的(通常是这样),则你可以通过在 INSERT和INTO之间添加关键字LOW_PRIORITY,指示MySQL 降低INSERT语句的优先级,如下所示:

INSERT LOW PRIORITY INTO

这也适用 UPDATE和 DELETE语句。

2. 插入多个行

可以使用多条INSERT语句,甚至一次提交它们,每条语句用一个分号结束;
只要每条INSERT语句中的列名(和次序)相同,可以如下组合各语句

INSERT INTO customers(cust_name,
								cust_address,
								cust_city, 
								cust_state, 
								cust_zip, 
								cust_country)
VALUES ('Pep E. LaPew',
			'100 Main Street',
			'Los Angeles',
			'CA',
			'90046',
			'USA'),
			('M. Martian',
			'42 Galaxy Way',
			'New York',
			'NY',
			'11213',
			'USA');

3. 插入检索出的数据

INSERT 将一条 SELECT语句的结果插入表中。这就是所谓的 INSERT SELECT,顾名思义,它是由一条INSERT语句和一条SELECT语句组成的。

INSERT INTO customers(cust_id,
				cust_contact,
				cust_email,
				cust_name,
				cust_address,
				cust_city,
				cust_state,
				cust_zip,
				cust_country)
SELECT cust_id,
			cust_contact,
			cust_email,
			cust_name,
			cust_address,
			cust_city,
			cust_state,
			cust_zip,
			cust_country
FROM custnew;

INSERT SELECT中的列名 为简单起见,这个例子在 INSERT和 SELECT语句中使用了相同的列名。但是,不一定要求列名匹配。
事实上,MySQL甚至不关心SELECT返回的列名。它使用的是列的位置,因此SELECT中的第一列(不管其列名)将用来填充表列中指定的第一个列,第二列将用来填充表列中指定的第二个列,如此等等。这对于从使用不同列名的表中导入数据是非常有用的。

二、更新数据

更新两种方式:

  • 更新表中特定行;
  • 更新表中所有行

基本的UPDATE语句由3部分组成:

  • 要更新的表;
  • 列名和它们的新值;
  • 确定要更新行的过滤条件。
UPDATE customers 
SET cust_name = 'The Fudds',
    cust_email = 'elmer@fudd.com'
WHERE cust_id = 10005;

在更新多个列时,只需要使用单个SET命令,每个“列=值”对之间用逗号分隔(最后一列之后不用逗号)。

IGNORE关键字
如果用UPDATE语句更新多行,并且在更新这些行中的一行或多行时出一个现错误,则整个UPDATE操作被取消(错误发生前更新的所有行被恢复到它们原来的值)。为即使是发生错误,也继续进行更新,可使用IGNORE关键字,如下所示:
UPDATE IGNORE customers…

三、删除数据

DELETE的两种方式:

  • 从表中删除特定的行
  • 从表中删除所有行
DELETE FROM customers 
WHERE cust_id = 10006;

更快的删除
如果想从表中删除所有行,不要使用DELETE。可使用TRUNCATE TABLE语句,它完成相同的工作,但速度更快(TRUNCATE实际是删除原来的表并重新创建一个表,而不是逐行删除表中的数据)

四、更新和删除的指导原则

  • 除非确实打算更新和删除每一行,否则绝对不要使用不带WHERE子句的UPDATE或DELETE语句。
  • 保证每个表都有主键,尽可能像WHERE子句那样使用它(可以指定各主键、多个值或值的范围)。
  • 在对 UPDATE或 DELETE语句使用 WHERE子句前,应该先用 SELECT进行测试,保证它过滤的是正确的记录,以防编写的WHERE子句不正确。
  • 使用强制实施引用完整性的数据库,这样MySQL将不允许删除具有与其他表相关联的数据的行。

五、创建和操作表

1. 创建表

为了用程序创建表,可使用SQL的CREATE TABLE语句。

1.1 表创建基础

为利用CREATE TABLE创建表,必须给出下列信息:

  • 新表的名字,在关键字CREATE TABLE之后给出;
  • 表列的名字和定义,用逗号分隔
CREATE TABLE customers
(
  cust_id      int       NOT NULL AUTO_INCREMENT,
  cust_name    char(50)  NOT NULL ,
  cust_address char(50)  NULL ,
  cust_city    char(50)  NULL ,
  cust_state   char(5)   NULL ,
  cust_zip     char(10)  NULL ,
  cust_country char(50)  NULL ,
  cust_contact char(50)  NULL ,
  cust_email   char(255) NULL ,
  PRIMARY KEY (cust_id)
) ENGINE=InnoDB;

处理现有的表: 在创建新表时,指定的表名必须不存在,否则将出错。如果要防止意外覆盖已有的表,SQL要求首先手工删除该表(请参阅后面的小节),然后再重建它,而不是简单地用创建表语句覆盖它。

如果你仅想在一个表不存在时创建它,应该在表名后给出 IF NOT EXISTS。这样做不检查已有表的模式是否与你打算创建的表模式相匹配。它只是查看表名是否存在,并且仅在表名不存在时创建它。

1.2 使用NULL值

NULL值就是没有值或缺值。允许NULL值的列也允许在插入行时不给出该列的值。不允许NULL值的列不接受该列没有值的行,换句话说,在插入或更新行时,该列必须有值。

CREATE TABLE orders
(
  order_num  int      NOT NULL AUTO_INCREMENT,
  order_date datetime NOT NULL ,
  cust_id    int      NOT NULL ,
  PRIMARY KEY (order_num)
) ENGINE=InnoDB;

不要把NULL值与空串相混淆。NULL值是没有值,它不是空串。如果指定’'(两个单引号,其间没有字符),这在NOT NULL列中是允许的。空串是一个有效的值,它不是无值。NULL值用关键字NULL而不是空串指定。

1.3 主键

主键值必须唯一。即,表中的每个行必须具有唯一的主键值。如果主键使用单个列,则它的值必须唯一。如果使用多个列,则这些列的组合值必须唯一。

创建由多个列组成的主键,应该以逗号分隔的列表给出各列名

CREATE TABLE orderitems
(
  order_num  int          NOT NULL ,
  order_item int          NOT NULL ,
  prod_id    char(10)     NOT NULL ,
  quantity   int          NOT NULL ,
  item_price decimal(8,2) NOT NULL ,
  PRIMARY KEY (order_num, order_item)
) ENGINE=InnoDB;

主键中只能使用不允许NULL值的列。允许NULL值的列不能作为唯一标识。

1.4 使用AUTO_INCREMENT

AUTO_INCREMENT告诉MySQL,本列每当增加一行时自动增量。每次执行一个INSERT操作时,MySQL自动对该列增量(从而才有这个关键字AUTO_INCREMENT),给该列赋予下一个可用的值。这样给每个行分配一个唯一的vend_id,从而可以用作主键值。

CREATE TABLE vendors
(
  vend_id      int      NOT NULL AUTO_INCREMENT,
  vend_name    char(50) NOT NULL ,
  vend_address char(50) NULL ,
  vend_city    char(50) NULL ,
  vend_state   char(5)  NULL ,
  vend_zip     char(10) NULL ,
  vend_country char(50) NULL ,
  PRIMARY KEY (vend_id)
) ENGINE=InnoDB;

每个表只允许一个AUTO_INCREMENT列,而且它必须被索引(如,通过使它成为主键)。

确定AUTO_INCREMENT值
让MySQL生成(通过自动增量)主键的一个缺点是你不知道这些值都是谁。
考虑这个场景:你正在增加一个新订单。这要求在orders表中创建一行,然后在orderitms表中对订购的每项物品创建一行。order_num在orderitems表中与订单细节一起存储。这就是为什么orders表和orderitems表为相互关联的表的原因。这显然要求你在插入orders行之后,插入orderitems行之前知道生成的order_num。

那么,如何在使用AUTO_INCREMENT列时获得这个值呢?可使
用last_insert_id()函数获得这个值,如下所示:
SELECT last_insert_id()

此语句返回最后一个AUTO_INCREMENT值,然后可以将它用于后续的MySQL语句。

1.5 指定默认值

如果在插入行时没有给出值,MySQL允许指定此时使用的默认值。默认值用CREATE TABLE语句的列定义中的DEFAULT关键字指定。

CREATE TABLE orderitems
(
  order_num  int          NOT NULL ,
  order_item int          NOT NULL ,
  prod_id    char(10)     NOT NULL ,
  quantity   int          NOT NULL DELETE 1,
  item_price decimal(8,2) NOT NULL ,
  PRIMARY KEY (order_num, order_item)
) ENGINE=InnoDB;

与大多数DBMS不一样,MySQL不允许使用函数作为默认值,它只支持常量。

1.6 引擎类型

迄今为止使用的CREATE TABLE语句全都以 ENGINE=InnoDB语句结束。

与其他DBMS一样,MySQL有一个具体管理和处理数据的内部引擎。在你使用CREATE TABLE语句时,该引擎具体创建表,而在你使用SELECT语句或进行其他数据库处理时,该引擎在内部处理你的请求。多数时候,此引擎都隐藏在DBMS内,不需要过多关注它。

但MySQL与其他DBMS不一样,它具有多种引擎。它打包多个引擎,这些引擎都隐藏在MySQL服务器内,全都能执行CREATE TABLE和SELECT等命令。

为什么要发行多种引擎呢?因为它们具有各自不同的功能和特性,为不同的任务选择正确的引擎能获得良好的功能和灵活性。

如果省略ENGINE=语句,则使用默认引擎(很可能是MyISAM),多数SQL语句都会默认使用它。但并不是所有语句都默认使用它,这就是为什么ENGINE=语句很重要的原因。

  • InnoDB是一个可靠的事务处理引擎,它不支持全文本搜索;
  • MEMORY在功能等同于MyISAM,但由于数据存储在内存(不是磁盘)中,速度很快(特别适合于临时表);
  • MyISAM是一个性能极高的引擎,它支持全文本搜索,但不支持事务处理。

外键不能跨引擎:混用引擎类型有一个大缺陷。外键(用于强制实施引用完整性)不能跨引擎,即使用一个引擎的表不能引用具有使用不同引擎的表的外键。

2. 更新表

为更新表定义,可使用ALTER TABLE语句。但是,理想状态下,当表中存储数据以后,该表就不应该再被更新。在表的设计过程中需要花费大量时间来考虑,以便后期不对该表进行大的改动。
使用 ALTER TABLE条件:

  • 在ALTER TABLE之后给出要更改的表名(该表必须存在,否则将
    出错);
  • 所做更改的列表。

给表添加一列

ALTER TABLE vendors
ADD vend_phone CHAR(20);

删除一列

ALTER TABLE vendors
DROP COLUMN vend_phone;

定义外键

ALTER TABLE orderitems ADD CONSTRAINT fk_orderitems_orders FOREIGN KEY (order_num) REFERENCES orders (order_num);
ALTER TABLE orderitems ADD CONSTRAINT fk_orderitems_products FOREIGN KEY (prod_id) REFERENCES products (prod_id);
ALTER TABLE orders ADD CONSTRAINT fk_orders_customers FOREIGN KEY (cust_id) REFERENCES customers (cust_id);
ALTER TABLE products ADD CONSTRAINT fk_products_vendors FOREIGN KEY (vend_id) REFERENCES vendors (vend_id);

复杂的表结构更改一般需要手动删除过程,它涉及以下步骤:

  • 用新的列布局创建一个新表;
  • 使用INSERT SELECT语句从旧表复制数据到新表。如果有必要,可使用转换函数和计算字段;
  • 检验包含所需数据的新表;
  • 重命名旧表(如果确定,可以删除它);
  • 用旧表原来的名字重命名新表;
  • 根据需要,重新创建触发器、存储过程、索引和外键。

小心使用ALTER TABLE

使用ALTER TABLE要极为小心,应该在进行改动前做一个完整的备份(模式和数据的备份)。数据库表的更改不能撤销,如果增加了不需要的列,可能不能删除它们。类似地,如果删除了不应该删除的列,可能会丢失该列中的所有数据

3. 删除表

删除表(删除整个表而不是其内容)非常简单,使用DROP TABLE语句即可:

DROP TABLE customers2;

4. 重命名表

使用RENAME TABLE语句可以重命名一个表:

RENAME TABLE customers2 TO customers;
文章来源:https://blog.csdn.net/guoxulieying/article/details/135552336
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。