8

私の質問は、アプリケーションのモデル層からデータベース接続をどのように抽象化するのですか? 主な関心事は、さまざまな種類のデータベースから簡単に変更できるようにすることです。おそらく、コンマ区切りのフラット ファイル データベースから始めることになるでしょう。次に、SQL データベースに移動します。その後、LDAP 実装の方が優れていると判断します。このようなことを簡単に計画するにはどうすればよいでしょうか。

簡単な例として、名前、姓、電子メールを持つユーザーがいるとします。これを表す非常に単純な PHP クラスは次のようになります (パブリック インスタンス変数の問題は無視してください)。

<?php

class User {
  public $first;
  public $last;
  public $email;
}

?>

SQLが埋め込まれたDAOクラスを持っている人をよく見てきました。

<?php

class UserDAO {
  public $id;
  public $fist;
  public $last;
  public $email;

  public function create( &$db ) {
    $sql = "INSERT INTO user VALUES( '$first', '$last', '$email' )";
    $db->query( $sql );
  }
}

?>

このような戦略に関する私の問題は、データベースを変更したい場合、新しいタイプのデータベースに対処するために、すべての DAO クラスの作成、更新、ロード、削除関数を変更する必要があることです。それらを自動生成するプログラムを持っている場合でも (私は特に好きではありません)、このプログラムを編集して機能させる必要があります。

これを処理する方法についての提案は何ですか?

私の現在の考えは、独自の作成、削除、更新、ロード機能を持つ DAO オブジェクトのスーパー クラスを作成することです。ただし、これらの関数は DAO の属性の配列を取得し、クエリ自体を生成します。このように、SQL は複数のクラスに分散するのではなく、SuperDAO クラスにのみ存在します。その後、データベース層を変更したい場合は、SuperDAO クラスがクエリを生成する方法を変更するだけで済みます。利点?短所は?予見可能な問題?良い点、悪い点、醜い点は?

4

10 に答える 10

9

PDO、PEAR::MDB2、Zend_Db などのさまざまなフレームワークを使用できますが、正直なところ、PHP 開発の 12 年間で、あるタイプのデータ ストレージ インフラストラクチャから別のタイプのデータ ストレージ インフラストラクチャに移行する必要はありませんでした。

Sqlite のような非常によく似たものから MySQL に移行することさえ非常にまれです。それ以上のことをすると、いずれにせよ、はるかに大きな問題が発生することになります。

于 2009-04-15T19:11:34.020 に答える
8

ORMの使用は、通常、データベースを抽象化するための推奨される方法です。PHP 実装の不完全なリストはWikipediaで入手できます。

于 2009-04-15T19:11:19.853 に答える
3

最良の方法は、ORM(オブジェクトリレーショナルマッピング)ライブラリを使用することです。PHPにはたくさんあります。私は個人的に使用しており、ドクトリンormを推奨できます(ミニマルなphpフレームワークであるsilexと組み合わせて使用​​しました)。

PHP ORMに関するStackOverflowスレッドを次に示します。必要に応じて、いくつかの代替案を見つけることができます。優れたPHP ORMライブラリ?

于 2009-04-15T19:21:38.940 に答える
3

私は、開発者がデータベースに依存しないコードを作成できるようにする興味深いコンセプトを思いつきましたが、ORM とは異なり、パフォーマンスを犠牲にしません

  • 使いやすい(ORMのように)
  • db-agnostic: SQL、NoSQL、ファイルなどで動作します
  • ベンダーが許可する場合は常にクエリを最適化します (サブセレクト、マップリデュース)

その結果がAgile Data - データベース アクセス フレームワークです (詳細な説明についてはビデオを参照してください)。

DB に依存しないコードとアジャイル データを使用して実際のタスクを解決する

  1. ビジネス モデルの説明から始めます。
  2. CSV ファイル、SQL、または LDAP などの持続性ドライバー$db(DB 接続の派手な言葉) を作成します。
  3. モデルを$db関連付けて表現するAction
  4. 実行するAction

この時点で、フレームワークはデータベースの機能を考慮して最適な戦略を決定し、フィールド宣言をマップし、クエリを準備して実行するので、それらを記述する必要はありません。

コード例

次のコード スニペットは、すべての VIP クライアントの現在の総負債を判断するというかなり複雑な問題を解決します。スキーマ:

ここに画像の説明を入力

次は、ベンダーに依存しないコードです。

$clients = new Model_Client($db);
// Object representing all clients - DataSet

$clients -> addCondition('is_vip', true);
// Now DataSet is limited to VIP clients only

$vip_client_orders = $clients->refSet('Order');
// This DataSet will contain only orders placed by VIP clients

$vip_client_orders->addExpression('item_price')->set(function($model, $query){
    return $model->ref('item_id')->fieldQuery('price');
});
// Defines a new field for a model expressed through relation with Item

$vip_client_orders->addExpression('paid')
  ->set(function($model, $query){
    return $model->ref('Payment')->sum('amount');
});
// Defines another field as sum of related payments

$vip_client_orders->addExpression('due')->set(function($model, $query){
    return $query->expr('{item_price} * {qty} - {paid}');
});
// Defines third field for calculating due

$total_due_payment = $vip_client_orders->sum('due')->getOne();
// Defines and executes "sum" action on our expression across specified data-set

結果のクエリ$dbが SQL の場合:

select sum(
  (select `price` from `item` where `item`.`id` = `order`.`item_id` )
  * `order`.`qty`
  - (select sum(`payment`.`amount`) `amount` 
     from `payment` where `payment`.`order_id` = `order`.`id` )
) `due` from `order` 
where `order`.`user_id` in (
  select `id` from `user` where `user`.`is_client` = 1 and `user`.`is_vip` = 1 
)

他のデータ ソースの場合、実行戦略はさらに多くのデータを処理する可能性がありますが、一貫して機能します。

私のアプローチはデータベースを抽象化するための優れた方法であり、MIT ライセンスの下で実装するために取り組んでいます。

https://github.com/atk4/data

于 2016-06-05T13:20:06.020 に答える
2

PDO ライブラリを調べる必要があります。

PDO はデータ アクセス抽象化レイヤーを提供します。つまり、使用しているデータベースに関係なく、同じ関数を使用してクエリを発行し、データをフェッチします。

PDO はデータベースの抽象化を提供しません。SQL を書き換えたり、不足している機能をエミュレートしたりしません。その機能が必要な場合は、本格的な抽象化レイヤーを使用する必要があります。

于 2009-04-15T19:10:00.763 に答える
1

一般的に言って、データベースの使用に問題がある場合、アプリケーションはデータベースの「ブランド」に固有の機能を使用することでメリットがあり、より堅実なアプリになります。

あるデータベースシステムから別のデータベースシステムに移動することは非常にまれです。実装する価値のある機能を現実的に考えることができるのは、大量消費を目的としたある種の緩く結合されたシステムまたはフレームワーク(Zend FrameworkやDjangoなど)を作成している場合のみです。

于 2009-04-15T19:20:40.707 に答える
1

私はいつも ADOdb を使うのが好きでした。私が見たところ、非常に異なるプラットフォーム間で切り替えることができるようです.

http://adodb.sf.net

于 2009-04-15T21:37:25.867 に答える
1

理論的には良さそうですが、おそらくYAGNIです。

PDOなどの SQL ライブラリを使用し、そこに到達するまで LDAP について心配する必要はありません。

于 2009-04-15T19:10:34.847 に答える
0

Axon ORMは、コードを再構築する必要なく、スキーマの変更を自動的に検出します。

于 2010-08-23T08:21:48.073 に答える