2011-11-08 90 views
0

的MySQL架构和CRUD查询让我们想象一下,我有视频,每个视频可以有一些标签(最高为每10个视频标签)。的标签系统

我计划我的SQL模式,它看起来像这样:

  • videosidtitlepath
  • tag_relsidtag_iditem_id(它将指向videosid。),
  • tagsidtag;

好吧,对我来说很好。

然后我写了SELECT应该得到视频,加上标签。

SELECT `videos`.`id`, `videos`.`title`, `videos`.`path`, `tags`.`tag` 
FROM `videos` 
JOIN `tag_rels` 
    ON `tag_rels`.`item_id` = `videos`.`id` 
JOIN `tags` 
    ON `tags`.`id` = `tag_rels`.`tag_id` 

它没有经过测试,因为它都在心灵层面。

大问题INSERT查询(我猜)。

虽然我明白:

  • 查询#1:videos插入视频。这将返回主键(videosid),对不对?
  • 查询#2:从数据库中选择标签#1,并得到它的主键,
  • #3
  • 查询:如果没有这样的记录(基于标签名(tagstag),执行插入查询和插入。它的目标是让该标记的主键,
  • 查询4:插入与tag_rels项视频的PK和标签的PK;

所以,这是每个视频一个查询,因为它是,加上2或3查询每个标签。

这意味着如果视频有10个标签和(最坏的情况),那么这些标签中的任何一个都不会被保存在数据库中,这将花费我1 + 10 * 3 ... em .... 31查询?!

有必须是一个更好的办法!非常感谢!

P.S.我不想在数据库中出现重复条目​​,并且我希望列中有used_intags以及使用该标记的视频数量。在未来...

回答

2

这看起来对于存储过程类似的情况。让商店制作视频数据和标签列表。然后在里面执行查询#1到#4。由于您不必前后移动数据,因此速度会更快。

这里是那种你需要什么。这只是一个起点,所以不要指望它的编译运行正常,而且你需要全部10个标记(我不认为mysql可以使用数组,但有人可能会更好)。

CREATE PROCEDURE insertvideo (IN videotitle CHAR(20),IN videopath CHAR(20), IN tag1 CHAR(20),IN tag2 CHAR(20), IN tag3 CHAR(20) ) 
    BEGIN 
     DECLARE myid INT; 
     DECLARE tagid INT; 
     INSERT INTO videos (title, path) VALUES (videotitle,videopath); 
     SELECT id INTO myid FROM videos WHERE title=videotitle AND path=videopath; 
     SET tagid=NULL; 
     SELECT id INTO tagid FROM tags WHERE tag=tag1; 
     IF tagid IS NULL THEN 
     INSERT INTO tags (tag) VALUES (tag1); 
     SELECT id INTO tagid FROM tags WHERE tag=tag1; 
     END IF; 
     INSERT INTO tag_rels (tag_id, item_id) VALUES (tagid,myid); 
     SET tagid=NULL; 
     SELECT id INTO tagid FROM tags WHERE tag=tag2; 
     IF tagid IS NULL THEN 
     INSERT INTO tags (tag) VALUES (tag1); 
     SELECT id INTO tagid FROM tags WHERE tag=tag2; 
     END IF; 
     INSERT INTO tag_rels (tag_id, item_id) VALUES (tagid,myid); 
     SET tagid=NULL; 
     SELECT id INTO tagid FROM tags WHERE tag=tag3; 
     IF tagid IS NULL THEN 
     INSERT INTO tags (tag) VALUES (tag1); 
     SELECT id INTO tagid FROM tags WHERE tag=tag3; 
     END IF; 
     INSERT INTO tag_rels (tag_id, item_id) VALUES (tagid,myid); 
    END 
+0

你能给(new_video_id是Video.id你插入一条记录到视频后得到)我是一个例子吗?我不知道程序是如何工作的 - 以前从未使用过。或者,至少有一些链接... – daGrevis

+0

以下是文档:http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html –

1

我想你的计算是错误的。无论标签编号如何,您都需要执行3个查询。
1. INSERT INTO Video ...
2. INSERT INTO tags(tag)
SELECT * FROM
(SELECT 'tag_1' as tag UNION SELECT 'tag_2' ...)a WHERE NOT EXISTS (SELECT 1 FROM tags b WHERE b.tag = a.tag)

3.Assuming你有(TAG_ID,ITEM_ID),INSERT IGNORE INTO tag_rels(tag_id, item_id) SELECT tag_id, new_video_id FROM tags WHERE tags.tag IN ([new tag_list])唯一索引 -