架构系统

CakePHP 提供了一个架构系统,能够反映和生成 SQL 数据存储中表格的架构信息。架构系统可以为 CakePHP 支持的任何 SQL 平台生成/反映架构。

架构系统的主要部分是 Cake\Database\Schema\CollectionCake\Database\Schema\TableSchema。这些类分别为您提供了对数据库范围和单个表格对象功能的访问。

架构系统的主要用途是用于 测试夹具。但是,如果需要,也可以在您的应用程序中使用它。

Schema\TableSchema 对象

class Cake\Database\Schema\TableSchema

架构子系统提供了一个简单的 TableSchema 对象来保存有关数据库中表格的数据。此对象由架构反射功能返回。

use Cake\Database\Schema\TableSchema;

// Create a table one column at a time.
$schema = new TableSchema('posts');
$schema->addColumn('id', [
  'type' => 'integer',
  'length' => 11,
  'null' => false,
  'default' => null,
])->addColumn('title', [
  'type' => 'string',
  'length' => 255,
  // Create a fixed length (char field)
  'fixed' => true
])->addConstraint('primary', [
  'type' => 'primary',
  'columns' => ['id']
]);

// Schema\TableSchema classes could also be created with array data
$schema = new TableSchema('posts', $columns);

Schema\TableSchema 对象允许您构建有关表格架构的信息。它有助于规范和验证用于描述表格的数据。例如,以下两种形式是等效的。

$schema->addColumn('title', 'string');
// and
$schema->addColumn('title', [
  'type' => 'string'
]);

虽然等效,但第二种形式允许更多细节和控制。这模拟了 2.x 中 Schema 文件 + 测试夹具架构中可用的现有功能。

访问列数据

列作为构造函数参数添加,或通过 addColumn() 添加。一旦字段被添加,可以使用 column()columns() 获取信息。

// Get the array of data about a column
$c = $schema->column('title');

// Get the list of all columns.
$cols = $schema->columns();

索引和约束

索引使用 addIndex() 添加。约束使用 addConstraint() 添加。索引和约束不能为不存在的列添加,因为这会导致无效状态。索引不同于约束,如果您尝试在方法之间混合类型,将会引发异常。以下两个方法的示例:

$schema = new TableSchema('posts');
$schema->addColumn('id', 'integer')
  ->addColumn('author_id', 'integer')
  ->addColumn('title', 'string')
  ->addColumn('slug', 'string');

// Add a primary key.
$schema->addConstraint('primary', [
  'type' => 'primary',
  'columns' => ['id']
]);
// Add a unique key
$schema->addConstraint('slug_idx', [
  'columns' => ['slug'],
  'type' => 'unique',
]);
// Add index
$schema->addIndex('slug_title', [
  'columns' => ['slug', 'title'],
  'type' => 'index'
]);
// Add a foreign key
$schema->addConstraint('author_id_idx', [
  'columns' => ['author_id'],
  'type' => 'foreign',
  'references' => ['authors', 'id'],
  'update' => 'cascade',
  'delete' => 'cascade'
]);

如果您将主键约束添加到单个整型列,它将根据数据库平台自动转换为自增/序列列。

$schema = new TableSchema('posts');
$schema->addColumn('id', 'integer')
->addConstraint('primary', [
    'type' => 'primary',
    'columns' => ['id']
]);

在上面的示例中,id 列将在 MySQL 中生成以下 SQL。

CREATE TABLE `posts` (
    `id` INTEGER AUTO_INCREMENT,
    PRIMARY KEY (`id`)
)

如果您的主键包含多个列,那么它们都不会自动转换为自增值。相反,您需要告诉表格对象要将哪个复合键列设置为自增。

$schema = new TableSchema('posts');
$schema->addColumn('id', [
    'type' => 'integer',
    'autoIncrement' => true,
])
->addColumn('account_id', 'integer')
->addConstraint('primary', [
    'type' => 'primary',
    'columns' => ['id', 'account_id']
]);

autoIncrement 选项仅适用于 integerbiginteger 列。

读取索引和约束

可以使用访问器方法从表格对象中读取索引和约束。假设 $schema 是一个已填充的 TableSchema 实例,您可以执行以下操作。

// Get constraints. Will return the
// names of all constraints.
$constraints = $schema->constraints()

// Get data about a single constraint.
$constraint = $schema->constraint('author_id_idx')

// Get indexes. Will return the
// names of all indexes.
$indexes = $schema->indexes()

// Get data about a single index.
$index = $schema->index('author_id_idx')

添加表选项

一些驱动程序(主要是 MySQL)支持并需要额外的表格元数据。在 MySQL 的情况下,CHARSETCOLLATEENGINE 属性是维护 MySQL 中表格结构所必需的。可以使用以下方法添加表选项。

$schema->options([
  'engine' => 'InnoDB',
  'collate' => 'utf8_unicode_ci',
]);

平台方言只处理它们感兴趣的键,而忽略其余的键。并非所有选项都在所有平台上都受支持。

将表格转换为 SQL

使用 createSql()dropSql(),您可以获取特定平台的 SQL 代码,用于创建或删除特定表格。

$db = ConnectionManager::get('default');
$schema = new TableSchema('posts', $fields, $indexes);

// Create a table
$queries = $schema->createSql($db);
foreach ($queries as $sql) {
  $db->execute($sql);
}

// Drop a table
$sql = $schema->dropSql($db);
$db->execute($sql);

通过使用连接的驱动程序,架构数据可以转换为特定平台的 SQL 代码。createSqldropSql 的返回值是创建表格和所需索引所需的 SQL 查询列表。一些平台可能需要多个语句来创建带有注释和/或索引的表格。始终返回一个查询数组。

架构集合

class Cake\Database\Schema\Collection

Collection 提供了对连接中可用表格的访问。您可以使用它来获取表格列表或将表格反映到 TableSchema 对象中。类的基本用法如下所示。

$db = ConnectionManager::get('default');

// Create a schema collection.
$collection = $db->getSchemaCollection();

// Get the table names
$tables = $collection->listTables();

// Get a single table (instance of Schema\TableSchema)
$tableSchema = $collection->describe('posts');