【问题标题】:MySQL: Data structure for transitive relationsMySQL:传递关系的数据结构
【发布时间】:2014-10-06 10:40:41
【问题描述】:

我尝试设计一种数据结构,方便快速查询(删除、插入更新速度对我来说并不重要)。

问题:传递关系,一个条目可能与其他条目之间存在关系,我不想为每种可能性单独保存这些条目的关系。

意思--> 我知道Entry-A 与Entry-B 相关,也知道Entry-B 与Entry-C 相关,即使我不明确知道Entry-A 与Entry- 相关C、我要查询。

我认为解决方案是:

在插入、删除或更新时消除传递部分。

Entry:
    id
    representative_id

我会将它们存储为集合,例如一组条目(不是 mysql 集合类型,数学集合,如果我的英语错误,抱歉)。每个集合都有一个代表条目,所有集合元素都与代表元素相关。

新的插入将插入条目并将代表设置为自身。

如果新插入的条目应该连接到另一个,我只需将新插入的条目的代表id设置为引用条目的rep.id。

将 B 附加到 A

没关系,如果我需要将它连接到不是代表条目的东西,那将是相同的,因为集合中的每个条目都将具有相同的 rep.id。

将 C 附加到 B

分离 B-C:分离的项目将成为代表条目,这意味着它将与自身相关。

分离 B-C 并将 C 附加到 X

删除: 如果我删除一个不具代表性的条目,它是不言自明的。但是删除 rep.entry 有点困难。我需要为集合选择一个新的 rep.entry,并将每个集合成员的 rep.id 设置为新的 rep.entry 的 rep.id。

所以,删除A:

会这样:

您对此有何看法?这是一个正确的方法吗?我错过了什么吗?我应该改进什么?

编辑: 查询: 所以,如果我想查询与某个条目相关的每个条目,我知道其 id:

选择 * FROM 条目 左连接条目 b ON (a.rep_id = b.rep_id) 在哪里 a.id = :id

SELECT * FROM AlkReferencia
WHERE rep_id=(SELECT rep_id FROM AlkReferencia
    WHERE id=:id);

关于需要这个的应用程序:

基本上,我存储车辆零件编号(参考),一个制造商可以制造多个可以替换另一个制造商的零件,而另一个制造商可以制造替换其他制造商零件的零件。

参考:某制造商对某产品的 OEM 编号。

交叉引用:制造商可以生产旨在替换其他制造商的另一种产品的产品。

我必须以某种方式连接这些参考资料,当客户搜索号码时(不管他有什么样的号码),我可以列出准确的结果和替代产品。

使用上面的示例(最后一张图片):B、D 和 E 是我们店内可能有的不同产品。每个都有一个制造商和一个字符串名称/参考(我之前称它为数字,但它几乎可以是任何字符链)。如果我搜索 B 的参考编号,我应该返回 B 作为精确结果,并返回 D,E 作为替代。

到目前为止一切顺利。但我需要上传这些参考号。我不能只从 ALL-IN-ONE 数据库中迁移它们。大多数时候,当我上传从制造商那里获得的参考资料时(不知何故,大部分时间是手动的,但我也可以使用目录),我只会得到一个列表,其中制造商告诉哪些其他参考编号指向他的编号。

示例:

作为过滤器制造商,“AS 1”过滤器有这些交叉引用(意味着,替换这些):

GOLDEN SUPER  -->  1
ALFA ROMEO  -->  101000603000
ALFA ROMEO  -->  105000603007
ALFA ROMEO  -->  1050006040
RENAULT TRUCKS (RVI)  -->  122577600
RENAULT TRUCKS (RVI)  -->  1225961
ALFA ROMEO  -->  131559401
FRAD  -->  19.36.03/10
LANDINI  -->  1896000
MASSEY FERGUSON  -->  1851815M1
...

