数据库 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
选项
为将创建数据库的文件传递文件扩展名。有效值为 db
和 sqlite
,默认为 db
。请记住,这些前面不应有句点。
:
php spark db:create foo --ext sqlite
上述命令将创建名为 WRITEPATH/foo.sqlite 的数据库文件。
备注
当使用特殊的 SQLite3 数据库名称 :memory:
时,请注意命令仍会生成成功消息,但不会创建数据库文件。这是因为 SQLite3 将只使用内存中的数据库。
创建表
在创建表时,你可能希望执行几件事。添加字段、向表添加键、更改列。CodeIgniter 为此提供了一种机制。
添加字段
$forge->addField()
字段通常通过关联数组创建。在数组中,你必须包含与字段的数据类型相关的 type
键。
例如, INT
、VARCHAR
、TEXT
等。许多数据类型(例如 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() 方法的调用来添加它们。
关于数据类型的注解
浮点类型
浮点类型,如 FLOAT
和 DOUBLE
,表示的是近似值。因此,当需要精确值时,不应使用它们。
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)
当需要保存精确的精度时,例如在处理货币数据,应使用 DECIMAL
或 NUMERIC
。
TEXT
SQLSRV 上不应使用 TEXT
,它已被弃用。
欲知详情,请参见 ntext, text, 和 image (Transact-SQL) - SQL Server | Microsoft Learn。
ENUM
并非所有数据库都支持 ENUM
。
从 v4.5.0 开始,SQLSRV
Forge 会将 ENUM
数据类型转换为 VARCHAR(n)
。
之前的版本转换为 TEXT
。
作为默认值的原始 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 utf8mb4 COLLATE utf8mb4_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,则可以利用它们的 AFTER
和 FIRST
子句来定位新列。
例子:
<?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()
之后, 向已有表添加索引。参见 向表添加键。