我在PHP
和MySQL
中有一个自制的web应用程序。使用我的系统的许多不同客户端都希望使用自定义字段来增强实体。每个客户端都希望存储自己的附加数据,因此这应该以动态方式进行。
例如,client1希望将"color"属性添加到其产品中,client2则希望为其产品提供一个名为"safety_level=/em>"的字段。
我想要一种不仅适用于产品,也适用于用户和任何其他实体的方法。
以下是我发现的两个最佳选项,但无法决定哪一个最有效:
选项1:
对于每个实体,我制作一个[entityname]_customfields
表,在其中我以1:1的方式存储附加字段值。例如:
+---------------------------------------------+
|products_custom_fields |
+---------------------------------------------+
|product_id (PK and FK related to products.id)|
|safety_level |
|some_other_fields |
+---------------------------------------------+
pro:此表的记录不能多于实体表(在本例中为产品),这意味着记录更少,而且很容易进行概述。
con:添加新字段或删除旧字段需要DDL查询。我不想向用户透露DDL。。。甚至没有管理员权限的操作员。
选项2:[entity]_custom_field_values
将具有与[entity]
表的N:1关系。每一行都包含自定义字段的类型和值本身。在这种情况下,我们需要另一个包含自定义字段类型的表。例如:
自定义字段值:
+----------------------------------------------------------------------+
|products_custom_field_values |
+----------------------------------------------------------------------+
|custom_field_id |
|custom_field_type (FK product_custom_field_types.custom_field_type_id)|
|value |
+----------------------------------------------------------------------+
自定义字段类型:
+---------------------------------------------------------+
|products_custom_field_types |
+---------------------------------------------------------+
|custom_field_type_id (PK AUTO_INCREMENT) |
|product_id (FK related to products.id) |
+---------------------------------------------------------+
pro:管理字段很容易,不需要更改表结构
con:更多的记录,所有类型的自定义字段值都一团糟。。。这并不一定是错误的,因为这就是MySQL的重点,从一堆混乱中提取有用的数据。问题是效率和性能如何?
注意:这个主题实际上包含在"SQL反模式"中,我强烈建议您阅读
我是一个懒惰的人,这意味着我倾向于将YANGI应用到我的代码中。所以这就是我的方法。
所以。假设有两组产品:
ProductFoo ProductBar
- productID - productID
- name - name
- price - price
- color - supply
- weight - manufacturerID
- safety
在这种情况下,主Products
表中有三个常见元素。自定义参数将使用表继承存储(这是一件事,谷歌一下)。因此,基本上您会得到三个表:Products
、ProductsFoo
和ProductsBar
,其中Products
表有一个"type"
字段,两个"子表"都有一个指向其父表的productID
外键。
如果您在开发时知道每个客户需要什么"自定义字段"。
现在,让我们假设客户很难理解,只要他们愿意,就想弥补自定义字段。
在这种情况下,我只需创建一个Products.data
字段,其中包含一个JSON,其中包含每个产品的所有自定义属性。当客户端希望通过自定义属性进行搜索时,只将特殊属性"提取"到继承表中(如果客户端希望通过新的"wallywanker"属性进行搜索,则没有合理的方法来索引JSON)。
您最终得到了相同的基本结构,但"子表"只包含预期可搜索的属性
我希望这是有道理的。
如果是公司项目,请遵循以前项目中遵循的标准。
看看匈牙利符号等惯例,这比重复前缀更有意义。此外,您的模型名称更有可能是您的表名称。
此外,如果您计划使用ORM,他们可能也有一些最佳实践。
https://en.wikipedia.org/wiki/Hungarian_notation