Как управлять «группами» в базе данных? - PullRequest
2 голосов
/ 12 мая 2009

Я задал этот вопрос здесь , но я не думаю, что понял свою точку зрения.

Допустим, у меня есть следующие таблицы (все PK являются полями IDENTITY):

  • Люди (PersonId (PK), Имя, SSN и т. Д.)
  • Кредиты (LoanId (PK), Сумма и т. Д.)
  • Заемщики (BorrowerId (PK), PersonId, LoanId)

Допустим, мистер Смит получил 2 займа на свое имя, 3 совместных займа с женой и 1 совместный займ с любовницей. Для целей применения я хочу, чтобы ГРУППЫ людей, чтобы я мог легко выделить кредиты, которые г-н Смит взял вместе со своей женой.

Для этого я добавил таблицу BorrowerGroup, теперь у меня есть следующее (все PK являются полями IDENTITY):

  • Люди (PersonId (PK), Имя, SSN и т. Д.)
  • Ссуды (LoanId (PK), Amount, BorrowerGroupId и т. Д.)
  • BorrowerGroup (GroupId (PK))
  • Заемщики (BorrowerId (PK), GroupId, PersonId)

Теперь мистер Смит состоит из 3 групп (он сам, он и его жена, он и его любовница), и я легко могу посмотреть его деятельность в любой из этих групп.

Проблемы с новым дизайном:

Единственный способ создать новую группу Borrower - это вставить MAX (GourpId) +1 с IDENTITY_INSERT ON, это просто не правильно. Кроме того, понятие таблицы с 1 столбцом является довольно странным.

Я твердо верю в суррогатные ключи и хотел бы придерживаться этого дизайна, если это возможно.

Это приложение не заботится о физических лицах, ГРУППА рассматривается как физическое лицо

Есть ли лучший способ группировать людей для целей этого приложения?

Ответы [ 6 ]

3 голосов
/ 12 мая 2009

Вы можете просто удалить таблицу 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 (только для удобства чтения), третий столбец должен представлять ваши группы. Они избыточны, поэтому вы должны быть осторожны, если меняете их.

Если вы найдете хороший способ получить уникальный GroupId из идентификаторов вовлеченных людей, вы можете сделать его вычисляемым столбцом. Если строка будет в качестве идентификатора группы, вы можете просто заказать идентификаторы людей и сопоставить их с разделителем.

Группа 60 только со Смитом получит идентификатор '1', группа 74 станет 1.2, а группа 89 станет 1.3. Не такой умный, но уникальный и простой в вычислениях.

2 голосов
/ 12 мая 2009

использовать оригинальную схему:

  • Люди (PersonId (PK), Имя, SSN и т. Д.)
  • Кредиты (LoanId (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
1 голос
/ 12 мая 2009

Дизайн базы данных выглядит нормально. Почему вы должны использовать MAX (GourpId) +1 при создании новой группы? Разве вы не можете просто создать строку и затем использовать SCOPE_IDENTITY (), чтобы вернуть новый идентификатор?

, например

INSERT INTO BorrowerGroup() DEFAULT VALUES
SELECT SCOPE_IDENTITY()

(см. этот другой вопрос )

(отредактируйте для SQL этот вопрос )

0 голосов
/ 13 мая 2009

У меня была бы таблица групп, а затем таблица членов группы (заемщиков), чтобы достичь отношения «многие ко многим» между кредитами и людьми. Это позволяет отслеживать данные о группе, а не только о списке участников (я полагаю, кто-то еще сделал это предложение?).

CREATE TABLE LoanGroup
(
    ID int NOT NULL 
    , Group_Name char(50) NULL 
    , Date_Started datetime NULL 
    , Primary_ContactID int NULL
    , Group_Type varchar(25)
)
0 голосов
/ 12 мая 2009

Похоже, что консенсус опускает таблицу BorrowerGroup, и я должен согласиться. Предположение, что вы будете использовать MAX (groupId + 1), имеет всевозможные проблемы с ACID / транзакциями и основной причиной существования полей IDENTITY.

Это сказал; SQL, предоставленный KM, выглядит хорошо. Есть много способов получить одинаковые результаты. Объединяет, подбирает и так далее. Настоящая проблема там ... это знание набора данных. Учитывая предоставленное вами объяснение, наборы данных будут очень маленькими. Это также поддерживает удаление таблицы BorrowerGroup.

0 голосов
/ 12 мая 2009

Я бы сделал что-то более похожее на это:

  • Люди (PersonId (PK), Имя, SSN и т. Д.)

  • Ссуды (LoanId (PK), Amount, BorrowerGroupId и т. Д.)

  • BorrowerGroup (BorrowerGroupId (PK))

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

Я избавился от таблицы Заемщиков. Просто сохраните информацию в таблице BorrowerGroup. Это мое предпочтение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...