158

ショッピング カート アプリケーションの開発中に、管理者の設定と要件に基づいて設定と構成を保存する必要があることがわかりました。この情報は、会社情報、配送アカウント ID、PayPal API キー、通知設定など、何でもかまいません。

リレーショナル データベース システムに 1 つの行を格納するためにテーブルを作成することは、非常に不適切に思えます。

この情報を保存する適切な方法は何ですか?

注: 私の DBMS は SQL Server 2008 で、プログラミング層は ASP.NET (C#) で実装されています。

4

12 に答える 12

207

私は過去にこの 2 つの方法 (単一行テーブルとキーと値のペア テーブル) を実行しましたが、それぞれのアプローチには長所と短所があります。

単列

  • 正: 値は正しい型で格納されます
  • 肯定的: コードで扱う方が簡単です (上記の理由により)
  • 正: 各設定に個別にデフォルト値を指定できます
  • マイナス: 新しい設定を追加するには、スキーマの変更が必要です
  • マイナス: 設定が多い場合、テーブルが非常に広くなる可能性があります

キーと値のペア

  • 肯定的: 新しい設定を追加しても、スキーマを変更する必要はありません
  • 肯定的: テーブル スキーマが狭く、新しい設定に余分な行が使用されている
  • 否定的: 各設定のデフォルト値は同じ (null/空?)
  • マイナス: すべてを文字列として保存する必要があります (つまり、nvarchar)
  • マイナス: コードで設定を扱うときは、設定の種類を知ってキャストする必要があります

単一行オプションは、作業が断然簡単です。これは、各設定を正しい型でデータベースに格納できるため、設定の型とその参照キーをコードに格納する必要がないためです。

このアプローチを使用する際に私が懸念したことの 1 つは、「特別な」単一行設定テーブルに複数の行があることでした。私は(SQL Serverで)これを克服しました:

  • デフォルト値が 0 の新しいビット列を追加する
  • この列の値が 0 であることを確認するチェック制約を作成する
  • ビット列に一意の制約を作成する

つまり、ビット列の値は 0 でなければならないため、テーブルには 1 つの行しか存在できませんが、一意の制約により、その値を持つ行は 1 つしか存在できません。

于 2010-02-20T00:13:40.143 に答える
11

情報の種類と情報の値 (少なくとも) の列を含むテーブルを作成する必要があります。これにより、新しい情報が追加されるたびに新しい列を作成する必要がなくなります。

于 2010-02-19T23:44:22.443 に答える
6

1 行でも問題なく動作します。強力な型もあります。

show_borders    bit
admin_name      varchar(50)
max_users       int

欠点の 1 つはalter table、新しい設定を追加するためにスキーマの変更 ( ) が必要になることです。1 つの代替手段は、次のようなテーブルになる正規化です。

pref_name       varchar(50) primary key
pref_value      varchar(50) 

これには弱い型 (すべてが varchar) がありますが、新しい設定を追加することは行を追加することであり、データベースへの書き込みアクセスだけで実行できます。

于 2010-02-20T00:06:30.410 に答える
5

個人的には、それが機能する場合は、単一の行に保存します。それをSQLテーブルに格納するのはやり過ぎですか? おそらくですが、そうしても実際に害はありません。

于 2010-02-19T23:57:17.207 に答える
4

ご想像のとおり、最も単純な状況を除いて、すべての構成パラメーターを 1 つの行に配置すると、多くの欠点があります。それは悪い考えです...

構成および/またはユーザー設定タイプの情報を保存する便利な方法は、 XMLです。多くの DBMS が XML データ型をサポートしています。XML 構文を使用すると、この構成が進化するにつれて、構成を記述する「言語」と構造を拡張できます。XML の利点の 1 つは、階層構造を暗黙的にサポートしていることです。たとえば、番号付きの接尾辞を付けて名前を付けることなく、構成パラメーターの小さなリストを格納できます。XML 形式の考えられる欠点は、このデータの検索と一般的な変更が他のアプローチほど単純ではないことです (複雑なことは何もありませんが、単純/自然ではありません)。

リレーショナル モデルに近づきたい場合はEntity-Attribute-Value モデルがおそらく必要なモデルです。これにより、個々の値が通常次のようなテーブルに格納されます。

EntityId     (foreign key to the "owner" of this attribute)
AttributeId  (foreign key to the "metadata" table where the attribute is defined)
StringValue  (it is often convenient to have different columns of different types
IntValue      allowing to store the various attributes in a format that befits 
              them)

ここで、AttributeId は、考えられる各属性 (この場合は「構成パラメーター」) が定義されているテーブルへの外部キーです。

AttributeId  (Primary Key)
Name
AttributeType     (some code  S = string, I = Int etc.)
Required          (some boolean indicating that this is required)
Some_other_fields   (for example to define in which order these attributes get displayed etc...)

最後に、EntityId を使用すると、これらのさまざまな属性を「所有」するエンティティを識別できます。あなたの場合、管理する構成が 1 つしかない場合は、UserId または単に暗黙的である可能性があります。

アプリケーションの進化に応じて可能な構成パラメータのリストを拡張できるようにすることは別として、EAV モデルは「メタデータ」、つまり属性自体に関連するデータをデータテーブルに配置するため、一般的に見られる列名のすべてのハードコーディングを回避します。構成パラメーターが単一の行に格納されている場合。

于 2010-02-20T00:03:42.997 に答える
3

正規化されたアプローチで新しい構成パラメーターを追加するときにスキーマを変更する必要はありませんが、新しい値を処理するためにコードを変更している可能性があります。

デプロイメントに「alter table」を追加することは、単一行アプローチの単純さと型の安全性との大きなトレードオフのようには思えません。

于 2011-03-22T13:48:28.550 に答える
2

キーと値のペアは、構成設定を保存できる .Net App.Config に似ています。

したがって、値を取得したい場合は、次のことができます。

SELECT value FROM configurationTable
WHERE ApplicationGroup = 'myappgroup'
AND keyDescription = 'myKey';
于 2011-05-02T22:06:57.620 に答える
1

これを行う一般的な方法は、プロパティ ファイルと同様の「プロパティ」テーブルを作成することです。ここには、すべてのアプリの定数を保存することも、必要な定数だけを保存することもできます。

必要に応じて、このテーブルから情報を取得できます。同様に、保存する設定が他にもあることがわかったら、それを追加できます。以下に例を示します。

property_entry_table

[id, scope, refId, propertyName, propertyValue, propertyType] 
1, 0, 1, "COMPANY_INFO", "Acme Tools", "ADMIN"  
2, 0, 1, "SHIPPING_ID", "12333484", "ADMIN"  
3, 0, 1, "PAYPAL_KEY", "2143123412341", "ADMIN"   
4, 0, 1, "PAYPAL_KEY", "123412341234123", "ADMIN"  
5, 0, 1, "NOTIF_PREF", "ON", "ADMIN"  
6, 0, 2, "NOTIF_PREF", "OFF", "ADMIN"   

このようにして、あなたが持っているデータと、来年持っていてまだ知らないデータを保存することができます :) .

