Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 通过迁移添加外键时,哪些表被锁定?_Mysql_Sql_Foreign Keys - Fatal编程技术网

Mysql 通过迁移添加外键时,哪些表被锁定?

Mysql 通过迁移添加外键时,哪些表被锁定?,mysql,sql,foreign-keys,Mysql,Sql,Foreign Keys,我正在向现有MYSQL表添加外键。假设我有一个表销售和一个表产品。我将FK添加到我的销售表中: ALTER TABLE sales ADD CONSTRAINT sales_product_item_fk FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE RESTRICT ON UPDATE RESTRICT 运行此操作时,将锁定哪些表?销售,产品,两者 (根据下面的注释进行编辑以指定MYSQL)两个表都将使用共享锁锁定。

我正在向现有MYSQL表添加外键。假设我有一个表销售和一个表产品。我将FK添加到我的销售表中:

ALTER TABLE sales ADD CONSTRAINT sales_product_item_fk FOREIGN KEY (product_id)  REFERENCES products(id) ON DELETE RESTRICT  ON UPDATE RESTRICT
运行此操作时,将锁定哪些表?销售,产品,两者


(根据下面的注释进行编辑以指定MYSQL)

两个表都将使用共享锁锁定。这允许您对表运行SELECT,并允许您执行其他需要共享锁的操作,但不允许您执行任何需要独占锁的操作,例如
更新

您可以确认这一点:创建两个表
sales
products
,并在
sales
表中填充几百万行,这样做至少需要几秒钟的时间。此测试表中每一行的product_id值可以相同

mysql> select * from sales limit 3;
+----+------------+
| id | product_id |
+----+------------+
|  1 |          1 |
|  2 |          1 |
|  3 |          1 |
...
并确保
products
表中有一行满足外键要求

mysql> select * from products;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | some name |
+----+-----------+
现在打开两个窗口,准备对每个窗口中的表运行查询

运行ALTER表以添加外键。如果外键没有索引,这将构建一个新索引。建立索引花费的时间最多。事实上,即使添加一个没有外键的索引,也会表现出相同的锁定行为

mysql> ALTER TABLE sales ADD CONSTRAINT sales_product_item_fk FOREIGN KEY (product_id)
  REFERENCES products(id) ON DELETE RESTRICT  ON UPDATE RESTRICT;
这将在构建索引时等待。在我的笔记本电脑上,有800万行,需要30秒以上。在第二个窗口中有足够的时间进行查询

mysql> update sales set product_id = null limit 2;
这将阻塞,等待获得
sales
中某些行的锁。你可能预料到了。当存在索引生成时,无法更新表

mysql> update products set name = 'othername';
这也会阻塞,等待对
产品中的行进行独占锁定。当表上有共享锁时,它无法获取独占锁

你能用
lock=NONE
条款解除对锁的要求吗

mysql> ALTER TABLE sales ADD CONSTRAINT sales_product_item_fk FOREIGN KEY (product_id)
  REFERENCES products(id) ON DELETE RESTRICT  ON UPDATE RESTRICT, LOCK=NONE;
ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: Adding foreign keys needs foreign_key_checks=OFF. Try LOCK=SHARED.

没有。更改锁定级别受到您请求的更改类型的限制。

您应该在问题上标记您所询问的特定品牌的SQL RDBMS。“sql”是一种语言,而不是特定的软件产品。根据实现的不同,您要寻找的答案可能会有所不同。