我正在设计MySQL数据库模式,我不确定我的方法是否足够好。
想象一下这种情况:
- 有一些人
- 每个人都喜欢网络上的一些文章(成千上万的文章)
- 每篇文章翻译成另一种语言(数十种语言,不同网站可翻译不同)
我希望能够指定文章的名称,源语言,目标语言,并找到这篇文章的所有翻译。我还可以指定一个人,只从他/她的"收藏夹"中查找文章。
我的想法:
创建4个表:CREATE TABLE Language (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE Person (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE Article (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NOT NULL,
`language` INT NOT NULL,
`person` INT NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`language`) REFERENCES Language (`id`),
FOREIGN KEY (`person`) REFERENCES Person (`id`)
) ENGINE=InnoDB;
CREATE TABLE Relation (
`article_1` INT NOT NULL,
`article_2` INT NOT NULL,
PRIMARY KEY (`article_1`, `article_2`),
FOREIGN KEY (`article_1`) REFERENCES Article (`id`) ON DELETE CASCADE,
FOREIGN KEY (`article_2`) REFERENCES Article (`id`) ON DELETE CASCADE
) ENGINE=InnoDB;
将每一篇文章作为一条记录存储在表中,并使用链接表Relation
"连接"它们。
每个人将创建一个文件,其中包含他/她最喜欢的文章的url和翻译链接:
url1_en url1_es url1_de url1_ko
url2_en url2_es url2_de url2_ko
url3_en url3_es url3_de url3_ko
url4_en url4_es url4_de url4_ko
当然,另一个人可以找到文章url1_en
的另一个德语翻译并上传:
url1_en url1_es url1_de_2 url1_ko
如果我以德语作为目标语言搜索url1_en
,我应该得到url1_de
和url_1_de_2
我这里的问题是如何处理文章的这种自引用多对多关系。此外,表关系将增长非常快。
也许有更好的方法来设计模式?
总的来说,你的方法还可以。不过我发现了一个错误。文章不应该和人联系在一起——如果两个人喜欢同一篇文章呢?
另外,由于人们可能喜欢一篇文章(而不是它的翻译),您可以增加更多的复杂性。文章只是一个没有内容的容器,内容在ArticleTranslation表
我建议的模式如下(我只关注表关系):
Article
*..* Person [with join table PersonArticle]
1..* ArticleContent
Person
*..* Article [with join table PersonArticle]
然后,您的查询将如下所示(再次-伪代码):
找到翻译
SELECT ac2.* FROM Article a
JOIN ArticleContent ac1
JOIN ArticleContent ac2 (ac1.Article=ac2.Article)
WHERE ac1.name=<NAME>
AND ac1.language=<SRC_LANG>
AND ac2.language=<TRG_LANG>
查找用户收藏夹的翻译
SELECT ac2.*
FROM
Person p
JOIN PersonArticle pa
JOIN Article a
JOIN ArticleContent ac1
JOIN ArticleContent ac2 (ac1.Article=ac2.Article)
WHERE
p.id=<PERSON_ID>
ac1.name=<NAME>
AND ac1.language=<SRC_LANG>
AND ac2.language=<TRG_LANG>
UPDATE—对于非常庞大的数据量,可以考虑使用一些NoSQL方法。其中一些是专门为绘制此类数据图而创建的。然而,这是一个更复杂的解决方案,SQL对于初学者来说很好。