Вложенность групп или элементов

#mysql #database-design #foreign-keys #entity-relationship

#mysql #база данных-дизайн #внешние ключи #сущность-отношение

Вопрос:

Я довольно новичок в Mysql, но у меня есть проблема, которую я не могу решить. Я приведу вам пример, чтобы продемонстрировать это. Пожалуйста, обратите внимание, что я знаю, что (для текущего примера) есть другие более простые и эффективные способы ее решения… но просто возьмите это как пример требуемой процедуры.

  • Сначала данные: данные будут именем человека.
СОЗДАТЬ ТАБЛИЦУ person(
идентификатор INT,
имя VARCHAR(100)
 ) ТИП=innodb;
  • Второе: создание группы… Так что это довольно просто … и может быть легко сделано с помощью таблицы « group с помощью внешнего ключа для person. Эти группы могут быть произвольными, содержать любое количество людей, дублироваться … или нет … (это просто !!)
  • В-третьих: МОЯ НАСТОЯЩАЯ ПРОБЛЕМА — я также хотел бы иметь группы, в которых другие группы являются элементами (вместо persons ). Вот где я действительно застрял, потому что я знаю, как создавать группы persons , группы groups (имеющие внешний ключ, ссылающийся на себя)… но я не знаю, как создать группу, которая МОЖЕТ ИМЕТЬ persons И Groups .

Я ценю любое предложение по решению этой проблемы.

Большое вам спасибо за ваши комментарии. С уважением

ACombo

Ответ №1:

Я бы сначала настроил таблицы myGroup и person.

Во-вторых, я бы настроил таблицу myGroupGroup со столбцами myGroupId, parentMyGroupId. Это позволит вам связать строки группы со строками дочерней группы, т.Е. «В этой группе есть эти группы внутри нее». Если у группы нет строк в этой таблице, то в ней нет дочерних групп.

В-третьих, я бы создал таблицу PersonGroup со столбцами PersonID, myGroupId. Это позволит вам связать строки person с заданной группой. Если у группы нет строк в этой таблице, то в ней нет людей.

 CREATE TABLE person(
      id INT UNSIGNED PRIMARY KEY,
      name VARCHAR(100)
    ) ENGINE=innodb;


CREATE TABLE myGroup(
      id INT UNSIGNED PRIMARY KEY,
      groupName VARCHAR(100)
    ) ENGINE=innodb;

-- Holds groups within groups
CREATE TABLE myGroupGroup(
      id INT UNSIGNED PRIMARY KEY,
      myGroupId INT UNSIGNED,
      parentMyGroupId INT UNSIGNED DEFAULT NULL,
      CONSTRAINT `fk_myGroupGroup_group1` FOREIGN KEY (`parentMyGroupId`) REFERENCES `myGroup` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
      CONSTRAINT `fk_myGroupGroup_group2` FOREIGN KEY (`myGroupId`) REFERENCES `myGroup` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ENGINE=innodb;

-- Holds persons within a group
CREATE TABLE personGroup(
      id INT,
      personId int UNSIGNED NOT NULL,
      myGroupId int UNSIGNED NOT NULL,
      CONSTRAINT `fk_personGroup_group1` FOREIGN KEY (`myGroupId`) REFERENCES `myGroup` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
      CONSTRAINT `fk_personGroup_person1` FOREIGN KEY (`personId`) REFERENCES `person` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ENGINE=innodb;
  

Я немного изменил ваш SQL:

1) Заменен TYPE на ENGINE

2) Заменено имя таблицы group на myGroup ( GROUP является зарезервированным словом)

Удачи!

Комментарии:

1. Дорогой Том, спасибо тебе за комментарии и пояснения. Что касается вашего решения, я думаю, что есть проблема (которая решается в решении, представленном ypercube): Мне может понадобиться, чтобы в какой-то группе были КАК участники, ТАК и участники группы. В любом случае я очень ценю ваш ответ. С уважением.

2. чтобы удовлетворить это, я предполагал, что в таблице PersonGroup должна быть строка (для людей в группе), например, groupId= 1, PersonID = 3 (таким образом, groupId 1 содержит person 3). В таблице myGroup родительское дочернее отношение для обозначения групп внутри группы. Итак, id = 2, name =’group2′ и parentGroupId =1, чтобы показать, что группа 2 является частью группы 1. Вы могли бы переместить внешний ключ, ссылающийся на себя, из таблицы myGroup в таблицу myGroupGroup или что-то подобное, если хотите сделать его более понятным. Надеюсь, это поможет!

3. На самом деле — я предпочитаю идею myGroupGroup (я думаю, это понятнее). Я соответствующим образом изменил свой ответ. Надеюсь, это имеет смысл

4. @Tom Mac: Я полагаю, вы хотели удалить myGroup.parentGroupId столбец.

5. @ypercube: Я сделал, да. Спасибо — хорошее место (боюсь, недостаток сна). Я изменил свой ответ.

Ответ №2:

Альтернатива:

 CREATE TABLE Entity
        ( EntityId INT                   --- this id could be AUTO_INCREMENT
        , PRIMARY KEY (EntityId)
        ) ENGINE = InnoDB ;

CREATE TABLE Person
        ( PersonId INT                   --- but not this id
        , PersonName VARCHAR(100)
        , PRIMARY KEY (PersonId)
        , FOREIGN KEY (PersonId) 
            REFERENCES Entity(EntityId)        
        ) ENGINE = InnoDB ;

CREATE TABLE Grouping
        ( GroupingId INT                 --- and neither this id
        , GroupingName VARCHAR(100)
        , PRIMARY KEY (GroupingId)
        , FOREIGN KEY (GroupingId) 
            REFERENCES Entity(EntityId)            
        ) ENGINE = InnoDB ;

CREATE TABLE Belongs
        ( EntityId INT
        , GroupingID INT
        , PRIMARY KEY (EntityId, GroupingId)
        , FOREIGN KEY (EntityId) 
            REFERENCES Entity(EntityId) 
        , FOREIGN KEY (GroupingID) 
            REFERENCES Grouping(GroupingId)            
        ) ENGINE = InnoDB ;
  

Комментарии:

1. Обратите внимание, что эта структура допускает циклические ссылки (группа, которая принадлежит самой себе, или группа A, которая принадлежит B, которая принадлежит … это принадлежит)