T-SQL学习中--强制数据完整性(创建表约束)

Because database store data in a persistent way, the tables in a database need some way to enforce various types of validations of the data no matter how the data might be changed from external sources. These types of validations go beyound just data types; the cover which columns should have unique values, What ranges of valid values a column might accept, and whether the value of a column should match some column in a different table.
因为数据库以持久的形式保存数据,所以数据库中的表需用一些方法以对数据实行各种类型的有效性验证,无论数据如从外源修改。这些有效性验证的类型超越了数据类型。它们涵盖哪个列必须是唯一值、一个列可以接受哪个有效性范围、以及一个列的值是否必须匹配另一个表中的某些列。

When you embed those methods of data validation inside the definnition of the table it self, it is called decarative data integrity. This is implemented use table constraints, and you use ISO standard SQL commands to create those constraints, on table-by-table basis.
当你在指定的表中植入那些数据有效性验证方法的时候,会调用它以描述数据完整性。它通过表约束来实现,你使用ISO标准SQL命令来创建这些约束,基于表对表。

This lesson covers the types of constraints that you can create on tables that help you enforce data integrity.
这一课涵盖了你能够创建在表上的约束的类型,创建约束有助于实现强制数据完整型。

Alter this lesson, you will be able to: 学完本课,你将能够:
* Implement declarative data integrity on your tables.在表上实现声明数据完整性
* Define and use primary key constraints 定义以及使用主键约束
* Define and use unique constraints. 定义以及使用唯一性约束
* Define and use foreign key constraints. 定义以及使用外键约束
* Define and use check constraints. 定义以及使用检查约束
* Define default constraints. 定义默认约束
Dstimated lesson time: 30 minutes 估计课时:30分钟

Using Constraints 使用约束

The best way to enforce data integrity in SQL Server tables is by creating or declaring constraints on base tables. You apply these constrints to a table and its columns by using the CREATE TABLE or ALTER TABLE statements.
在SQL Server数据表中保持数据完整型的最佳方法是在基表上创建或者声明约束。你可以使用CREATE TABLE或者ALTER TABLE语句对表和它的列应用这些约束。

NOTE DO NOT USE DEPERCATED RULES 注意,不要使用不赞成使用的Rule
The very first versions of SQL Server did not support constraints and use database "rules" instead. employing the CREATE RULE command. Rules are not as well suited for enforcing data integrity as declarative constraints. Also, rules are deprecated and will be removed in a future version of SQL Server. IN any case, you should avoid using rules and use constraints instead
最初版本的SQL Server不支持约束,而使用数据库“Rule”来代替它,采用CREATE RULE命令。Rule远不如声明约束更适合用来强制数据完整性。而且,Rule是建议弃用的,会在将来版本的SQL Server中被删除。无论如何,你必须避免使用rule,而要使用约束来代替它。

In SQL Server, all table constraints are database objects, just like tables, views, stored procedures, functions, and so on. Therefore, constraints must have unique names across the database. But because every table constraint is scoped to an individual table, it makes sense to adopt a naming convention that states that type of constraint, the table name, and then, if relevant, the key columns declared in the constraint. For example, the table Production. Categories has its primary key named PK_Categories. When you adopt a naming convention like that, it is easy to tell what the object does from its name.
在SQL Server中,所有的表约束都是数据库对象,就像表、视图、存储过程、函数等一样。然而,约束必须在数据库中拥有唯一名称。但是因为每个表约束作用范围只对单个的表,它最好继承一个陈述约束的类型的命名惯例。例如,表Production.Categories拥有它的主键名为PK_Categories,当你如此继承一个命名惯例时,很容易表达它的名字来自哪个对象。

Primary Key Constraints 主键约束

Every table in a relational database should have some method of distinguishing each row from all the others. The most common method is to designate a column as the primary key that will have a unique value for each row. sometimes a combination of columns may be required, but the most common approach is to use a single column.
在关系数据库中,每个表必须有一些方法来把每一行与其它行区分开。最常用的方法是设置一个列,作为主键,它将使每一行具有一个唯一。有时候需要一个列组合,但是最常见的方法是使用单个列。

A column( or combination of columns) within the data of a table that uniquely identities every row (such as the category name in the TSQL2012 Production.Categories table) is called the natural key or business key of the table. You can use the natural key of a table as its primary key,
包括在一个表数据中的一个列(或者几个列的组合)用来唯一性标识每个行的特征ID(例如在TSQL2012 Production.Categories表中的类名)被称为自然键或者商业键。你可以使用一个表的自然键作为它的主键,但是数据库设计者在长期的实践中发现,创建一个特殊的数据类型(比如说整型数)的列,具有唯一但是无其它意义的值,会更方便。这个列称为代理键。然后代理键作为主键来用,自然键的唯一性可用唯一性约束来实现。

