Reputation: 183
The idea of the SaaS tool is to have dynamic tables with dynamic custom fields and values of different types, we were thinking to use "force.com/salesforce.com" example but is seems to be too complicated to maintain moving forward, also making some reports to create with a huge abstraction level, so we came up with simple idea but we have to be sure that this is kinda good approach.
This is the architecture we have today (in few steps).
TEXT/INTEGER/BOOLEAN/DATETIME
etc. and attribute value - as string, only as reference).50 character varying
columns with names like: attribute1...50
which are NULL-able.Example flow today:
Brand, Class, Year, Price
columns.Brand = attribute2, Class = attribute 5, Year = attribute6 and Price = attribute7
.SELECT [attr...2,5,6,7] FROM DATA
and then show the results to user, if user decide to do some filters on it, based on this data e.g. Year > 2017 AND Class = 'A'
we use CAST()
functionality of SQL
for example SELECT CAST(attribute6 AS int) AND attribute5 FROM DATA WHERE CAST(attribute6 AS int) > 2017 AND attribute5 = 'A';
, so then we can actually support most principles of SQL.However moving forward we are scared a bit:
(e.g. 50 per customer, with roughly 1-5 mil per TABLE (
5mil is maximum which we allow, for bigger data we have BigQuery) which is giving us 50-250 mil rows in single table DATA_X)
which might affect performance of the queries, especially when we gave possibilities to manage simple WHERE statements (less,equal,null etc.) using some abstraction language e.g. GET CARS [BRAND,CLASS,PRICE...] FILTER [EQ(CLASS,A),MT(YEAR,2017)]
developed to be similar to JQL (Jira Query Language).DATA_X
so once they want to load e.g. 1GB of the data, it kinda locks the table for other systems to access the DATA table.DATA_5, DATA_10, DATA_15, DATA_20, DATA_30, DATA_50
, where numbers corresponds to limitations of the attribute columns, and those entities are different, we also support migration option if they decide to switch from 5 to 10 attributes etc.We are on super early stage, so we can/should make those before we scale, as we knew that this is most likely not the best approach, but we kept it to run the project for small customers which for now is working just fine.
We were thinking also about JSONB objects but that is not the option, as we want to keep it simple for getting the data.
What do you think about this solution (fyi DATA has PRIMARY key out of 2 tables - (ID,TABLEID) and built in column CreatedAt which is used form most of the queries, so there will be maximum 3 indexes)?
If it seem bad, what would you recommend as the alternative to this solution based on the details which I shared (basically schema-less RDBMS)?
Upvotes: 0
Views: 301
Reputation: 7854
IMHO, I anticipate issues when you wanted to join tables and also using cast etc.
We had followed the approach below that will be of help to you
We have a table called as Cars
and also have a couple of tables like CarsMeta
, CarsExtension
columns. The underlying Cars
table will have all the common fields for a ll tenant's. Also, we will have the CarsMeta
table point out what are the types of columns that you can have for extending the Cars
entity. In the CarsExtension
table, you will have columns like StringCol1...5, IntCol1....5, LongCol1...10
In this way, you can easily filter for data also like,
CarsExtension
table to get the list of exentended rows for this entityAs we will have the extension table organized like below
id - UniqueId
entityid - uniqueid (points to the primary key of the entity)
StringCol1 - string,
...
IntCol1 - int, ...
In this case, it will be easy to do a join for entity and then get the data along with the extension fields.
In case you are having the table metadata and data being inferred from separate tables, it will be a difficult task to maintain this over long period of time and also huge volume of data.
HTH
Upvotes: 1