数据库 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 中创建 db 文件。

注意

当使用特殊的 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:在字段上生成一个自动递增标志。请注意,字段类型必须是支持此功能的类型,例如 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

TEXT 不应该在 SQLSRV 上使用。它已弃用。请参阅 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`)

您可以指定约束的“on update”和“on delete”属性以及名称的所需操作。

<?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() 将始终使用您配置的 *charset* 和 *DBCollat* 值添加它们,只要它们不为空(仅限 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

注意

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

注意

由于一个 bug,在 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 重命名。

<?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

向用于创建表的集合中添加一个外键。用法:参见 添加外键

注意

$fkName 可从 v4.3.0 版本开始使用。

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

  • $primary (bool) – 设置为 true 表示它是主键,否则为普通键

  • $unique (bool) – 设置为 true 表示它是唯一键,否则为普通键

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

返回值:

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

返回类型:

\CodeIgniter\Database\Forge

向用于创建表的集合中添加一个键。用法:参见 添加键

注意

$keyName 可从 v4.3.0 版本开始使用。

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

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

返回值:

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

返回类型:

\CodeIgniter\Database\Forge

向用于创建表的集合中添加一个主键。用法:参见 添加键

注意

$keyName 可从 v4.3.0 版本开始使用。

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

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

返回值:

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

返回类型:

\CodeIgniter\Database\Forge

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

注意

$keyName 可从 v4.3.0 版本开始使用。

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

返回类型:

混合类型

创建一个新表。用法:参见 创建表

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

删除索引或唯一索引。

注意

$keyName$prefixKeyName 可从 v4.3.0 版本开始使用。

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

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

返回值:

成功返回 true,失败返回 false

返回类型:

bool

从表中删除主键。

注意

$keyName 可从 v4.3.0 版本开始使用。

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

返回类型:

混合类型

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