如果索引不存在,有没有办法在 MySQL 中创建索引?
MySQL 不支持明显的格式:
CREATE INDEX IF NOT EXISTS index_name ON table(column) ERROR 1064 (42000): You have an error in your SQL syntax;...
MySQL版本( mysql -V)是5.1.48,但我认为MySQLCREATE INDEX IF NOT EXIST在它的所有版本中都缺乏这个能力。
mysql -V
CREATE INDEX IF NOT EXIST
只有在 MySQL 中不存在索引时才创建索引的正确方法是什么?
该功能不存在。有两件事要记住:
您可以通过创建索引的方式生成索引,而无需提前检查索引是否存在。例如,您可以运行以下命令:
ALTER TABLE table_name ADD INDEX (column_to_index); ALTER TABLE table_name ADD INDEX (column_to_index);
这肯定会在不检查的情况下创建两个索引。每个索引都将被分配一个名称(可能是 column_to_index、column_to_index_1)。当然,您正试图避免这种情况。
这是 INFORMATION_SCHEMA.STATISTICS 的布局:
mysql> show create table statistics\G *************************** 1. row *************************** Table: STATISTICS Create Table: CREATE TEMPORARY TABLE `STATISTICS` ( `TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '', `TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '', `TABLE_NAME` varchar(64) NOT NULL DEFAULT '', `NON_UNIQUE` bigint(1) NOT NULL DEFAULT '0', `INDEX_SCHEMA` varchar(64) NOT NULL DEFAULT '', `INDEX_NAME` varchar(64) NOT NULL DEFAULT '', `SEQ_IN_INDEX` bigint(2) NOT NULL DEFAULT '0', `COLUMN_NAME` varchar(64) NOT NULL DEFAULT '', `COLLATION` varchar(1) DEFAULT NULL, `CARDINALITY` bigint(21) DEFAULT NULL, `SUB_PART` bigint(3) DEFAULT NULL, `PACKED` varchar(10) DEFAULT NULL, `NULLABLE` varchar(3) NOT NULL DEFAULT '', `INDEX_TYPE` varchar(16) NOT NULL DEFAULT '', `COMMENT` varchar(16) DEFAULT NULL, `INDEX_COMMENT` varchar(1024) NOT NULL DEFAULT '' ) ENGINE=MEMORY DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql>
您可以只按名称查询索引是否存在。例如,在你跑步之前
CREATE INDEX index_name ON mytable(column);
你需要跑
SELECT COUNT(1) IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name='mytable' AND index_name='index_name';
如果 IndexIsThere 为 0,则可以在索引中创建。也许您可以编写一个存储过程来在您选择的表上创建索引。
DELIMITER $$ DROP PROCEDURE IF EXISTS `adam_matan`.`CreateIndex` $$ CREATE PROCEDURE `adam_matan`.`CreateIndex` ( given_database VARCHAR(64), given_table VARCHAR(64), given_index VARCHAR(64), given_columns VARCHAR(64) ) BEGIN DECLARE IndexIsThere INTEGER; SELECT COUNT(1) INTO IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema = given_database AND table_name = given_table AND index_name = given_index; IF IndexIsThere = 0 THEN SET @sqlstmt = CONCAT('CREATE INDEX ',given_index,' ON ', given_database,'.',given_table,' (',given_columns,')'); PREPARE st FROM @sqlstmt; EXECUTE st; DEALLOCATE PREPARE st; ELSE SELECT CONCAT('Index ',given_index,' already exists on Table ', given_database,'.',given_table) CreateindexErrorMessage; END IF; END $$ DELIMITER ;
这是一个示例运行(嘿,还记得这张表吗?它来自您在 2012 年 6 月 27 日提出的问题):
mysql> show create table pixels\G *************************** 1. row *************************** Table: pixels Create Table: CREATE TABLE `pixels` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` varchar(30) DEFAULT NULL, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `pixel_data` blob, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> call createindex('adam_matan','pixels','type_timestamp_id_ndx','type,timestamp,id'); Query OK, 0 rows affected (0.20 sec) mysql> show create table pixels\G *************************** 1. row *************************** Table: pixels Create Table: CREATE TABLE `pixels` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` varchar(30) DEFAULT NULL, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `pixel_data` blob, PRIMARY KEY (`id`), KEY `type_timestamp_id_ndx` (`type`,`timestamp`,`id`) ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> call createindex('adam_matan','pixels','type_timestamp_id_ndx','type,timestamp,id'); +-----------------------------------------------------------------------+ | CreateindexErrorMessage | +-----------------------------------------------------------------------+ | Index type_timestamp_id_ndx Already Exists on Table adam_matan.pixels | +-----------------------------------------------------------------------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.01 sec) mysql>
试试看 !!!