I'd like some feedback on having all properties a model can have in a properties table accessed via relationship (using laravel relationships) vs storing all properties/settings in the same table but in a json column.
Currently, my application has a propeties table called settings that is also polymorphic in nature so multiple models can store their properties there. This table has columns like
key (string),
value(string),
type (string) - tells if the value is of string, integer, boolean, json type
so that I do not send strings to javascript frontend, but instead I can send string, integer, boolean native types for better handling of types in frontend. I do this conversion before I send the properties to the frontend using php function that cast string values to int, boolean, json or string, depending on the type.
This means if a model has 40 properties, all get stored in its own row, so creating one model leads to creating 40 rows that store all properties it may have.
Now the above approach vs approach where I just have a single json column, we can call it settings and I dump all these 40 properties there.
What do I win with json column approach? I shave off a table and I shave off an extra relationship that I need to load on this model each time I do some queries. I also shave off having to each time I get properties cast them to integer, boolean, json or string. (remember the type column above) To keep in mind these properties do not need to be searchable, I need them only for reading from them. I will never use them in queries to return posts based on these properties.
Which one is a better idea to use, I'm building a CMS btw you can see it in action here: https://www.youtube.com/watch?v=pCjZpwH88Z0
As long as you don't try to use the properties for searching or sorting, there's not much difference.
As you said, putting a JSON column in your model table allows you to avoid a JOIN to the properties table.
I think your properties table actually needs to have one more column, to name the property. So it should be:
key (string),
property (string),
value(string),
type (string) - tells if the value is of string, integer, boolean, json type
The downsides are pretty similar for both solutions.
Queries will be more complex with either solution, compared to querying normal columns.
Storing non-string values as strings is inefficient. It takes more space to store a numeric or datetime value as a string than as a native data type.
You can't apply constraints to the properties. No way to make a property mandatory (you would use NOT NULL for a normal column). No way to enforce uniqueness or foreign key references.
There's one case I can think of that gives JSON an advantage. If one of your custom properties is itself multi-valued, there's a straightforward way to represent this in JSON: as an array within your JSON document. But if you try to use a property table, do you store multiple rows for the one property? Or serialize the set of values into an array on one row? Both solutions feel pretty janky.
Because the "schemaless properties" pattern breaks rules of relational database design anyway, there's not much you can do to "do it right." You're choosing the lesser of two evils, so you can feel free to use the solution that makes your code more convenient.
来源:https://stackoverflow.com/questions/55854169/properties-table-pattern-vs-storing-all-properties-in-json-column