リレーショナルデータベースでシングルトンをモデル化する最良の方法


12

Webアプリケーション用のリレーショナルデータベーススキーマを設計するとき、1つの行と1つの行のみを含むテーブルを作成する場合がよくあります。それはそれを設計する間違った方法のように感じますが、私は大幅に良いものを思い付くことができません、またはそれは明らかに「それを行うための正しい方法」です。

最近の例は、ユーザーがホームページのコンテンツを手動で制御できるサイトです。さて、ホームページは1つしかありません。説明テキストを含む領域のテキストフィールドなど、ホームページを作成するために必要なすべてのフィールドを持つテーブルを作成しました。大きな画像ファイルの名前を保存するフィールド。ホームページなどで紹介される記事を指すいくつかの外部キー。それは機能しますが、1行だけのテーブルがあるのは間違っているように感じます。

過去に、ホームページのテーブルで複数の行を許可したり、ランダムに1つの行を選択するなど、他の多くのデザインを試しました。「active」という名前のブールフィールドを追加して、アクティブなホームページの1つをランダムに選択しようとしました。アプリケーションロジックで、常に1行のみをアクティブにしようとしました。ホームページテーブルを作成せず、記事などの他のすべてのアイテムにfeatured_on_homepageのような名前のブールフィールドを持たせることさえしませんでした。

ほとんどの場合、設定ファイルに一連の定数を含むホームページを作成できます。設定ファイルの主な問題は、開発者が制御できることです。ホームページの内容のようなものはユーザーが編集するものなので、データベースに入れなければなりません。

多くのサイトでは、5つの最新記事を選択するなどのクエリを使用してホームページのようなものを作成できるため、この問題はありません。しかし、厳密な要件で手動でキュレーションされたページがある場合、データベースでモデル化するのは難しいです。しかし、写真の表と記事の表があるとします。要件は、ホームページにユーザーが手動で制御する写真を正確に5つ、記事を3つ、任意のテキストのブロックを2つ表示することです。データベースでそれを正しい方法でどのようにモデル化しますか?

また、ホームページだけでなく、他の多くのケースでもこのモデリングの問題があります。これは、私が思いつく最も簡単で最も一般的に適用可能な例です。


単一の行のテーブルがどのような問題をあなたに提示するのかは、それが何らかの形でテーブルの無駄を表していることを除いて、まったく明確ではありません。実際に苦しんでいる問題を解決しようとしていると確信していますか?
デビッドアルドリッジ

回答:


10

1つの簡単なアプローチは、名前と値の列で構成される[プロパティ]テーブルにホームページのプロパティを保存する(または別の名前を付ける)ことです。

HomePageProperty1-UserValue1

HomePageProperty2-UserValue2

理想的なソリューションではないかもしれませんが、シンプルで柔軟です。また、1行のシナリオのテーブルも削除されます。


1
このアプローチは複数の目的で機能します。たとえば、スキーマバージョン情報、毎日サイクルする必要があるもののローテーションポインターなどを保存します。スキーマバージョン情報は、問題を診断するときに重要です。これは、データベースのみの修正にパッチを確実に適用するための合理的な方法です。
ベリンロリチュ

2
+1-これは、データアーキテクトが同様の目的で提供してくれた正確なテーブルレイアウトです。
アリ

3
このアプローチの問題は、異なる変数タイプを異なる列として表現する必要があり、どの列を使用し、どの列が必須であるかを示すロジックを持っていることです。ブール値がブール値であること、日付が日付であること、特定の属性がnullであること、特定の範囲内に収まること、または条件を満たす必要があることを定義することはできません。単一行テーブルを使用します。
デビッドアルドリッジ

3

解決する必要のある問題があることは私には明らかではありません。

単一行のテーブルはデータベース自体の問題ではなく、データにデータ型と制約を適用できます。

正直に言って、あなたが本当の問題を解決しようとしているのかどうかはわかりません。


2

実際にファイルとして保存する必要があるものにデータベースを使用しているように思えます。

