2

私が思いついたこのデータモデルを見ていますが、快適ではありません。エンティティ名を変更したので、(うまくいけば)より意味がありました。いずれにせよ、以下をどのようにモデル化しますか?

私は3つのエンティティを持っています。政府顧客、個人顧客、公共顧客。プライベート カスタマーとパブリック カスタマーはどちらも CorporateCustomer です。企業および政府の顧客はアカウントです。すべてのアカウントは同じキー スペースを共有します (したがって、PrivateCustomer の PK が 1 の場合、Public または GovernmentCustomer の PK が 1 になることはありません)。CorporateCustomers には、GovernmentCustomer にはない 1:M の関係があります。PublicCustomers には、PrivateCustomers にはない 1:M の関係があります。

継承:

Account
  CorporateCustomer
    PrivateCustomer
    PublicCustomer
  GovernmentCustomer

現在、私のモデルには 5 つのテーブルがあります。「アカウント」テーブルはこの階層のルートであり、各子テーブルの PK はその親の PK の FK です。したがって、すべてのテーブルの PK は同じです。

ええ、これをどのようにモデル化しますか?ここで何かが大きく間違っていないことを願っています:)。

編集:

また: - アプリではなく、DB が ref の整合性を処理するようにしたいと思います。- CorporateCustomer は、Private または Public のいずれかの顧客にならずに存在することはできません。その抽象。

4

6 に答える 6

1

すべてのクラスを同じテーブルに配置することを約束する前に、属性ではなく、それらが関係している関係を確認します。レコード タイプが 'X' の場合、特定のフィールドを null のままにしておくのは簡単ですが、テーブル内の特定のレコードにのみ適用されるリレーションシップを作成しようとするのは非常に扱いにくいものです。

クラスと他のエンティティとの関係がまったく同じである場合、それらすべてを 1 つのテーブルに詰め込むことができますが、実際の欠点はありません。

于 2011-04-28T22:46:24.920 に答える
1

1つの方法は次のとおりです。

ACCOUNTS -> ACCOUNT_CUSTOMERS <- CUSTOMERS

CUSTOMERS に、Corporate(C)、Private(P)、Public(Z)、Government(G) の CUSTOMER_TYPE 列を持たせます。すべてのパブリックおよび pivate 顧客も企業であるため、すべての法人顧客を取得する必要がある場合は、次のようにすることができます。

SELECT *
  FROM ACCOUNTS
     , ACCOUNT_CUSTOMERS
     , CUSTOMERS
 WHERE ACCOUNTS.ID = ACCOUNT_CUSTOMERS.ACCT_ID
   AND CUSTOMERS.ID = ACCOUNT_CUSTOMERS.CUST_ID
   AND CUSTOMERS.CUSTOMER_TYPE in ('C','P','Z')

私は ORACLE 構文を使用しましたが、おわかりいただけたと思います。

In response to your edit:

2 種類の顧客しかいないようですね。企業および政府。これはさらに簡単です。false が非公開の場合は PUBLIC_IND と呼ばれる CUSTOMERS のブール値インジケーターを使用するか、Private(P)、Public(Z)、または None(N) の可能性がある ENTITY_TYPE のような別の型を使用します。次に、すべてのパブリック法人顧客ユーザーを取得する場合:

SELECT *
      FROM ACCOUNTS
         , ACCOUNT_CUSTOMERS
         , CUSTOMERS
     WHERE ACCOUNTS.ID = ACCOUNT_CUSTOMERS.ACCT_ID
       AND CUSTOMERS.ID = ACCOUNT_CUSTOMERS.CUST_ID
       AND CUSTOMERS.CUSTOMER_TYPE in ('C')
       AND CUSTOMERS.ENTITY_TYPE = 'Z'
于 2009-06-19T04:29:14.660 に答える
0

異なるタイプの顧客が類似している場合は、customerTypeフィールドで十分であることに同意します。

とはいえ、おそらく企業の顧客だけがテーブルを共有しますが、政府の顧客は十分に異なっているため、独自のテーブルで定義する必要があります。これが保証されている場合、PK制約を適用するのに役立つ1つの設計は、ID(PK制約)によってすべての顧客を参照するMasterAccountテーブルを持ち、次のレベルの顧客のタイプへの参照を持つことです。階層(企業または政府)。

1- *リレーションシップをマッピングする必要があります。これは、リレーションシップテーブルとアカウントリレーションシップマッピングテーブルの2つのテーブルで行うことができます。

于 2009-06-19T04:58:49.503 に答える
0

さまざまなタイプの顧客間で追跡される属性に大きな違いがない限り、いくつかの CustomerType フィールドを持つ Account という名前のテーブルを 1 つだけ用意します。AccountID への FK を持つ詳細テーブルによって、1:m の関係を表現できます。

編集: 最新のデータベースは、FK 参照整合性を超えたデータ整合性ルールを追加できます。たとえば、SQL Server では、CHECK 制約を追加して、特定の詳細テーブルのマスターに対して AccountType を GovernmentCustomer に強制することができます。次のようになります。

