Silverstripe FulltextSearchable 将 table 引擎转换为 MyIsam

Silverstripe FulltextSearchable converts the table Engines to MyIsam

为了添加 SiteSearch 功能,当我在 Silverstripe 中启用 FullTextSearchable 时,它​​默认将页表转换为 MyISAM,但我只需要保留表 InnoDB。 我使用的是 MySQL 版本 > 5.6(因此,它确实支持全文)

全文搜索仅在 MyISAM 中可用。这是 MyISAM 相对于 InnoDB 的主要优势之一。相关:https://dba.stackexchange.com/questions/1/what-are-the-main-differences-between-innodb-and-myisam

正如您所指出的,InnoDB 从版本 MySQL 5.6 版开始就支持全文搜索,但是框架附带的 MySQLSchemaManager 会阻止您将 InnoDB 用于定义了全文索引的表。或许您可以在 GitHub 上提出问题。您可以不受此限制创建自己的 SchemaManager(通过扩展 MySQLSchemaManager 并覆盖 alterTable()):

# Compare this to https://github.com/silverstripe/silverstripe-framework/blob/3.5/model/connect/MySQLSchemaManager.php#L100
class MyCustomSchemaManager extends MySQLSchemaManager
{

    public function alterTable($tableName, $newFields = null, $newIndexes = null, $alteredFields = null,
                               $alteredIndexes = null, $alteredOptions = null, $advancedOptions = null
    ) {
        if ($this->isView($tableName)) {
            $this->alterationMessage(
                sprintf("Table %s not changed as it is a view", $tableName),
                "changed"
            );
            return;
        }
        $alterList = array();

        if ($newFields) {
            foreach ($newFields as $k => $v) {
                $alterList[] .= "ADD \"$k\" $v";
            }
        }
        if ($newIndexes) {
            foreach ($newIndexes as $k => $v) {
                $alterList[] .= "ADD " . $this->getIndexSqlDefinition($k, $v);
            }
        }
        if ($alteredFields) {
            foreach ($alteredFields as $k => $v) {
                $alterList[] .= "CHANGE \"$k\" \"$k\" $v";
            }
        }
        if ($alteredIndexes) {
            foreach ($alteredIndexes as $k => $v) {
                $alterList[] .= "DROP INDEX \"$k\"";
                $alterList[] .= "ADD " . $this->getIndexSqlDefinition($k, $v);
            }
        }

        $dbID = self::ID;
        if ($alteredOptions && isset($alteredOptions[$dbID])) {
            $this->query(sprintf("ALTER TABLE \"%s\" %s", $tableName, $alteredOptions[$dbID]));
            $this->alterationMessage(
                sprintf("Table %s options changed: %s", $tableName, $alteredOptions[$dbID]),
                "changed"
            );
        }

        $alterations = implode(",\n", $alterList);
        $this->query("ALTER TABLE \"$tableName\" $alterations");
    }

}

然后你可以使用Injector来使用你的自定义class:

# Config.yml
Injector:
  MySQLSchemaManager:
    class: MyCustomSchemaManager

您现在应该可以使用静态 create_table_options 强制 InnoDB 引擎,并通过 indexes 静态创建全文索引。

示例:

# SomePage.php    

/**
 * Force InnoDB database engine.
 *
 * @var array
 */
private static $create_table_options = [
    'MySQLDatabase' => 'ENGINE=InnoDB'
];

/** 
 * Define what fulltext indexes to create.
 *
 * @var array
 */
private static $indexes = [
    'SearchFields' => [
        'type' => 'fulltext',
        'name' => 'SearchFields',
        'value' => '"MyField", "Tags"',
    ]
];