web-dev-qa-db-fra.com

Développer une base de données pour une entreprise de transferts de fonds où (a) les personnes et les organisations peuvent (b) envoyer et recevoir de l'argent

Dans le contexte commercial de pertinence, les deux membres et Organisations besoin d'avoir un compte Pour Fonds. Fonds peut être transféré

  • de membre to membre,
  • de membre to organisation,
  • de organisation to organisation, et
  • de organisation to membre.

Considérations

Afin de créer une base de données pour un tel scénario, j'ai créé les trois tables suivantes:

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 
);

Je pense que la table TransferHistory est nécessaire pour montrer qui/quoi Envoyé Fonds to Qui/What =.

Le problème est, puisque Members et Organizations sont des tables différentes, comment puis-je les référer à partir de la table TransferHistory?

Par exemple, les données impliquées peuvent apparaître comme suit:

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

Cela suggérerait que comptes doit être enregistré dans la même table, mais comptes sont pour deux types différents de propriétaires ( Membres et Organisations), chacun est conservé dans leur table respective.

Je pourrais créer une table appelée Accounts, alors maintenant j'aurais quatre tables:

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 
);

... Mais maintenant, je dois m'assurer que chaque clé étrangère de Members et Organizations tables ne pointe pas sur la même Account rangée dans Accounts table. ..

... ou je pourrais avoir une table Accounts ayant deux clés étrangères, l'une pointant vers Members et une autre à Organizations (et une colonne de clé étrangère devraient contenir une nulle marque à tout moment). Mais maintenant, les choses se déroulent un peu confondes par rapport aux requêtes. La conception de la base de données serait en général, comme suit:

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 
);

Donc, quelqu'un a-t-il une suggestion sur la façon de résoudre ce problème?

7
aarnes

L'ajout du tableau de compte ne semble pas modifier le problème fondamental.

En transfert, vous pourriez avoir transféréfrom et transfertType, où le transfert est membre d'un membre ou d'une valeur d'identification de l'organisation, et que Transferfromtype est "M" ou "O". Vous ne pouvez pas utiliser des clés étrangères ici et devriez maintenir une intégrité référentielle "manuellement" (par exemple, avec des déclencheurs). Idem pour transfert.

Une requête ressemblerait à ceci (remplacer par les champs réels au besoin):

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')
;

Ou, vous avez 4 champs, TransferFromMember, TransferFrom Org, Transfert] andtransfertoorg`, toutes les clés étrangères et utilisez des contraintes pour en assurer un seul et un à celui de celui-ci.

Une requête ressemblerait à ceci (remplacer par les champs réels au besoin):

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