In versions of SQL
Server prior to 2005, all database objects were both owned by database
users and referenced by owner name. So to select from a table that was
not owned by dbo, the table name would
have to be prefixed with the name of the database user that owned it
(unless you were logged in as that user). In addition to owner name
prefixing, other difficult security scenarios were also created. For
instance, there was no easy way to assign permissions to all of the
tables owned by a certain user, meaning that ownership did not work as a
method by which to easily logically segment tables into groups.
The situation changes with
SQL Server 2005, thanks to support for ANSI standard schemas. Schemas
are essentially containers into which any database object can be placed,
and security rules applied en masse. By dividing your database into
schemas, you can easily group related objects and control permissions,
without having to worry about what objects might be added or removed
over time. As new objects are added to a schema, existing permissions
propagate, thereby allowing you to set up access rights for a given
schema once, and not have to manipulate them again as the database
changes.
To create a schema, use the CREATE SCHEMA command. The following T-SQL creates a schema called Sales:
CREATE SCHEMA Sales
Optionally, you can specify a schema owner by using the AUTHORIZATION clause. If an owner is not specified, the user that creates the schema will be automatically used by SQL Server.
Once a schema is created,
you can begin creating database objects within the schema, using
two-part naming, similar to creating objects by owner in previous
versions of SQL Server:
CREATE TABLE Sales.SalesData
(
SaleNumber INT,
SaleDate DATETIME,
...
)
Once an object is created, it can be referenced by schema name; so to select from the SalesData table, the following SQL is used:
SELECT *
FROM Sales.SalesData
This same SQL is used no
matter who owns the table. Remember, owner names are never used to
qualify objects, as of SQL Server 2005.
The beauty of schemas
becomes obvious when it is time to apply permissions to the objects in
the schema. Assuming that each object is equivalent from a permissions
point of view, only a single grant is necessary to give a user access to
every object within a schema. For instance, after the following T-SQL
is run, the Alejandro user will have access to select rows from every table in the Sales schema, even if new tables are added later:
CREATE USER Alejandro
WITHOUT LOGIN
GO
GRANT SELECT ON SCHEMA::Sales
TO Alejandro
GO
It's important to
note that when initially created, the owner of any object in a schema
will be the same as the owner of the schema itself. The individual
object owners can be changed later, but in most cases I recommend that
you keep everything in any given schema owned by the same user. In addition, because two-part naming now references a schema
rather than an object owner, the process for explicitly setting an
object's owner changes with SQL Server 2005. A new command, ALTER AUTHORIZATION, is used in order to set ownership on objects. The following T-SQL shows the basics of how it is used:
--Create a user
CREATE USER Javier
WITHOUT LOGIN
GO
--Create a table
CREATE TABLE JaviersData
(
SomeColumn INT
)
GO
--Set Javier as the owner of the table
ALTER AUTHORIZATION ON JaviersData
TO Javier
GO
As a final note on schemas, there is also a command that can be used to move objects between them. By using ALTER SCHEMA with the TRANSFER option, you can specify that a table should be moved to another schema:
--Create a new schema
CREATE SCHEMA Purchases
GO
--Move the SalesData table into the new schema
ALTER SCHEMA Purchases
TRANSFER Sales.SalesData
GO
--Reference the table by its new schema name
SELECT *
FROM Purchases.SalesData
GO
Schemas are a
powerful feature in SQL Server, and I recommend their use any time
you're dealing with sets of tables that are tightly related to one
another. The AdventureWorks sample database that ships with SQL Server
2005 makes great use of schemas, and I highly recommend that you take a
look at what Microsoft has done in that example and try to design new
databases along similar lines. Legacy database applications that use
multiple databases in order to create logical boundaries between objects
might also benefit from schemas. The multiple databases can be
consolidated to a single database that uses schemas. The benefit is that
the same logical boundaries will exist, but because the objects are in
the same database, they can participate in declarative referential
integrity and can be backed up together.