For example, consider again the TSQL2012 table Production.Categories. The following show how it is defined in the TSQL2012 sql script
举个例子,回想一下TSQL2012数据库的表Production.Categories。下面显示了如何用sql脚本在TSQL2012中定义它:

SQLCREATE TABLE Production.Categories
(
categoryid INT NOT NULL IDENTITY,
categoryname NVARCHAR(15) NOT NULL,
description NVARCHAR(200) NOT NULL,
CONSTRAINT PK_Categories PRIMARY KEY(categoryid)
)

In this table, categoryid is the primary key, which you can tell because of the added CONSTRAINT clause that the end of the CREATE TABLE statement. The name of the constraint is PK_Categories, which is a name that you supply.
在这个表中,categoryid是主键,在CREATE TABLE语句末尾添加的CONSTRAINT子句告诉你它是一个主键。这个约束的名称是PK_Categories,你可以指定其它名称。

Another way of declaring a column as a primary key is to use the ALTER TABLE statement, which you could write as follows.
另一个把某列声明为主键的方法是使用ALTER TABLE语句。你可以用下面的方式写:

SQLALTER TABLE Production.Categories
    ADD CONSTRAINT PK_Categories PRIMARY KEY(categoryid);
GO

It's important to remember that the columns you choose as primary keys will end up being used in other tables to refer back to the original table. It is a best practice to use the same name for the column in both tables, if at all possible. Also, you can make it easier for people to query the referenced table by using a descriptive column name. In other words, choose a name for the primary key column that flows naturally from the table name. Then it's easier to recognize when that column is a foreign key in other tables. You'll notice, for example, that all the primary keys in the TSQL2012 database are just the table name with "id" on the end. This makes it really easy in other tables to know the table that a foreign key will reference.
记住你选中作为主键的列很重要,因为毕竟它将被用在别的表中,用于回顾源表。在两张表中使用同一列名是一种好的做法。如果可以的话,尽量在两表中使用同一列名。而且,使用带有描述性的列名,能使人们更容易查询引用表。换句话说,为主键选择一个自然呼应表名的名称,当这个列在别的表中用作外键的时候,将较容易识别。举例来说,你将注意到,在TSQL2012数据库中,所有的主键名都是表名末尾加一个“id”。这使得在别的表中很容易知道这个外键引用了哪个表。

To create a primary key on a column, there are a number of requirements:
要想在一个列上创建一个主键,有下面几项要求:

  • The column or columns connot allow NULL. If the column or columns allow NULL, the constraint command will fail.
    这个列或者这几个列不允许为空。如果主键列允许为空,约束命令将失败。
  • Any data already in the table must have unique values in the primary key column or columns.If there are any duplicates, the ALTER TABLE statement will fail.
    在数据表中的任何数据必须在主键表中有唯一的值。如果有任何重复的,ALTER TABLE语句将失败。
  • There can be only one primary key constraint at a time in a table. If you try to create two primary key constraints on the same table, the command will fail.
    同一时间里一张表里只允许有一个主键约束。如果你企图在同一个表上创建两个主键约束,这个命令将失败。

When you create a primary key, SQL Server enforces the constraint behind the scenes by creating a unique index on that column and using the primary key column or columns as the keys of the index.
当你创建一个主键时,SQL Server强制在幕后对这个列创建唯一性索引,并使用主键列作为索引的键。

To list the primary key constraints in a database, you can query the sys.key_constraints table filtering on a type of PK.
为了在数据库中列出主键索引,你可以查询sys.key_constraints表,并用type='PK'作为筛选。

SQLSELECT *
FROM sys.key_constraints
WHERE type = 'PK'

Also you can find the unique index that SQL Server uses to enforce a primary key constraint by querying sys.indexes. For example, the following query shows the unique index declared on the Production.Categories table for the PK_Categories primary key constraint.
同样的,你也可以在通过查询sys.indexes表来找到SQL Server中用来强制主键约束的唯一性索引。比如说,下面的查询显示了d Production.Categories表上的针对PK_Categories主键约束的唯一性索引。

SQLSELeCT * FROM sys.indexes
WHERE object_id=OBJECT_ID('Production.Categories') AND name = 'PK_Categories';

