数据库 Forge 类

数据库 Forge 类包含帮助你管理数据库的方法。

初始化 Forge 类

重要

为了初始化 Forge 类,你的数据库驱动程序必须已经运行,因为 Forge 类依赖于它。

如下加载 Forge 类:

<?php

$forge = \Config\Database::forge();

你也可以向 DB Forge 加载器传递另一个数据库组名称,以防要管理的数据库不是默认数据库:

<?php

$this->myforge = \Config\Database::forge('other_db');

在上面的示例中,我们正在作为第一个参数传递一个不同的数据库组名称进行连接。

创建和删除数据库

$forge->createDatabase(‘db_name’)

允许你创建第一个参数中指定的数据库。基于成功或失败返回 true/false:

<?php

if ($forge->createDatabase('my_db')) {
    echo 'Database created!';
}

可选的第二个参数设置为 true 将添加 IF EXISTS 语句或检查数据库是否存在,然后再创建它(取决于 DBMS)。

<?php

$forge->createDatabase('my_db', true);
/*
 * gives CREATE DATABASE IF NOT EXISTS `my_db`
 * or will check if a database exists
 */

$forge->dropDatabase(‘db_name’)

允许你删除第一个参数中指定的数据库。基于成功或失败返回 true/false:

<?php

if ($forge->dropDatabase('my_db')) {
    echo 'Database deleted!';
}

在命令行中创建数据库

CodeIgniter 支持直接从喜欢的终端使用专用的 db:create 命令创建数据库。通过使用此命令,假定数据库还不存在。否则,CodeIgniter 将抱怨数据库创建失败。

首先,只需键入命令和数据库名称(例如 foo):

php spark db:create foo

如果一切顺利,你应该会看到显示的 Database "foo" successfully created. 消息。

如果你在测试环境中或正在使用 SQLite3 驱动程序,可以使用 --ext 选项 为将创建数据库的文件传递文件扩展名。有效值为 dbsqlite,默认为 db。请记住,这些前面不应有句点。 :

php spark db:create foo --ext sqlite

上述命令将创建名为 WRITEPATH/foo.sqlite 的数据库文件。

备注

当使用特殊的 SQLite3 数据库名称 :memory: 时,请注意命令仍会生成成功消息,但不会创建数据库文件。这是因为 SQLite3 将只使用内存中的数据库。

创建表

在创建表时,你可能希望执行几件事。添加字段、向表添加键、更改列。CodeIgniter 为此提供了一种机制。

添加字段

$forge->addField()

字段通常通过关联数组创建。在数组中,你必须包含与字段的数据类型相关的 type 键。

例如, INTVARCHARTEXT 等。许多数据类型(例如 VARCHAR)还需要一个 constraint 键。

<?php

$fields = [
    'users' => [
        'type'       => 'VARCHAR',
        'constraint' => 100,
    ],
];
// will translate to "users VARCHAR(100)" when the field is added.

另外,可以使用以下键/值:

  • unsigned/true : 在字段定义中生成 UNSIGNED

  • default/value : 在字段定义中生成 DEFAULT 约束。

  • null/true : 在字段定义中生成 null。如果不指定,字段将默认为 NOT null

  • auto_increment/true : 在字段上生成 auto_increment 标志。请注意,字段类型必须是支持这一点的类型,如 INTEGER

  • unique/true : 为字段定义生成唯一键。

<?php

$fields = [
    'id' => [
        'type'           => 'INT',
        'constraint'     => 5,
        'unsigned'       => true,
        'auto_increment' => true,
    ],
    'title' => [
        'type'       => 'VARCHAR',
        'constraint' => '100',
        'unique'     => true,
    ],
    'author' => [
        'type'       => 'VARCHAR',
        'constraint' => 100,
        'default'    => 'King of Town',
    ],
    'description' => [
        'type' => 'TEXT',
        'null' => true,
    ],
    'status' => [
        'type'       => 'ENUM',
        'constraint' => ['publish', 'pending', 'draft'],
        'default'    => 'pending',
    ],
];
$forge->addField($fields);

在定义了字段后,可以使用 $forge->addField($fields) 后跟对 createTable() 方法的调用来添加它们。

关于数据类型的注解

浮点类型

