单个查询中的MySQL项目及其属性

问题描述 投票:1回答:2

我创建了MySQL数据模型来存储内容及其自定义属性/字段。下面是它的简化版本。

用于存储内容的一个:

CREATE TABLE `cms_content` (
  `id` int(11) NOT NULL,
  `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `content_type_id` int(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `cms_content`
  ADD PRIMARY KEY (`id`),
  ADD KEY `content_type_id` (`content_type_id`);

第二个内容类型(例如文章,电影,人物):

CREATE TABLE `cms_content_type` (
  `id` int(6) NOT NULL,
  `name` varchar(20) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `cms_content_type`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `key` (`name`);

自定义字段:

CREATE TABLE `cms_custom_field` (
  `id` int(11) NOT NULL,
  `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `content_type_id` int(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `cms_custom_field`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `name` (`name`,`content_type_id`),
  ADD KEY `name_2` (`name`);

最后是用于连接自定义字段和数据的一个:

CREATE TABLE `cms_content_data` (
  `id` int(11) NOT NULL,
  `custom_field_id` int(11) NOT NULL,
  `content_id` int(11) NOT NULL,
  `value` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `value_content_id` int(11) DEFAULT NULL,
  `value_taxonomy_value_id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `cms_content_data`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `key` (`value`,`content_id`,`custom_field_id`) USING BTREE,
  ADD KEY `content_id` (`content_id`),
  ADD KEY `custom_field_id` (`custom_field_id`),
  ADD KEY `value` (`value`),
  ADD KEY `value_content_id` (`value_content_id`),
  ADD KEY `value_taxonomy_value_id` (`value_taxonomy_value_id`),
  ADD KEY `custom_field_id_2` (`custom_field_id`,`content_id`);

挑战

我需要创建一个查询,该查询使用其所有自定义字段获取某种类型的内容。注意!这里的一个技巧是一个自定义字段可以有多个content_data值。例如电影的genre字段可以在content_data中包含多行。

非工作查询

我能够动态生成以下查询:

SELECT 
`content`.`id` AS `_content_id`, 
`content`.`title` AS `_content_title`, 
`content_data_0`.`value_taxonomy_value_id` AS `genres`, 
`content_data_1`.`value_content_id` AS `production_company`, 
`content_data_2`.`value` AS `date_released`, 
`content_data_3`.`value` AS `runtime`, 
`content_data_4`.`value` AS `tagline`, 
`content_data_5`.`value` AS `imdb_rating`, 
`content_data_6`.`value` AS `rt_rating`, 
`content_data_7`.`value` AS `imdb_id`, 
`content_data_8`.`value` AS `trailer_url`, 
`content_data_9`.`value` AS `api_id`, 
`content_data_10`.`value_taxonomy_value_id` AS `rating`, 
`content_data_11`.`value` AS `revenue`, 
`content_data_12`.`value` AS `poster_original_path`, 
`content_data_13`.`value` AS `rt_rating_users`, 
`content_data_14`.`value` AS `rt_url`, 
`content_data_15`.`value` AS `rt_consensus`, 
`content_data_16`.`value` AS `mc_rating`, 
`content_data_17`.`value` AS `year`, 
`content_data_18`.`value` AS `budget`, 
`content_data_19`.`value_taxonomy_value_id` AS `original_language`, 
`content_data_20`.`value_taxonomy_value_id` AS `production_countries`, 
`content_data_21`.`value` AS `original_title` 
FROM `cms_content` AS `content` 
INNER JOIN cms_content_type ON cms_content_type.id = content.content_type_id
INNER JOIN `cms_content_data` AS `content_data_0` ON `content_data_0`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_1` ON `content_data_1`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_2` ON `content_data_2`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_3` ON `content_data_3`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_4` ON `content_data_4`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_5` ON `content_data_5`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_6` ON `content_data_6`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_7` ON `content_data_7`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_8` ON `content_data_8`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_9` ON `content_data_9`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_10` ON `content_data_10`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_11` ON `content_data_11`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_12` ON `content_data_12`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_13` ON `content_data_13`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_14` ON `content_data_14`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_15` ON `content_data_15`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_16` ON `content_data_16`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_17` ON `content_data_17`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_18` ON `content_data_18`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_19` ON `content_data_19`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_20` ON `content_data_20`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_data` AS `content_data_21` ON `content_data_21`.`content_id` = `content`.`id` 
INNER JOIN `cms_content_type` AS `content_type` ON `content_type`.`id` = `content`.`content_type_id` 

WHERE `content_type`.`name` = 'movie' 
AND `content_data_0`.`custom_field_id` = 141 
AND `content_data_1`.`custom_field_id` = 143 
AND `content_data_2`.`custom_field_id` = 144 
AND `content_data_3`.`custom_field_id` = 146
AND `content_data_4`.`custom_field_id` = 148 
AND `content_data_5`.`custom_field_id` = 154 
AND `content_data_6`.`custom_field_id` = 155 
AND `content_data_7`.`custom_field_id` = 156 
AND `content_data_8`.`custom_field_id` = 158 
AND `content_data_9`.`custom_field_id` = 159 
AND `content_data_10`.`custom_field_id` = 162 
AND `content_data_11`.`custom_field_id` = 163 
AND `content_data_12`.`custom_field_id` = 164 
AND `content_data_13`.`custom_field_id` = 174 
AND `content_data_14`.`custom_field_id` = 175 
AND `content_data_15`.`custom_field_id` = 176 
AND `content_data_16`.`custom_field_id` = 177 
AND `content_data_17`.`custom_field_id` = 185 
AND `content_data_18`.`custom_field_id` = 184 
AND `content_data_19`.`custom_field_id` = 186 
AND `content_data_20`.`custom_field_id` = 187 
AND `content_data_21`.`custom_field_id` = 188 
DESC LIMIT 100

这里的问题:1.错误的回报。显然,由于每个content_data可以有多个值,因此MySQL以各种方式将它们组合在一起,最后我得到了一个movie和自定义字段的各种组合。2.查询速度非常慢(可能是由于许多联接以及字段值的组合)

问题

MySQL中是否有任何方法(当然还有一些PHP后端魔术)可以在一个查询中返回所有必需的数据?考虑当前的数据模型。

对于多行,用逗号分隔的字段值中的值将对我有用(除非有更好的方法)。>>

或者这个数据模型只是非常有缺陷,我需要以某种方式进行更改吗?

提前感谢!

我创建了MySQL数据模型来存储内容及其自定义属性/字段。下面是它的简化版本。一种用于存储内容的方法:CREATE TABLE`cms_content`(`id` int(11)NOT ...

mysql sql
2个回答
0
投票

您需要条件聚合。我认为这是:


0
投票

您可以通过条件聚合来解决此问题。使用这种技术,需要单个连接,然后条件聚合表达式会提取期望值。

© www.soinside.com 2019 - 2024. All rights reserved.