在 5.1
版本中增加了多种数据库协程客户端的支持,并且全部以 PDO
接口的方式提供,旧的业务代码无需做任何更改即可一键切换为协程模式,异步非阻塞地并发执行。
包括:
pdo_pgsql
pdo_odbc
pdo_sqlite
pdo_oci
(Oracle
数据库)
开启方法
增加了 4
个编译参数和 Runtime Hook
选项,开启这些协程客户端。
编译选项
--with-swoole-odbc
,依赖unixodbc-dev
--with-swoole-pgsql
,依赖libpq-dev
--with-swoole-sqlite
,依赖libsqlite3-dev
--with-swoole-oracle
,依赖oracle-instantclient
Runtime Hook
选项
SWOOLE_HOOK_PDO_PGSQL
SWOOLE_HOOK_PDO_ODBC
SWOOLE_HOOK_PDO_SQLITE
SWOOLE_HOOK_PDO_ORACLE
这些选项已包含在 SWOOLE_HOOK_ALL
中,也可单独启用其中一个客户端。
PDO_PGSQL
在之前的版本中,提供了 Swoole\Coroutine\PostgreSQL
客户,由于是全新的 API
,用户需要兼容 PHP-FPM
和 Swoole
,使用并不广泛。
go(function () {
$pg = new Swoole\Coroutine\PostgreSql();
$conn = $pg->connect("host=127.0.0.1 port=5432 dbname=test user=test password=");
$result = $pg->query($conn, 'SELECT * FROM test;');
$arr = $pg->fetchAll($result);
var_dump($arr);
});
5.1
版本中增加了 Runtime Hook PDO_PGSQL
,可以直接使用 FPM
下的历史代码。
go(function () {
$pdo = new PDO("pgsql:host={$host};port={$port};dbname={$dbname}", $user, $password);
$statement = $pdo->query('select * from user where id =1 limit 1');
var_dump($statement->fetch(PDO::FETCH_ASSOC));
});
PDO_ODBC
ODBC
(Open Database Connectivity
)是一种为多种数据库管理系统提供统一接口的标准化技术。它是由微软公司提出的,目的是为了实现异构性,使得应用程序能够访问多种不同类型的数据源。 ODBC
的标准定义了应用程序发出请求的 API
,以及由驱动程序提供的响应请求的 API
。ODBC
是一种开放的、跨平台的技术,可以在多种操作系统和编程语言中使用。
绝大多数关系型数据库都支持 ODBC
驱动,其中包括:
Microsoft SQL Server
Oracle
IBM DB2
MySQL
PostgreSQL
SQLite
Teradata
Microsoft Access
SAP Sybase Adaptive Server Enterprise (ASE)
Informix
这些数据库使用 ODBC
驱动程序来提供访问接口,从而使开发人员可以在使用不同的数据库时使用相同的代码访问数据。
5.1
版本支持了 PDO_ODBC
的协程化支持,借助 ODBC
几乎可以支持所有数据库,使得这些数据库也可以运行在 Swoole
协程模式下。
在 Linux
下需要安装 unixodbc
库来支持 odbc
sudo apt install unixodbc-dev
与其他数据库驱动不同,odbc
需要先使用 odbcinst
工具注册数据库。在 Linux
下要配置 /etc/odbcinst.ini
文件实现。
odbcinst.ini
[mysql]
Driver=libmaodbc.so
Description=MariaDB Connector/ODBC(Unicode)
Threading=0
UsageCount=1
配置文件放置于 /etc/odbcinst.ini
,Driver=libmaodbc.so
就是告诉 odbc
使用这个动态链接库作为驱动层。
若要支持其他更多数据库类型,就需要安装该数据库的 ODBC
驱动。例如 MySQL ODBC
驱动可以使用 odbc-mariadb
sudo apt install odbc-mariadb
执行成功后,就会安装 libmaodbc.so
到系统库目录中。
mysql_odbc.ini
注册数据库到 ODBC
,需要编写一份配置文件,包含数据库的主机地址、用户名、密码等信息
[mysql-test]
Description = MySQL test database
Trace = On
TraceFile = stderr
Driver = mysql
SERVER = 127.0.0.1
USER = root
PASSWORD = root
PORT = 3306
DATABASE = test
然后使用 odbcinst
工具注册数据库:
odbcinst -i -d -f ~/mysql-odbc.ini
可以使用 isql
工具执行 SQL
htf@swoole-12:/etc$ isql mysql-test
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> show tables
+-----------------------------------------------------------------+
| Tables_in_test |
+-----------------------------------------------------------------+
| ckl |
| custom |
| firmware |
| numbers |
| userinfo |
+-----------------------------------------------------------------+
SQLRowCount returns 5
5 rows fetched
SQL>
代码
Co\run(function () {
$pdo = new PDO('odbc:mysql-test');
$statement = $pdo->prepare('show tables');
$statement->execute();
var_dump(count($statement->fetchAll(PDO::FETCH_COLUMN)), 1);
});
PDO_SQLITE
SQLite
一款轻量级的、开源的、嵌入式关系型数据库管理系统。其最主要的优势是小巧、快速,具有对事务的支持,并且具有可移植性。以下是SQLite
的一些优点:
- 占用资源少:
SQLite
是一款嵌入式数据库,不需要安装或维护,以一个文件的形式存放在本地操作系统文件系统上,不需要独立运行一个数据库服务器进程。因此,其占用资源非常少,可以在资源受限的嵌入式设备、移动设备上运行。 - 速度快:
SQLite
是一款非常快速的关系型数据库,能够轻松处理中小型数据集。相比于其他传统的关系型数据库,它的读写速度相对较快。 - 对事务的支持:与其他轻量级数据库相比,
SQLite
对事务的支持非常好,并支持Acid属性,可以防止数据丢失或损坏。 - 可移植性:SQLite的文件格式是独立于操作系统的,这使得用户能够将其数据库文件从一个操作系统迁移到另一个操作系统。
在以下情况下可以考虑使用 SQLite
:
- 本地数据存储:
SQLite
适合在应用程序中存储本地数据,如移动应用程序中的用户个人数据、本地设置和缓存等。 - 中小型数据量存储:
SQLite
适合存储中小型数据集,例如小型企业或单个用户的数据,而不是应用场景复杂或数据集非常大的情况。 - 需要进行离线数据读写操作:由于
SQLite
的文件格式独立于操作系统,因此可以将数据存储为文件,并在离线情况下进行读写操作。 - 快速原型开发:由于
SQLite
易于使用和管理,因此适合进行快速原型开发,以便在真正的生产中测试和优化应用程序。
5.1
版本提供了 sqlite
嵌入式数据库的协程客户端支持,同样也是使用 PDO
作为接口层。
编译选项
./configure --enable-swoole-sqlite
需要依赖 libsqlite3-dev
代码实例
go(function() {
$db = new PDO('sqlite::memory:');
$db->exec('create table test (id int)');
$stmt = $db->prepare('insert into test values(?)');
$i = 2024;
$stmt->execute([$i]);
$stmt = $db->prepare('select id from test where id = ?');
$stmt->execute([$i]);
var_dump($stmt->fetch(PDO::FETCH_ASSOC)['id'] == $i);
});
PDO_OCI
Oracle
数据库是美国甲骨文公司研发的大型关系型数据库,在全球范围内有很多大型企业使用 Oracle
数据库。电商平台、银行、金融、电信等很多商业项目核心系统使用了 Oracle
数据库。
以下是Oracle数据库的一些特点和功能:
- 高性能:
Oracle
数据库能够处理大量的并发用户请求,并快速的处理大规模的数据。 - 规模性:
Oracle
数据库支持大规模的数据库集群和复杂的汇聚操作,使得它在大型企业中和关键业务应用中非常受欢迎。 - 冗余备份:
Oracle
数据库提供强大的冗余备份和恢复功能,支持在线备份和恢复、增量备份和恢复、点时间恢复等。 - 安全性:
Oracle
数据库提供用于对数据库进行加密、数据脱敏、访问控制和身份验证的功能。 - 灵活性:
Oracle
数据库支持多种数据类型和编程语言,并提供了强大的存储、索引和查询功能。 - 高可用性:
Oracle
数据库具有高可用性,支持主从同步、自动故障转移和容错功能,这些功能可以确保系统的连续性和稳定性。 - 性能优化:
Oracle
数据库提供了丰富的性能优化功能,并支持各种调优技术,以确保数据库在高负载下稳定运行。
5.1
版本提供了原生的 pdo_oci
协程客户端实现。可在协程环境下并发连接操作 Oracle
数据库。
编译选项
需要增加 --with-swoole-oracle=instantclient,/path/to/instant/client/lib
参数来启用 PDO_OCI
协程客户端。
可在 Oracle
官网下载客户端驱动
apt install -y libaio-dev
apt install -y libaio1
wget -nv https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip
unzip instantclient-basiclite-linuxx64.zip && rm instantclient-basiclite-linuxx64.zip
wget -nv https://download.oracle.com/otn_software/linux/instantclient/instantclient-sdk-linuxx64.zip
unzip instantclient-sdk-linuxx64.zip && rm instantclient-sdk-linuxx64.zip
mv instantclient_*_* ./instantclient
rm ./instantclient/sdk/include/ldap.h
# fix debug build warning: zend_signal: handler was replaced for signal (2) after startup
echo DISABLE_INTERRUPT=on > ./instantclient/network/admin/sqlnet.ora
mv ./instantclient /usr/local/
echo '/usr/local/instantclient' > /etc/ld.so.conf.d/oracle-instantclient.conf
ldconfig
代码实例
Co\run(function () {
$db = new PDO('oci:dbname=127.0.0.1:'.$ORACLE_PORT.'/'.$ORACLE_SERVICE_NAME.';charset=AL32UTF8', $ORACLE_USER, $ORACLE_PASSWORD);
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$db->exec("create table test (id int)");
for($i = 0; $i < 10; $i++) {
go(function () use($db, $i){
$stmt = $db->prepare("insert into test values (?)");
$stmt->execute([$i]);
$stmt = $db->prepare("select id from test where id = ?");
$stmt->execute([$i]);
var_dump($stmt->fetch(PDO::FETCH_ASSOC)['id'] == $i);
});
}
});
结语
在 5.1
版本中增加了更多数据库协程客户端的支持,使得 Swoole
协程模式下可以支持多种数据库。
接口上选择了使用 PDO API
,保持了与 PHP-FPM
的兼容性。无需修改代码,也没有额外的学习成本。
在实现上使用了原生 API
+ swoole::coroutine::async
,基于可伸缩的 AIO
线程池和协程调度 API
。
这样的方式更加安全健壮,可直接用于生产环境。