我已经解散了这个项目,因为它的工作量太大,虽然这个想法一开始看起来确实很愚蠢,但实际上它确实有效,直到我发现分页时存在很多问题,并且就性能而言,我认为集群是最好的。使用它需要您自担风险,制作这个项目很有趣。
这是一个免费、易于使用、轻量级且功能强大的PHP 库,允许您使用 PDO 连接到多个 MySQL 数据库。我专门为 MySQL 构建了这个,但我相信这将适用于 PostgreSQL、MariaDB、CouchDB 等。请记住,这是针对 SQL 数据库的,因此它不适用于 MongoDB 和 Apache Cassandra 等数据库管理系统。
✔ 使用 PDO 连接到多个 MySQL 数据库。
✔ 从多个数据库检索行。
✔ 只需执行 1 个查询即可高效执行插入查询,而不是在每个数据库的所有表中添加新行。
✔ 轻松排序、限制和管理结果/行。
✔ 只需添加更多数据库即可轻松扩展(无需使用从数据库、主数据库或集群)。
✔ 生成真正唯一的标识符(称为 MDGUID)。
➔ PHP 7+ 和 Apache/Nginx(使用 PHP 7 及更高版本的功能)。
➔ MySQL 5.7+(澄清 MySQL 5.7 工作正常,因此任何高于 MySQL 5.7 的版本都很好)。
➔ 与 PDO 兼容的数据库驱动程序(在此处阅读有关此内容的更多信息)。
您可以根据以下条款将MultiDatabasePDO用于个人、教育和商业用途:
➔ 您不得向其他用户出售、赠送或托管此库(原始或编辑的副本),您必须将他们链接到此存储库。
➔ 您不要更改文件中的注释或将其删除,这样做会让我认为您想将其声明为您自己的。
1. 连接到您的数据库!
在开始之前,请确保您了解 PDO 的基础知识。只需下载最新版本并包含名为MultiDatabasePDO .php
的文件,该文件将自动为您包含所有额外的类。您的设置代码应如下所示:
require " ./ MultiDatabasePDO / MultiDatabasePDO .php " ;
$ multiPDO = new WulfGamesYT MultiDatabasePDO MultiDatabasePDO ([
[ " mysql " , " 1.1.1.1 " , " database_1 " , " username " , " password " ],
[ " mysql " , " 2.2.2.2 " , " database_2 " , " username " , " password " ]
]);
现在我们需要使用一个名为hasAnyErrors()
简单函数来检查是否有任何错误。您可以使用函数getFailedConnections()
列出失败的连接。
if ( $ multiPDO -> hasAnyErrors ()) {
error_log ( " Error connecting to database(s): " . $ multiPDO -> getFailedConnections ());
exit ( " Error connecting to our main databases! Please try again later. " );
}
2. 阅读 Wiki 并以正确的方式使用该库!
接下来,我建议阅读 wiki 上的文档以了解每个函数的作用。另外,重要的是要知道该库与标准 PDO 库之间存在一些差异,特别是:
execute()
方法中传递占位符/值数组,请使用bindValue()
或bindValues()
。ORDER BY
、 LIMIT
或OFFSET
,请参阅本指南。AUTO INCREMENT
,如果您有 ID 列,请使用此函数。 3. 设置您的数据库和表格!
如果您计划使用MultiDatabasePDO ,则必须确保您连接到的每个数据库中的所有表的结构都相同:
出于示例目的,假设我们有来自 2 个不同数据库的以下 2 个表,它们的结构和名称都相同。下面的自述文件中的每个示例都使用这些表。实际上,在您需要考虑使用MultiDatabasePDO之前(或者如果您想准备扩展您的 Web 应用程序),您的表将有数千甚至数百万行。
“Users”表,来自数据库 1。
ID(整数) | 用户名(文本) | 密码哈希(文本) | 电子邮件(文本) | 名字(文本) | 姓氏(文本) |
---|---|---|---|---|---|
1 | WulfGamesYT | ThLfkbQFyvDx | [email protected] | 利亚姆 | 艾伦 |
2 | 印第安纳琼斯55 | npxCn975RSaP | 我@indiana.jones | 印第安纳州 | 琼斯 |
3 | YaBoiTableFlipper69 | BT7V2U6VJv2d | [email protected] | 史蒂夫 | 琼斯 |
“Users”表,来自数据库 2。
ID(整数) | 用户名(文本) | 密码哈希(文本) | 电子邮件(文本) | 名字(文本) | 姓氏(文本) |
---|---|---|---|---|---|
4 | 真的哥们 | 6XBmD4bzGP87 | [email protected] | 利亚姆 | 石匠 |
5 | 地狱耶博伊 | LeyTpTwvvMUM | [email protected] | 朱莉 | 克罗斯比 |
要从所有数据库和所有表中选择行,您可以简单地执行以下操作,就像 PHP 中的普通 PDO 一样:
$ selectQuery = $ multiPDO -> prepare ( " SELECT ID, Username, Email FROM Users WHERE Username = :username " );
$ selectQuery -> bindValue ( " :username " , " WulfGamesYT " );
$ selectQuery -> execute ();
while ( $ row = $ selectQuery -> getNextRow ()) { var_dump ( $ row ); }
假设我们有一个表单,您可以将信息 POST 到您的 PHP 文件,并且您想要从名为“Users”的数据库中向表中插入 1 条新记录,您所需要做的就是以下操作。请注意,这将被插入到上面示例表中的第二个表中,因为它的行数最少。使用下面的generateMDGUID()
函数,而不是手动输入ID 并在表中使用int 数据类型。
$ longSQL = " INSERT INTO Users VALUES (6, :username, :pass, :email, :firstname, :lastname) " ;
$ insertQuery = $ multiPDO -> prepare ( $ longSQL );
$ insertQuery -> bindValues ([
" :username " => $ _POST [ " username " ],
" :pass " => password_hash ( $ _POST [ " password " ], PASSWORD_DEFAULT ),
" :email " => $ _POST [ " email " ],
" :firstname " => $ _POST [ " name-first " ],
" :lastname " => $ _POST [ " name-last " ]
]);
$ insertQuery -> execute ( true , " Users " );
请注意,我们在execute()
方法中传递了2 个参数,这是插入新行所必需的,因为它告诉类我们要在名为“Users”的表中插入(通过传入:true)新行。不要将不受信任的用户输入作为第二个参数,因为可能会发生 SQL 注入。
这与执行 SELECT 查询基本相同,这将更新所有数据库中与 WHERE 子句匹配的所有表(如果指定),例如:
$ updateQuery = $ multiPDO -> prepare ( " UPDATE Users SET Username = :newusername WHERE Username = :oldusername " );
$ updateQuery -> bindValues ([ " :newusername " => " MyFancyUsername " , " :oldusername " => " WulfGamesYT " ]);
$ updateQuery -> execute ();
现在,如果我们对所有名为“Users”的表运行 SELECT 查询,我们将看到更新的行。
再说一次,我们需要做的是:
$ deleteQuery = $ multiPDO -> prepare ( " DELETE FROM Users WHERE Username = :username " );
$ deleteQuery -> bindValue ( " :username " , " MyFancyUsername " );
$ deleteQuery -> execute ();
现在,如果我们对所有名为“Users”的表运行 SELECT 查询,我们将看到更新的行。
需要注意的是,您不能在 SQL 查询中使用ORDER BY
、 LIMIT
或OFFSET
来对每个数据库中的所有行进行排序,只能对 1 个数据库中当前表中的行进行排序。相反,您必须使用MultiDatabasePDO提供的以下函数,以便轻松组织最终结果/行。
对结果排序(而不是“ORDER BY”):您可以像在 SQL 查询中一样对结果进行排序,将“ASC”或“DESC”传递到sortBy()
方法的第二个参数中。
这是对数字列进行排序的方式:
$ selectQuery = $ multiPDO -> prepare ( " SELECT * FROM Users " );
$ selectQuery -> execute ();
//Now sort by the "ID" column in descending order.
$ selectQuery -> sortBy ( " ID " , " DESC " );
while ( $ row = $ selectQuery -> getNextRow ()) { var_dump ( $ row ); }
这是对字符串/对象列进行排序的方式:
$ selectQuery = $ multiPDO -> prepare ( " SELECT * FROM Users " );
$ selectQuery -> execute ();
//Now sort by the "Username" column in ascending order.
$ selectQuery -> sortBy ( " Username " , " ASC " );
while ( $ row = $ selectQuery -> getNextRow ()) { var_dump ( $ row ); }
如果需要,您可以订购多列或多次。在下面的示例中,我们将按降序对名为“FirstName”的列进行排序,然后对名为“LastName”的列进行排序。这将按字母顺序列出表中的用户,如果他们具有相同的名字,那么它也会按姓氏排序。将最不重要的顺序列放在前面,然后将最重要的顺序列放在最后,如代码中所示:
$ selectQuery = $ multiPDO -> prepare ( " SELECT * FROM Users " );
$ selectQuery -> execute ();
//Now sort both the columns.
$ selectQuery -> sortBy ( " LastName " , " ASC " );
$ selectQuery -> sortBy ( " FirstName " , " ASC " );
while ( $ row = $ selectQuery -> getNextRow ()) { var_dump ( $ row ); }
除了AUTO INCREMENT
之外,或者如果您需要一种跨多个数据库生成真正唯一的 GUID 的方法,您可以使用我们的函数generateMDGUID()
。下面是有关它们如何工作以及如何保证 100% 唯一性的指南,以及如何在向表中插入新行时使用该函数的示例。
MDGUID 的工作原理和保证唯一性:
例子:
//Here we generate the MDGUID.
$ mdguid = $ multiPDO -> generateMDGUID ();
$ longSQL = " INSERT INTO Users VALUES (:mdguid, :username, :pass, :email, :firstname, :lastname) " ;
$ insertQuery = $ multiPDO -> prepare ( $ longSQL );
$ insertQuery -> bindValues ([
" :mdguid " => $ mdguid ,
" :username " => $ _POST [ " username " ],
" :pass " => password_hash ( $ _POST [ " password " ], PASSWORD_DEFAULT ),
" :email " => $ _POST [ " email " ],
" :firstname " => $ _POST [ " name-first " ],
" :lastname " => $ _POST [ " name-last " ]
]);
$ insertQuery -> execute ( true , " Users " );
如果您需要提问,请在 Twitter 上与我联系。
推特:https://www.twitter.com/WulfGamesYT
如果您喜欢这个库,请考虑给它加星标并与喜欢 PHP 和 MySQL 的开发人员分享!请继续关注更新,并务必向我报告您发现的任何错误。感谢您的阅读!