跳转到内容

MySQL/语言/数据操作

来自维基教科书,开放的书籍,开放的世界

语法如下

将 value1 插入 Column1,value2 插入 Column2,value3 插入 Column3

 INSERT INTO TableName (Column1, Column2, Column3)
 VALUES (value1, value2, value3)

插入一条记录(值按数据库中列的顺序插入)

 INSERT INTO TableName
 VALUES (value1, value2, value3)

插入两条记录

 INSERT INTO TableName
 VALUES (value1, value2, value3), (value4, value5, value6)

 INSERT INTO antiques VALUES (21, 01, 'Ottoman', 200.00);
 INSERT INTO antiques (buyerid, sellerid, item) VALUES (01, 21, 'Ottoman');

您也可以插入从其他表中'选择'的记录。

 INSERT INTO table1(field1, field2)
 SELECT field1, field2
 FROM table2

 INSERT INTO World_Events SELECT * FROM National_Events

性能提示

  • 要插入多行,请考虑使用 LOAD DATA INFILE 代替。
  • 如果批量 INSERT 速度太慢,并且它们对索引的非空表进行操作,您可能应该增加 bulk_insert_buffer_size 的值。
  • 在执行批量插入之前,您可能需要禁用键。
  • 锁定表也可以加快 INSERT 的速度。

语法是

 UPDATE table SET field1 = newvalue1, field2 = newvalue2 WHERE criteria ORDER BY field LIMIT n

示例如下

 UPDATE owner SET ownerfirstname = 'John'
   WHERE ownerid = (SELECT buyerid FROM antiques WHERE item = 'Bookcase');
 
 UPDATE antiques SET price = 500.00 WHERE item = 'Chair';
 
 UPDATE order SET discount=discount * 1.05
 
 UPDATE tbl1 JOIN tbl2 ON tbl1.ID = tbl2.ID
   SET tbl1.col1 = tbl1.col1 + 1
   WHERE tbl2.status='Active'
 
 UPDATE tbl SET names = REPLACE(names, 'aaa', 'zzz')
 
 UPDATE products_categories AS pc
   INNER JOIN products AS p ON pc.prod_id = p.id
   SET pc.prod_sequential_id = p.sequential_id
 
 UPDATE table_name SET col_name =
   REPLACE(col_name, 'host.domain.com', 'host2.domain.com')

 UPDATE posts SET deleted=True
   ORDER BY date LIMIT 1

使用 ORDER BY,您可以在更新行之前对行进行排序,并且只更新给定数量的行 (LIMIT)。

目前无法在对同一表执行子查询时更新表。例如,如果我想重置我在 SPIP 中忘记的密码

mysql> UPDATE spip_auteurs SET pass =
 (SELECT pass FROM spip_auteurs WHERE login='paul') where login='admin';
ERROR 1093 (HY000): You can't specify target table 'spip_auteurs' for update in FROM clause

TODO:描述一个我无法使用 MySQL 4.1 进行操作的解决方法。目前,解决方法是不使用 2 个子查询,可能使用事务[1]

性能提示

  • UPDATE 的速度取决于更新了多少索引。
  • 如果您更新使用动态格式的 MyISAM 表,如果您使行变大,它们可能会被分成多个部分。这会导致读取开销。因此,如果您的应用程序经常这样做,您可能需要定期运行 OPTIMIZE TABLE 语句。
  • 在锁定表上一起执行多个 UPDATE 比分别执行它们更快。

REPLACE 的工作方式与 INSERT 完全相同,只是如果表中的一条旧记录与新记录的 PRIMARY KEY 或 UNIQUE 索引的值相同,则会在插入新记录之前删除旧记录。

从 MySQL 5.5[2] 开始,“INSERT IGNORE” 和 “REPLACE IGNORE” 允许在出现重复键错误时显示一些警告并避免语句中止。

在 MySQL 4.0.1 之前,INSERT ... SELECT 隐式以 IGNORE 模式运行。从 MySQL 4.0.1 开始,请显式指定 IGNORE 以忽略会导致重复键冲突的记录。

DELETE 和 TRUNCATE

[编辑 | 编辑源代码]
 DELETE [QUICK] FROM `table1`
 TRUNCATE [TABLE] `table1`
  • 如果您没有对 DELETE 使用 WHERE 子句,则将删除所有记录。
  • 它在一个大型表中可能非常慢,尤其是在表中包含很多索引的情况下。
  • 如果表包含很多索引,您可以增大缓存以尝试使 DELETE 更快 (key_buffer_size 变量)。
  • 对于索引的 MyISAM 表,在某些情况下,如果指定 QUICK 关键字,则 DELETE 会更快 (DELETE QUICK FROM ...)。这仅对删除的索引值将被重用的表有用。
  • TRUNCATE 通过 DROP 和重新创建表来快速删除所有行(并非所有存储引擎都支持此操作)。
  • TRUNCATE 不是事务安全也不是锁定安全。
  • DELETE 会告知您删除了多少行,但 TRUNCATE 不会。
  • 在删除大量行(约 30%)后,OPTIMIZE TABLE 命令应该使后续语句更快。
  • 对于具有 FOREIGN KEY 约束的 InnoDB 表,TRUNCATE 的行为类似于 DELETE。
 DELETE FROM `antiques`
   WHERE item = 'Ottoman'
   ORDER BY `id`
   LIMIT 1

您可以在删除行之前对行进行排序,然后只删除给定数量的行。

参考资料

[编辑 | 编辑源代码]
华夏公益教科书