У меня есть БД MySQL, которая должна предоставлять атрибуты, связанные с таксономией. Я хочу иметь список всех атрибутов, включая «унаследованные атрибуты» для данного элемента в таксономии. Я не эксперт SQL & многому научился (и плагиат) с этого сайта. Одна вещь, которую я узнал здесь, - это использовать таблицу закрытия для представления моей Иерархии. То, что мне нужно сделать для моей базы данных, - связать большое количество атрибутов с элементами внутри иерархии. Однако я не могу понять, как захватить все атрибуты, связанные с данным узлом и всеми его родителями. Я создал следующую примерную базу данных для этого вопроса (не стесняйтесь комментировать что-либо об этой схеме, поддельные данные - это просто шум).Список всех атрибутов из каждого элемента в таксономии в MySQL
Моей пример структура базы данных MySQL выглядит следующим образом:
-- Simple Sample
SET FOREIGN_KEY_CHECKS=0;
DROP TRIGGER IF EXISTS inheritance_tree_insert;
DROP TRIGGER IF EXISTS inheritance_tree_update;
DROP TABLE IF EXISTS inheritance_paths;
DROP TABLE IF EXISTS inheritance_tree;
DROP TABLE IF EXISTS attributes;
SET FOREIGN_KEY_CHECKS=1;
CREATE TABLE `inheritance_tree` (
`it_id` INT NOT NULL, -- PK
`parent` INT, -- Parent id & FK
`child_order` INT, -- Oder of siblings
`name` VARCHAR(500) NOT NULL, -- Name for the entry
PRIMARY KEY (`it_id`),
FOREIGN KEY (`parent`) REFERENCES inheritance_tree(`it_id`) ON DELETE CASCADE,
INDEX(`name`)
) ENGINE = INNODB;
-- Trigger to update the paths table for new entries
DELIMITER //
CREATE TRIGGER `inheritance_tree_insert` AFTER INSERT ON `inheritance_tree` FOR EACH ROW
BEGIN
INSERT INTO `inheritance_paths` (`ancestor`, `descendant`, `len`)
SELECT `ancestor`, NEW.`it_id`, len + 1 FROM `inheritance_paths`
WHERE `descendant` = NEW.`parent`
UNION ALL SELECT NEW.`it_id`, NEW.`it_id`, 0;
END; //
DELIMITER ;
DELIMITER //
CREATE TRIGGER `inheritance_tree_update` BEFORE UPDATE ON `inheritance_tree` FOR EACH ROW
BEGIN
-- From http://www.mysqlperformanceblog.com/2011/02/14/moving-subtrees-in-closure-table/
IF OLD.`parent` != NEW.`parent` THEN
-- Remove the node from its current parent
DELETE a FROM `inheritance_paths` AS a
JOIN `inheritance_paths` AS d ON a.`descendant` = d.`descendant`
LEFT JOIN `inheritance_paths` AS x
ON x.`ancestor` = d.`ancestor` AND x.`descendant` = a.`ancestor`
WHERE d.`ancestor` = OLD.`it_id` AND x.`ancestor` IS NULL;
-- Add the node to its new parent
INSERT `inheritance_paths` (`ancestor`, `descendant`, `len`)
SELECT supertree.`ancestor`, subtree.`descendant`, supertree.`len`+subtree.`len`+1
FROM `inheritance_paths` AS supertree JOIN `inheritance_paths` AS subtree
WHERE subtree.`ancestor` = OLD.`it_id`
AND supertree.`descendant` = NEW.`parent`;
END IF;
END; //
DELIMITER ;
CREATE TABLE `inheritance_paths` (
`ancestor` INT NOT NULL,
`descendant` INT NOT NULL,
`len` INT NOT NULL,
PRIMARY KEY (`ancestor`, `descendant`),
FOREIGN KEY (`ancestor`) REFERENCES inheritance_tree(`it_id`) ON DELETE CASCADE,
FOREIGN KEY (`descendant`) REFERENCES inheritance_tree(`it_id`) ON DELETE CASCADE
) ENGINE = INNODB;
INSERT INTO `inheritance_tree` VALUES(1, NULL, NULL, 'Animal');
INSERT INTO `inheritance_tree` VALUES(2, 1, 1, 'Mammal');
INSERT INTO `inheritance_tree` VALUES(3, 1, 2, 'Bird');
INSERT INTO `inheritance_tree` VALUES(4, 1, 3, 'Reptile');
INSERT INTO `inheritance_tree` VALUES(5, 2, 2, 'Feline');
INSERT INTO `inheritance_tree` VALUES(6, 2, 1, 'Bovine');
INSERT INTO `inheritance_tree` VALUES(7, 1, 3, 'Fish');
INSERT INTO `inheritance_tree` VALUES(8, 4, 1, 'Snake');
INSERT INTO `inheritance_tree` VALUES(9, 4, 2, 'Lizard');
INSERT INTO `inheritance_tree` VALUES(10, NULL, NULL, 'Machine');
INSERT INTO `inheritance_tree` VALUES(11, 10, 1, 'Automobile');
INSERT INTO `inheritance_tree` VALUES(12, 10, 2, 'OfficeMachine');
INSERT INTO `inheritance_tree` VALUES(13, 10, 3, 'Robot');
DELIMITER ;
CREATE TABLE `attributes` (
`a_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'the unique identifier',
`attribute_name` varchar(255) DEFAULT NULL,
`attribute_type` int(11) NOT NULL,
PRIMARY KEY (`a_id`),
KEY `fk_attributes_attribute_type1_idx` (`attribute_type`),
CONSTRAINT `fk_attributes_attribute_type1_idx` FOREIGN KEY (`attribute_type`) REFERENCES `inheritance_tree` (`it_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
INSERT INTO `attributes` VALUES(1, 'IsAlive', 1); -- Animal
INSERT INTO `attributes` VALUES(2, 'HasMaximumLifeSpan', 1); -- Animal
INSERT INTO `attributes` VALUES(3, 'IsNotAlive', 10); -- Machine
INSERT INTO `attributes` VALUES(4, 'HasIndeterminantLifeSpan', 10); -- Machine
INSERT INTO `attributes` VALUES(5, 'BreathesAir', 2); -- Mammal
INSERT INTO `attributes` VALUES(6, 'CanFly', 3); -- Bird
INSERT INTO `attributes` VALUES(7, 'HasFeathers', 3); -- Bird
INSERT INTO `attributes` VALUES(8, 'ColdBlooded', 4); -- Reptile
INSERT INTO `attributes` VALUES(9, 'HasFourLegs', 5); -- Feline
INSERT INTO `attributes` VALUES(10, 'HasFourLegs', 6); -- Bovine
INSERT INTO `attributes` VALUES(11, 'ColdBlooded', 7); -- Fish
INSERT INTO `attributes` VALUES(12, 'HasNoLegs', 8); -- Snake
INSERT INTO `attributes` VALUES(13, 'HasFourLegs', 9); -- Lizard
INSERT INTO `attributes` VALUES(14, 'ConsumesGasoline', 11); -- Automobile
INSERT INTO `attributes` VALUES(15, 'ConsumesElectricity', 12); -- OfficeMachine
INSERT INTO `attributes` VALUES(16, 'ConsumesElectricity', 13); -- Robot
INSERT INTO `attributes` VALUES(17, 'WarmBlooded', 2); -- Mammal
INSERT INTO `attributes` VALUES(18, 'WarmBlooded', 3); -- Bird
INSERT INTO `attributes` VALUES(19, 'BreathesWater', 7); -- Fish
INSERT INTO `attributes` VALUES(20, 'HasScales', 8); -- Snake
INSERT INTO `attributes` VALUES(21, 'HasSkin', 9); -- Lizard
Предположение:
1.Вс сущности в систематике имеют уникальные имена. Это означает, что в любом из деревьев таксономии есть один и только один подтип, называемый «Рыба».
2.Attributes не являются уникальными и могут повторить
ЦЕЛЬ:
Учитывая тип входа «Ящерица» Я хотел бы один запрос, который возвращает следующий список записей атрибутов:
1 , IsAlive, 1
2, HasMaximumLifeSpan, 1
5, BreathesAir, 2
8, холоднокровных, 4
13, HasFourLegs, 9
21, HasSkin, 9
Как вы связываете атрибут a_id с атрибутом inheritence_tree? Я бы предположил, что вам понадобится какая-то ассоциация, чтобы вы могли каскадировать атрибуты. Возможно, это самая проблема, которую вы пытаетесь решить. Если это так, используйте таблицу атрибутов в качестве таблицы «look_up», из которой вы привязываете запись inhertience_tree, поэтому вы должны добавить дополнительный столбец или иметь таблицу inheritence_tree_attribute для создания ассоциации. Имеет смысл? –
Поле таблицы атрибутов 'attribute_type' указывает на один узел в иерархии (таблица inheritance_tree). –
Ниже приведен пример извлечения атрибутов только для Lizard (без унаследованных атрибутов): SELECT * FROM атрибуты WHERE attribute_type IN (SELECT it_id FROM inheritance_tree WHERE name LIKE 'Lizard') Это приводит к возврату 2 записей: 13, HasFourLegs, 9 21, HasSkin, 9 –