我正在开发一个Q / A网站项目,这个网站上的问题可以与多个标签链接。
例如:How can I implement quicksort in C++ ?
这个问题的标签可以是C, C++, Algorithm
我的问题是我如何在MySQL表中存储这些标签?
我的方法:
上面的问题有id = 123
-------------------------
|question_id | tags |
-------------------------
| 123 | C |
-------------------------
| 123 | C++ |
-------------------------
| 123 |Algorithm |
-------------------------
| 124 | Java |
-------------------------
但是,如果我在这个意义上创建一个表,那么对于很多问题,表将变得非常大。
有没有更好,更有效的方法来存储这种数据?
有一个额外的表格,正好有3列:标记项目的标识,标记,订购信息。
添加或删除项目时,添加或删除此表中的所有相关行。
详细信息如下:http://mysql.rjweb.org/doc.php/lists 高效,快速,简便,高度可扩展。
要使标记保持紧凑,请将标记本身设为第一类实体,而不仅仅是一些随机字符串列:
CREATE TABLE tags (
id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
label VARCHAR(255) NOT NULL,
UNIQUE KEY `index_on_label` (label)
);
然后在问题和标签之间有一个小而简单的连接表:
CREATE TABLE question_tags (
question_id INT NOT NULL,
tag_id INT NOT NULL,
UNIQUE KEY `index_on_question_tag` (question_id, tag_id),
KEY `index_on_tag` (tag_id)
);
这应该包括查询问题的标签和标签的问题。
管理信息系统中的标签可以通过两种方法完成。我们在简单性,低性能,复杂性,难度和高性能之间进行权衡。
第一个解决方案:使用TAG表和Our_Table与TAG表之间的多对多关系。 (正如@tadman描述的那样)
第二种解决方案:如果我们想要一种非常快速和高性能的方法来检索与特定标签相关的数据,我们可以使用Bit-Mask解决方案。
用于TAG管理系统的位掩码解决方案(之前针对类似问题here进行了描述)
在这个方法中我们有相同的表(如@tadman所说)。只需添加1个字段,一个long
或bigint
(与我们的DBMS相关)到想要有TAG的表中(如Question
)
该字段以二进制格式显示Question
的TAG。例如,假设我们在TAG表中有8条记录。
1-一些标签1
2-一些TAG 2
...
8-一些标签8
那么如果我们想将TAG 1,3,6,7设置为一个Question
,只需使用此号码01100101。
(我提议使用反向版本的二进制(0,1)放置来支持将来的其他TAG。)
我们可以使用10个基数添加到数据库中(101而不是01100101)
然后,为任何给定的TAG找到合适的Question
s,只需从Question
中选择并使用如下所示的bitwise AND
。
答:(显示我们在问题中查找的TAG序列,如5作为00000101)
B :(显示任何Question
的标签,如101为01100101)
select * from Question q
where A & q.B = q.B
此查询返回具有特定TAG子集的所有问题。
我们可以使用像A & q.B > 0
这样的Bit-Wise操作的其他功能来在A
和B
之间返回至少1个相等的TAG。等等。
注意:
1:添加新TAG或删除时,我们会遇到一些额外的困难。但这是一种权衡。添加或删除新TAG较少发生。
2:我们也应该使用Question
,Tags
和Question_Tags
表。但在搜索中,我们只是使用新的领域。