Hello! Could use some input on how to best construct a schema here, having some trouble conceptualizing how it’d look in Grist.
Short version
I have a use case for polymorphic relations, which I’d like to solve with class table inheritance. But I don’t see any way to create SQL-style triggers, so that’d require double inserts, which I’d like to avoid. Any ideas or suggestions on alternatives, or on methods to ease the double insertion?
Long version
Simplified example: I have a database of entities of varying types, such as: part, assembly, container, location. Each type has a set of attributes unique to that type, along with a set of common attributes that are shared among all types. So, one table per entity type.
One such common attribute is placement, which indicates where an entity is physically present. In my tables, this is a parent field that references the same entities table, along with its two-way counterpart children. Each entity can have only one parent, and placement must be acyclic. Thus, entity placement can be shown as a tree. Great!
parts (
id PRIMARY KEY,
parent REFERENCES assemblies,
example_part_attribute,
. . .
)
assemblies (
id PRIMARY KEY,
parent REFERENCES containers,
example_assembly_attribute,
. . .
)
First problem: while placement has a hierarchy, rungs can be skipped or repeated; all these configurations are valid:
location > container > assembly > part
location > assembly
assembly
container > container > part
My parent column can’t reference multiple tables. But, since rungs can be skipped or repeated, I can’t have a separate parent field for each type (e.g. parent_assembly). So I combine all my disparate type tables into one large entities single-inheritance table:
entities (
id PRIMARY KEY,
type ENUM('part', 'assembly', 'location', 'container'),
parent REFERENCES entities,
example_part_attribute,
example_assembly_attribute,
. . .
)
Second problem: This gets cumbersome quickly; some types have many unique attributes, so my one giant table end up with lots of columns and nulls. Worse, many formulas are specific to entity type, so every formula would need to first validate the type and split to sub-functions. Dropdown conditionals helps with some of this, but not most.
Class table inheritance solves this, where one entities table holds all the common fields (including parent), and then each type gets its own subtable with all the extended fields, with one row for each corresponding row of that type in entities:
entities (
id PRIMARY KEY,
type ENUM('item', 'assembly', 'location', 'container'),
parent REFERENCES entities,
. . .
)
parts (
id PRIMARY KEY REFERENCES entities,
example_part_attribute,
. . .
)
assemblies (
id PRIMARY KEY REFERENCES entities,
example_assembly_attribute,
. . .
)
Third problem: This works great, except now adding a new entity requires an insertion in both the entities table and the entity’s type subtable, which is also cumbersome. Maybe I’m missing it, but I couldn’t find any way to automatically TRIGGER insertion of a record in a table when a record is created in another table. Is such a feature possible?
I also couldn’t find a satisfying way to make the UX of double insertion feel smoother, but I may well have missed a good method. Any ideas for making the data entry smoother, or a better way to approach this entirely? I did find this previous question which is related, but not quite right. Apologies if I missed something else.
Thank you so much for the time and help!