ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] # 数据库迁移 迁移是一种以结构化和有组织的方式更改数据库的便捷方式。 >[danger] Phalcon开发者工具中提供了迁移您至少需要Phalcon Framework 0.5.0才能使用开发人员工具。 通常在开发中,我们需要更新生产环境中的更改。其中一些更改可能是数据库修改,如新字段,新表,删除索引等。 生成迁移时,会创建一组类来描述在特定时刻数据库的结构。这些类可用于同步远程数据库上的模式结构,使您的数据库可以使用应用程序实现的新更改。迁移使用普通PHP描述这些转换。 ## 架构转储 [Phalcon开发者工具](https://github.com/phalcon/docs/blob/3.3/zh/devtools-usage.md) 提供了用于管理迁移(生成,运行和回滚)的脚本。 用于生成迁移的可用选项包括: ![](https://docs.phalconphp.com/images/content/migrations-1.png) 在没有任何参数的情况下运行此脚本只会将数据库中的每个对象(表和视图)转储到迁移类中。 每个迁移都有一个与之关联的版本标识符。版本号允许我们确定迁移是否比我们数据库的当前“版本”更新或更旧。版本还将在执行迁移时通知Phalcon正在运行的订单。 ![](https://docs.phalconphp.com/images/content/migrations-2.png) 生成迁移时,控制台上会显示说明,以描述迁移的不同步骤和这些语句的执行时间。最后,生成迁移版本。 默认情况下,Phalcon开发者工具使用`app/migrations`目录转储迁移文件。您可以通过在生成脚本上设置其中一个参数来更改位置。数据库中的每个表都在一个分隔文件中生成其各自的类,该文件位于引用其版本的目录下: ![](https://docs.phalconphp.com/images/images/content/migrations-2.png) ## 迁移类解剖 每个文件都包含一个扩展`Phalcon\Mvc\Model\Migration`类的唯一类。这些类通常有两种方法:`up()`和`down()`。`up()`执行迁移,而`down()`将其回滚。 `up()` 还包含magic方法`morphTable()`。当它识别出将数据库中的实际表与给定描述同步所需的更改时,就会产生魔术方法。 ```php <?php use Phalcon\Db\Column as Column; use Phalcon\Db\Index as Index; use Phalcon\Db\Reference as Reference; use Phalcon\Mvc\Model\Migration; class ProductsMigration_100 extends Migration { public function up() { $this->morphTable( 'products', [ 'columns' => [ new Column( 'id', [ 'type' => Column::TYPE_INTEGER, 'size' => 10, 'unsigned' => true, 'notNull' => true, 'autoIncrement' => true, 'first' => true, ] ), new Column( 'product_types_id', [ 'type' => Column::TYPE_INTEGER, 'size' => 10, 'unsigned' => true, 'notNull' => true, 'after' => 'id', ] ), new Column( 'name', [ 'type' => Column::TYPE_VARCHAR, 'size' => 70, 'notNull' => true, 'after' => 'product_types_id', ] ), new Column( 'price', [ 'type' => Column::TYPE_DECIMAL, 'size' => 16, 'scale' => 2, 'notNull' => true, 'after' => 'name', ] ), ], 'indexes' => [ new Index( 'PRIMARY', [ 'id', ] ), new Index( 'product_types_id', [ 'product_types_id', ] ), ], 'references' => [ new Reference( 'products_ibfk_1', [ 'referencedSchema' => 'invo', 'referencedTable' => 'product_types', 'columns' => ['product_types_id'], 'referencedColumns' => ['id'], ] ), ], 'options' => [ 'TABLE_TYPE' => 'BASE TABLE', 'ENGINE' => 'InnoDB', 'TABLE_COLLATION' => 'utf8_general_ci', ], ] ); } } ``` 该类称为`ProductsMigration_100`。后缀100指的是版本1.0.0。`morphTable()` 接收一个包含4个可能部分的关联数组: | Index | 描述 | 是否可选 | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |:--------:| | `columns` | 带有一组表列的数组 | No | | `indexes` | 包含一组表索引的数组。 | Yes | | `references` |带有一组表引用(外键)的数组。 | Yes | | `options` | 包含一组表创建选项的数组。这些选项通常与生成迁移的数据库系统相关。| Yes | ### 列定义 `Phalcon\Db\Column` 用于定义表列。它封装了各种与列相关的功能。它的构造函数接收列名称和描述列的数组作为第一个参数。描述列时可以使用以下选项: | 选项 | 描述 | 是否可选 | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |:--------:| | `type` | 列类型。必须是`Phalcon\Db\Column` 常量(见下文) | No | | `size` | 某些类型的列(如`VARCHAR`或`INTEGER`)可能具有特定大小 | Yes | | `scale` | `DECIMAL` 或 `NUMBER` 列可以有一个比例来指定它必须存储多少小数 | Yes | | `unsigned` | `INTEGER` 列可以是有符号或无符号的。此选项不适用于其他类型的列 | Yes | | `notNull` | 列可以存储 null 值吗? | Yes | | `default` | 定义列的默认值(只能是实际值,而不是 `NOW()`等函数)) | Yes | | `autoIncrement` | 使用此属性列将自动填充自动增量整数。表中只有一列可以具有此属性。| Yes | | `primary` | 使用`columnName_pkey` 作为标识符将此列设置为主键索引。类型 - `BOOLEAN` | Yes | | `first` | 列必须按列顺序放置在第一个位置 | Yes | | `after` | 必须在指定的列之后放置 | Yes | 数据库迁移支持以下数据库列类型: * `Phalcon\Db\Column::TYPE_INTEGER` * `Phalcon\Db\Column::TYPE_VARCHAR` * `Phalcon\Db\Column::TYPE_CHAR` * `Phalcon\Db\Column::TYPE_DATE` * `Phalcon\Db\Column::TYPE_DATETIME` * `Phalcon\Db\Column::TYPE_TIMESTAMP` * `Phalcon\Db\Column::TYPE_DECIMAL` * `Phalcon\Db\Column::TYPE_TEXT` * `Phalcon\Db\Column::TYPE_BOOLEAN` * `Phalcon\Db\Column::TYPE_FLOAT` * `Phalcon\Db\Column::TYPE_DOUBLE` * `Phalcon\Db\Column::TYPE_TINYBLOB` * `Phalcon\Db\Column::TYPE_BLOB` * `Phalcon\Db\Column::TYPE_MEDIUMBLOB` * `Phalcon\Db\Column::TYPE_LONGBLOB` * `Phalcon\Db\Column::TYPE_JSON` * `Phalcon\Db\Column::TYPE_JSONB` * `Phalcon\Db\Column::TYPE_BIGINTEGER` ### 索引定义 `Phalcon\Db\Index` 定义表索引。索引仅要求您为其定义名称及其列的列表。请注意,如果任何索引的名称为`PRIMARY`,Phalcon将为该表创建主键索引。 ### 引用定义 `Phalcon\Db\Reference` 定义表引用(也称为外键)。以下选项可用于定义引用: | Index | 描述 | 是否可选 | 作用于 | | ------------------- | --------------------------------------------------------------------------------------------------- |:--------:| ---------------- | | `referencedTable` | 它是自动描述性的。它指的是引用表的名称。 | No | All | | `columns` | 一个数组,其中包含表中具有引用的列的名称| No | All | | `referencedColumns` | 一个数组,其中包含引用表中列的名称 | No | All | | `referencedSchema` | 引用的表可能在另一个模式或数据库上。此选项允许您定义它。 | Yes | All | | `onDelete` | 如果删除了外部记录,请在本地记录上执行此操作。 | Yes | MySQL PostgreSQL | | `onUpdate` | 如果更新了外部记录,请对本地记录执行此操作。 | Yes | MySQL PostgreSQL | ## 编写迁移 迁移不仅设计为“变形”表。迁移只是一个常规的PHP类,因此您不仅限于这些函数。例如,在添加列之后,您可以编写代码来为现有记录设置该列的值。有关各个方法的更多详细信息和示例,请检查数据库组件。 ```php <?php use Phalcon\Mvc\Model\Migration; class ProductsMigration_100 extends Migration { public function up() { // ... self::$_connection->insert( 'products', [ 'Malabar spinach', 14.50, ], [ 'name', 'price', ] ); } } ``` ## 运行迁移 生成的迁移在目标服务器上上传后,您可以轻松运行它们,如以下示例所示: ![](https://docs.phalconphp.com/images/content/migrations-4.png) ![](https://docs.phalconphp.com/images/content/migrations-5.png) 根据数据库在迁移方面的过时程度,Phalcon可能会在同一迁移过程中运行多个迁移版本。如果指定目标版本,Phalcon将运行所需的迁移,直到达到指定的版本。