0

私の理解では、Webサイト/データベースに新しいユーザーを登録する方法は、ユーザーのテーブルに新しいエントリを作成することです。その後、別のデータテーブルから特定のユーザーデータを取得する場合は常に、ユーザーテーブルをクエリしてユーザーIDを取得する必要があります(もちろん、まだ保存されていない場合)。そのIDをデータに対する新しいクエリで使用します。テーブル。よりモジュール化された設計が必要な場合は、最初の方法ほど一般的ではありませんが、新しいユーザーごとに新しいデータベースを作成できます。私の理解が正しいかどうかわかりませんので、適切と思われる箇所で訂正してください。

私が考えているのは、たまたま私のお気に入りのプレーヤーであるPostgreSQLでは、スキーマを使用できるということです。スキーマは、データベース内のデータベースのようなものです。次に、クエリを実行するときに、テーブル名の前にスキーマ名を付け、その間にドットを入れます。スキーマがクラスであり、その中の静的プロパティなどにアクセスしたい場合とよく似ています。表記が大好きです!

..だから、管理者関連のもののためのデータベースを1つ持っていないのはなぜですか。おそらく、そのためのユーザーテーブルですらあります。しかし、ユーザーデータ専用の別のデータベースがあり、各ユーザーは独自のスキーマを持っています。次に、PHPに格納する必要があるのはこのスキーマ名を保持する変数だけです。ユーザー固有のデータをデータベースから取得するたびに、この変数が使用されます。

新しいユーザーを登録するためのベストプラクティスは何ですか、すべきこととすべきでないことは何ですか?スキーマ設計の利点または欠点を確認できますか?

編集

この質問は私の最終目標が何であるかについていくらかの混乱を引き起こしたので、ここで私の問題を明らかにします。実際には、データベースの設計はもう少し複雑ですが、Webアプリに3つのクラスがあるとしましょう。それらの1つ(ここではFooと呼びます)は、オプションで、他の2つであるBar1およびBar2と関係があります。私のサイトの登録ユーザーは、Foo、Bar1、Bar2を互いに独立して「作成」することができます。

Fooは現在、データベース内のいくつかのテーブルに保存されています。シリアルがインクリメントする彼のメインテーブルは次のとおりです。

TABLE foo
(
  foo_id serial NOT NULL,
  title text
  CONSTRAINT foo_pk PRIMARY KEY (foo_id)
)

他のテーブルの詳細やバーの保存方法については掘り下げないでください。テーブルの数をできるだけ少なくするように注意しましたが、それでも、エンティティの関係とその制約を考慮してデータベースを設計する必要があります。

Fooは、Bar1とBar2の存在に依存している可能性があります。Fooは、Bar1とBar2を好きなだけ持つことができます。したがって、この所有権を説明するための2つの表を次に示します。

TABLE foo_has_bar1
(
  foo_id integer NOT NULL,
  bar1_id integer NOT NULL
  CONSTRAINT foo_has_bar1_pk PRIMARY KEY (foo_id, bar1_id),
  CONSTRAINT foo_has_bar1_fk1 FOREIGN KEY (foo_id) REFERENCES foo (foo_id),
  CONSTRAINT foo_has_bar1_fk2 FOREIGN KEY (bar1_id) REFERENCES bar1 (bar1_id)
)

TABLE foo_has_bar2
(
  foo_id integer NOT NULL,
  bar2_id integer NOT NULL
  CONSTRAINT foo_has_bar2_pk PRIMARY KEY (foo_id, bar2_id),
  CONSTRAINT foo_has_bar2_fk1 FOREIGN KEY (foo_id) REFERENCES foo (foo_id),
  CONSTRAINT foo_has_bar2_fk2 FOREIGN KEY (bar2_id) REFERENCES bar2 (bar2_id)
)

現在、登録ユーザーのuser_idの列はどこにもありません。私はいつもユーザーデータをスキーマで分離すると思っていました。もちろん、それらのスキーマはuser_idと一緒に別のデータベースまたはパブリックスキーマに保存されます。Catcallこのスレッドの答えの中である意味でそう言った、そして私は引用する:

「スキーマはPostgreSQLのデータベース内の名前空間です。」

[..]

「各ユーザーがそのユーザー専用のデータベースオブジェクトを持っている場合、ユーザーごとに1つのスキーマを実装するという決定を簡単に防御できます[..]。」

だから私は心配しています、ベストプラクティスは何ですか?このスレッドのすべての答えの感覚によると、私は別々のスキーマを使用することを検討するべきではありません。しかし、それでは、object_idとuser_id [1]を結び付けるオブジェクトのタイプごとに、もう1つのテーブルを用意する必要はありませんか?現在は管理可能ですが、個別のスキーマを使用するだけでなく、これによって「名前空間」がどのように乱雑になるかを確認できます。

[1] PostgreSQLでは、各行がユーザーを表し、user_idの後の各列がオブジェクトの関係を識別する整数配列の列である場合、これを1つのテーブルに分割できます。しかし、PostgreSQLの配列(PHPでの配列の読み取りと変更)に関する私の経験は悪い悪い悪いです。また、それらの処理は複数のテーブルよりも遅いと思います。

4

3 に答える 3

2

私はそれに反対することをお勧めします。

