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"',
]
];
为了添加 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"',
]
];