For more information about indexes, see Chapter 15.
关于索引的更多信息,请看第15章。

Unique Constraints唯一性约束

Unique constraints are very similar to primary key constraints. Often, you will have more that one column or set of columns that uniquely determine rows in a table. For example, if you have a surrogate key defined as the primary key, you will most likely also have a natural key whose uniqueness you would also like to enforce. For natural keys or business unique keys, you can use the unique constraint. (sometimes people call it a uniquenes constraint, but the technically accurate term is unique constraint.)
唯一性约束与主键约束很相似。通常地,在一个表里,会有多于一个列或者列的集合,用于唯一性定义行。举例来说,如果定义了一个代理键作为主键,对于自然键或者商业唯一键,你可以使用唯一性约束。(某些人称它为单值性约束,但是从技术上来说,准确的术语是唯一性约束。)

For example, in the Production.Categories table, you might also want to enforce that all category names be unique, so you could declare a unique constraint on the categoryname column, with the following.

举个例子,在Production.Categories表中,你可能还想要强制所有的类名是唯珠。所以你可以在categoryname表上定义一个唯一性约束,用下面的语句:

SQLALTER TABLE Production.Categories
    ADD CONSTRAINT UC_Categories UNIQUE (categoryname);
GO

Like the primary key constraint, the unique constraint automatically creates a unique index with the same name as the constraint. By default, the index will be nonclustered. SQL uses that index to enforce the uniqueness of the column or combination of columns.
和主键约束一样,唯一性约束自动创建一个与约束同名的唯一性索引。默认的,这个索引是非簇索引。SQL使用索引来强制列或者列组合的唯一性。


Exam Tip考试提示
The unique constraint does not require the column to be NOT NULL. You can allow NULL in a column and still have a unique constraint, but only one row can ba NULL.
唯一性索引不要求列必须是非空。你可以对某行允许为空,并依然有一个唯一性约束。但是最多只有一行可以是空。


Both primary key and unique constraints have the same size limitations as an index: you can combine no more than 16 columns as the key columns of the index, and there is a maximum combined width of 900 bytes of data across those columns.
主键约束和唯一性约束作为一个索引,有同一个大小的限制:你可以组合不超过16列作为索引的关键列。而且在一行中,这些列合并起来的最大宽度为900字节数据。

NOTE CONSTRAINTS AND COMPUTED COLUMNS 注意索引以及计算列
you can also create both primary key and unique constraints on computed columns你可以在一个计算列上同时创建主键以及唯一性约束。

Just as with the primary key constraints, you can list unique constraints in a dabase by querying the sys.key_constraints table filtering on a type of UQ.
类似于主键约束,你可以通过查询sys.key_constraints表,使用type='UQ'作为筛选,来列出数据库中所有的唯一性约束。

SQLSELECT *
FROM sys.key_constaints
WHERE type = 'UQ';

You can find the unique index that SQL Server uses to enforce a primary key constraint by querying sys.indexes and filtering on the constraint name.
通过查询sys.indexes系统表,使用约束名作为筛选,你可以找到SQL Server用来强制主键约束的唯一性索引。


Quick Check 快速测试
1. How does SQL Server enforce uniqueness in both primary key and unique constraints?
SQL Server在主键约束和唯一性约束中如何强制唯一性?
2. Can a primary key on one table have the same name as the primary key in another table in the same database?
在同一个数据库里,一个表的主键约束可以与另一个表的主键约束同名吗?
Quick Check Answer 快速测试答案
1. SQL Server use unique indexes to enforce uniqueness for both primary key and unique constraints.
SQL Server使用唯一性索引来强制主键约束和唯一性约束中的唯一性。
2. No. all table constraints must have unique names in a database.
不,在一个数据库中所有的表约束必须有唯一的名称。


Foreign Key Constraints 外键约束

A foreign key is a column or combination of a columns in one table that serve as a link to look up data in another table. In the second table, often called a lookup table, the corresponding column or combination of columns have a primary key or unique constraint applied to them, or a unique index. So a value in the first table may be duplicated, but in the second table where you look up the corresponding value, it must be unique. If you know the value in the first table, the foreign key relationship allows you to get related data from the other table by looking up the corresponding data.
一个外键是某个表中的一个列或列组合,担当链接,查阅另一个表的数据。在第二个表(通常被称为查阅表)中,相应的列或者列组合具有一个应用于其上的主键或者唯一性约束,或者有一个唯一性索引。所以在第一个表中,一个值可以是重复的,但是在第二个表中,你查阅的相应值,它必须是唯一的。如果你知道第一个表中的这个值,外键关系允许你通过查阅相应数据得到别的表中相关联的数据。

