如何管理数据库中的“组”?

时间:2009-05-11 20:45:10

标签: sql sql-server database-design

我已经问了这个问题here,但我认为我没有理解我的观点。

假设我有以下表格(所有PK都是IDENTITY字段):

  • 人(PersonId(PK),姓名,SSN等)
  • 贷款(贷款(PK),金额等)
  • 借款人(BorrowerId(PK),PersonId,LoanId)

让我们说史密斯先生的名字是2笔贷款,与妻子共同获得3笔贷款,还有1位与情妇一起贷款。出于申请的目的,我想要GROUP人员,这样我就可以轻松地单独列出史密斯先生与妻子共同提供的贷款。

为了实现这一点,我添加了BorrowerGroup表,现在我有以下内容(所有PK都是IDENTITY字段):

  • 人(PersonId(PK),姓名,SSN等)
  • 贷款(LoanId(PK),金额,BorrowerGroupId等)
  • BorrowerGroup(GroupId(PK))
  • 借款人(BorrowerId(PK),GroupId,PersonId)

现在,史密斯先生分为3组(他本人,他和他的妻子,他和他的情妇),我可以轻松地在任何一组中查找他的活动。

新设计的问题:

生成新BorrowerGroup的唯一方法是在IDENTITY_INSERT ON时插入MAX(GourpId)+1,这感觉不对。此外,具有1列的表的概念有点奇怪。

我坚信代理密钥,并且如果可能的话,我希望坚持这个设计。

此应用程序不关心个人,GROUP被视为个人

是否有更好的方法可以为此应用程序分组人员?

6 个答案:

答案 0 :(得分:3)

你可以删除表BorrowerGroups - 它不包含任何信息。此信息已通过Loans People分享显示 - 我假设您有一个PeopleLoans表格。

People          Loans           PeopleLoans
-----------     ------------    -----------
1  Smith         6  S1    60    1   6
2  Wife          7  S2    60    1   7
3  Mistress      8  S+W1  74    1   8
                 9  S+W2  74    1   9
                10  S+W3  74    1  10
                11  S+M1  89    1  11
                                2   8
                                2   9
                                2  10
                                3  11

所以你的BorrowerGroups实际上几乎只有Loans - 6和7只与史密斯,8到10与史密斯和妻子,11与史密斯和女主人。 因此首先不需要BorrowerGroups,因为它们与Loans分组的People相同。

但要有效地检索此信息可能非常困难,因此您可以考虑直接向GroupId添加Loans。忽略Loans的第二列(仅为了便于阅读),第三列可以代表您的组。它们是多余的,所以如果你改变它们就必须小心。

如果您找到一种从相关人员的ID中派生唯一GroupId的好方法,您可以将其设为计算列。如果一个字符串可以作为一个组ID,你可以命令人们的id用一个分隔符连接它们。

仅使用Smith的小组60将获得ID '1',小组74将成为1.2,而小组89将成为1.3。不是那么聪明,而是独特且易于计算。

答案 1 :(得分:2)

使用原始架构:

  • 人(PersonId(PK),姓名,SSN等)
  • 贷款(贷款(PK),金额等)
  • 借款人(BorrowerId(PK),PersonId,LoanId)

只是查询你需要的数据(你在同一笔贷款中寻找丈夫和妻子的例子):

SELECT
    l.*
    FROM Borrowers            b1
        INNER JOIN Borrowers  b2 ON b1.LoanId=b2.LoanId
        INNER JOIN Loans       l ON b1.LoanId=l.LoanId
    WHERE b1.PersonId=@HusbandID
        AND b2.PersonId=@WifeID

答案 2 :(得分:1)

数据库的设计似乎没问题。为什么在创建新组时必须使用MAX(GourpId)+1?你不能只创建行然后使用SCOPE_IDENTITY()来返回新的ID吗?

e.g。

INSERT INTO BorrowerGroup() DEFAULT VALUES
SELECT SCOPE_IDENTITY()

(见this other question

(编辑为this question提供的SQL)

答案 3 :(得分:0)

我会做更像这样的事情:

  
      
  • 人(PersonId(PK),姓名,SSN等)

  •   
  • 贷款(LoanId(PK),金额,BorrowerGroupId等)

  •   
  • BorrowerGroup(BorrowerGroupId(PK))

  •   
  • PersonBelongsToBorrowerGroup(BorrowerGroupId   (PK),PersonId(PK))

  •   

我摆脱了借款人表。只需将信息存储在BorrowerGroup表中即可。这是我的偏好。

答案 4 :(得分:0)

共识似乎是省略了BorrowerGroup表,我不得不同意。建议您使用MAX(groupId + 1)具有各种ACID /事务问题以及IDENTITY字段存在的主要原因。

那说; KM提供的SQL看起来不错。有多种方法可以获得相同的结果。加入,子选择等等。那里的真正问题是了解数据集。鉴于您提供的解释,数据集将非常小。这也支持删除BorrowerGroup表。

答案 5 :(得分:0)

我会有一个小组表,然后是一个小组成员(借款人)表,以实现贷款与人之间的多对多关系。这允许跟踪组中的数据而不仅仅是成员列表(我相信其他人提出了这个建议?)。

CREATE TABLE LoanGroup
(
    ID int NOT NULL 
    , Group_Name char(50) NULL 
    , Date_Started datetime NULL 
    , Primary_ContactID int NULL
    , Group_Type varchar(25)
)