写下所有 AS 1 引用需要很长时间,但有很多(~1500 ?)。它是一个过滤器。有超过 4000 个过滤器,我需要在那里存储参考(这些只是过滤器)。我想你可以看到,我无法连接所有东西,但我必须知道阿尔法罗密欧 101000603000 和 105000603007 是相同的,即使我只知道 (AS 1 --> alfa romeo 101000603000) 和 (as 1 --> alfa罗密欧 105000603007)。 这就是为什么我想将它们组织成一组。每个集合成员只能连接到另一个具有 rep_id 的集合成员,该成员将是代表成员。当有人想要(例如,管理员,在上传这些参考资料时)将新参考资料附加到集合成员时,我只需 INSERT INTO References (rep_id,attached_to_originally_id,refnumber) VALUES([rep_id of the entry what I am trying to attach to],[id of the entry what I am trying to attach to], "16548752324551..");

另一件事:我不需要那么担心插入、删除、更新速度,因为这是我们系统中的管理任务,很少会做。

【问题讨论】:

  • MySQ>L 目前不支持递归查询。因此,您必须构建一些辅助结构来获得任何深度关系的结果。
  • 这就是我试图避免的,将代表 ID 存储到每个连接的条目中
  • 你不能在 MySQL 中有效地查询这样的结构。您必须为深入的每一步添加另一个自联接。
  • 这样查询一个集合很容易: SELECT * FROM entries WHERE XYentry.rep_id = :repid 这将返回集合中的所有内容。
  • 那是一年级相关的对象。要获得二年级相关的,那么你必须加入你的表(因此自我加入)并将相同的条件应用于第二个table。对于三年级,您再次加入您的餐桌并做同样的事情,...

标签: mysql database-design relational-database


【解决方案1】:

不清楚您要做什么,也不清楚您是否了解如何关联地思考和设计。但是您似乎想要满足“[id] 是由成员 [rep_id] 命名的集合的成员”的行。

停止考虑表示和指针。只需找到填写(命名)空白语句(“谓词”),这些语句说明您对您的应用程序情况的了解,并且您可以结合起来询问您的应用程序情况。每个语句都有一个表(“关系”)。表格的列是空白的名称。表的行是使其陈述成立的行。查询具有从其表的语句构建的语句。结果的行是使其陈述成立的行。 (当查询有表名的 JOIN 时,它的语句 AND 表的语句。UNION 或它们。EXCEPT 放入 AND NOT。WHERE 与一个条件。通过 SELECT 删除列对应于逻辑 EXISTS。)

也许你的应用场景是一堆带有值和指针的单元格。但我怀疑你的单元格、指针和连接以及附加和插入只是你解释和证明你的表格设计的方式。您的应用程序似乎与集合或分区有关。如果您真的试图表示关系,那么您应该了解关系表表示(是)关系。无论如何,您应该确定您的表语句是什么。如果您需要设计帮助或批评,请告诉我们更多关于您的应用情况,而不是关于它们的表示。所有的关系表示都是由满足语句的行的表来表示的。

你真的需要用代表元素来命名集合吗?如果我们不关心名称是什么,那么我们通常使用由 DBMS 选择的“代理”名称,通常是通过一些整数自动增量工具。为集合使用这种与成员无关的名称的好处是我们不必重命名,尤其是通过选择元素。

【讨论】:

  • 我承认我的命名可能不合适,我的母语是匈牙利语,我不太了解英语中的技术术语。
  • 我不明白您的评论与我的回答有何关联。 (您的信息“不清楚”关于“问题:传递关系”,因为您选择写的很少(而不是“解决方案”),而且您写的内容含糊不清。)
  • 我认为及物性的定义是微不足道的(甚至提到它,但en.wikipedia.org/wiki/Transitive_relation)。我在最后一部分解释了它。如果不重复自己,我不知道我还应该写什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 2012-07-10
  • 2013-09-13
  • 2011-04-30
  • 2020-03-22
相关资源
最近更新 更多