I use MariaDB to store data using EAV model. I need EAV, because each attribute of each entity can have its own validity (validFrom
, validTo
). For example, I have entity person and I track changes made to their homeCity
and degree
attributes:
attributes
table:
attributeId name ------------------------ 1 'homeCity' 2 'degree'
values
table:
valueId entityId attributeId value validFrom validTo ------------------------------------------------------------------ 1 1 1 'London' 2022-01-01 2022-12-31 2 1 1 'Paris' 2023-01-01 NULL 3 1 2 'BSc' 2022-01-01 2022-06-30 4 1 2 'MSc' 2022-07-01 NULL 5 2 1 'Madrid' 2022-01-01 NULL
The problem is that I want to query the data conveniently (using WHERE
clauses, JOIN
s with other tables etc.), which is possible only if it is a standard SQL table with rows and columns looking like this:
entityId homeCity degree ---------------------------- 1 'Paris' 'Msc' 2 'Madrid' NULL
So I need to programmatically create/update such table from EAV model data after each EAV data update (or maybe create/update it only when user really requests the data).
Another problem is that such table would be valid only for certain date (typically for the current date). If I want to query data valid to a different date (e.g. 2022-01-01
), I need to dynamically create another table:
entityId homeCity degree ---------------------------- 1 'London' 'Bsc' 2 'Madrid' NULL
Is it a good approach to dynamically create a table if user asks to view data valid to a distinct date?
Another solution would be to store all validity data (i.e. all versions of given entity) in a single dynamically created table:
id entityId homeCity degree validFrom validTo -------------------------------------------------------- 1 1 'London' 'MSc' 2022-01-01 2022-06-30 2 1 'London' 'BSc' 2022-07-01 2022-12-31 3 1 'Paris' 'BSc' 2023-01-01 NULL 4 2 'Madrid' NULL 2022-01-01 NULL
In the query I just need to specify filter on validity: WHERE '2022-01-01' BETWEEN validFrom AND IFNULL(validTo, '9999-01-01')
. This solution is ideal for querying, but creating the table is slower, because it is necessary to compute all possible date versions of the entity.
Is this a good approach or is it better not to use EAV model at all?
Some details on my business domain: It is an app of school agenda (students, classes, etc). Each entity has about 50 attributes, almost every of them is potentially changeable (surname, e-mail, nationality...). Some of them only change rarely (home address), some change regularly (e.g. every year - school class which student attends). Attributes usually change individually, but it is not a rule - e.g. when home address changes, ale parts of it change at once (street, city, etc.). I don't expect many users editing the entity at the same time.
valueId
?