web-dev-qa-db-ja.com

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

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

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

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

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

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

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

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

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

11
Gaz_Edge

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

しないでください。

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

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

あなたはREST apiがGET /users/{userID}/clients/{clientID}/sales/{salesID}で識別されるリソースのリクエストを適切なデータベースクエリに変換し、行を取得し、Saleを表すリソースを作成してクライアントに返します。

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

31

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

補足として:user/{userID}をURIに含めます。認証情報からテナント(userID)がわかります。

9
Remus Rusanu

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

0
Matt Koskela