Mysql 标签系统:Toxi解决方案问题
对于标记数据库模式的Toxi解决方案,我有点不知所措。我正在开发一个系统,用户可以向该系统提交项目,这些项目可以有与之关联的标签。在阅读了TagSchema之后,我发现Toxi解决方案最适合我的需要。然而,我不完全确定我是否计划好了,所以我想听听你对此的意见 我有三个数据库。Mysql 标签系统:Toxi解决方案问题,mysql,database-design,database-schema,tagging,Mysql,Database Design,Database Schema,Tagging,对于标记数据库模式的Toxi解决方案,我有点不知所措。我正在开发一个系统,用户可以向该系统提交项目,这些项目可以有与之关联的标签。在阅读了TagSchema之后,我发现Toxi解决方案最适合我的需要。然而,我不完全确定我是否计划好了,所以我想听听你对此的意见 我有三个数据库。 项目包含项目id和其他 tagmap使用item\u id和tag\u id作为外键 标签包含标签id和标签文本 在添加新项时,我是否正确地假设将标记添加到数据库的过程如下 将提交的标记排序到数组中 对于阵列中的每个标记:
项目
包含项目id
和其他
tagmap
使用item\u id
和tag\u id
作为外键
标签
包含标签id
和标签文本
在添加新项时,我是否正确地假设将标记添加到数据库的过程如下
INSERT IGNORE INTO tagmap (item_id, tag_id)
SELECT 1, tag_id FROM tags WHERE tag_text IN ('tag1', 'tag2', 'tag3');
忽略
允许此操作成功,即使项目已连接到其中一些标记
这假定所有必需的标记都已在标记中。假设tag.tag\u id
是自动递增的,您可以这样做以确保它们是:
INSERT IGNORE INTO tags (tag_text) VALUES ('tag1'), ('tag2'), ('tag3');
这意味着我们将在tagmap中为每个项目的每个标记创建一个条目。这似乎是正确的,但我忍不住认为有一个更好的方法来做到这一点,然后以大量的条目结束
没有魔法。如果“项连接到特定标记”是您想要记录的知识,那么它必须在数据库中具有某种物理表示形式
至于编辑标签
您的意思是重新标记项目(而不是修改标记本身)
要删除列表中不包含的所有标记,请执行以下操作:
DELETE FROM tagmap
WHERE
item_id = 1
AND tag_id NOT IN (
SELECT tag_id FROM tags
WHERE tag_text IN ('tag1', 'tag3')
);
这将断开项目与除“tag1”和“tag3”之外的所有标签的连接。执行上面的插入,然后逐个删除,以“覆盖”添加和删除标记
你可以在游戏中玩这些
当然,当删除标记映射行时,相关的项目不会被删除,因为它指向一个外键而不是一个外键,对吗
对。FK的子端点不会触发引用操作(例如在删除级联上),只有父端点会触发引用操作
顺便说一句,您之所以使用此模式,是因为您希望在标记
(在标记(text
)旁边)中有其他字段,对吗?如果您这样做了,那么不要仅仅因为所有连接都已断开而丢失这些额外的数据,这是理想的行为
但是,如果您只是想要标记\u文本
,您可以使用一个更简单的模式,其中删除所有连接与删除标记本身相同:
这不仅可以简化SQL,还可以提供更好的性能
乍一看,“toxi”可能看起来节省了空间,但实际上可能不是这样,因为它需要额外的表和索引(标记往往很短)
另外,我可能想记录一个标签的次数。。。cron作业
在你决定做这样的事情之前先测量一下。上面提到的我的SQL FIDLE在tagmap
PK中使用了非常谨慎的字段顺序,因此数据以一种对这种计数非常友好的方式进行集群(记住:)。在这成为一个问题之前,您必须拥有大量的项目(或要求异常高的性能)
在任何情况下,测量实际数据量 哇,这真是一个精心设计的答案!我学到了很多,我想这足以让我继续前进。非常感谢你!(此外,还有一个小问题