【问题标题】:Symfony form large data setSymfony 形式大数据集
【发布时间】:2021-02-22 04:36:56
【问题描述】:

对于 Symfony 4 项目,我们需要制作一个包含多个字段的关于 surfaces 的大型 inpection 表单。我们正在寻找如何组织结构和关系并牢记加载速度的方法。

我创建了下面的基本实体示例,将其存储在一个数据库表中仍然很简单。下面的字段是简单的关系或字符串字段,因此 InspectionType 很容易。

class Inspection
{
    /** @var string */
    protected $projectName;

    /** @var string */
    protected $projectPlace;

    /** @var User */
    protected $inpector;

    /** @var Customer */
    protected $customer;

    /** @var string */
    protected $conclusion;

    /** @var string */
    protected $advice;

    // Complex part
    
    /** @var Collection */
    protected $surfaces;
}

现在是复杂的部分。 每个检查可能包含一个或多个表面 (ArrayCollection)。 每个表面由不同的字段组成,见下文:

  • 屋顶表面(4个字段);
  1. 文字类型
  2. 选择类型(单个)
  3. 选择类型(多)
  4. 日期类型
  • 泄漏(3 个字段);
  1. 文字类型
  2. 图像(关系,OneToMany)
  3. 选择类型(单个)
  • 张力(3个字段);
  • 坡度(3 个字段);
  • 屋顶污染(3 个字段);
  • 伤害(5 个字段);
  • 镇流器(3个字段);
  • 屋檐(3个领域);
  • UprightWork(4 个字段);
  • Dilation Rebellion(5 个字段);
  • 烟囱(3 个字段);
  • 分流箱(3 个字段);
  • ...还有9个+;

我的问题是如何设置surfaces 和数据库结构,表面中的每个部分是否应该像下面这样在表上具有返回检查的关系(这会创建很多表,这很糟糕吗?):

  • 表检查
  • 表检查泄漏
  • 表检查张力
  • ...

我正在考虑创建一个如下所示的嵌入集合表单

class InspectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ...

        $builder->add('surfaces', CollectionType::class, [
            'entry_type' => SurfaceType::class,
            'entry_options' => ['label' => false],
        ]);
    }
}

class SurfaceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('leakage', LeakageTyoe::class);
        $builder->add('tension', Tension::class);
        $builder->add('slope', Slope::class);
        ...
    }
}

这是要走的路吗:)

【问题讨论】:

    标签: php forms symfony symfony4


    【解决方案1】:

    我建议为您的表面实体使用discriminator/inheritance map,并使用single_table 策略。这为您提供所需的速度和灵活性。

    【讨论】:

    • 当一些孩子有自己的字段时,这个方法不会创建很多列吗?因为每个单独的表(Leakage, Tension)没有所有相同的字段,见上面代码中的更新
    • 单个表确实创建了更多列,但这没关系。加载 Leakage 实体时,它只会使用泄漏所需的字段,张力也是如此。类表继承确实也是一种选择。它基本上与单表继承做同样的事情。但是,请注意,当您有许多记录时,您可能会遇到性能下降的情况。这就是我建议 single_table 策略的原因。
    • 表继承是否为每个表面创建一个表(leakagetension)。那么相同的字段(继承)呢?我应该只将这些字段放在其父项和子项中吗?我倾向于类表继承,因为它描述如下: 这种映射策略在设计时提供了最大的灵活性,因为对任何类型的更改总是仅限于该类型的专用表。以后可以开机吗?以及图像怎么样。这是一个新关系,所以是一个新表?
    • 是的,类表继承 (CTI) 为每个表面创建一个表。对于单表,重叠字段应放置在父表中,而 CTI 则将其放置在其自己的类中。只需尝试它们,看看哪种最适合您。至于以后切换到单桌:是的,这是可能的。但是,您需要手动编写迁移来执行此操作。如果要添加图像,我想您需要一个新实体,因此将创建一个新表。将其与您的表面相关联应该不是问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    相关资源
    最近更新 更多