この例では、スコープと refId をバックエンドで必要なものに使用できます。したがって、propertyType "ADMIN" のスコープが 0 refId 2 の場合、それがどのような設定であるかがわかります。

プロパティ タイプは、管理者以外の情報もここに格納する必要がある場合に役立ちます。

この方法でカートのデータを保存したり、検索したりしないでください。ただし、データがシステム固有の場合は、この方法を確実に使用できます。

例: DATABASE_VERSIONを保存する場合は、次のようなテーブルを使用します。こうすることで、アプリをアップグレードする必要があるときに、プロパティ テーブルをチェックして、クライアントが使用しているソフトウェアのバージョンを確認できます。

ポイントは、これをカートに関連するものに使用したくないということです。適切に定義されたリレーショナル テーブルにビジネス ロジックを保持します。プロパティ テーブルはシステム情報専用です。

于 2010-02-20T00:02:20.410 に答える
1

キー列を varchar に、値列を JSON にします。1は数値"1"ですが、文字列です。trueおよびfalse両方ともブール値です。オブジェクトを持つこともできます。

于 2016-04-11T16:30:26.923 に答える
0

単一の行が構成の最適な実装であるかどうかはわかりません。構成アイテムごとに 2 つの列 (configName、configValue) を持つ行を持つ方がよいかもしれませんが、これにはすべての値を文字列にキャストして戻す必要があります。

とにかく、グローバル構成に単一の行を使用しても害はありません。それをDB(グローバル変数)に保存するための他のオプションはもっと悪いです。最初の構成行を挿入してから、テーブルへの挿入を無効にして複数の行を防ぐことで、それを制御できます。

于 2010-02-19T23:44:07.437 に答える
0

各主要なタイプの列と、データがどの列にあるかを示す 1 つの列を追加することで、変換せずにキー/値のペアを実行できます。

したがって、テーブルは次のようになります。

id, column_num, property_name, intValue, floatValue, charValue, dateValue
1, 1, weeks, 51, , ,
2, 2, pi, , 3.14159, , 
3, 4, FiscYearEnd, , , , 1/31/2015
4, 3, CompanyName, , , ACME, 

もう少し多くのスペースを使用しますが、せいぜい数十の属性を使用しています。column_num 値から case ステートメントを使用して、右側のフィールドをプル/結合できます。

于 2015-01-16T01:11:11.803 に答える
0

ごめんなさい、何年も後に来て。とにかく、私がしていることはシンプルで効果的です。3 つの () 列を持つテーブルを作成するだけです。

ID - 整数 (11)

名前 - varchar (64)

値 - テキスト

新しい構成列を作成、更新、または読み取る前に行うことは、「値」をシリアル化することです! このようにして、私はタイプを確信しています(まあ、phpは:)です)

例えば:

b:0; BOOLEAN用( false )

b:1; BOOLEAN用( true )

私:1988; 私はNTのためです

s:5:"ケーダー"; は5 文字の長さのS TRING 用です

これが役立つことを願っています:)

于 2016-02-01T06:28:07.093 に答える