最終的には、ユーザーごとに多くのスキーマが作成されます。これらすべてのユーザーに対して何かをクエリしたい場合は、フープを飛び越える必要があります。

例を挙げましょう。ユーザーごとにユーザーがログインした回数を保存するとします。次に、すべてのユーザーがログインした回数を知りたいとします。

保存するエンティティごとに1つのテーブルを使用し、それにユーザーIDを追加することをお勧めします。

CREATE TABLE tbluserdata(
  userdataid SERIAL PRIMARY KEY,
  userid integer REFERENCES tblusers(userid),
  nroflogins integer,
  mydata TEXT,
  whatever integer,
  etc. etc.
);

そして、各クエリでユーザーIDを使用します。私の意見でははるかにきれいです。

于 2012-10-02T10:47:18.897 に答える
2

あなたはあなたのウェブユーザーとデータベースユーザーを混乱させていると思います。

一般的な方法は、ユーザーをユーザーテーブルに保存することです。データを複数のスキーマに分散させると、実際のメリットなしに効果的なクエリを実行することが不可能になります。

CREATE TABLE users (
    id   serial PRIMARY KEY,
    name text NOT NULL
);

行う:

  • 暗号化されたパスワードとソルトを保存する
  • 主キーを使用してクエリを高速化する
  • データベースに挿入する前にデータを検証する

しないでください:

  • パスワードをプレーンテキストで保存する
  • ユーザー入力を信頼する
于 2012-10-02T10:58:13.653 に答える
2

私の理解では、Webサイト/データベースに新しいユーザーを登録する方法は、ユーザーのテーブルに新しいエントリを作成することです。その後、別のデータテーブルから特定のユーザーデータを取得する場合は常に、ユーザーテーブルをクエリしてユーザーIDを取得する必要があります。

通常、ログインしたユーザーのIDをアプリケーション変数に保存します。そうすれば、データベースにクエリを実行する必要はありません。Webアプリの場合、このようなものはセッション変数またはCookieに保存されることがよくあります。ユーザーが他人のデータにアクセスするために任意のID番号を単純に入力できないように注意してください。

よりモジュール化された設計が必要な場合は、最初の方法ほど一般的ではありませんが、新しいユーザーごとに新しいデータベースを作成できます。私の理解が正しいかどうかわかりませんので、適切と思われる箇所で訂正してください。

「ユーザーごとに1つのデータベース」は、マルチテナント(マルチカスタマー)データベース設計へのさまざまなアプローチの一端です。たとえば、オンライン会計ソフトウェアを構築した場合、テナントごとに1つのデータベースを実装することを合理的に選択できます。これにより、データの分離が最も簡単になり、ディザスタリカバリが最も簡単になり、カスタマイズの機会が最も多くなります。

「ユーザーごとに1つのデータベース」は、マルチユーザーデータベースの設計には適していません。StackOverflowは、この意味でマルチユーザーシステムです。

スキーマは、データベース内のデータベースのようなものです。

スキーマは、PostgreSQLのデータベース内の名前空間です。オンライン会計ソフトウェアを構築する場合、テナントごとに1つのスキーマを実装することを合理的に選択できます。スキーマレベルでアクセス許可を付与できるため、1人のユーザーのデータを他のすべてのユーザーから簡単に分離できます。災害復旧はかなり簡単です。単一のスキーマを復元するだけです。共有テーブル、ビュー、およびプロシージャを、すべてのユーザーが読み取ることができる別のスキーマに配置することもできます。

設計上、PostgreSQLではデータベース間でのクエリが比較的困難になっています。スキーマ間でのクエリは比較的簡単です。

「ユーザーごとに1つのスキーマ」は、マルチユーザーデータベースの設計には適していません。たとえば、StackOverflowを実行すると、400万のスキーマが作成される可能性があります。

..だから、管理者関連のもののためのデータベースを1つ持っていないのはなぜですか。おそらく、そのためのユーザーテーブルですらあります。しかし、ユーザーデータ専用の別のデータベースがあり、各ユーザーは独自のスキーマを持っています。次に、PHPに格納する必要があるのはこのスキーマ名を保持する変数だけです。ユーザー固有のデータをデータベースから取得するたびに、この変数が使用されます。

各ユーザーがそのユーザー専用のデータベースオブジェクトを持っている場合、ユーザーごとに1つのスキーマを実装し、共有テーブル、ビュー、プロシージャなどに準パブリックスキーマを使用するという決定を簡単に防御できます。アプリケーション最適な決定。

「ユーザーごとに1つのスキーマ」は、マルチテナントデータベース設計の範囲におけるもう1つのポイントです。

そのスペクトルの遠端は、「すべてのユーザーが(ほぼ)すべてのテーブルを共有する」ことです。各行には、各行を所有しているユーザーを示すユーザーの識別子が含まれています。あるユーザーのデータを別のユーザーに誤って公開しないように、コーディングにはさらに注意を払う必要があります。災害復旧は面倒です。

SOにはマルチテナントタグがあります。あなたはそれをあなたのお気に入りの1つにしたいかもしれません。それがあなたが向かっている方向であるように思われるので、私はあなたの質問にそのタグを追加しました。

于 2012-10-02T13:24:38.840 に答える