属性 table 模式与将所有属性存储在 json 列中
properties table pattern vs storing all properties in json column
我想要一些关于模型可以在通过关系(使用 laravel 关系)访问的属性 table 中拥有的所有属性与将所有 properties/settings 存储在同一个属性中的反馈table 但在 json 列中。
目前,我的应用程序有一个名为设置的属性 table,它本质上也是多态的,因此多个模型可以在其中存储它们的属性。这个 table 有像
这样的列
key (string),
value(string),
type (string) - tells if the value is of string, integer, boolean, json type
这样我就不会将字符串发送到 javascript 前端,而是可以发送字符串、整数、布尔本机类型,以便更好地处理前端的类型。我在使用 php 函数将属性发送到前端之前执行此转换,该函数将字符串值转换为 int、布尔值、json 或字符串,具体取决于类型。
这意味着如果一个模型有 40 个属性,所有属性都存储在它自己的行中,因此创建一个模型会导致创建 40 行来存储它可能具有的所有属性。
现在上面的方法与我只有一个 json 列的方法相比,我们可以将其称为设置,我将所有这 40 个属性转储到那里。
json 列方法有什么好处?我剃掉了一个 table 并且我剃掉了一个额外的关系,每次我做一些查询时我都需要加载到这个模型上。我还省去了每次获取属性时将它们转换为整数、布尔值、json 或字符串的麻烦。 (记住上面的类型列)要记住这些属性不需要是可搜索的,我只需要它们来读取它们。我永远不会在基于这些属性的 return 帖子查询中使用它们。
使用哪个更好,我正在构建一个 CMS 顺便说一下,您可以在此处查看它的实际效果:
https://www.youtube.com/watch?v=pCjZpwH88Z0
只要您不尝试使用属性进行搜索或排序,就没有太大区别。
如您所说,在您的模型中放置一个 JSON 列 table 可以避免对属性 table.
的 JOIN
我认为您的属性 table 实际上需要多一列,以命名 属性。所以应该是:
key (string),
property (string),
value(string),
type (string) - tells if the value is of string, integer, boolean, json type
两种解决方案的缺点非常相似。
与查询普通列相比,使用任一解决方案的查询都会更加复杂。
将非字符串值存储为字符串效率低下。将数字或日期时间值存储为字符串比存储为本机数据类型需要更多 space。
您不能对属性应用约束。没有办法使 属性 成为强制性的(您将对普通列使用 NOT NULL)。无法强制执行唯一性或外键引用。
我能想到的一种情况给 JSON 带来了优势。如果您的自定义属性之一本身是多值的,那么在 JSON 中有一种直接的方法来表示它:作为 JSON 文档中的数组。但是,如果您尝试使用 属性 table,您会为一个 属性 存储多行吗?或者将一组值序列化为一行的数组?这两种解决方案都感觉很糟糕。
因为 "schemaless properties" 模式无论如何都违反了关系数据库设计的规则,所以您无能为力 "do it right." 您正在选择两害相权取其轻,因此您可以放心使用使您的代码更方便的解决方案。
我想要一些关于模型可以在通过关系(使用 laravel 关系)访问的属性 table 中拥有的所有属性与将所有 properties/settings 存储在同一个属性中的反馈table 但在 json 列中。
目前,我的应用程序有一个名为设置的属性 table,它本质上也是多态的,因此多个模型可以在其中存储它们的属性。这个 table 有像
这样的列key (string),
value(string),
type (string) - tells if the value is of string, integer, boolean, json type
这样我就不会将字符串发送到 javascript 前端,而是可以发送字符串、整数、布尔本机类型,以便更好地处理前端的类型。我在使用 php 函数将属性发送到前端之前执行此转换,该函数将字符串值转换为 int、布尔值、json 或字符串,具体取决于类型。
这意味着如果一个模型有 40 个属性,所有属性都存储在它自己的行中,因此创建一个模型会导致创建 40 行来存储它可能具有的所有属性。
现在上面的方法与我只有一个 json 列的方法相比,我们可以将其称为设置,我将所有这 40 个属性转储到那里。
json 列方法有什么好处?我剃掉了一个 table 并且我剃掉了一个额外的关系,每次我做一些查询时我都需要加载到这个模型上。我还省去了每次获取属性时将它们转换为整数、布尔值、json 或字符串的麻烦。 (记住上面的类型列)要记住这些属性不需要是可搜索的,我只需要它们来读取它们。我永远不会在基于这些属性的 return 帖子查询中使用它们。
使用哪个更好,我正在构建一个 CMS 顺便说一下,您可以在此处查看它的实际效果: https://www.youtube.com/watch?v=pCjZpwH88Z0
只要您不尝试使用属性进行搜索或排序,就没有太大区别。
如您所说,在您的模型中放置一个 JSON 列 table 可以避免对属性 table.
的 JOIN我认为您的属性 table 实际上需要多一列,以命名 属性。所以应该是:
key (string),
property (string),
value(string),
type (string) - tells if the value is of string, integer, boolean, json type
两种解决方案的缺点非常相似。
与查询普通列相比,使用任一解决方案的查询都会更加复杂。
将非字符串值存储为字符串效率低下。将数字或日期时间值存储为字符串比存储为本机数据类型需要更多 space。
您不能对属性应用约束。没有办法使 属性 成为强制性的(您将对普通列使用 NOT NULL)。无法强制执行唯一性或外键引用。
我能想到的一种情况给 JSON 带来了优势。如果您的自定义属性之一本身是多值的,那么在 JSON 中有一种直接的方法来表示它:作为 JSON 文档中的数组。但是,如果您尝试使用 属性 table,您会为一个 属性 存储多行吗?或者将一组值序列化为一行的数组?这两种解决方案都感觉很糟糕。
因为 "schemaless properties" 模式无论如何都违反了关系数据库设计的规则,所以您无能为力 "do it right." 您正在选择两害相权取其轻,因此您可以放心使用使您的代码更方便的解决方案。