配置声明模式

更新

在 Magento 2.3 之前,扩展开发者需要编写代码(PHP 脚本)来改变数据库模式。在 Magento 2.3 之前,存在以下类型的脚本。

  • InstallData 和 InstallSchema 脚本,它们在第一次安装模块时被执行。
  • UpgradeData 和 UpgradeSchema 增量脚本,用于补充现有模块模式。
  • 循环脚本,在你每次安装或升级 Magento 时执行。

每个脚本都会反复增加变化。在安装过程中,升级脚本只应用那些尚未应用的变化。例如,如果你安装了一个版本为 2.1.8 的模块,而最新的版本是 2.1.11,那么当你升级到 2.1.11 时,2.1.9、2.1.10 和 2.1.11 的升级脚本变化将被依次应用。每个升级脚本都负责检查每个变化所需的版本,以便应用。Magento 安装只知道一个模块有一个升级脚本,而不知道它影响了哪些版本。这个程序被称为迁移设置或迁移脚本。

这种方法的主要缺点是,Magento 会盲目地应用变化。例如,在一个版本中可能会引入一个新的数据库列,但在下一个版本中却被删除。声明式设置消除了这种类型的不必要的工作。

声明式设置是基于数据库结构声明的,并被用于 Doctrine 等项目。模式文件声明了数据库结构应该是什么,而 Magento 则确定当前表结构和它应该是什么之间的差异。这些差异可以用原子化的 SQL 操作来表示。

Magento 会优先考虑声明性模式,并在数据和模式补丁之前执行声明性安装模式。

下面的例子是从 Catalog/etc/db_schema.xml 文件中提取的,定义了 catalog_product_entity_datetime 表。

<table name="catalog_product_entity_datetime" resource="default" engine="innodb"
           comment="Catalog Product Datetime Attribute Backend Table">
    <column xsi:type="int" name="value_id" padding="11" unsigned="false" nullable="false" identity="true" comment="Value ID"/>
    <column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Attribute ID"/>
    <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/>
    <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity ID"/>
    <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/>
    <constraint xsi:type="primary" referenceId="PRIMARY">
        <column name="value_id"/>
    </constraint>
    <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/>
    <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_datetime" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/>
    <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/>
    <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID">
        <column name="entity_id"/>
        <column name="attribute_id"/>
        <column name="store_id"/>
    </constraint>
    <index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree">
        <column name="attribute_id"/>
    </index>
    <index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID" indexType="btree">
        <column name="store_id"/>
    </index>
</table>

db_schema 结构

The <Module_Vendor>/<Module_Name>/etc/db_schema.xml 文件声明了一个模块的数据库结构。

如果你已经启用了 URN 高亮,你可以在选择一个节点的 xsi:type 之后使用 PhpStorm 的自动完成功能。这也将允许你查看在你的 db_schema.xml 文件的每一行中哪些属性是可用的

Top-level node

Schema 节点定义了 schema.xsd 文件的位置。

<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">

table node

每个 db_schema.xml 文件应该包含一个或多个表节点。每个表节点代表数据库中的一个表。一个表节点可以包含以下属性。

  • Name - 表名.
  • engine - SQL 引擎,innodb or memory.
  • resource - The database shard on which to install the table。values: default, checkout 或者 sales
  • Comment - 表注释

一个 table node 可以包含三个类型的子节点 subsides:

  • column
  • constraint
  • index

column subnode

column subnode 定义了了表中的一个字段,每个字段有各自的声明, 例如:

| ATTRIBUTE | DESCRIPTION | | :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | xsi:type | Specifies the column type. Must be one of the following:blob (includes blob, mediumblob, longblob)booleandatedatetimedecimalfloatint (includes smallint, bigint, tinyint)real (includes decimal, float, double, real)smallinttext (includes text, mediumtext, longtext)timestampvarbinaryvarchar | | default | Initializes the column with the specified default value. The default value should have the same datatype defined in xsi:type. | | disabled | Disables or deletes the declared table, column, constraint, or index. | | identity | Indicates whether a column is auto incremented. | | length | Specifies the length of a column. Can be used for char, varchar, and varbinary types. | | nullable | Indicates whether column can be nullable. | | onCreate | This is a DDL trigger that allows you to move data from an existing column to a newly created column. This trigger works only when a column is created. | | padding | The size of an integer column. | | precision | The number of allowed digits in a real data type. | | scale | The number of digits after the decimal in a real data type. | | unsigned | For numeric data types, specifies whether the column can contain positive and negative values or only positive values. |

关于每个类型的更多信息,可以参阅相应的 XSD 文件中的注释.

  • Composer 或者 Github 安装:

    <Magento_root_directory/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc

    
    <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="true" comment="Credit ID"/>
    
    

约束子节点 constraint subnode

约束子节点使用包含下名的属性

| ATTRIBUTE | DESCRIPTION | | :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | type | One of primary, unique, or foreign | | referenceId | A custom identifier that is used only for relation mapping in the scope of db_schema.xml files. The real entity in the database has a system-generated name. The most convenient way to set the value of this attribute is to use the value that is written in the module’s db_schema_whitelist.json file when you run the generate-whitelist command. |

主约束和唯一约束被称为 "内部 "约束,因为它们只能应用于创建它们的表的范围内。内部约束定义了一个或多个列的子节点。每个子节点都定义了一个受约束的列。

下面的例子显示了一个内部约束的格式。

<constraint xsi:type="primary" referenceId="PRIMARY">
    <column name="entity_id"/>
</constraint>

外来约束类似于 SQL 中的外键。这种类型的约束将两个表相互连接起来。以下属性定义了一个外置约束。

| ATTRIBUTE | DESCRIPTION | | :---------------- | :------------------------------------------------------------------------------ | | table | The name of the current table | | column | A column in the current table that refers to a specific column in another table | | referenceTable | The table being referenced | | referenceColumn | A column in the referenceTable | | onDelete | Foreign key trigger. The value must be CASCADE, SET NULL, or NO ACTION |

为了保持实体标识符为不可变的值,声明式模式不支持约束的 ON UPDATE 动作。

例如:


<constraint xsi:type="foreign" referenceId="COMPANY_CREDIT_COMPANY_ID_DIRECTORY_COUNTRY_COUNTRY_ID" table="company_credit" column="company_id" referenceTable="company" referenceColumn="entity_id" onDelete="CASCADE"/>


更多内容参考:

https://devdocs.magento.com/guides/v2.3/extension-dev-guide/declarative-schema/db-schema.html