Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 标签系统:Toxi解决方案问题_Mysql_Database Design_Database Schema_Tagging - Fatal编程技术网

Mysql 标签系统: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和标签文本 在添加新项时,我是否正确地假设将标记添加到数据库的过程如下 将提交的标记排序到数组中 对于阵列中的每个标记:

对于标记数据库模式的Toxi解决方案,我有点不知所措。我正在开发一个系统,用户可以向该系统提交项目,这些项目可以有与之关联的标签。在阅读了TagSchema之后,我发现Toxi解决方案最适合我的需要。然而,我不完全确定我是否计划好了,所以我想听听你对此的意见

我有三个数据库。
项目
包含
项目id
和其他
tagmap
使用
item\u id
tag\u id
作为外键
标签
包含
标签id
标签文本

在添加新项时,我是否正确地假设将标记添加到数据库的过程如下

  • 将提交的标记排序到数组中
  • 对于阵列中的每个标记:
  • 从标记文本与当前标记匹配的标记中获取标记id
  • 如果返回0行:
  • 将标记添加到标记表
  • 获取标签id
  • 将项目id和标记id添加到tagmap
  • 完成(给用户a-okay等)
  • 这意味着我们将在tagmap中为每个项目的每个标记创建一个条目。这似乎是正确的,但我忍不住认为有一个更好的方法来做这件事,而不是以大量的条目结束

    至于编辑标签,我已经想到了下面的过程,尽管我认为还有一个更好的方法,我还没有找到

  • 使用项目id获取标签并插入可编辑字段
  • 用户进行更改。提交时:
  • 从tagmap中删除项_id与正在编辑的项匹配的行
  • 与上面列出的过程相同
  • 我对第三点有点怀疑。是否有一种方法可以让我检查是否有任何标记已被删除,这样我就可以有选择地删除标记,而不只是删除并重新添加它们? 当然,当删除标记映射行时,相关的项目不会被删除,因为它指向一个外键而不是一个外键,对吗

    此外,我可能希望跟踪标记的使用次数,但我不希望每次需要显示时都运行查询来计算这些次数。我想让cron作业每小时或每两小时计算一次tagmap中每个tag_id的实例数,然后更新tags表中的tag_use值。这是一个正确的方法,还是有更好的方法

    回顾过去,这是相当大的文本量。Welp,与其说信息太少,不如说信息太详细;与其说问题太多,学到了很多新东西,不如说问题太少。 很有可能我今天花了太多时间研究这个问题,明天一切都会变得更有意义

    提前谢谢

    首先,“toxi”不是一个标准术语。始终定义您的术语!或者至少提供相关链接

    现在谈谈问题本身

    我有三个数据库

    不,你们有三张桌子

    添加新项目时

    除了可以使用SQL的基于集合的特性来“合并”其中的许多步骤之外,您已经走上了正确的道路。例如,用标签“tag1”、“tag2”和“tag3”标记项目1可以这样做

    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中使用了非常谨慎的字段顺序,因此数据以一种对这种计数非常友好的方式进行集群(记住:)。在这成为一个问题之前,您必须拥有大量的项目(或要求异常高的性能)


    在任何情况下,测量实际数据量

    哇,这真是一个精心设计的答案!我学到了很多,我想这足以让我继续前进。非常感谢你!(此外,还有一个小问题