web-dev-qa-db-ja.com

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

多数のデータベース抽象化レイヤーにさらされた後、データにアクセスするための独自のパラダイムを発明しているすべてのライブラリーの要点は何なのかと思い始めています。新しい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構文の何が問題になっていますか?特定の目的のために作成され、その目的に美しく適合します。多分それは私だけかもしれませんが、私は最初の2つよりはるかに簡単にスニペットCを理解します。名前が変更されたキーワードと構文のトリックはかわいらしいですが、IMOはそれがまさしくその行である場合、コーダーにとって行の取得を容易にしません。

これはおそらく長い怒りのように思われましたが、isが本当の質問です。すべてのDALは、実績のあるSQLを解析するだけでなく、クエリ用の新しいDSLを発明するように思われるため、異なる構文を使用することの利点、または標準SQL構文の欠点があり、私が認識していないことに気づいています。私がここで見落としていることを誰かが指摘してもらえますか?

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

次の問題は、実際の結果です。コードにSQLが書かれているだけでは、コンパイラーはそれについて何もできません。列名のタイプミスなどのエラーは、実行時にのみ発生します。これが基本的に、ソースコード内のクエリの文字列表現だけではなく、コンパイラが静的に分析してすべてのfacepalmバグの95%を防ぐことができる理由です。

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

したがって、問題1と2はSQLを取り除くDALがあることを示唆していますが、問題3は、(少なくともOOPの場合)1を持つ簡単な解決策がないことを意味し、したがって、さまざまな長所と制限を持つDALの海が常に存在します。結局、あなたができることは、慎重にいくつかを選んでそれらに固執することです。

10
back2dos

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

9
Bernard

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

作業は現在進行中であるため、提案され、試行され、放棄され、統合された多くのさまざまなアプローチを楽しんでいます。何らかの共通のアプローチや業界標準の前に、それが明らかになれば、もっと多くのことを目にするはずです。

データアクセスコードを同じレベルで操作でき、アプリケーションコードで作業するときに適用するのと同じパラダイムを使用できる場合は、確実にEdgeが提供されます。

一言で言えば、簡素化、俊敏性、迅速性、これらは目標です。

5
user8685

ジョエルは10年前にニースの記事を書いていました: Do n't Let Architecture Astronauts Scare Yo

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

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

4
m5ba