あなたの説明は、ユーザーがコンテンツを編集できる多くのWikiページを思い出させます。Wiki、または少なくとも私が見た実装では、ページはファイルとして保持されます。

これにより、ユーザーがホームページをキャッシュできるようにするなど、他のWebの詳細に役立ちます。これは、ページをファイルとして保存すると実質的に無料になりますが、データベースに保存されているコンテンツに基づいて、すべてのリクエストのページ。

いずれにせよ、アプリケーションの永続データのほとんどがデータベースに保存されていても、そこにすべてを保存する必要があるわけではないことを明確にしたいだけです。データベースは、私たちの取引のツールの1つにすぎません。できる限り多くの異なるツールをうまく活用することを学ばなければなりません。


2

1行のテーブルには何の問題もありません。

これが設計の一部である場合、強制する必要があります。テーブルにID列を指定し、一意性制約を指定してから、列制約を追加して単一の値のみを許可します。これにより、誰も2番目の行を追加できなくなります。これは、テーブルを読み取るSQLステートメントに(当然のことながら)where句がない場合、壊滅的な結果になる可能性があります。

多数の列を取得し始めると、テーブルを絞り込み、代わりに構成アイテムごとに1行を作成したくなる場合があります。型の安全性と検証を失うため、これは最善のアイデアではありません。また、マルチテナンシーとの前方互換性が失われますが、これはあなたにとって重要かもしれません。より良い解決策は、エンティティが実際に何であるかを再考し、エンティティごとに個別の単一行テーブルを用意することです。

はい、私は単一行のテーブルがOKであると言っているだけではありませんが、複数のテーブルが必要かもしれません。


1

STATIC_CONTENTというテーブルを作成し、キーとコンテンツ、アクティブ/非アクティブトラッカーなどの列を作成します。次に、「HomePage」というキーを持つ行を作成し、ホームページにそのキーの静的コンテンツを読み込みます。表示します。そのようにして、他の静的コンテンツ(ページ、連絡先ページなど)がある場合、そのテーブルに行を追加できます。


1

1行のみのテーブルを作成すること自体に問題はありません。特定のエンティティのインスタンスが1つしかない場合は、これを表現する最も自然な方法かもしれません。

しかし、行をランダムに選択することは間違っていて悪いことです。ドメインロジックが単一の行のみを想定している場合、実際にそれ以上ある場合は明らかにデータのエラーです。だから、誰が何を無効なデータをデータベースに書き込んでいるかを把握し、そうしないようにする必要があります!データベースによっては、テーブルに制約を追加して、最初にこれが発生しないようにすることができます。たとえば、特定の値のみを主キーとして許可します。


0

Walterに追加するだけです。

プロパティテーブルの構造は、複数のデータ型を許可する必要があります。

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue

これで、行ごとに1つのプロパティ値のみが設定されることをどのように保証しますか?アプリケーションでそれを実施するのは十分簡単ですが、誰かがデータベースを手動で更新し、そこにいくつかのデータを貼り付けるとどうなりますか?
アプレッシュ

0

1レベル以上抽象化できたようです。結局、「HomePage」は「ページ」です。必要なプロパティを持つさまざまなタイプのページを作成できます。サイトにセクションがある場合は、おそらく「SectionHomePage」が必要になりますが、これは「Home Page」と同じように機能します。

要件は、ホームページにユーザーが手動で制御する写真を正確に5つ、記事を3つ、任意のテキストのブロックを2つ表示することです。データベースでそれを正しい方法でどのようにモデル化しますか?

このように試してみましょう。ArticlePageテーブルを追加するので、それに応じてプロパティを分離する方法がわかります。

PAGES
Id
Title
Description

HOMEPAGES
PageId (FK)
PhotoListLimit
ArticleListLimit
TextBlockListLimit

ARTICLEPAGE
PageId (FK)
ArticleMainQuote
ArticleMainBody
ArticlePhoto1
ArticlePhoto2

それは私にとってはうまくいくでしょうし、大きなサイトにとってもうまくいくでしょう。

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