Unfortunately, the term "schema" has come to take on different definitions for different databases. We're using SQL Server 2008 R2, and with that in mind, I have a better understanding thanks to some other questions here with people asking similar questions. However, before I begin making the database, I want to be sure I have this right for my specific scenario.
Basically it's a database for various departments of the company. For example, Administration will manage employees with a bunch of tables related to employee management. Marketing will have a lot of marketing related tables. And tech support will have a lot of tech support related tables. These "groups" will probably never interact with one another, but they're all part of the same project, so I'm putting them all in one database, rather than three separate databases.
Am I correct in understanding that this means I would want three different schemas? So that for Administration, for example, the tables would be named:
Administration.Employees
Administration.VacationDays
Administration.EmployeeAddresses
etc.
and then for tech support, for example:
Techsupport.Clients
Techsupport.OpenIssues
Techsupport.ClosedIssues
etc.
And then am I correct in understanding that the PURPOSE of this, instead of just having every table in the dbo schema, is for A) organization purposes, and B) permission purposes (users with Techsupport schema access shouldn't be able to access the Administration schema, for instance). The idea I've come to in my head is that schemas in the SQL Server definition is that a schema is just like a virtual folder that groups related tables together.
I think this is right, after all the similar questions that I've read, but I just really want to be sure I'm on the right path before I get too far in and realize I'm doing it completely wrong.
Is throwing everything into the dbo schema and calling a day discouraged / not intended? Should you use a schema, even for small databases that don't necessarily need multiple schemas?
Thanks.
Schemas support two primary purposes:
security container. Permissions can be granted on schemas and such permissions apply to all objects in the schema. Eg. GRANT SELECT ON SCHEMA::Administration TO [foo\bar]; grants the SELECT permission to any table in the schema, including future added tables.
namespace. You can deploy your application in the schema [CptSupermarkt] and know that your app has a very low probability of a name conflict with other applications.
The prevalent use is the first one because most apps are not concerned with side-by-side deployment with other applications and usually assume ownership of an entire database (if not an entire instance). However there are types of applications (eg. audit tools and monitoring apps) that use the namespace aspect of schemas (or, at least, most should use it...).
Related
I'm working on a system which for every "company" has their own "users" and their own "bills". That scenario is better in performance and management? Handle all companies in the same database and link everything to an idempresa, or database for each client?
This is called multi tenancy architecture and each customer is a tenant. There are various strategies to deal with it and each one might bring potential problems.
Having a separate database for each tenant is an option that provides data separation and do not require you to add a column to identify each tenant in your tables and queries, but also has the downside to keep multiple databases up to date.
Having a column in each table of a single database to identify your tenants is also a good strategy, but then it brings problems when scaling and managing different features for different customer for example.
You need to study all available strategies and decides which one is best based on your requirements and pain points.
Putting a tenant data in a separate Database is a straight forward approach and less painful option but then in a long run, when your product gets wildly successful, maintaining this database will become a nightmare.
On the Other hand keeping all the Tenants data in a single database could also make your application non scalable and less performable. The better approach would be the combination of both, the decision of making the choice between these two is completely based on the type, usage and size of the customer.
In certain cases, you may need to provision a separate database for a particular module or feature of your application may be for security or to isolate the specific data alone. I have written an article on these lines; kindly have a look at http://blog.techcello.com/2012/07/database-sharding-scaling-data-in-a-multi-tenant-environment/
I think the scaling problem of multi-tenant in a single database can be overcome by proper planning up-front. Plan to make it easy to migrate a tenant and their data to another database anything they become big enough to justify it.
If you can automate this migration, based on tenant ID, in each table then it should be easy and safe. I'd just make sure I tested it often as development of new features are going on.
You can mitigate the risks of multi-tenant on one database. You can't really do much when there are multiple databases. You can only be diligent and disciplined to make sure all the databases stay in sync.
Good luck!!!
This is an old thread, but it's worth mentioning this for others with this question who may come across this post in the future.
I've had great success on projects in the past by using PostgreSQL and putting the global tables in the "public" schema (like users, groups, etc.) and the same set of tables for each tenant in their own separate schemas.
For example:
For every tenant that's added to the system, a new schema is created with a standard set of tables for the application:
CREATE SCHEMA tenant1;
CREATE TABLE tenant1.products (...);
CREATE TABLE tenant1.orders (...);
etc.
Each tenant's schema would have its own isolated section within the database with the same set of tables that every other tenant has but filled with their own data.
In the default "public" schema you'd have global "users" and "tenants" tables (along with tables for things like groups and access control lists). Every user belongs only to a single tenant. Upon login, the tenant for that user is looked up and from that point forward any time you connect to the database you set it to use that tenant's schema:
SET search_path TO tenant1, public;
Once the schema search_path is set, all your SQL queries can be written as if you're working with a single database with tables named "products", "orders", and so forth (along with the tables in the "public" schema). So you can just use something like "SELECT * FROM products" and it would get the products belonging to this user's tenant.
I'm creating a brand new database with no legacy constraints, so I'm curious as to what the schema best practices are.
The database will be called "SecurityData". It stores information about bonds.
The schema I have already identified are:
import - Views and procs that are really linked server calls to other databases
export - Views and procs meant to be used by other databases
staging - Tables used for bulk inserts so we can verify and scrub the data.
??? - The real tables containing useful data
history - Change logs for the real tables
Questions:
Am I going schema crazy or does this make sense?
Should I use dbo for my "real tables" or should I avoid that schema as it tends to become a garbage dump?
Schemas serve a dual purpose:
security containers. Grants/deny/revokes on a schema apply to all objects in the schema. Separating related security objects into a shcema allows for easy maintenance and control of access.
namespaces. Qualifying object names with schemas allows reduced conflict probability with names used by other applications and even other modules within your own application.
So my question to you is: why do you want to use schemas in the first place? I'm not saying you shouldn't, but i want to understand which advantage of the schemas are you most appealed to. If you know the answer to that, then you'll know how many schemas you need and what those schemas are. Of course, the answer can be a mixture of the two reasons I give at start, that is OK. In that case you may find that what makes sense from a namespace point of view is a disaster from security point or view or vice-versa.
I myself I used separate schemas just like you plan to, and soley for programming namespace benefits. during development it helped me to see, just from the name of an object, where to it belongs logically in the app.
I use schemas in my databases, but other than the security benefits and the fact that my OCD is happy, I don't really know whay it is good practice to use them. Besides the more granular security, are there other reasons for using schemas when building a database?
The primary pupose of schemas is indeed security. A secondary benefit is that they act like namepaces for your application tables and objects, thus allowing a conflict free side-by-side deployment with other applications that may use same names for its object.
Schema's arose from the original Sql Server. They didn't have schemas which meant that every single object in the database had to be owned by someone. If jill from accounting left the company then you had to manually reassign all her stuff to someone else etc. Schemas now own objects and users belong to schemas, which makes all the DB Admins very happy people :).
Basically you can have users leave and you remove their privileges by removing them from schemas and deleting the user. Adding privileges to a user is now as simple as adding the user to the schema.
I have a database that's going to record data for different customers. Most of the customers have the same data requirements; however, that's not always the case. For the different requirements, I'm going to create extension tables that are going to be specific for their needs. For each customer, I'm going to create a schema and I will then put the specific extension tables, views, etc under their schema.
However, for the common data tables, should I create those under the default dbo schema or should I create a new schema instead?
Thank You.
I would create a Common schema. You don't want to give your users access to the dbo schema if you can help it. Especially if you have stats, etc there.
Schemas are a great way to separate namespaces as well as administer security. Take advantage of that and organize your databases as simply as possible. It makes it much more readable when you're going through that list of tables!
The only reason to use the dbo schema is convenience, so you don't have to plan your schemas roles, rights and requirements out in great detail. However, if you are already planning a multi-schema database, then I would definitely recommends that you plan out your own s common application schema, and leave the dbo schema for explicit DBA/privved objects.
I have designed and written about multi-tenant databases here and here, which you nmight find useful. This is primarily shared-schema stuff, but the first article has a lot of pointers to other articles including some multi-schema stuff.
I can see in the AdventureWorks database that different schemas are used to group tables. Why is this done (security, ...?) and are there best-practices I can find?
thx, Lieven Cardoen
As a manager of Business Intelligence, we rely on schema for logical grouping and managing security. Here are some cases as to how we use schema:
LOGICAL ORGANIZATION
We have a general database that is loaded by SSIS packages solely for staging data before we load our operational data store (ODS). In this database, with the exception of the schema all objects are indentical in structure (table names, column names, data types, nullability, etc.) to their original source. We use the schema to indicate the original source system of the table. In some rare instances, two different databases have tables with the same name and schema allows us to continue to use the original name in the staging database.
In every database on our BI servers each team member has a test_username schema. When we create test objects in a database, this makes it easy to keep track of who made the object. It also makes it a lot easier to purge the test objects later since everyone knows who made what. Frankly, just knowing that we made it is usually enough to know it can be deleted safely, especially when we can't remember when or why we made it!
In our data controller database, we rely on schema to separate different types of processes between reports, etl, and generic resources.
In our star schema data warehouse, all objects are devided into dimension and fact schemas.
When we push data to other departmental servers, we make all BI objects on their servers use the schema bi. This makes it REALLY easy to know bi loads and maintains the table even though it isn't on our server. If the target server isn't a 2008/2005 SQL Server box, then we prefix the table with bi_.
When it gets down to it, we use schema for logical organization anytime we WOULD have appended a prefix or suffix to an object to help organize it in the absence of schema. Having said this, there are a few instances where we don't use schema on our BI servers. In our WorkingDB, everything is dbo. Our WorkingDB is used like TempDB to create temporary tables, but these tables are temporary tables that we know we will create everytime an ETL process runs. The special property of WorkingDB is that we don't ever backup the database and all ETL processes that use the database must be able to recreate their objects from scratch in the absence of the table. In this instance, we felt using schema didn't add ANY organizational value since we don't actually use the objects outside of their temporary ETL process.
SECURITY
Since we are a BI group, we don't generally build and support our own applications. We almost exclusively use other people's applications and bring data from their back-end databases to our server. However, we do have one database called bi_applications that is the back-end for a variety of small CRUD applications. These applications are usually data entry forms that we provide to the business so that they can capture data we would otherwise have to maintain in BI. It is a way of getting data that should be in production applications into BI while we wait for our low priority application enhancements to gather dust in the future development lists. Each application has a separate schema and the application account used to update the underlying tables ONLY has access to objects of the associated schema. This makes it really easy to understand, secure, and maintain the separate applications.
In a few instances, I have let power users have direct database access to our tables or stored procedures. We rely on using schema combined with roles to secure the objects. We grant permissions to the schema and users are added to roles. This allows us to easily understand which objects are used by whom without having to dig through roles to figure it out.
In short, we use schema for security purposes when we probably would have considered separating the objects out into their own databases and when we expect an application or user outside of BI to access our databases.
Although these aren't best business practices for application developers, I hope my bi use-cases may help you think of some of the ways to use schema in your end of the business.