#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, которая принадлежит … это принадлежит)