标签系统:Toxi 解决方案问题

2024-04-27

我对标签数据库模式的 Toxi 解决方案感到有点困惑。我正在开发一个系统,用户可以向该系统提交项目,并且这些项目可以具有与其关联的标签。在阅读了 tagchemas 后,我发现 Toxi 解决方案最适合我的需求。但是,我不完全确定我的计划是否正确,所以我想请您对此发表意见。

我将拥有三个数据库。
items含有item_id和别的
tagmap using item_id and tag_id作为外键
tags含有tag_id and tag_text

添加新项目时,我是否可以假设将标签添加到数据库的过程如下?

  1. 将提交的标签排序到数组中
  2. for every tag in the array:
    1. 从 tag_text 与当前标签匹配的标签中获取 tag_id
    2. if that returns 0 rows:
      1. 将标签添加到标签表
      2. 获取tag_id
    3. 将 item_id 和 tag_id 添加到 tagmap
  3. 完成(给用户“好的”等)

这意味着我们最终会在标签映射中为每个项目的每个标签提供一个条目。这似乎是正确的,但我忍不住认为有一个更好的方法来做到这一点,而不是最终在那里有大量的条目......

至于编辑标签,我想出了以下过程,尽管我认为还有更好的方法,但我还没有找到。

  1. 使用 item_id 获取标签并插入可编辑字段
  2. 用户进行更改。提交时:
  3. 从 tagmap 中删除 item_id 与正在编辑的行匹配的行
  4. 与上面列出的过程相同

我对第三点有点怀疑。有没有办法让我检查是否有任何标签已被删除,以便我可以有选择地删除标签,而不仅仅是删除并重新添加它们? 并且可以确定的是:删除标记映射行时,相关项目不会随之删除,因为它指向外键而不是充当外键,对吧?

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

回想起来,这是相当大量的文字。好吧,宁可太详细,也不要缺少信息;宁可问太多问题并学习很多新东西,而不是问太少。 很可能我今天花了太多时间研究这个问题,明天一切都会变得更有意义。

提前致谢!


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

现在回答问题本身......

我将拥有三个数据库。

不,你会有 3 张桌子。

添加新项目时...

您几乎走在正确的轨道上,只是您可以使用 SQL 基于集合的性质来“合并”其中许多步骤。例如,用标签标记项目 1:'tag1'、'tag2' 和 'tag3' 可以这样完成...

INSERT IGNORE INTO tagmap (item_id, tag_id)
SELECT 1, tag_id FROM tags WHERE tag_text IN ('tag1', 'tag2', 'tag3');

The IGNORE即使项目已经连接到其中一些标签,也允许此操作成功。

这假设所有必需的标签已经存在tags。假设tag.tag_id是自动递增的,你可以这样做来确保它们是:

INSERT IGNORE INTO tags (tag_text) VALUES ('tag1'), ('tag2'), ('tag3');

这意味着我们最终会在标签映射中为每个项目的每个标签提供一个条目。这似乎是正确的,但我忍不住认为有一个更好的方法可以做到这一点,然后在那里结束大量的条目......

没有魔法。如果“项目连接到特定标签”是您想要记录的知识,那么它将have在数据库中有某种物理表示。

至于编辑标签...

您的意思是重新标记项目(而不是修改标签本身)?

要删除列表中没有的所有标签,请执行以下操作:

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”之外的所有标签的连接。依次执行上面的 INSERT 和这个 DELETE 以“覆盖”添加和删除标签。

你可以在SQL小提琴 http://sqlfiddle.com/#!2/49981/3.

并且可以确定的是:删除标记映射行时,相关项目不会随之删除,因为它指向外键而不是充当外键,对吧?

正确的。 FK 的子端点不会触发引用操作(例如 ON DELETE CASCADE),只有父端点会触发。

顺便说一句,您正在使用此架构,因为您需要其他字段tags(旁tag_text), 正确的?如果这样做,不要仅仅因为所有连接都消失而丢失这些附加数据是理想的行为。

但如果你只是想要tag_text,您可以使用更简单的架构,其中删除所有连接与删除标签本身相同:

这不仅会简化 SQL,还会提供更好的聚类 http://use-the-index-luke.com/sql/clustering.

乍一看,“toxi”可能看起来像是在节省空间,但实际上可能并非如此,因为它需要额外的表和索引(并且标签往往很短)。

另外,我可能想跟踪标签的次数... cron 作业...

