1

テーブル間に単純な1対多の関係を持つデータベーススキーマを設計する方法を理解しています。そのセット内の特定の関係を主要な関係として指定するための規則またはベストプラクティスが何であるかを知りたいです。たとえば、1人の人が多くのクレジットカードを持っています。私はそれをモデル化する方法を知っています。それらのカードの1つをその人のプライマリとしてどのように指定しますか?私が思いついた解決策は、せいぜいエレガントではないようです。


私の実際の状況を明らかにしようと思います。(残念ながら、実際のドメインは物事を混乱させるだけです。)私は2つのテーブルを持っており、それぞれに多くの列があります。たとえば、PersonとTaskです。いくつかのプロパティしかないProjectもあります。1人の人には多くのプロジェクトがありますが、主要なプロジェクトがあります。1つのプロジェクトには多くのタスクがありますが、1つのプライマリタスクに代替のタスクがある場合もあれば、プライマリタスクがなく、代わりに一連のタスクがある場合もあります。プロジェクトの一部ではないタスクはありませんが、厳密に禁止されているわけではありません。

PERSON (PERSON_ID, NAME, ...)
TASK (TASK_ID, NAME, DESC, EST, ...)
PROJECT (NAME, DESC)

過度の複雑さや純粋な悪を導入せずに、プライマリプロジェクト、プライマリタスク、およびタスクシーケンスをすべて同時にモデル化する方法を理解することはできないようです。

これは私がこれまでに思いついた中で最高です:

PERSON (PERSON_ID, NAME, ...)
TASK (TASK_ID, NAME, DESC, EST, ...)
PROJECT (PROJECT_ID, PERSON_FK, TASK_FK, INDEX, NAME, DESC)
PERSON_PRIMARY_PROJECT (PERSON_FK, PROJECT_FK)
PROJECT_PRIMARY_TASK (PROJECT_FK, TASK_FK)

単純な概念にはテーブルが多すぎるようです。


これが私が見つけた非常によく似た状況を扱っている質問です:データベース設計:循環依存

残念ながら、この状況をどのように処理するかについてはコンセンサスが得られていないようで、「正しい」答えはデータベースの整合性チェックメカニズムを無効にすることでした。クールではありません。

4

4 に答える 4

3

さて、人はクレジットカードと2つの関係を持っているように私には思えます。1つはその人がそれを所有しているということであり、もう1つはそれを彼らの主要なクレジットカードと見なしているということです。それはあなたが1対1と1対多の関係を持っていることを私に教えてくれます。1対多の関係があるため、1対1の返品関係はすでにクレジットカードにあります。

これは、Personのフィールドとしてprimary_cc_idを追加し、CreditCardをそのままにしておくことを意味します。

于 2010-02-07T10:35:09.850 に答える
2

2つの戦略:

  1. ビット列を使用して、優先カードを示します。
  2. PrefferedCardTableを使用して、各個人をその優先カードのIDに関連付けます。
于 2010-02-07T10:36:23.700 に答える
0

1人が多くのクレジットカードを持つことができます。次に、特定のクレジットカードを1人の個人に実際にリンクするには、各クレジットカードに識別子が必要です。これは、モデルですでに作成されていると思います(その人をそのクレジットカードにリンクするある種のID)。

プライマリクレジットカード(たとえば、デフォルトのクレジットカードとしての意味ですか?)これは、ある種の手動操作である必要があります(たとえば、3番目のテーブルがあり、それらをリンクし、どれがデフォルトになるかを指定する列があります)。 )。

Person (SSN, Name)
CreditCard (CCID, AccountNumber)
P_CC (SSN, CCID, NoID)

つまり、人をクレジットカードに接続する場合は、「1」などのNoIDを指定してから、デフォルトでNoID「1」を持つこの個人に属するクレジットカードを検索するようにクエリを設計する必要があります。 '。

もちろん、これは1つの方法にすぎません。おそらく、0、1で制限し、クレジットカードがその人に追加された日付で並べ替えることができます。

たぶん、あなたがあなたのコラムとアイデアについて詳しく説明して、より多くの情報を与えるならば、それはそれをより簡単にするでしょう。

于 2010-02-07T10:40:18.700 に答える
0

そこで、ここでNorthwindとC#Windowsアプリを試してみたところ、1つのクエリしか実行されませんでした。

私のコード:

DataClasses1DataContext context = new DataClasses1DataContext();
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith<Product>(b => b.Category);
            context.LoadOptions = dlo;

            context.DeferredLoadingEnabled = false;

            context.Log = Console.Out;


            List<Product> test = context.Products.ToList();


            MessageBox.Show(test[0].Category.CategoryName);

結果:

SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued], [t2].[test], [t2].[CategoryID] AS [CategoryID2], [t2].[CategoryName], [t2].[Description], [t2].[Picture]
FROM [dbo].[Products] AS [t0]
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[CategoryID], [t1].[CategoryName], [t1].[Description], [t1].[Picture]
    FROM [dbo].[Categories] AS [t1]
    ) AS [t2] ON [t2].[CategoryID] = [t0].[CategoryID]
于 2010-11-09T02:19:40.417 に答える