浮点类型,如 FLOATDOUBLE,表示的是近似值。因此,当需要精确值时,不应使用它们。

mysql> CREATE TABLE t (f FLOAT, d DOUBLE);
mysql> INSERT INTO t VALUES(99.9, 99.9);

mysql> SELECT * FROM t WHERE f=99.9;
Empty set (0.00 sec)

mysql> SELECT * FROM t WHERE f > 99.89 AND f < 99.91;
+------+------+
| f    | d    |
+------+------+
| 99.9 | 99.9 |
+------+------+
1 row in set (0.01 sec)

当需要保存精确的精度时,例如在处理货币数据,应使用 DECIMALNUMERIC

TEXT

SQLSRV 上不应使用 TEXT,它已被弃用。 欲知详情,请参见 ntext, text, 和 image (Transact-SQL) - SQL Server | Microsoft Learn

作为默认值的原始 SQL 字符串

在 4.2.0 版本加入.

从 v4.2.0 开始, $forge->addField() 接受一个 CodeIgniter\Database\RawSql 实例,它表示原始 SQL 字符串。

<?php

use CodeIgniter\Database\RawSql;

$fields = [
    'id' => [
        'type'           => 'INT',
        'constraint'     => 5,
        'unsigned'       => true,
        'auto_increment' => true,
    ],
    'created_at' => [
        'type'    => 'TIMESTAMP',
        'default' => new RawSql('CURRENT_TIMESTAMP'),
    ],
];
$forge->addField($fields);
/*
gives:
    "id" INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
    "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
*/

警告

当你使用 RawSql 时,必须手动对数据进行转义。否则可能会导致 SQL 注入。

作为字段传递字符串

如果确切知道如何创建字段,可以将字符串传递到 addField() 中的字段定义中:

<?php

$forge->addField("label varchar(100) NOT NULL DEFAULT 'default label'");

备注

不能在传递原始字符串作为字段后对这些字段调用 addKey()

备注

addField() 的多次调用是累积的。

创建 id 字段

创建 id 字段有一个特殊的例外。类型为 id 的字段将自动被赋值为 INT(9) 自增主键。

<?php

$forge->addField('id');
// gives `id` INT(9) NOT NULL AUTO_INCREMENT

添加键

$forge->addKey()

通常,你会希望表具有键。这是通过 $forge->addKey('field') 完成的。可选的第二个参数设置为 true 将使其成为主键,第三个参数设置为 true 将使其成为唯一键。你可以使用第四个参数指定名称。请注意, addKey() 必须在表已存在的情况下后跟对 createTable()processIndexes() 的调用。

多个非主键列必须作为数组发送。以下为 MySQL 的示例输出。

<?php

$forge->addKey('blog_id', true);
// gives PRIMARY KEY `blog_id` (`blog_id`)

$forge->addKey('blog_id', true);
$forge->addKey('site_id', true);
// gives PRIMARY KEY `blog_id_site_id` (`blog_id`, `site_id`)

$forge->addKey('blog_name');
// gives KEY `blog_name` (`blog_name`)

$forge->addKey(['blog_name', 'blog_label'], false, false, 'my_key_name');
// gives KEY `my_key_name` (`blog_name`, `blog_label`)

$forge->addKey(['blog_id', 'uri'], false, true, 'my_key_name');
// gives UNIQUE KEY `my_key_name` (`blog_id`, `uri`)

$forge->addPrimaryKey()

$forge->addUniqueKey()

为了使代码更易读,也可以使用特定方法添加主键和唯一键:

<?php

$forge->addPrimaryKey('blog_id', 'pd_name');
// gives PRIMARY KEY `pd_name` (`blog_id`)

$forge->addUniqueKey(['blog_id', 'uri'], 'key_name');
// gives UNIQUE KEY `key_name` (`blog_id`, `uri`)

备注

当你添加主键时,即使提供了名称,MySQL 和 SQLite 也会假定名称为 PRIMARY

添加外键

外键有助于在表之间强制关系和操作。对于支持外键的表,可以直接在 forge 中添加它们:

<?php

$forge->addForeignKey('users_id', 'users', 'id');
// gives CONSTRAINT `TABLENAME_users_id_foreign` FOREIGN KEY(`users_id`) REFERENCES `users`(`id`)