For example, there is a column called categoryid in the Production.Products table. The column corresponds to the primary key categoryid in the Production.Categories table. For any specified product in the Products table, you can find related category information by looking it up in the Categories table.
举个例子,在Production.Products表中有一个列称为categoryid,这个列对应到Production.Categories表的主键categoryid。对产品表中任何指定的产品,你可以通过查阅产品类表,找到相关联的类目信息。

You can use the foreign key constraint to enforce that every entry into the categoryid column of the Production.Products table is a valid categoryid from the Production.Categories table. Here's the code to create the foreign key.
你可以使用外键约束来强制进入Production.Products表的categoryid列的每个条目都是一个来自Production.Categories表的可用的categoryid。下面的代码创建了一个外键。

SQLUSE TSQL2012
GO
ALTER TABLE Production.Products WITH CHECK
    ADD CONSTRAINT FK_Products_Categories FOREIGN KEY(categoryid)
    REFERENCES Production.Categories(categoryid)
GO

Here's how the command works:
下面解释这个命令是如何工作的:

  • You always declare the foreign key constraint on the table for which this key is "foreign"-- that is, a key from a different table. So that's why you must ALTER the Production.Products table.
    你总是在表上声明外键约束,以指明这些键是“外来的”,也就是说,来自别的表的键。这也是为什么你要修改Production.Product表的原因。

  • You can decide whether to allow violations when you create the constraint. Creating a constraint WITH CHECK implies that if there is any data in the table already, and if there would be violations of the constraint, then the ALTER TABLE will fail.
    你可以在创建该约束时,决定是否允许冲突。创建一个WITH CHECK的约束隐含着如果这个表中已经有一些数据,而且如果数据与约束相冲突,则这个ALTER TABLE命令将失败。

  • You add the constraint and specify the name of the foreign key constraint. In this case, TSQL2012 use FK_as a prefix for foreign keys.
    你添加约束并指定外键约束的名称,在这种情况下,TSQL2012使用FK_作为外键的前缀。
  • After entering the type of constraint, FOREIGN KEY, you then in parentheses state the column(or combination of a columns) in this table that you are constraining to be validated by a lookup into a different table.
    在输入约束类型FOREIGN KEY之后,你接下来在括号中指明这个表中你想约束的列(或者列组合)以确认在另一个表能查阅到。
  • Then you state what the other table is-- that is, what table in the current database that this constraint REFERENCES, along with the column or combination of columns. This column(or columns) is from the referenced table and must be a primary key or unique constraint in the table. or else it may instead have a unique index.
    然后你指明哪个表是,即,当前数据库中的哪个表是这个约束的引用来源,连同列或者列组合。这个列(或列组合)来自于引用的表,而且必须是这个表的主键列或者唯一性约束列,或者说它必须有一个唯一性索引。

Keep the following rules in mind when creating foreign keys:
在创建外键时,头脑中需要记住下面这些规则

  • The column or set of columns from each table must have exactly the same datatypes and collation(if they have a string data type).
    来自每个列的列或者列集合必须拥有完全相同的数据类型以及排序规则(如果它们有一个字符串数据类型)。

  • As mentioned eralier, the columns of the referenced table must have a unique index created on them, either implicity with a primary key or a unique constraint, or explicitly by creating the index.
    正如前面提到的,引用表的列必须创建有一个唯一性索引,既可以是主键约束,也可以是唯一性约束,或者说创建了一个索引。

  • You can also create foreign key constraints on computed columns.
    你可以在计算列上创建外键约束。

Tables are often joined based on foreign keys so that a query can return a data that is related between two tables. For example, the following query returns the categoryname of a set of products from the Production.Products table.

SQLSELECT P.productname, C.categoryname
FROM Production.Products AS P
JOIN Production.Categories AS C
    ON P.categoryid = C.categoryid;  

Notice that the query returns the corrent categoryname for each product because the JOIN is on the foreign key P.categoryid and its referenced column C.categoryid in Production.Categoryies.


EXAM TIP
Because joins often occur on foreign keys, it can help query performance to create a nonclustered index on the foreign key in the referencing table. There is already a unique index on the corresponding column in the referenced table, but if the referencing table, like Production.Products, has a lot of rows, it may help SQL Server resolve the join faster if it can use an index on the big table.


你可能感兴趣的:(transact-sql)