我创建了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 ...
您需要条件聚合。我认为这是:
您可以通过条件聚合来解决此问题。使用这种技术,需要单个连接,然后条件聚合表达式会提取期望值。