$forge->addForeignKey(['users_id', 'users_name'], 'users', ['id', 'name']);
// gives CONSTRAINT `TABLENAME_users_id_foreign` FOREIGN KEY(`users_id`, `users_name`) REFERENCES `users`(`id`, `name`)

你还可以指定约束的“更新时”和“删除时”属性的所需操作以及名称:

<?php

$forge->addForeignKey('users_id', 'users', 'id', 'CASCADE', 'CASCADE', 'my_fk_name');
// gives CONSTRAINT `my_fk_name` FOREIGN KEY(`users_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE CASCADE

$forge->addForeignKey('users_id', 'users', 'id', '', 'CASCADE');
// gives CONSTRAINT `TABLENAME_users_foreign` FOREIGN KEY(`users_id`) REFERENCES `users`(`id`) ON DELETE CASCADE

$forge->addForeignKey(['users_id', 'users_name'], 'users', ['id', 'name'], 'CASCADE', 'CASCADE', 'my_fk_name');
// gives CONSTRAINT `my_fk_name` FOREIGN KEY(`users_id`, `users_name`) REFERENCES `users`(`id`, `name`) ON DELETE CASCADE ON UPDATE CASCADE

备注

SQLite3 不支持命名外键。CodeIgniter 将引用它们的 prefix_table_column_foreign

创建表格

在声明字段和键之后,可以使用以下方法创建新表格

<?php

$forge->createTable('table_name');
// gives CREATE TABLE table_name

可选的第二个参数设置为 true 将只在表不存在时创建该表。

<?php

$forge->createTable('table_name', true);
// creates table only if table does not exist

你也可以传递可选的表属性,例如 MySQL 的 ENGINE:

<?php

$attributes = ['ENGINE' => 'InnoDB'];
$forge->createTable('table_name', false, $attributes);
// produces: CREATE TABLE `table_name` (...) ENGINE = InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci

备注

除非指定了 CHARACTER SET 和/或 COLLATE 属性,否则 createTable() 将始终使用配置的 charsetDBCollat 值添加它们,只要它们不为空(仅限 MySQL)。

删除表

删除一张表

执行 DROP TABLE 语句,并可选地添加 IF EXISTS 子句。

<?php

// Produces: DROP TABLE `table_name`
$forge->dropTable('table_name');

// Produces: DROP TABLE IF EXISTS `table_name`
$forge->dropTable('table_name', true);

可以传递第三个参数以添加 CASCADE 选项,某些驱动程序可能需要它来处理具有外键的表的删除。

<?php

// Produces: DROP TABLE `table_name` CASCADE
$forge->dropTable('table_name', false, true);

修改表

向表中添加字段

$forge->addColumn()

addColumn() 方法用于修改现有表。它接受与 创建表 相同的字段数组,可用于添加其他字段。

备注

与创建表不同,如果未指定 null,列将为 NULL,而不是 NOT NULL

<?php

$fields = [
    'preferences' => ['type' => 'TEXT'],
];
$forge->addColumn('table_name', $fields);
// Executes: ALTER TABLE `table_name` ADD `preferences` TEXT

如果使用 MySQL 或 CUBIRD,则可以利用它们的 AFTERFIRST 子句来定位新列。

例子:

<?php

// Will place the new column after the `another_field` column:
$fields = [
    'preferences' => ['type' => 'TEXT', 'after' => 'another_field'],
];

// Will place the new column at the start of the table definition:
$fields = [
    'preferences' => ['type' => 'TEXT', 'first' => true],
];

从表中删除字段

$forge->dropColumn()

用于从表中删除列。

<?php

$forge->dropColumn('table_name', 'column_to_drop'); // to drop one single column

用于从表中删除多个列。

<?php

$forge->dropColumn('table_name', 'column_1,column_2');      // by proving comma separated column names
$forge->dropColumn('table_name', ['column_1', 'column_2']); // by proving array of column names

修改表中的字段

$forge->modifyColumn()

此方法的使用与 addColumn() 相同,只是它更改现有列而不是添加新列。为了更改名称,可以将“name”键添加到定义字段的数组中。

<?php

