Best practice for storing tags in a database?

前端 未结 3 1253
情书的邮戳
情书的邮戳 2020-12-23 18:28

I developed a site that uses tags (key words) in order to categorize photographs. Right now, what I have in my MySQL database is a table with the following structure:

相关标签:
3条回答
  • 2020-12-23 18:59

    In multi tag search query you will have to hit every tag that is requested. Hence image tag set I has to be a superset of the request tag set U.

    I >= U
    

    To implement this complex comparison in SQL is a bit of challenge as each of the image has to be qualified individually. Given that tags are unique set per image:

    SELECT i.* FROM images AS i WHERE {n} = (
      SELECT COUNT(*) 
      FROM image_tags AS t 
      WHERE t.image_id = i.image_id
        AND t.tag IN ({tag1}, {tag2}, ... {tagn})
    )
    

    Schema:

    CREATE TABLE images (
      image_id varchar NOT NULL,
      PRIMARY KEY (image_id)
    )
    
    CREATE TABLE image_tags (
      image_id varchar NOT NULL,
      tag varchar NOT NULL,
      PRIMARY KEY (image_id, tag)
    )
    
    0 讨论(0)
  • 2020-12-23 19:03

    Use a many-to-many table to link a TAG record to an IMAGE record:

    IMAGE

    DROP TABLE IF EXISTS `example`.`image`;
    CREATE TABLE  `example`.`image` (
      `image_id` int(10) unsigned NOT NULL auto_increment,
      PRIMARY KEY  (`image_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    

    TAG

    DROP TABLE IF EXISTS `example`.`tag`;
    CREATE TABLE  `example`.`tag` (
     `tag_id` int(10) unsigned NOT NULL auto_increment,
     `description` varchar(45) NOT NULL default '',
     PRIMARY KEY  (`tag_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    

    IMAGE_TAG_MAP

    DROP TABLE IF EXISTS `example`.`image_tag_map`;
    CREATE TABLE  `example`.`image_tag_map` (
     `image_id` int(10) unsigned NOT NULL default '0',
     `tag_id` int(10) unsigned NOT NULL default '0',
     PRIMARY KEY  (`image_id`,`tag_id`),
     KEY `tag_fk` (`tag_id`),
     CONSTRAINT `image_fk` FOREIGN KEY (`image_id`) REFERENCES `image` (`image_id`),
     CONSTRAINT `tag_fk` FOREIGN KEY (`tag_id`) REFERENCES `tag` (`tag_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    0 讨论(0)
  • 2020-12-23 19:25

    You can make a tags table which is just an id and tag with a unique constraint on tag and then photo_tags table which has tag_id and photo_id. Insert a tag into the tags table only if it doesn't already exist.

    Then you will be querying by a pk instead of varchar text comparison when doing queries like how many photos are tagged with a certain tag.

    0 讨论(0)
提交回复
热议问题