データベースの抽象化—やり過ぎですか?


18

多数のデータベース抽象化レイヤーにさらされた後、私は、データにアクセスするための独自の異なるパラダイムを発明するすべてのライブラリーのポイントが何であるか疑問に思い始めています。新しいDALを取得することは、新しい言語をもう一度学習するように感じます。通常、やりたいことは、既に自分の頭に書いたSQLクエリを出力するようにレイヤーを説得することだけです。

そして、それは事後の読みやすさにさえ触れていない:

# Exhibit A:  A typical DAL
rows = db(db.ips_x_users.ip_addr == '127.0.0.1')
    .inner_join(db.ips_x_users.user_id == db.users.id)
    .select(order=(db.ips_x_users.last_seen, 'desc'), limit=10)

# Exhibit B:  Another typical DAL
rows = db.ips_x_users
    .join(db.users, on=db.ips_x_users.user_id == db.users.id)
    .filter(db.ips_x_users.ip_addr == '127.0.0.1')
    .select(sort=~db.ips_x_users, limit=10)

# Exhibit C:  A hypothetical DAL based on standard SQL syntax
rows = db('''SELECT * FROM ips_x_users
             INNER JOIN users ON
                 (ips_x_users.user_id = users.id)
             WHERE ips_x_users.ip_addr = ip
             ORDER BY last_seen DESC LIMIT 10''', ip='127.0.0.1')

標準のSQL構文の何が問題になっていますか?特定の目的のために作成され、その目的に美しく適合します。たぶんそれは私だけかもしれませんが、スニペットCは最初の2つよりはるかに簡単に理解できます。名前が変更されたキーワードと構文のトリックはかわいいですが、IMOは、すぐに言えば、コーダーが行を簡単に取得できないようにします。

これはおそらく長い暴言のように思えました、ここに本当の疑問があります。すべてのDALは、実証済みのSQLを単に解析するのではなく、クエリ用の新しいDSLを発明しているように見えるため、異なる構文を使用する利点があるか、標準のSQL構文に欠陥があることを認識している必要があります。誰かが私がここで見落としているものを指摘してもらえますか?


2
標準SQLの最大の問題は、データベース固有のクエリが多数あることです。「ウィンドウ」クエリを取得するプロセスと同様に、外部結合構文は大きく異なります。それがDALの必要性です。さて、DALが使用するSQLの標準バリアントがあり、さまざまなSQLベンダーのイディオシンクラシーに対処する方法を知っているなら、それを歓迎します。
ベリンロリチュ

回答:


10

一般的なSQL使用の最も基本的な問題は、SQLクエリが文字列であり、何らかの方法で別の言語から構成されていることです。これは、SQLインジェクションやその他の脆弱性やWTFの原因です(クエリには実際にはパラメーターがないため、サンプルの選択は非常に不適切です)。

次の問題は実際には当然の結果です。コードにSQLを記述しただけでは、コンパイラはそれについて何もできません。列名のタイプミスなどのエラーは、実行時にのみ発生します。これは基本的に、ソースコードにクエリの文字列表現だけが必要なわけではありませんが、すべてのfacepalm-bugsの95%を防ぐためにコンパイラが静的に分析できるものです。

そして、リレーショナルデータベースを言語のセマンティクスとプログラミングモデルにマップしようとすると、最後の問題が発生します。RDBMSはOOP(またはナビゲーションデータの取得)とうまく連動しません。実際、これはこれら2つを組み合わせた非常に恐ろしいアイデアですが、SQLデータベース(つまりORM)のすべてのオブジェクト指向DALの目的です。しかし、これらのすべての抽象化レイヤーはリークが非難されます。これが基本的にそれらの多くが存在する理由だと思います:あなたは彼らと仕事をしているので、あなたは彼らに欠陥があるのを見て、それを正しく行い、最終的に失敗するDALを書き始めました。

したがって、問題1と2はSQLを削除するDALを持つことを示唆していますが、問題3は1つ(少なくともOOPの場合)を持つ直接的な解決策がないことを示唆しているため、異なる長所と制限を持つDALの海が常に存在します。最後に、できることは、いくつかを慎重に選択してそれらに固執することだけです。


3
「RDBMSはOOPと相性がよくありません」- ソフトウェアのすべてがオブジェクト指向である必要がありますか?
-quant_dev