$fields = [
    'old_name' => [
        'name' => 'new_name',
        'type' => 'TEXT',
        'null' => false,
    ],
];
$forge->modifyColumn('table_name', $fields);
// gives ALTER TABLE `table_name` CHANGE `old_name` `new_name` TEXT NOT NULL

备注

modifyColumn() 可能会意外地更改 NULL/NOT NULL。因此,建议始终为 null 键指定值。与创建表不同,如果未指定 null,列将为 NULL,而不是 NOT NULL

备注

由于一个错误,在 v4.3.4 之前,即使指定 'null' => false,SQLite3 也可能不设置 NOT NULL

备注

由于一个错误,在 v4.3.4 之前,Postgres 和 SQLSRV 即使指定 'null' => true 也会设置 NOT NULL

向表添加键

在 4.3.0 版本加入.

你可以通过使用 addKey()addPrimaryKey()addUniqueKey()addForeignKey()processIndexes() 向现有表添加键:

<?php

$this->forge->addKey(['category', 'name'], false, false, 'category_name');
$this->forge->addPrimaryKey('id', 'pk_actions');
$this->forge->addForeignKey('userid', 'user', 'id', '', '', 'userid_fk');
$this->forge->processIndexes('actions');
/* gives:
ALTER TABLE `actions` ADD KEY `category_name` (`category`, `name`);
ALTER TABLE `actions` ADD CONSTRAINT `pk_actions` PRIMARY KEY(`id`);
ALTER TABLE `actions` ADD CONSTRAINT `userid_fk` FOREIGN KEY (`userid`) REFERENCES `user`(`id`);
*/

删除主键

在 4.3.0 版本加入.

执行 DROP PRIMARY KEY。

<?php

// MySQLi Produces: ALTER TABLE `tablename` DROP PRIMARY KEY
// Others Produces: ALTER TABLE `tablename` DROP CONSTRAINT `pk_tablename`
$forge->dropPrimaryKey('tablename');

删除键

执行 DROP KEY。

<?php

// For Indexes Produces:        DROP INDEX `users_index` ON `tablename`
// For Unique Indexes Produces: ALTER TABLE `tablename` DROP CONSTRAINT `users_index`
$forge->dropKey('tablename', 'users_index', false);

删除外键

执行 DROP FOREIGN KEY。

<?php

// Produces: ALTER TABLE `tablename` DROP FOREIGN KEY `users_foreign`
$forge->dropForeignKey('tablename', 'users_foreign');

重命名表

执行 TABLE RENAME

<?php

$forge->renameTable('old_table_name', 'new_table_name');
// gives ALTER TABLE `old_table_name` RENAME TO `new_table_name`

类参考

class CodeIgniter\Database\Forge
addColumn($table[, $field = []])
参数:
  • $table (string) – 要向其中添加列的表名

  • $field (array) – 列定义

返回:

成功则为 true,失败则为 false

返回类型:

bool

向现有表添加列。用法:参见 向表中添加字段.

addField($field)
参数:
  • $field (array) – 要添加的字段定义

返回:

\CodeIgniter\Database\Forge 实例(方法链)

返回类型:

\CodeIgniter\Database\Forge

将用于创建表的字段添加到集合中。用法:参见 添加字段

addForeignKey($fieldName, $tableName, $tableField[, $onUpdate = '', $onDelete = '', $fkName = ''])
参数:
  • $fieldName (string|string[]) – 键字段的名称或字段数组

  • $tableName (string) – 父表的名称

  • $tableField (string|string[]) – 父表字段的名称或字段数组

  • $onUpdate (string) – “更新时”的所需操作

  • $onDelete (string) – “删除时”的所需操作

  • $fkName (string) – 外键的名称。这与 SQLite3 不兼容

返回:

\CodeIgniter\Database\Forge 实例(方法链)

返回类型:

\CodeIgniter\Database\Forge

将用于创建表的外键添加到集合中。用法:参见 添加外键

备注

从 v4.3.0 开始可以使用 $fkName

addKey($key[, $primary = false[, $unique = false[, $keyName = '']]])
参数:
  • $key (mixed) – 键字段的名称或字段数组

  • $primary (bool) – 设置为 true 将其设置为主键,否则设置为常规键

  • $unique (bool) – 设置为 true 将其设置为唯一键,否则设置为常规键

  • $keyName (string) – 要添加的键的名称

