ID为多对多表格的最佳做法

时间:2018-10-20 10:56:39

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

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

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

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

我要问的问题是,是否值得利用其他表的属性中的FK之类的中间表的ID。

示例:

在我的应用程序中,我具有以下模型:

  • 机器
  • 产品
  • 限制

这四个表:

  • 机器(id,名称,...)[机器]
  • 产品(编号,名称,...)[产品]
  • machine_products(id,machine_id [FK],product_id [FK],价格)[无型号]
  • 限制(id,machine_product_id [FK],日期,begin_hour,end_hour)[限制]

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

如您所见,我利用自动增量ID(中间表的主键)来关联限制。但是以这种方式,使用Eloquent有点奇怪,就像从Restriction访问Machine / Product或从Restriction::where('machine_product_id', Machine::find(1)->products()->first()->pivot->id ); 访问Product一样简单:

Machine

如果要从给定的Restriction中获得machine_product_idmachine_id and product_id,则必须从带有{{1}的行中找到'machine_id'和'product_id' }的限制。

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

    如果指定了特定的machine_id和product_id,
  • restrictions将只有一个价格。
  • MachineProduct在给定特定的machine_id和product_id的情况下,该集合的N行将由day,begin_hour,end_hour组成。

或者如果我创建一个名为val nums :Stream[Int] = 1 #:: 10 #:: 9 #:: 12 #:: 3 #:: 4 #:: nums def thirt(n :Long) :Long = { val s :Long = Stream.iterate(n)(_ / 10) .takeWhile(_ > 0) .zip(nums) .foldLeft(0L){case (sum, (i, num)) => sum + i%10 * num} if (s == n) s else thirt(s) } 的模型会更好?我不知道...

您能告诉我还是推荐解决此难题的最佳方法?已经修改了表格,模型或其他所需的内容。

谢谢。

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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

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

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

因此,您的machines_products表不是纯粹的many:many中间表。相反,它是Job表(或应称为MachineProduct表),应该被称为。

最后,您具有与此关系的限制实体

  Job :: one-to-many :: Restriction

因此,要使您的真实世界的口才模型清晰明了,请将该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 */