在 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)boolean
date
datetime
decimal
float
int
(includes smallint, bigint, tinyint)real
(includes decimal, float, double, real)smallint
text
(includes text, mediumtext, longtext)timestamp
varbinary
varchar
|
| 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