Tim*_*imo 7 mysql if-not-exists temporary-tables
我想用一些选择数据创建一个临时表。
我的(奇怪的)问题是我必须多次执行相同的查询。
CREATE TEMPORARY TABLE IF NOT EXISTS cache (id int(11) NOT NULL, INDEX (id))
SELECT id FROM table WHERE xyz;
CREATE TEMPORARY TABLE IF NOT EXISTS cache (id int(11) NOT NULL, INDEX (id))
SELECT id FROM table WHERE xyz;
Run Code Online (Sandbox Code Playgroud)
不幸的是,尽管临时表已经存在,MySQL 还是执行了第二个查询。
SELECT
查询在表不存在的情况下才执行?此致,
蒂莫
这是表创建的本质CREATE TEMPORARY TABLE
创建表时可以使用 TEMPORARY 关键字。TEMPORARY 表仅对当前连接可见,并在连接关闭时自动删除。这意味着两个不同的连接可以使用相同的临时表名称,而不会相互冲突或与现有的同名非 TEMPORARY 表发生冲突。(现有表将被隐藏,直到临时表被删除。)要创建临时表,您必须具有 CREATE TEMPORARY TABLES 权限。
我的猜测是您一定已经完成了以下一系列事件:
CREATE TEMPORARY TABLE
CREATE TEMPORARY TABLE
再次运行,因为他的表不存在我看到这个问题让许多开发人员受害,尤其是在 MySQL 复制方面。例如,如果您运行STOP SLAVE;
,SQL 线程将关闭。使用创建的任何表都CREATE TEMPORARY TABLE
将被删除。当您运行时START SLAVE;
,MySQL 复制会立即中断,因为 INSERT、UPDATE 或 DELETE 所需的表不再存在。我必须在中继日志上执行 mysqlbinlog 转储来定位原始CREATE TEMPORARY TABLE
语句,运行它们,CREATE TABLE
以便表仍然可供其他数据库连接访问,包括START SLAVE;
重新发出时的 SQL 线程。
至于你的问题
SELECT
有没有办法告诉MySQL,如果表不存在,则只执行临时表的创建和查询?您无法检查 information_schema 是否存在临时表。在操作系统中,没有体现.frm
出来datadir
。您可以在 中定义的文件夹中找到它tmpdir
。
下面是一个例子:我将创建一个名为的临时表test.junk
并尝试定位该表的下落。(注:我使用的是 Windows 版 MySQL)
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.12-log MySQL Community Server (GPL)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use test
Database changed
mysql> create temporary table junk (a int) engine=MyISAM;
Query OK, 0 rows affected (0.02 sec)
mysql> show create table junk\G
*************************** 1. row ***************************
Table: junk
Create Table: CREATE TEMPORARY TABLE `junk` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.01 sec)
mysql> select count(1) from information_schema.tables
-> where table_schema='test' and table_name='junk';
+----------+
| count(1) |
+----------+
| 0 |
+----------+
1 row in set (0.08 sec)
mysql> show variables like 'datadir';
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| datadir | C:\MySQL_5.5.12\data\ |
+---------------+-----------------------+
1 row in set (0.00 sec)
mysql> show variables like 'tmpdir';
+---------------+--------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------+
| tmpdir | C:\Users\redwards\AppData\Local\Temp |
+---------------+--------------------------------------+
1 row in set (0.00 sec)
mysql>
Run Code Online (Sandbox Code Playgroud)
该表在 INFORMATION_SCHEMA.TABLES 中不可见。让我们在操作系统中找到该表
C:\MySQL_5.5.12\data\test>cd
C:\MySQL_5.5.12\data\test
C:\MySQL_5.5.12\data\test>dir junk.*
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\MySQL_5.5.12\data\test
File Not Found
C:\MySQL_5.5.12\data\test>dir C:\Users\redwards\AppData\Local\Temp\*.frm
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\Users\redwards\AppData\Local\Temp
10/19/2012 11:04 AM 8,554 #sql7ac_3_0.frm
1 File(s) 8,554 bytes
0 Dir(s) 190,200,049,664 bytes free
C:\MySQL_5.5.12\data\test>dir C:\Users\redwards\AppData\Local\Temp\*.MY*
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\Users\redwards\AppData\Local\Temp
10/19/2012 11:04 AM 0 #sql7ac_3_0.MYD
10/19/2012 11:04 AM 1,024 #sql7ac_3_0.MYI
2 File(s) 1,024 bytes
0 Dir(s) 190,200,049,664 bytes free
C:\MySQL_5.5.12\data\test>
Run Code Online (Sandbox Code Playgroud)
tmpdir 文件夹中有临时表。当我关闭 mysql 客户端并运行时dir C:\Users\redwards\AppData\Local\Temp\*.frm
,该表消失了。
你可以做两件事之一
CREATE TEMPORARY TABLE IF NOT EXISTS
(这实际上是针对不当设计的创可贴,但可能会规避问题)。如果您使用相同的数据库连接但仍然遇到此问题,这里还有一些先前未提及的内容:您为临时表提供了一个索引。那应该是唯一索引或主键。
您可以将操作从 a 转移CREATE TABLE ... SELECT
到CREATE TABLE ... INSERT IGNORE
如果要使用临时表,请指定MyISAM。如果发生崩溃或数据库连接终止,InnoDB 往往会在数据字典中留下 ibdata1 的鸽子洞。
考虑到这三(3)个观察结果,这是我建议的更改
CREATE TEMPORARY TABLE IF NOT EXISTS cache
(id int(11) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM;
INSERT IGNORE INTO cache SELECT id FROM table WHERE xyz;
CREATE TEMPORARY TABLE IF NOT EXISTS cache
(id int(11) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM;
INSERT IGNORE INTO cache SELECT id FROM table WHERE xyz;
Run Code Online (Sandbox Code Playgroud)
试一试 !!!
归档时间: |
|
查看次数: |
48297 次 |
最近记录: |