在你决定做这样的事情之前先衡量一下。上面提到的 My SQL Fiddle 使用了非常谨慎的字段顺序tagmapPK,因此数据以对这种计数非常友好的方式进行聚类(记住:InnoDB表是集群的 http://www.ovaistariq.net/521/understanding-innodb-clustered-indexes/)。在这成为问题之前,您必须拥有真正大量的物品(或需要异常高的性能)。

任何状况之下,measure基于实际数据量!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

标签系统:Toxi 解决方案问题 的相关文章

  • 在 ASP.NET MVC 中使用 MySQL 的 AccountController

    在 Visual Studio 中创建默认的 ASP NET MVC 项目会设置一个可以在其中注册用户的基本项目 我将如何继续更改它以使用 MySQL 服务器而不是 SQLServer 现在可以使用了 安装最新的 Connector NET
  • 导入 CSV 以更新表中的行

    大约有 26K 个产品 帖子 每个产品都有如下元值 post id 列是数据库中的产品 ID sku meta key 是每个产品的唯一 ID 我收到了一个新的 CSV 文件 该文件更新了每个产品的 sale price meta key
  • 从多个表中选择 - 一对多关系

    我有这样的表 表产品 身份证 姓名 表格图像 产品 ID 网址 订单号 表价 产品 ID 组合 货币 价格 表数量 产品 ID 组合 数量 表 Product 与其他表是一对多关系 我需要查询表并得到类似这样的结果 伪数组 ProductI
  • PHP:使用输入和输出参数(不是“INOUT”)调用 MySQL 存储过程

    我想从 PHP 调用 MySQL 中的存储过程 该过程需要输入and输出参数 not INOUT 参数 举一个简单的例子 假设我在 MySQL 中有以下存储过程 DELIMITER DROP PROCEDURE IF EXISTS test
  • PDO::commit 之后使用 PDOStatement::rowCount 结果?

    在 MySQL 文档中 有一个关于使用的注释mysql affected rows事务提交后 http php net manual en function mysql affected rows php http php net manu
  • PHP 中的异步数据库/服务调用:Gearman 与 pthreads

    在我们的 LAMP 站点上 我们遇到一些服务必须多次调用数据库才能提取数据的问题 通常在 PHP 中完成此操作的方式 至少我的经验 是串行的 这显然是低效的 我们可以通过使用缓存和聚合一些查询来缓解一些低效率的问题 但在某些情况下我们仍然需
  • 使用 mysql2 gem 获取最后插入的 id

    我有这样的代码 require mysql2 db query insert into clients Name values client 我可以通过 1 个查询返回最后插入的 ID 吗 您可以使用last id客户端实例的方法 clie
  • MySQL 5左连接未知列

    我有以下查询在 mysql 4 1 中工作 但在 5 0 中不起作用 SELECT FROM email e event email ee LEFT JOIN member m on m email e email WHERE ee ema
  • 如何使用 PHP 从 MySQL 查询中按升序对值进行排序?

    我使用以下 PHP 脚本从 MySQL 表中获取和更改数据 并将结果打印在 HTML 表中 我希望按升序对数据进行排序 utilization percentage变量 它是由创建的 total client time total avai
  • 更改Docker容器中的mysql密码

    我如何更改 docker 容器中的 root 密码 因为一旦我停止 mysql 服务 容器就会自动停止 我应该停止 mysql 容器并部署一个新容器吗 您可以使用正在运行的容器更改它docker exec session https doc
  • RMySQL fetch - 找不到继承的方法

    使用 RMySQL 我想将数据从数据库加载到 R 中的数据帧中 为此 我使用以下代码 R连接数据库 con lt dbConnect MySQL user root password password dbname prediction h
  • SQL 大表中的随机行(使用 where 子句)

    我有一个网站 人们可以在其中对汽车进行投票 向用户展示 4 辆汽车 他 她可以投票选出他们最喜欢的汽车 桌子cars有重要的列 car id int 10 not auto increment so has gaps views int 7
  • 在 MySQL 中将行转置为列

    如何在 MySQL 查询中将行转换为列 您可以将行变成a列与GROUP CONCAT 但您无法以任何自动方式转置整个结果集 您可以编写手动生成每一列的查询 也可以在应用程序中执行此操作 以下是有关编写复杂查询来模拟转置的教程 http ww
  • 如何将 php Web 应用程序转换为桌面应用程序并保留数据库 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我们有一个用 PHP 开发的 Web 应用程序 但大多数客户并没有一直连接到互联网 那么 有没有办法将应用程序转换为桌面应用程序 以便
  • 更新重复密钥上的复合密钥 [重复]

    这个问题在这里已经有答案了 我需要更新新行 如果两者都满足 date dat and empId who 作为复合键 但如果其中之一或两者不同 则插入 sql INSERT INTO history SET endtimestamp now
  • 如何修复 InterfaceError: 2003: 无法连接到“127.0.0.1:3306:3306”上的 MySQL 服务器(11001 getaddrinfo 失败)

    我的MySQL连接成功但是遇到这个界面错误 import mysql connector db mysql connector connect host 127 0 0 1 3306 user root passwd teja databa
  • 我可以在一个查询中更新/选择表吗?

    我需要在查看页面时选择数据并更新 视图 列 有没有一种方法可以在一个查询中执行此操作 或者我是否必须使用不同的查询 如果您不想 不需要使用事务 则可以创建一个存储过程 该过程首先更新视图计数 然后选择值并将其返回给用户
  • 如何在Sequelize中从主模型同一级别的包含模型返回结果?

    这是我在项目中完成的代码和结果 我想获得包含模型的结果与主模型相同的结果 下面的代码是我所做的 序列化查询 User findAll include model Position attributes POSITION NAME then
  • 高效插入和更新时检查唯一性

    我的员工表中有 2 列 每列值必须是唯一的 staff code staff name staff id staff code staff name 1 MGT Management 2 IT IT staff 当向表中插入或更新项目时 我
  • 让 Prometheus 发送 SQL 查询

    我正在尝试使用普罗米修斯 https prometheus io 监视我的 MySQL 数据库 但似乎找不到添加 SQL 查询的区域 例如 我想运行一个返回值的 SQL 查询 然后将该值添加到图表中 发送警报 有没有办法让 Promethe

随机推荐