我对多对多表ID(主键)有一些疑问。根据Laravel文档,多对多关系由两个模型和三个表组成。每个模型都有其对应的表,中间表具有作为字段:
到目前为止,一切都很好。我已经使用了很多东西,使用帮助程序“ pivot”访问这些字段,并使用“ updateExistingPivot”等更新这些字段。
我要问的问题是,是否值得利用其他表的属性中的FK之类的中间表的ID。
示例:
在我的应用程序中,我具有以下模型:
这四个表:
给定一台特定的机器和一个产品,有N个限制。 一种限制属于一种特定的机器和产品。
如您所见,我利用自动增量ID(中间表的主键)来关联限制。但是以这种方式,使用Eloquent有点奇怪,就像从Restriction
访问Machine / Product
或从Restriction::where('machine_product_id', Machine::find(1)->products()->first()->pivot->id );
访问Product
一样简单:
Machine
如果要从给定的Restriction
中获得machine_product_id
或machine_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(限制)。我的意思是:
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)
}
的模型会更好?我不知道...
您能告诉我还是推荐解决此难题的最佳方法?已经修改了表格,模型或其他所需的内容。
谢谢。
答案 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 */