Laravel Schema 中的 MySQL 数据类型 SET 等价物是啥?
Posted
技术标签:
【中文标题】Laravel Schema 中的 MySQL 数据类型 SET 等价物是啥?【英文标题】:What is the MySQL datatype SET equivalent in Laravel Schema?Laravel Schema 中的 MySQL 数据类型 SET 等价物是什么? 【发布时间】:2014-08-08 22:20:36 【问题描述】:Laravel Schema 有一个与表等效的 ENUM 命令。什么是 SET 等价于表?
【问题讨论】:
【参考方案1】:到目前为止,Laravel Schema Builder 不支持列的 SET 数据类型。因此,在有人将这些代码添加到 Laravel 之前,这是一个替代解决方案。
第 1 步:创建表,使用 ENUM 而不是 SET。
Schema::create('schools', function($table)
$table->increments('id');
$table->char('id_number', 6);
$table->string('school_name');
$table->enum('level', array('Preschool', 'Kindergarten', 'Primary', 'Secondary'))->index(); // *** fix this
$table->string('phone');
$table->string('email');
$table->string('location');
$table->smallInteger('city')->unsigned()->index();
$table->smallInteger('country')->unsigned()->index();
$table->smallInteger('head_teacher')->unsigned()->index();
$table->smallInteger('director')->unsigned()->index();
$table->smallInteger('created_by')->unsigned();
$table->smallInteger('modified_by')->unsigned();
$table->timestamps();
);
第 2 步:现在将 ENUM 更改为 SET。
$table_prefix = DB::getTablePrefix();
DB::statement("ALTER TABLE `" . $table_prefix . "schools` CHANGE `level` `level` SET('Preschool','Kindergarten','Primary','Secondary');");
如果您有更好的解决方案,请告诉我。
【讨论】:
为什么不在之后添加表格(使用DB::statement
调用)?为什么要添加它,然后再更改它?
@ajon 好问题。我这样做是为了尽量减少DB::statement
的使用。【参考方案2】:
第 1 步。 扩展默认类(将此代码添加到您的迁移文件中 use
部分之后):
class ExtendedBlueprint extends Blueprint
/**
* Create a new set column on the table.
*
* @param string $column
* @param array $allowed
* @return \Illuminate\Support\Fluent
*/
public function set($column, array $allowed)
return $this->addColumn('set', $column, compact('allowed'));
class ExtendedmysqlGrammar extends Illuminate\Database\Schema\Grammars\MySqlGrammar
/**
* Create the column definition for an set type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeSet(\Illuminate\Support\Fluent $column)
return "set('".implode("', '", $column->allowed)."')";
第 2 步。 然后,我们需要将默认语法和蓝图类更改为我们的自定义:
// set new grammar class
DB::connection()->setSchemaGrammar(new ExtendedMySqlGrammar());
// get custom schema object
$schema = DB::connection()->getSchemaBuilder();
// bind new blueprint class
$schema->blueprintResolver(function($table, $callback)
return new ExtendedBlueprint($table, $callback);
);
// then create tables
$schema->create('table name', function(ExtendedBlueprint $table)
$table->increments('id');
$table->text('sentence');
$table->string('author')->nullable();
$table->string('source')->nullable();
$table->set('difficulty', range(1, 10)); // use our new mysql type
$table->boolean('enabled')->default(true);
);
这个方法在composer update
之后也可以使用,因为我们没有编辑任何框架代码。
【讨论】:
执行此操作时出现错误。Argument 1 passed to CreateTableName::closure() must be an instance of ExtendedBlueprint, instance of Illuminate\Database\Schema\Blueprint given
有什么想法吗?我确实在我的创建回调中将 Blueprint 更改为 ExtendedBlueprint。
我想通了。我使用 Schema::create( ... )
而不是 $schema->create( ... )【参考方案3】:
Roman Nazarkin 的方法几乎可以完美运行,但是表前缀存在一个小问题(此方法不考虑),但是让这个建议适用于表前缀很简单:
$grammar = DB::connection()->withTablePrefix(new ExtendedMySqlGrammar());
// set new grammar class
DB::connection()->setSchemaGrammar($grammar);
// get custom schema object
$schema = DB::connection()->getSchemaBuilder();
// bind new blueprint class
$schema->blueprintResolver(function($table, $callback)
return new ExtendedBlueprint($table, $callback);
);
// then create tables
$schema->create('table name', function(ExtendedBlueprint $table)
$table->increments('id');
$table->text('sentence');
$table->string('author')->nullable();
$table->string('source')->nullable();
$table->set('difficulty', range(1, 10)); // use our new mysql type
$table->boolean('enabled')->default(true);
);
【讨论】:
【参考方案4】:扩展 laravel 数据库模式方法并不难。就像 Roman 写的那样,你也可以更新你的
,而不是扩展vendor/laravel/framework/src/Illuminate/Database/Schema/Grammers/MysqlGrammer.php
/**
* Create the column definition for an set type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeSet(Fluent $column)
return "set('".implode("', '", $column->allowed)."')";
vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php
/**
* Create a new set column on the table.
*
* @param string $column
* @param array $allowed
* @return \Illuminate\Support\Fluent
*/
public function set($column, array $allowed)
return $this->addColumn('set', $column, compact('allowed'));
在此之后,按 Ctrl + C 终止您的服务器。然后键入 php artisan serve 启动 laravel。
【讨论】:
【参考方案5】:当您需要创建自定义列而不创建其他文件来描述扩展语法时,我的简单一次性解决方案。在这里,我将自定义类型 rsvp_statuses
添加到 PostgresGrammar
:
public function up()
DB::connection()->setSchemaGrammar(new class extends PostgresGrammar
protected function typeRsvp_statuses(\Illuminate\Support\Fluent $column)
return 'rsvp_statuses';
);
Schema::create('mytable', function (Blueprint $table)
$table->bigIncrements('id');
//...
$table->addColumn('rsvp_statuses', 'status');
$table->timestamps();
);
【讨论】:
【参考方案6】:Laravel 5.8 and onwards 在迁移中支持 SET 数据类型。对于最新版本,您只需使用 set()
函数:
// SET equivalent column named flavors
// Allowed values: strawberry , vanilla
$table->set('flavors', ['strawberry', 'vanilla']);
查看最新文档中的更多详细信息:
https://laravel.com/docs/master/migrations https://laravel.com/api/master/Illuminate/Database/Schema/Blueprint.html#method_set【讨论】:
以上是关于Laravel Schema 中的 MySQL 数据类型 SET 等价物是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel API 的 mysql 查询未在 performance_schema.events_statements_summary_by_digest 中被跟踪
在 MySQL 中更新记录时,Laravel 的 useCurrent() 不起作用