1
  • 我有一个庞大的电影数据库(超过 4000 部电影),我想按从各种商店 XML 获得的流派进行过滤
  • 每部电影都可以有不止一种类型,因此电影和类型之间是多对多的关系
  • 每种类型都可以有多个名称(不同的语言、拼写错误)
  • 原始形式的每种类型(所有拼写错误)都与交叉连接表连接,然后与电影表连接
  • 每种类型都有一列将坏名和好名分组(或聚类),另一列显示我可能想要输出的那个
  • 我想过滤电影数据库并从 1 或 2 流派中选择电影,无论流派如何拼写

movies我的表是这样设置的(为简洁起见,删除了一些列):

  CREATE TABLE `movies` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `title` varchar(255) NOT NULL DEFAULT '',
    `alias` varchar(255) NOT NULL,
    PRIMARY KEY (`id`),
    KEY `alias` (`alias`),
    KEY `title` (`title`)
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8
  CREATE TABLE `movies_x_genre` (
    `movieid` int(11) NOT NULL,
    `genreid` int(11) unsigned NOT NULL,
    PRIMARY KEY (`movieid`,`genreid`),
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  CREATE TABLE `genre` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `genre` varchar(100) NOT NULL,
    `group` int(11) unsigned DEFAULT NULL,
    `type_id` tinyint(1) DEFAULT NULL,
    `valid` tinyint(1) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    UNIQUE KEY `genre` (`genre`,`type_id`),
    KEY `idx_genre` (`genre`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

例子:

我有有效或无效的流派

  INSERT INTO `genre` (`id`,`genre`,`group`,`type_id`,`valid`) VALUES 
  (1,"Comedy",1,1,1),
  (2,"Comedies",1,1,0),
  (3,"Action",2,1,1),
  (4,"Acton",2,1,0);

  INSERT INTO `movie_x_genre` (`movieid`,`genreid`) VALUES 
  (1,1),
  (2,2),
  (1,3),
  (2,4);

解释

我面临的问题是,我将电影流派存储到多种语言的流派表中,并且通常是某些语言中流派的变体,具有相同含义或至少具有相同含义但使用不同语言的每种流派都有一个共同点“组” id 存储在group手动设置的列中,电影与随之而来的流派结合,流派以新 ID 存储在数据库中,如果是新流派,这允许我存储流派现在让它可用,如果它应该属于一个组,以后再修复它,因为我根本无法每天手动对流派进行分组。

流派的语言 ID 存储在 type_id 中,而该valid列标记流派名称的哪个变体是正确的。

选择查询

当我运行以下查询时,无论是什么语言或变体,都选择“喜剧”类型中的所有电影

当我选择“喜剧”时,我想选择 id 1 和 id 2 的电影,因为它们都是喜剧,只是写法不同但是选择查询非常慢,大约需要 0.5 秒当我运行以下部分时,我看到“复制到 tmp 表”需要很长时间

SET profiling = 1;
SELECT SQL_NO_CACHE i.id,i.alias,i.title 
FROM genre g
INNER JOIN genre g2 ON g.`group`=g2.`group`
INNER JOIN movies_x_genre x ON x.genreid=g.id
INNER JOIN movies i ON i.id=x.movieid
WHERE g2.`genre` = "comedy"
GROUP BY i.id;
SHOW profile;

我遇到了这个答案,跳过复制到磁盘 mysql 上的 tmp 表并运行

SHOW VARIABLES LIKE '%tmp_table_size%';#1073741824 = 1GB
SHOW VARIABLES LIKE '%max_heap_table_size%';#1073741824 = 1GB

我认为我不应该增加这些

为什么选择这么慢?我整理好桌子了吗?我缺少索引吗?如果桌子错了,我应该如何组织我的桌子?存储信息以过滤此类电影的最有效方法是什么?

4

0 回答 0