【问题标题】:Best practices with id's of many-to-many tables多对多表 id 的最佳实践
【发布时间】:2019-03-25 02:03:28
【问题描述】:

我对多对多表 id(主键)有一些疑问。根据 Laravel 文档,多对多关系由两个模型和三个表组成。每个模型都有对应的表,中间表有as字段:

  • 自动增量 ID
  • table1_id
  • table2_id
  • other_attributes ...

到目前为止,一切都很好。我已经用过很多次了,使用助手“pivot”访问字段,并使用“updateExistingPivot”等更新这些字段。

我的问题是是否值得从其他表的属性中利用中间表的ID,例如FK。

示例:

在我的应用程序中,我有这些模型:

  • 机器
  • 产品
  • 限制

还有这四张表:

  • 机器(ID、名称、...)[机器]
  • 产品(ID、名称、...)[产品]
  • machine_products (id, machine_id[FK], product_id[FK], price) [无型号]
  • 限制(id、machine_product_id[FK]、day、begin_hour、end_hour)[限制]

给定特定的机器和产品,有 N 个限制。 一种限制属于一种特定的机器和产品。

如您所见,我利用自动增量 ID(中间表的主键)来关联限制。但是这样一来,使用 Eloquent 就有点奇怪了,就像从 Machine / Product 访问 Restriction 或者反过来一样,并不容易:

Restriction::where('machine_product_id', Machine::find(1)->products()->first()->pivot->id );

如果我要从给定的Restriction 中获得ProductMachine,我将不得不从我拥有的限制的machine_product_id 行中找到'machine_id' 和'product_id'。

我不知道在使用 Eloquent 时是否出于实用性和功能性问题,最好使用machine_id and product_id 做两个多对多表,一个使用price (machine_products),另一个使用day, begin_hour, end_hour (restrictions) .第一个表是 1 到 1(machine_products)和另一个 1 到 N(限制)。我的意思是:

  • 给定特定的 machine_id 和 product_id,machine_products 将只有一个价格。
  • 给定特定的 machine_id 和 product_id,restrictions 将包含 N 行,包括 day、begin_hour、end_hour。

或者我做一个模型叫MachineProduct会更好?我不知道...

你能告诉我或推荐解决这个困境的最佳方法吗?已经在修改表、模型或任何需要的东西。

谢谢。

【问题讨论】:

    标签: mysql laravel eloquent many-to-many relationship


    【解决方案1】:

    如果您仅对 MachineProduct 实体应用严格的实体关系设计,则中间表将只有两列。

     machine_id  INT PK  FK to machine.id
     product_it  INT PK  FK to product.id
    

    这实现了Machine :: many-to-many :: Product 关系。

    这个中间表会有一个复合主键。主键的唯一性将决定每台机器只能与每个产品有一个关系。通过插入一行来创建关系,并通过删除该行来切断它。

    但是您的实际应用程序中还有两个东西,价格和限制。看起来您的应用程序规定价格与机器和产品都有关系。

    因此,我们需要另一个实体来清楚地描述您的应用程序。我们称之为工作。每个 Job 都有一个 price 属性。它使用一台机器生产一种产品。因此它有这些关系。

      Machine  :: many-to-one :: Job 
      Product  :: many-to-one :: Job
    

    因此,您的machines_products 表不是纯粹的多:多中间表。相反,它是并且应该称为 Job 表(或者如您所说的 MachineProduct 表)。

    最后,你有一个具有这种关系的 Restriction 实体

      Job :: one-to-many :: Restriction
    

    因此,为了使您的 Eloquent 模型对现实世界更加清晰,请将 Job (MachineProduct) 实体添加到您的模型中。整个模型看起来像这样。 (有趣的是,它的核心是 Job / MachineProduct 实体。)

     +-------------+     +------------+     +---------------+   
     |             |    /|            |\    |               |   
     |   Product   |-----|     Job    |-----|     Machine   |   
     |             |    \|            |/    |               |   
     +-------------+     +------------+     +---------------+   
                                |                                
                                |                               
                               /|\
                         +-------------+                        
                         |             |                        
                         | Restriction |                        
                         |             |                        
                         +-------------+                        
    

    专业提示:最好在开始创建表格之前弄清楚您的实体和关系。

    专业提示:如果您避免使用machine.id 之类的列名,而是使用machine.machine_id,您的数据库架构可能更容易理解。这样你就可以在查询中这样说

     FROM Job j JOIN Machine m ON j.machine_id = m.machine_id
    

    而不是

     FROM Job j JOIN Machine m ON j.machine_id = m.id
    

    不必怀疑,等等,id 是什么,也不要冒险误操作:

    FROM Job j JOIN Product p ON j.machine_id = p.id  /* wrong */
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-06
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-02
      • 2017-02-12
      相关资源
      最近更新 更多