@quant_dev:いいえ。しかし、「抽象化」レイヤーは本質的に少なくとも「抽象化指向」です。また、提供されているコードスニペットは、OOコードについて話していることを示唆しています。
back2dos

私は常にSQLをCに埋め込むか、考えられる限り最も愚かなことだと思っていました。そのようなことをしなければならなかったとき、テーブル間の関係を定義し、それをデータベースに保存し、その関係を使用して実行時にSQLを作成してデータベースと通信する手段を作成しました。私のCコードは、「このキーを使用してこのエンティティを見つける」、「変更を保存する」だけでした。

9

すべてのデータベースプラットフォームが同じSQL構文を受け入れるわけではないという明らかな事実を見落としているため、アプリケーション全体にSQLステートメントを埋め込むことは、すべてのデータベースプラットフォームで機能するとは限りません。複数のデータベースプラットフォームをサポートする必要がある場合、これらのSQLステートメントのほとんど(すべてではないにしても)を再考する必要があります。


3
@注-ただし、DALには完全なSQLパーサーが必要であり、特定のデータベースとは異なる独自のサポートされた方言が必要です。そして、適切なデータベース固有のSQLステートメントを生成するという現在の複雑さをすべて備えています。たとえば、この例のLIMITキーワードはMySQLでは有効ですが、OracleまたはSQL Serverでは無効です。
ジャスティン洞窟

2
今、私たちは問題の核心に近づいています。メソッドの非標準のセットと演算子のオーバーロードが、SQLの非標準の方言より優れているのはなぜですか?SQLを使用すると、少なくともフレームワークの学習を開始するためのコーダーに馴染みのある基盤が提供されます。
自己への注意-名前を考える

3
@Note to self:おそらく、SQLの方言でSQLパーサーを作成し、それを他のSQLの方言に変換するよりも、流styleなスタイルのAPIを作成する方が簡単だからです。
ディーンハーディング

1
記録のために、「ネイティブ」SQLの使用も好みます。私のプロジェクトのほとんどは、複数のデータベースをサポートする必要がなかったため、私にとっては決して問題になりませんでした。
ディーンハーディング

3
はい、しかしどのくらいの頻度はに対して実行されるコードを書くのです- 「あなたがいないすべてのデータベースプラットフォームが同じSQL構文を受け入れるという明白な事実見下ろすされている」すべてのデータベースを?通常、DBプラットフォームは重要な投資であり、頻繁に変更されることはありません。また、既知の種類のデータベースに対してクエリを最適化することにより、効率を大幅に向上させる必要があります。
-quant_dev

5

SQLは、ポインタが10年前と同じ大きな変化を経験しているように感じます。SQLによる手動作業を排除し、より高い抽象化レベルに引き上げる試みが継続的に行われています。同じことが、何年も前にポインタと手動メモリ管理で発生しました。

作業は現在進行中であるため、多くの異なるアプローチが提案され、試行され、放棄され、統合されています。マニフェスト自体を希望する場合は、何らかの一般的なアプローチまたは業界標準の前に、より多くのことを見ると確信しています。

同じレベルでデータアクセスコードを操作し、アプリケーションコードを操作するときに適用するのと同じパラダイムを使用できる場合、確かに優位性が得られます。

簡単に言えば、単純化、敏g性、迅速性、これらが目標です。


4

ジョエルは10年前に素敵な記事を書いていました:建築宇宙飛行士にあなたを怖がらせないでください

まさにそうだと思います。パターンを見つけたので、自分のアプリケーションで抽象化レイヤーを使用していましたが、この方法は簡単でした。しかし、ソースコードのすべての行=>フルコントロールを知っていたのは私のDALでした。しかし、私のフレームワークを私のチーム/プロジェクト以外の人に使用することはお勧めしません。

そのようなものを使用する場合、その実装方法を知ることが重要です。つまり、ライブラリ/ツールの学習に多くの時間を費やす必要があります。それを学ぶ時間がない場合-使用しないでください。たとえ最初から非常に簡単に見えても。


はい、私が過去に働いていた会社がHibernateを熱心に使用し始めました。次に、フレームワークによって生成されたクエリがどれほど驚くべきものであるか(奇妙な方法で)発見しました。
quant_dev

@quant_devはい、それはトラップです-HibernateまたはJPAで簡単なことを始めるのは簡単です。
m5ba
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.