CREATE FUNCTION EnforceGovernmentCustomer(@AccountID int)
RETURNS bit
AS 
BEGIN
   DECLARE @retval bit
   SELECT @retval = 0
   SELECT @retval = 1
   FROM Account
   WHERE AccountID = @AccountID AND AccountType = 3

   RETURN @retval
END;
GO
ALTER TABLE GovernmentCustomerDetail
ADD CONSTRAINT chkGovernmentCustomer CHECK (dbo.EnforceGovernmentCustomer(AccountID) = 1);
GO
于 2009-06-19T04:21:34.860 に答える
0

CustomerRelationship テーブルに加えて、Account テーブルと Customer テーブルがあればよいと思います。さまざまな種類の顧客を何らかの種類のコードで区別でき、CustomerRelationship テーブルを使用して関係を維持できます。

于 2009-06-19T04:22:35.017 に答える
0

この質問が非常に古いことは知っていますが、まだ受け入れられた回答がないため、いくつかのアイデアがあります。

1 つの可能性は、ORDBMS 機能を使用することです。つまり、テーブルの継承を使用します。PostgreSQL では、次のようにモデル化できます。

(PostgresSQL の継承に関するドキュメントを参照してください http://www.postgresql.org/docs/9.3/static/ddl-inherit.html )

CREATE TABLE account
(
   account_id INT,
   PRIMARY KEY(account_id)
);

CREATE TABLE corporate_customer
(
   company_name VARCHAR(32),
   country_code CHAR(2),
   PRIMARY KEY(company_name)
) INHERITS(account);

CREATE TABLE private_corp_customer
(
   private_comp_id INT,
   company_owner VARCHAR(32),
   PRIMARY KEY(private_comp_int)
) INHERITS(corporate_customer);

CREATE TABLE public_corp_customer
(
   stock_ticker VARCHAR(6),
   PRIMARY KEY(stock_ticker)
) INHERITS(corporate_customer);

CREATE TABLE government_customer
(
   dept_nbr INT,
   country CHAR(2),
   PRIMARY KEY(dept_nbr)
) INHERITS(account);

異なる DBMS ベンダーは、さまざまな方法でこれを実装します。PostgresSQL では、ここで説明する重要な注意事項がいくつかあります。

http://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-3-table.html

特に、主キーと外部キーが継承されないという部分に注意してください。

DBMS の制限が気に入らない場合、またはオブジェクト リレーショナル機能を持​​たない DBMS を使用している場合は、上記の記事で提案されている代替手段を使用し、2 次キーを使用するという別のオプションがあります。これは次のようにモデル化されます。

CREATE TABLE account
(
   account_id INT,
   account_type INT NOT NULL,
   PRIMARY KEY(account_id),
   UNIQUE (account_id, account_type)
);

CREATE TABLE corporate_customer
(
   account_id INT,
   account_type INT NOT NULL CHECK(account_type IN (1,2)),
   company_name VARCHAR(32),
   country_code CHAR(2),
   PRIMARY KEY(account_id, account_type),
   FOREIGN KEY(account_id, account_type) REFERENCES account(account_id, account_type),
   UNIQUE(account_id, account_type, company_name)
);

CREATE TABLE private_corp_customer
(
   account_id INT,
   account_type INT NOT NULL CHECK(account_type = 1),
   company_name VARCHAR(32),
   company_owner VARCHAR(32),
   PRIMARY KEY(account_id, account_type, company_name),
   FOREIGN KEY(account_id, account_type, company_name) REFERENCES corporate_customer (account_id, account_type, company_name)
);

CREATE TABLE public_corp_customer
(
   account_id INT,
   account_type INT NOT NULL CHECK (account_type = 2),
   company_name VARCHAR(32),
   stock_ticker CHAR(6),
   PRIMARY KEY(account_id, account_type, company_name),
   FOREIGN KEY(account_id, account_type, company_name) 
   REFERENCES corporate_customer (account_id, account_type, company_name)
) INHERITS(corporate_customer);

CREATE TABLE government_customer
(
   account_id INT,
   account_type INT NOT NULL CHECK(account_type = 3),
   dept_nbr INT,
   country_code CHAR(2),
   PRIMARY KEY(account_id, account_type),
   FOREIGN KEY(account_id, account_type) REFERENCES account(account_id, account_type),
   UNIQUE(account_id, account_type, dept_nbr)
 );

上記の設計にもいくつかの重要な制限があります (上記の記事でも説明されています)。1 つには、個人、公的、または政府の顧客以外のアカウントを持つことは可能であってはなりませんが、そうすることが可能です。パブリックでもプライベートでもない企業アカウントだけを持つことができます...維持するのは悪夢になります. 制約によってパフォーマンスも低下するCHECK可能性があり、子エンティティにデータの重複があり、企業の子エンティティ (country_code) に情報が欠落していることに気付くでしょう。

どの制限を選択するかは、DBMS ベンダーと、管理したい問題の程度によって異なります。

于 2014-07-20T06:03:45.833 に答える