SaaS, Multi-tenant (shared schema) - one table or two? - database-schema

I am creating a multi-tenant (shared-schema) database for a SaaS application. The application will allow the subscribing company (the tenant) to collaborate with other companies (accounts – such as vendors, business partners, customers, etc.). Users will be associated with both the tenant and the accounts.
Here is my question: from a design perspective, is it okay to put the tenants and accounts in one table? I’m thinking “yes” because a company is a company regardless of whether they are a tenant or an account. Further, I was thinking of deciphering a tenant with a field such as is_tenant (Boolean) and perhaps put tenant specific information in a separate table. Here is a proposed schema:
companies (company_id, is_tenant, name, address, etc.)
users (user_id, name, email, username, password, etc.)
company_users (company_id, user_id)
tenant_information (company_id, billing_address, billing_state, etc.)
tenant_accounts (tenant_id, account_id) – associates tenants with accounts [where tenant_id and account_id would be f_keys to the companies table]
I read through the MS article, Multi-Tenant Data Architecture and, while helpful, it was short on providing an answer.
Any additional thoughts/comments/pitfalls regarding this schema would be greatly appreciated.
Thanks in advance.

I would also agree with that... if all the properties are same, then there is no need to create another table (data contract) for that.
We are also using something of that sort. In a SAAS framework you always need to be careful in creating tables otherwise it will take a huge effort to refactor & migrate.
I have a question though! Cant see any "Company_Information" table which will have company specific info (which are not your tenants)

Related

PostgreSQL: create a personalized role for any customer

I am new to Postgres, sorry if the question is basic:)
I need to create a personalized role for any customer already existing in the DB.
Role name must be client_{first_name}_{last_name} (without curly brackets).
Also, this customer can only access his own data in "table_1" and "table_2" tables.
I took ALICE STEWART (id 51).
What I did:
I created role Customer with Select privilege. Then tried to create role for ALICE STEWART and I get an infinite recursion error.
But how to create role for one customer so that he could access only his info in 2 tables?
How to do that properly?
There is nothing wrong with personalized database users, but I would only consider that if you don't have very many users. I wouldn't want to deal with a pg_authid that contains 100000 users.
I would not play this with permissions, but with row level security. The exact way in which that would work depends on your data. The easiest way is to have and owner column that lists the user that can see the data.
Watch out for overly complicated policies, as they will make your queries slow.

Designing a role based access on DB level

I am working on designing role based access for an application. Here, there are various department like HR, Finance , Developer ,etc. I am planning to have department level accesses on their respective related table like Finance user can access Payroll table...
I have done some R&D and came up with following approach.
Currently I have thought to have Department level user roles.
I have planned 3 roles Viz. super admin ,admin & user. So lets suppose if HR user makes a request to write data on employee we can check if user is from HR and then we grant this access.
Problem is that I am not able to design how to place an access table which can have collection of all accesses like employee_read_write or payroll_read_write ,etc.
Should I be creating a new access & map it somehow to user roles & department OR map the different tables that can be accessed on department level like Finance department has payroll accesses.
Since, I am new to RBAC kindly let me know if this is the right approach that I am planning or there is some better way. Appreciate your inputs !!

Seperate Database for Users

In my postgreSQL I currently have one database with user and business relevant tables. Our company is planing in future to add more categories, therefor I would like to seperate the categories into individual databases, as most of the data is quiet static once initialized. Below I am a showing an example with cars, please keep in mind that our company services differ much more as Pkw and LorryTruck and need much more extra tables within their scope.
Current State:
PostgreSQL:
CompanyDB
UserTable
PkwTable
ServiceTable
BookingTable
Future State
PostgreSQL:
UserDB
UserTable
PkwDB
PkwTable
ServiceTable
BookingTable
LorryTruckDB
LorryTruckTable
ServiceTable
BookingTable
My concern is if and how I could connect user relevant Data to the desired databases. In example a user can register for Pkw services and might be later on interested in LorryTruck services. The main goal is also that a user should only register once on our system.
Is this possible or could I design this better?
Please provide your opinion or experiences.
Thank you!
I would use a SCHEMA, not a different database. It's not possible (or easy) to get some data from a different database, while using different schema's is standard and working great.

Dependent multipick lists

I have a question regarding dependent multipick lists. I have subjects Client and organization. Client and Organization can come together in tjnClient^Organization. Within tblOrganization, you are able to select various services that the organization can offer. On the junction table between these subjects, there is a relationship to the same lookup table for services, offering a choice of services used by the client. I am needing a way to limit the choice of services for each client/org pair based on the org's choices on their table.
Here is what I have done:
I created a query, qryOrganization_Services. In that query, I have returned the primary keys of the organizations and their services, using an inner join to only collect the organizations which have picked services.
qryOrganization_Services
I have limited this query to have an organization primary key equal to the cboOrganization-RecordIdentifier, which is the combo box where the user selects an organization on the junction form between Client and Organization.
The rowsource for the combo box to select services that the client uses has been set up with an inner join between the services lookup table and the query mentioned earlier.
rowsource
I placed a requery macro on the AfterUpdate for the combo box to choose an organization, as well as a requery on the OnCurrent for the form.
The issue is the following. It appears that every single record updates its client services box based on the very first record’s choice of organization. I am not sure what is causing this.
Any thoughts appreciated.

REST API Design for systems with multiple companies or organizations

Most of the examples I see implement REST URL patterns like http://www.app.com/books/1 to access a book with ID 1 or http://www.app.com/books to access all the books.
That's great, but commonly I work on applications that support multiple companies. For example, Company ABC has 2 users and Company DEF has 2 users. A user from company ABC creates a book with id 100. Now when a RESTful call comes in from a user at company DEF:
http://www.app.com/books/100
there would need to be an Access exception, or
http://www.app.com/books
would only list all books belonging to DEF (not the new book with id 100). For many entities, like Book, the company ID is part of the table, but for other entities that may not be the case. For example, if there was a REST operation for one chapter in a book, http://www.app.com/chapter/333 the chapter table would have a foreign key reference to the book but not the company.
What would best practices be for managing access to this resource? If somebody from DEF tried to access a chapter from ABC I would have to construct a query to join the chapter to the book to verify the company id was valid.
I'm using Grails 3.x where most of this logic is abstracted and thinks happen "automagically". So a URL that comes in for a specific book ID is returned automatically and the request to list all returns every book in the database. It seems that to proceed I would have to override most of this automatic functionality and implement my own security, perhaps in the service layer where the company id would be a required parameter for every operation. Does that sound reasonable?
Is there an established best practice for this sort of thing?
Don't know if it fits your needs but it's interesting to know there is an ACL plugin written by Burt Beckwith :
Spring Security ACL Plugin