web-dev-qa-db-ja.com

(a)人と組織が(b)送金と受け取りができる送金ビジネスのデータベースを開発する

関連性のビジネスコンテキストでは、 members organizations の両方に account が必要です資金資金送金可能

  • member から member
  • member から organization
  • organization から organization まで、および
  • organization から member へ。

考慮事項

このようなシナリオのデータベースを構築するために、次の3つのテーブルを作成しました。

CREATE TABLE Members ( 
  memberid serial primary key, 
  name varchar(50) unique, 
  passwd varchar(32), 
  account integer 
);

CREATE TABLE Organizations (  
  organizationid serial primary key, 
  name varchar(150) unique, 
  administrator integer references Members(memberid), 
  account integer 
);

CREATE TABLE TransferHistory  
  "from" integer, -- foreign key?
  "to" integer, -- foreign key?
  quantity integer 
);

who/what funds whomに送信するには、TransferHistoryテーブルが必要だと思います/ what

問題は、MembersOrganizationsが異なるテーブルであるため、TransferHistoryテーブルからそれらをどのように参照できるかです。

たとえば、関連するデータは次のように表示されます。

Account      Account      Quantity
-----------  -----------  --------
 1072561733  38574637847       500
38574637847   1072561733       281

accounts は同じテーブルに記録する必要があることを示唆していますが、 accounts は2種類の用ですowners members および organizations )、それぞれがそれぞれのテーブルに保持されます。

Accountsというテーブルを作成できたので、次の4つのテーブルができます。

CREATE TABLE Members (
  memberid serial primary key, 
  name varchar(50) unique, 
  passwd varchar(32), 
  accountid integer references Accounts(accountid) 
);

CREATE TABLE Organizations (
  organizationid serial primary key, 
  name varchar(150) unique, 
  administrator integer references Members(memberid), 
  accountid integer references Accounts(accountid)
);

CREATE TABLE Accounts ( 
  accountid serial primary key, 
  state integer 
);

CREATE TABLE TransferHistory ( 
  "from" integer references Accounts(accountid), 
  "to" integer references Accounts(accountid), 
  quantity integer 
);

...しかし、私はMembersおよびOrganizationsテーブルの各外部キーがAccountテーブルの同じAccounts行を指さないことを確認する必要があります。 ..

...または、1つのAccountsを指し、もう1つがMembersを指す2つの外部キーを持つOrganizationsテーブルを持つことができます(1つの外部キー列にはNULLを含める必要があります)常にマーク)。しかし今、物事はクエリに関して少し混乱します。データベースの設計は、一般的に言えば、次のようになります。

CREATE TABLE Members ( 
  memberid serial primary key, 
  name varchar(50) unique, 
  passwd varchar(32) 
);

CREATE TABLE Organizations (
  organizationid serial primary key, 
  name varchar(150) unique, 
  administrator integer references Members(memberid) 
);

CREATE TABLE Accounts ( 
  accountid serial primary key, 
  member integer references Members(memberid), 
  organization integer references Organizations(organizationid),
  state integer 
);

CREATE TABLE TransferHistory ( 
  "from" integer references Accounts(accountid), 
  "to" integer references Accounts(accountid), 
  quantity integer 
);

それで、誰かがこの問題を解決する方法について提案をしていますか?

7
aarnes

アカウントテーブルを追加しても、根本的な問題は変わりません。

TransferHistoryでは、TransferFromとTransferFromTypeを使用できます。ここで、TransferFromはメンバーまたは組織IDの値であり、TransferFromTypeは「M」または「O」です。ここでは外部キーをまったく使用できず、参照の整合性を「手動で」(たとえば、トリガーを使用して)維持する必要があります。 TransferToについても同様です。

クエリは次のようになります(必要に応じて実際のフィールドに置き換えます)。

SELECT COALESCE(of.OrgName, mf.MemberName) as "From"
      ,COALESCE(ot.OrgName, mt.MemberName) as "To"
      ,th.*
  FROM TransferHistory th
         LEFT JOIN Organization ot ON (th.TransferTo = ot.ID AND th.TransferToType = 'O')
         LEFT JOIN Member mt ON (th.TransferTo = mt.ID AND th.TransferToType = 'M')
         LEFT JOIN Organization of ON (th.TransferFrom = of.ID AND th.TransferFromType = 'O')
         LEFT JOIN Member mf ON (th.TransferFrom = mf.ID AND th.TransferFromType = 'M')
;

または、TransferFromMemberTransferFrom Org、TransferToMember andTransferToOrg`、すべての外部キーの4つのフィールドがあり、制約を使用してFromとToが1つだけ設定されるようにします。

クエリは次のようになります(必要に応じて実際のフィールドに置き換えます)。

SELECT COALESCE(of.OrgName, mf.MemberName) as "From"
      ,COALESCE(ot.OrgName, mt.MemberName) as "To"
      ,th.*
  FROM TransferHistory th
         LEFT JOIN Organization ot ON (th.TransferToOrg = ot.ID)
         LEFT JOIN Member mt ON (th.TransferToMember = mt.ID)
         LEFT JOIN Organization of ON (th.TransferFromOrg = of.ID)
         LEFT JOIN Member mf ON (th.TransferFromMember = mf.ID)
;
1
RDFozz