不,不是一般意义上的,我不相信即使是5.6(这个答案刚开始写的时候的最新版本)也有这个功能。 值得注意的是,8.0.13和更高版本现在支持函数索引,允许您在不需要下面描述的触发器方法的情况下实现所需的内容。
请参阅https://dev.mysql.com/doc/refman/8.0/en/create-index.html以获得更多详细信息。
如果您运行的是较旧版本的MySQL
,则可以只使用列的前导部分(此功能已存在很长时间),而不能使用从第二个或后续字符开始的部分,也不能使用任何其他更复杂的函数。
例如,下面使用名称的前五个字符创建索引:
create index name_first_five on cust_table (name(5));
对于更复杂的表达式,可以通过另一列中包含可索引数据,然后使用INSERT/UPDATE触发器确保正确填充该列来实现类似的效果。
除了为冗余数据浪费空间之外,这几乎是一回事。
而且,尽管它在技术上违反了3NF,但通过使用触发器来保持数据同步(这是为了增加性能而经常做的事情),这一点得到了缓解。
MySQL从8.0.13开始支持此功能
https://dev.mysql.com/doc/refman/8.0/en/create-index.html#create-index-functional-key-parts
MySQL8.0.13和更高版本支持索引表达式值而不是列或列前缀值的功能关键部分。 使用功能性关键部件可以对不直接存储在表中的值进行索引。 示例:
CREATE TABLE t1 (col1 INT, col2 INT, INDEX func_index ((ABS(col1))));
CREATE INDEX idx1 ON t1 ((col1 + col2));
CREATE INDEX idx2 ON t1 ((col1 + col2), (col1 - col2), col1);
ALTER TABLE t1 ADD INDEX ((col1 * 40) DESC);
一个具有多个关键部分的索引可以混合非功能性和功能性关键部分。
对于8.0.13之前的版本,有以下备选方案:
1.自MySQL 5.7.6以来
您可以使用自动生成的列来保存子字符串,其中包含索引:
CREATE TABLE SomeTable (
id CHAR(10),
sub_id CHAR(8) AS SUBSTRING(id, 1, 8) STORED, INDEX(sub_id)
)
正如Benjamin所指出的,InnoDB支持虚拟列的辅助索引,因此可以省略STORED关键字。 实际上,虚拟列上的辅助索引可能更可取。 此处提供更多信息:辅助索引和生成的列
2.MySQL 5.7.6之前的版本
可以使用触发器更新的列,列上有索引:
CREATE TABLE SomeTable (
id CHAR(10),
sub_id CHAR(8) , INDEX(sub_id)
);
CREATE TRIGGER TR_SomeTable_INSERT_sub_id
BEFORE INSERT
ON SomeTable FOR EACH ROW
SET NEW.sub_id = SUBSTRING(NEW.id, 1, 8);
CREATE TRIGGER TR_SomeTable_UPDATE_sub_id
BEFORE UPDATE
ON SomeTable FOR EACH ROW
SET NEW.sub_id = SUBSTRING(NEW.id, 1, 8);
从MySQL5.7.5开始,使用新生成的列,这是可能的。