Elastic Db tools and unique indexes - indexing

I read the documentation for the Microsoft Elastic DB tools and I wanted to ask what are the best practices for sharing a database with multiple tenants and also using unique index.
Let's say that we have a users table, in which all users for a tenant are saved. We define that the email must be unique for each user. But, If a user is present in 2 tenants and he wants to reuse his email, he can't because the unique index is in place.
In this case, we need to include in the unique index the tenant id. Is this the right approach? In this case we would need to explicitly use the tenant id in all of our queries so that the performance is not affected.

Yes, including the tenant id in each sharded table is a common practice in SaaS programming models. Here is some context on the spectrum of multi-tenant per database to single tenant per database models for SaaS applications: https://learn.microsoft.com/en-us/azure/sql-database/sql-database-design-patterns-multi-tenancy-saas-applications#multitenant-data-models

Related

Designing a database for a multiple-shop ecom platform

I'm designing database for an mobile-based ecom platform.
Currently, the system have one and only one shop. The design for the database of the system has the tables below:
User
Product
Category
Review
Order
Now, I want to scale up the system so that it can support multiple shops. User can sign-up as a seller and create their own shop, manage their own products and orders.
How can I design such a database from the original database which was designed only for one shop?
I have two options in mind but I have no idea whether they will works or not:
For each record in the table, I add a field shopId that ref to the id of the shop it belongs to. Then I will index this field to increase query's performance.
For each shop, I create a new collection/table to store the data that belongs to it. For example: shop1_product, shop1_order,... are the tables i will create for the shop1.
Are the approach above valid? Is there any other better approach.
P/s: I'm using MongoDB, and the system doesn't require operations across many shops.
Thank you guys!

Create multiple users in SQL Server databasse

I want to create two users
App_dbo which is used to deploy scripts
App_batch which is used to run jobs
I googled it and found SQL Script
I did not understand why I need to create a LOGIN.
What is the process to create a user ?
Let me try to explain how the login and users work on a little example.
Imagine you are going to stay in a hotel, you've booked a room. At the reception they check your id and give you the key for your room. The id is your login, it is only checked once at the reception and you get access to whatever you are eligible for. If you paid for more rooms, you will get multiple keys.
In the SQL server, the rooms are the databases and the keys are your users. You can map multiple users to the login as long as the users are in a different databases - you get keys for all rooms you've paid for using just one id.
There is also a case where login doesn't have any users mapped. It can have permissions to create new databases or update infrastructure, but will not have access to the existing databases. This can be a case of a server admin. In the hotel example it is the technical maintenance employee who fixes pipes or electric wires. He has access to the hotel, but doesn't have keys for any rooms.
Therefore, login gives access to the sql server (hotel common areas), however, it doesn't give you access to any database. You need user(s) mapped to your login to get a database(s) access(es).
Afaik, you can't map two users from the same db to one login (you only get one key for each room you've access too).
There are also other cases, like the AD one mentioned in the discussion below the question, where you can map multiple (external) identities to a single login etc, you can have users without login etc. I recommend to study documentation or get some good book explaining all possibilities. Good start might be here.
Hope this helps to understand how it works to a human being, there are plenty of answers how to set it up technically, for example the one you've referenced.

Database Client Specific Tables v/s Relational Tables

I have a scenario, my application is a SAAS based app catering to multiple clients. Data Integrity to clients is very essential.
Is it better to keep my Tables
Client specific
OR
Relational Tables
For Ex: I have a mapping table with fields MapField1,MapField2. I need this kind of data for each client.
Should I have tables like MappingData_
or a Single Table with mapping to the ClientId
MappingData with Fields MapField1,MapField2,ClientId
I would have a separate database for each customer. (Multiple databases in a single SQL Server instance.)
This would allow you to design it once, with a single schema.
No dynamically named tables compromising test & development
Upgrades and maintenance can be designed and tested in one DB, then rolled out to all
A single customer's data can be backed-up, restored or dropped exceedingly simply
Bugs discovered/exploited in one DB won't comprise the integrity of other DBs
Data access (read and write) can be managed using SQL Logins (No re-inventing the wheel)
If there is a need for globally shared data, that would go in another database, with it's own set of permissions for the different SQL Logins.
The use of a single database, with all users in it is my next best choice. You still have a single schema. But you don't get to partition the customers' data, you need to manage access rights and permissions yourself, and a whole host of other additional design and testing work.
I would never go near dynamically creating new tables for additional customers. A new table name means all your queries need to be updated with the new table name, and a whole host of other maintenance head-aches.
I'm pretty much of the opinion that if you want to create tables dynamically during the Business As Usual use of an application/service, you've designed it badly.
SO has a tag for the thing you're describing: "multi-tenant".
Visualize the architecture for supporting a multi-tenant database application as a spectrum. At one extreme of the spectrum is "shared nothing", which means each tenant has its own database. At the other extreme of the spectrum is "shared everything", which means tenants share tables, and each row in each table belongs to one tenant. (Each row contains a tenant identifier.)
Terminology seems to overlap, so read carefully. What one writer means by shared schema might be identical to what another writer means by shared everything.
This SO answer, also written by me, describes the differences and the tradeoffs in terms of cost, data isolation and protection, maintenance, and disaster recovery. It also links to a fairly good introductory article.

Can SQL Azure Reporting support a multi-tenancy model discretely/opaquely?

We are storing multiple tenants in one instance of SQL Azure. I have been doing some research, but I cannot determine if SQL Azure Reporting can support a multi-tenant model discretely.
For example, we want to run reports for a user based on their "tenancy", but we want their tenant ID to be completely opaque to them- not contained in a query string, or anything view-able by the user.
Has anyone encountered this problem before? What was your solution?
If you had the restriction that a User can only belong to a single tenant, you can hop from a User to the corresponding tenant without them having to know their tenant Id. So any of your Tenant related queries could automatically be filtered by the logged-in user.

Is Federation ID Predicate just a SQL Azure thing?

Im setting up a multi tenant database and came across the following blog post on federations: SQL Azure Multi Tenant
They write about assigning a predicate to filter data between tenants:
In a single-tenant app, the query logic in application is coded with the assumption that all data in a database belongs to one tenant. With multi-tenant apps that work with identical schemas, refactored code simply injects tenant_id into the schema (tables, indexes etc) and every query the app issues, contains the tenant_id=? predicate. In a federation, where tenant_id is the federation key, you are asked to still implement the schema changes. However federations provide a connection type called a FILTERING connection that automatically injects this tenant_id predicate without requiring app refactoring. Our data-dependent routing sets up a FILTERING connection by default. Here is how;
1: USE FEDERATION orders_federation(tenant_id=155) WITH RESET, FILTERING=ON
My question is, is this just a SQL azure thing? Or can this be accomplished with any sql server instance?
Thanks in advance
Federations are available only on SQL Azure.