Stackoverflows Tags system, How To

2020-08-02 07:26发布

问题:

OK so now I can understand that SO's search system is primarily based around tags, the tag system they use is a very good one at that but what I want to do is replicate it for my own projects.

Now I can understand how to use foreign keys and such, but I'm not exactly sure how it's been developed here, do they use 3 tables or 2 etc.

How have they developed it, can you show me some MySql examples?

回答1:

SO considers questions and answers to be the same thing - a Post. Here's a stripped down MySQL equivalent table:

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

Tags are stored in a typical type code table:

DROP TABLE IF EXISTS `example`.`tags`;
CREATE TABLE  `example`.`tags` (
  `tagid` int(10) unsigned NOT NULL auto_increment,
  `tagname` VARCHAR(45) NOT NULL,
  PRIMARY KEY  (`tagid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Associating a tag to a question/post is recorded in the database in a many-to-many table - in SO, it's called POSTTAGS:

DROP TABLE IF EXISTS `example`.`posttags`;
CREATE TABLE  `example`.`posttags` (
  `postid` int(10) unsigned NOT NULL auto_increment,
  `tagid` int(10) unsigned NOT NULL default '0',
  PRIMARY KEY  (`postid`,`tagid`),
  KEY `fk_tag` (`tagid`),
  CONSTRAINT `fk_post` FOREIGN KEY (`postid`) REFERENCES `post` (`postid`),
  CONSTRAINT `fk_tag` FOREIGN KEY (`tagid`) REFERENCES `tags` (`tagid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

The POSTTAGS table:

  • is only two columns, and those columns are the primary key - this makes sure there can't be duplicates, and that either side (post or tag) can never be NULL.
  • The foreign key requires that the data stored in the table must already exist in the respective foreign table...

If you ever want to look at the SO schema, check out the Stack Data Explorer - when you compose a query, the SO schema is available on the righthand side.