RESTful APIのSQLデータベース構造


11

RESTful APIを作成しています。リソースを中心にデータベーステーブルを設計する最良の方法を決定するのに苦労しています。

最初は、リソースごとのテーブルが適していますが、これにより、リソースチェーンをさらに下っていくと、テーブルが指数的に大きくなるのではないかと心配しています。

たとえば、ユーザー、クライアント、販売の3つのリソースがあるとします。ユーザーは私のAPIのサブスクライバーであり、クライアントはユーザーの顧客であり、販売は各クライアントがユーザーアカウントに対して行った購入です。

次のように販売リソースにアクセスします

GET /users/{userID}/clients/{clientID}/sales/{salesID}

したがって、10人のユーザーがあり、それぞれに10人の顧客がいて、それぞれの顧客について10件の売上がある場合、テーブルサイズは、リソースチェーンを下に行くほど大きくなります。

SQLが大きなテーブルに対応できるとは確信していますが、読み取りと書き込みがどのように遅くなるかはわかりません。上の例はそれを説明していないかもしれませんが、私のAPIは次第に多くの書き込みと読み取りを行って、リソースチェーンのさらに下に行きます。したがって、データベース内の最大のテーブルが、小さいテーブルよりも多くの回数読み書きされるシナリオがあります。

クエリを実行する前にテーブルを結合する必要もあります。その理由は、各ユーザーが同じ名前のクライアントを持つことを許可するためです。間違ったクライアントデータを取得しないように、usersテーブルとclientsテーブルは{userID}によって結合されます。これは販売にも当てはまります。大きなテーブルを結合して読み取りと書き込みを実行すると、処理がさらに遅くなりますか?

回答:


31

リソースを中心にデータベーステーブルを設計する最良の方法を決定するのに苦労しています。

しないでください。

RESTful 原則に従ってAPIを設計し、正規化の原則に従ってデータベースを設計します。一方が他方に影響を与える必要はありません。

データベースにはSaleResourceテーブルを含めず、Sale(または購入/注文)テーブルを含める必要があります。そのテーブルには、Saleを一意に識別する主キーと、関連するUserテーブルとCustomerテーブルへの外部キーが含まれます。

REST APIは、によって識別されたリソースのリクエストをGET /users/{userID}/clients/{clientID}/sales/{salesID}適切なデータベースクエリに変換し、行を取得して、Saleを表すリソースを構築し、それをクライアントに返します。

現在、内部データベース識別子(UserID / ClientId / SalesID)のように見えるものを外部に公開していることに注意してください。それはあなたの場合には適切かもしれませんが、一般的<entity>IDにはRESTful APIで気分を害します。


ありがとう。つまり、基本的に言っているのは、データベースを正規化し、適切なインデックス作成などを設定している限り、達成したいパフォーマンスの問題はないということです
Gaz_Edge

3
はい。あなたが述べたことは、正規化されたスキーマから逸脱する必要があることを示唆していません。
Mark Storey-Smith

9

リレーショナルデータベース(したがってSQL)は、巨大なテーブルから1つ(またはいくつか)の行を見つけるのに非常に適しています。これがインデックスの目的です。また、結合の処理にも優れています。あなたは本当に質問はありません。行の間に、あなたは基本的にマルチテナントのデータベース設計を行う方法について尋ねています。さらに質問する前に、マルチテナントデータアーキテクチャを読むことをお勧めします。パターンの1つ(個別のデータベース、共有データベースの個別のスキーマ、共有データベースの共有スキーマ)を選択してから、詳細について説明します。現時点では、最後のパターンのみを想定していますが、賛否両論は考慮していません。読んでください。

補足としてuser/{userID}、URI は必要ありません。認証情報からテナント(userID)がわかります。


おかげで、ええ、私はさらに読む必要があります。これまでの私のプロジェクトでは、データベース作業はほとんどありませんでした。お勧めのリソースを読みます
Gaz_Edge

共有共有は私のために行く方法だと思います。私の「ユーザー」は「テナント」ではありません。分離されたデータは必要なく、データベース管理機能に直接アクセスする必要はありません。私が読んだことから、これは共有共有が最善であることを示唆していますか?どう思いますか?
Gaz_Edge 2013

2
共有が最も簡単です。あなたは追加する必要がありuser_id、すべてのテーブルへのキーとして追加し、left.user_id = right.user_id関連する(通常は、すべての)参加します。一部のORMは、アクセスのスコープをサポートしています。そして、だまされてはいけません。ユーザー「foo」にユーザー「bar」の売上を表示/変更させたくないので、ユーザーテナントです。
Remus Rusanu 2013

ありがとう。インデックスがデータベース構造を作成するための鍵であることがわかり始めました。
Gaz_Edge 2013

0

ここですでに述べられていることを追加するだけです。実際のAPIとデータベース層の間のインターフェースを構築したい場合があります。キャッシングテーブルとサマリーテーブルを簡単に追加できるようになります...


1
いくつかのリンクまたは詳細な説明が役に立つでしょう
Gaz_Edge

申し訳ありませんが、まだコメントできません..
Matt Koskela
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.