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.
由於數據庫以持久的形式保存數據,因此數據庫中的表需用一些方法以對數據實行各類類型的有效性驗證,不管數據如從外源修改。這些有效性驗證的類型超越了數據類型。它們涵蓋哪一個列必須是惟一值、一個列能夠接受哪一個有效性範圍、以及一個列的值是否必須匹配另外一個表中的某些列。sql

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.
這一課涵蓋了你可以建立在表上的約束的類型,建立約束有助於實現強制數據完整型。app

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分鐘less

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,而要使用約束來代替它。ide

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表中的類名)被稱爲天然鍵或者商業鍵。你可使用一個表的天然鍵做爲它的主鍵,可是數據庫設計者在長期的實踐中發現,建立一個特殊的數據類型(好比說整型數)的列,具備惟一可是無其它意義的值,會更方便。這個列稱爲代理鍵。而後代理鍵做爲主鍵來用,天然鍵的惟一性可用惟一性約束來實現。ui

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中定義它:this

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.

相關文章
相關標籤/搜索