返回:

\CodeIgniter\Database\Forge 实例(方法链)

返回类型:

\CodeIgniter\Database\Forge

将用于创建表的键添加到集合中。用法:参见 添加键

备注

从 v4.3.0 开始可以使用 $keyName

addPrimaryKey($key[, $keyName = ''])
参数:
  • $key (mixed) – 键字段的名称或字段数组

  • $keyName (string) – 要添加的键的名称

返回:

\CodeIgniter\Database\Forge 实例(方法链)

返回类型:

\CodeIgniter\Database\Forge

将用于创建表的主键添加到集合中。用法:参见 添加键

备注

从 v4.3.0 开始可以使用 $keyName

addUniqueKey($key[, $keyName = ''])
参数:
  • $key (mixed) – 键字段的名称或字段数组

  • $keyName (string) – 要添加的键的名称

返回:

\CodeIgniter\Database\Forge 实例(方法链)

返回类型:

\CodeIgniter\Database\Forge

将用于创建表的唯一键添加到集合中。用法:参见 添加键

备注

从 v4.3.0 开始可以使用 $keyName

createDatabase($dbName[, $ifNotExists = false])
参数:
  • $db_name (string) – 要创建的数据库名称

  • $ifNotExists (string) – 设置为 true 将添加 IF NOT EXISTS 子句或检查数据库是否存在

返回:

成功则为 true,失败则为 false

返回类型:

bool

创建新数据库。用法:参见 创建和删除数据库

createTable($table[, $if_not_exists = false[, array $attributes = []]])
参数:
  • $table (string) – 要创建的表的名称

  • $if_not_exists (string) – 设置为 true 将添加 IF NOT EXISTS 子句

  • $attributes (string) – 表属性的关联数组

返回:

成功则为查询对象,失败则为 false

返回类型:

mixed

创建新表。用法:参见 创建表格

dropColumn($table, $column_name)
参数:
  • $table (string) – 表名

  • $column_names (mixed) – 逗号分隔的字符串或列名称数组

返回:

成功则为 true,失败则为 false

返回类型:

bool

从表中删除单个或多个列。用法:参见 从表中删除字段

dropDatabase($dbName)
参数:
  • $dbName (string) – 要删除的数据库名称

返回:

成功则为 true,失败则为 false

返回类型:

bool

删除数据库。用法:参见 创建和删除数据库

dropKey($table, $keyName[, $prefixKeyName = true])
参数:
  • $table (string) – 具有键的表的名称

  • $keyName (string) – 要删除的键的名称

  • $prefixKeyName (string) – 是否要添加数据库前缀到 $keyName

返回:

成功则为 true,失败则为 false

返回类型:

bool

删除索引或唯一索引。

备注

从 v4.3.0 开始可以使用 $keyName$prefixKeyName

dropPrimaryKey($table[, $keyName = ''])
参数:
  • $table (string) – 要删除主键的表的名称

  • $keyName (string) – 要删除的主键的名称

返回:

成功则为 true,失败则为 false

返回类型:

bool

从表中删除主键。

备注

从 v4.3.0 开始可以使用 $keyName

dropTable($table_name[, $if_exists = false])
参数:
  • $table (string) – 要删除的表的名称

  • $if_exists (string) – 设置为 true 将添加 IF EXISTS 子句

返回:

成功则为 true,失败则为 false

返回类型:

bool

删除表。用法:参见 删除一张表

processIndexes($table)

在 4.3.0 版本加入.

参数:
  • $table (string) – 要向其中添加索引的表的名称

返回:

成功则为 true,失败则为 false

返回类型:

bool

跟在 addKey()addPrimaryKey()addUniqueKey()addForeignKey() 之后, 向已有表添加索引。参见 向表添加键

modifyColumn($table, $field)
参数:
  • $table (string) – 表名

  • $field (array) – 列定义

返回:

成功则为 true,失败则为 false

返回类型:

bool

修改表列。用法:参见 修改表中的字段

renameTable($table_name, $new_table_name)
参数:
  • $table (string) – 表的当前名称

  • $new_table_name (string) – 表的新名称

返回:

成功则为查询对象,失败则为 false

返回类型:

mixed

重命名表。用法:参见 重命名表