sidus/eav-model-bundle

Symfony3 & Doctrine 实现的实体-属性-值模型,易于扩展

v1.3.18 2021-05-17 14:46 UTC

README

SensioLabsInsight

此文档的规范版本可在此找到:https://vincentchalnot.github.io/SidusEAVModelBundle

简介

此包允许您使用 Doctrine 在 Symfony 项目中快速设置动态模型。
模型配置使用 Yaml 完成,一切都可以轻松扩展。

据我所知,此模型的主要特性是能够根据您需要的**尽可能多的上下文轴**来**上下文化数据**。

所有 EAV 模型都允许您根据语言或国家(是的:国际化是数据上下文化的一个子集)来上下文化数据,一些模型允许您根据某些渠道或范围来上下文化数据,但这个特定的实现允许您管理上下文轴以符合您的业务逻辑,而不是反过来。

主要功能

文档索引

其他文档条目

在寻找什么?

请查看 问答部分,并在 issues 中提问。

什么是 EAV 模型

EAV 代表实体-属性-值

其主要特性是将值存储在与实体不同的表中。查看令人困惑且不太准确的 维基百科文章

这种实现实际上更类似于E(A)V模型,而不是传统的EAV模型,因为属性不是存储在数据库中,而是存储在YAML文件中。

如果您不熟悉EAV模型的关键概念,请阅读以下内容。

为什么使用它

  • 允许超快地设计模型,因为它非常容易启动。
  • 将模型和元数据(如:表单配置、验证、序列化选项等)放在同一个地方。
  • 以相同的方式管理单值属性和多值属性,并且可以在不进行数据恢复的情况下更改主意。
  • 按:区域、国家、渠道(网络/打印/移动)、版本存储上下文值。
  • 对属性进行分组和排序。
  • 简单的CRUD:您的表单已经配置好了!

为什么不使用它?

性能?这不是真正的问题,因为MySQL无论如何都不适用于在大量数据中搜索,无论是EAV模型还是更标准的关联模型。解决方案:Elastic Search:目前通过Sidus/FilterBundle以及Sidus/ElasticaFilterBundle可选支持。

关联模型

如果您有一个复杂的关联模型,并且计划使用大量的连接来检索数据,最好将关联模型保留在EAV模型之外,但两者可以共存而不存在问题。然而,在使用EAV模型的这种实现时存在一个技术限制:只有一个用于数据条目的表和一个用于值的表。

实现

我们使用Doctrine,因为它是最受Symfony社区支持的ORM,我们旨在只针对MySQL/MariaDB实现数据存储。

任何EAV模型都有两个面

  • 模型本身:家族(数据类型)、属性和属性类型。
  • 数据:值以及包含值的类,在这里称为“数据”。

在某些实现中,模型存储在数据库中,但在这里我们选择将模型维护在Symfony服务配置中,原因如下

  • 出于性能原因,您始终需要从您的模型访问大量组件,并且懒加载会生成许多不必要的SQL请求。Symfony服务是从PHP缓存系统中懒加载的,与任何其他存储系统相比,它非常非常快。
  • 出于复杂性原因:使用服务,您始终可以定义新的服务,使用注入,扩展现有服务,并为您的实体提供复杂的行为。
  • Symfony配置易于编写和维护,可以进行版本控制,当您的模型与数据一起存储在数据库中时,您将很难在不同的环境中维护相同的模型。
  • 因为最终用户永远不会直接在生产环境中编辑模型,总是有些专家或开发人员在测试环境中先进行编辑,我们更喜欢简单的YAML配置文件而不是可能失败的复杂管理系统。
  • 它允许您为特殊需求添加配置层,例如,您可以直接在属性声明中配置一些表单选项。
  • 最后,如果需要,您可以将配置拆分并组织到不同的文件中,并且可以对其进行注释,这对于模型开始变得越来越大,有数百个不同的属性时是一个强大的功能。

家族和属性是自动从您的配置中生成的服务,属性类型是标准的Symfony服务。

示例

对于基本的博客,配置看起来像这样

sidus_eav_model:
    families:
        Post:
            attributeAsLabel: title
            attributes:
                title: # Default type is string
                    required: true

                content:
                    type: html # This type is available through the EAVBootstrapBundle

                publicationDate:
                    type: datetime

                publicationStatus:
                    type: choice
                    form_options: # Symfony form options are passed directly
                        choices:
                            draft: Draft
                            published: Published
                            archived: Archived

                author:
                    type: data_selector # This type allows to select an other entity inside the EAV model
                    options:
                        autoload: true # Autoload author when loading Post
                        allowed_families:
                            - Author

                tags:
                    multiple: true
                    form_options:
                        collection_options:
                            sortable: true

                isFeatured:
                    type: boolean

        Author:
            attributeAsLabel: name
            attributes:
                name:
                    required: true

                email:
                    validation_rules: # Validation rules can be applied directly in the model
                        - Email: ~

请注意,按照惯例,我们声明家族为大驼峰式,属性为小驼峰式,我们鼓励您这样做。