翻译4

      通向T-SQL DML3级的阶梯:在SQL Sever中实现关系模型

                        ---作者 Gregory Larsen, 2017/08/02 第一次发表时间为: 2011/11/09)

系列

这篇文章是阶梯系列的一部分:T-SQL的阶梯。

这个阶梯为您提供了一个基本的,易理解关于如何使用SQL Sever的Transact-SQL方言处理来自SQL Sever表的数据的基本知识。UUDML是一种数据处理语言,是处理数据语言的一个方面。其中包括声明SELECT、INSERT、UPDATE、UPDATE、和DELETE.这阶梯也提供了一些历史上的SQL语言以及一些一般性的概念集。每个级别都将建立在先前的级别之上。所以,当你完成时,你将很好地了解如何从SQL Sever中选择和修改数据。

在本阶梯的前几个级别中,我向你提供了关于基本的SELECT语句以及SQL的历史信息。这些级别为你提供了一个基础,可以让你明白如何检索数据,以及随着技术和解决方案的改变,SQL环境是如何演变的。在这个级别上,我将探索如何实现基于关系模型的简单的SQL Sever数据库。在创建数据库之前。首先让我分享一下有关关系模型创建者的一些历史。

关系数据模型之父

关系数据库设计是由EdgarF.Codd于1970年首次提出,并发表了一篇题为“大型数据库的数据关系模型”的论文。Codd在IBM.IBM工作时开发了这种建模理论。但IBM在Codd的数据建模概念上不够灵活,因而并不是第一个提供利用Codd新关系数据建模理论的关系数据库引擎的供应商。Codd的关系建模概念现在是用于在SQL Server和其他关系数据库引擎中创建关系数据库的框架。

Codd出生于英国波特兰岛,在加入皇家空军成为二战飞行员之前,他就学习了数学和化学。他与1948年搬到纽约,开始在IBM工作,在那里他始终是一名数学程序员。他漂泊了好几年,最终搬到加利福尼亚在IBM圣何塞研究实验室工作。Codd继续努力完善和证明关系数据模型的合理性,直到上世纪90年代,他的健康状况不好使他不得不退休。EdgarF.Codd于2003年8月18去世,享年79.

在SQL Server中实现关系模型

这个阶梯不是为了教你如何进行关系数据建模或数据库设计,而是只向你展示如何从关系模型创建SQL Server数据库。但是,在为你提供于创建SQL Server数据库代码块之前,我们首先需要探索将实现的关系数据模型。我的简单模型将包含几个实体(数据表),其中包含主键定义和不同实体之间的一些关系(外键约束)

扫描二维码关注公众号,回复: 1625651 查看本文章

我的简单关系模型将是一个简单的酒店预订系统。此预订系统需要跟踪客户预定的信息。图1演示了我将使用T-SQL实现这个简单的关系模型:

图1:由6个表组成的简单关系数据库模型

通过查看此模型,您可以看到它包含多个实体(由框表示)以跟踪保留相关信息。每个实体由多个属性(列)组成,其中一个或多个属性被标识为主键(粗体和带下划线的名称)。还表示了实体之间的一些关系(由箭头表示),其示出了不同实体如何彼此相关。我将使用这个模型的实体、属性、主键和关系,然后开发一个代表这个关系模型的设计的物理SQLServer数据库。

要从这个模型构建一个物理数据库,我们需要识别SQLServer中的不同对象,我们将根据这个模型来定义这些对象。对于图1中的每个实体或框,我将在SQLServer中创建一个表。对于每个实体的每个属性,我将在关联表中创建一个列。对于每个主键,我将创建一个唯一的聚集索引(注意,也可以使用唯一的非聚集索引创建主键。有关索引更多信息,请参阅索引阶梯http://www.sqlservercentral.com/stairway/72399/最后,对于每个关系,我将创建一个外键约束。

要开始构建我的数据库,我首先需要创建一个SQLServer数据库,以保存我计划创建的所有新数据库对象。我的数据库叫Room订票。我将使用以下T-SQL代码创建数据库:

CREATE DATABASE RoomReservation;

 

为了开始从我的模型构建RoomReserve数据库对象,我将创建表对象。要在SQLServer中创建表,我需要使用CREATETABLE语句。使用CREATETABLE语句,我将能够定义每个表和每个表中的所有列。下面是创建SQLServer表的简单语法:

CREATE TABLE <table_name> (<column_definition> [,…N]);

其中:<table_name>=name of table

<Columnamedata_type,[NULL NOTNULL]

用于CREATETABLE语句的完整语法,请参阅SQLServerBooks Online。我创建的第一个表将是Customer表,它使用清单1中的代码创建。

USE RoomReservation;

GOCREATE TABLE dbo.Customer (

CustomerId INT NOT NULL,

FirstName NVARCHAR(50) NOT NULL, 

LastName NVARCHAR(50) NOT NULL,

Address1 NVARCHAR(100) NOT NULL, 

Address2 NVARCHAR(100) NULL,

PhoneNumber NVARCHAR(22) NOT NULL, 

EmailAddress VARCHAR(100) NULL, 

City VARCHAR(100) NOT NULL,

StateProvince NVARCHAR(100) NOT NULL,

PostalCode NVARCHAR(100) NOT NULL);

 

1. 创建客户表

在这个代码中,当我创建我所需要的客户列表时我创建了我需要的所有列。但是我也指定了当一条记录被插入或上传到表格中时是否需要一个值。我通过指定设置一些列不为空,而其他的列为空。

如果列的定义为非空意味着你不能创建一条记录除非你填充一个真实有意义的值进入这列。反之定义一列的为空意味着你可以不用指定这列的值创建一条记录,或者另一种办法让这列允许为空。在我创建你表的语句上面我允许列地址2和邮件地址为空,而其他所有的列需要一个真实的值去创建一行。

由于关系数据模型是在我的表上表示的所以这个创建标的语句并没有完全定义我的客户表。我仍然需要创建一个约束客户D列的主键。这个主键将会确保在表中的客户D列中没有两个相同的记录。在讲义2中是创建主键的代码。

USE RoomReservation;

GO

ALTER TABLE dbo.Customer ADD CONSTRAINT

     PK_Customer PRIMARY KEY CLUSTERED (CustomerId);

2. 在客户表中添加主键约束

这个添加的表格声明了在我的客户表中添加主键。这个之间将会以一个聚集的名叫PK顾客的索引形式建立。

在Transact-SQL语言中通常有不止一种方法来做同样的事情。或者,我可以创建我的客户表和主键同时在讲义3中的创建表声明中同时运行USE RoomReservation;

GO

CREATE TABLE dbo.Customer (

CustomerId INT NOT NULL CONSTRAINT PK_Customer PRIMARY KEY,

FirstName NVARCHAR(50) NOT NULL, 

LastName NVARCHAR(50) NOT NULL,

Address1 NVARCHAR(100) NOT NULL, 

Address2 NVARCHAR(100) NULL,

PhoneNumber NVARCHAR(22) NOT NULL, 

EmailAddress NVARCHAR(100) NULL, 

City VARCHAR(100) NOT NULL,

StateProvince NVARCHAR(100) NOT NULL,

PostalCode NVARCHAR(100) NOT NULL);

3. 用主键创建顾客表的替代方法

    在这一点上我已经向你展示了如何创建一个有主键约束的表。剩下的唯一的事是告诉你如何创建一个外键约束。但是在这之前,让我先为你提供创建关系数据库中其他表和主键的脚本。你可以在讲义4中找到USE RoomReservation;

GO

 

CREATE TABLE dbo.Reservation (

ReservationId INT NOT NULL, 

ArrivalDate DATETIME NOT NULL,

DepartureDate DATETIME NOT NULL,

DailyRate SMALLMONEY NOT NULL,

ReservationStatusID INT NOT NULL,

CustomerId INT NOT NULL, 

RoomTypeID INT NOT NULL);

ALTER TABLE dbo.Reservation ADD CONSTRAINT

    PK_Reservation PRIMARY KEY CLUSTERED (ReservationId);

CREATE TABLE dbo.RoomType (

RoomTypeId INT NOT NULL,

RoomDesc NVARCHAR(1000) NOT NULL); 

ALTER TABLE dbo.RoomType ADD CONSTRAINT

    PK_RoomType PRIMARY KEY CLUSTERED (RoomTypeId);

 

CREATE TABLE dbo.ReservationStatus (

ReservationStatusId INT NOT NULL, 

ReservationStatusDesc NVARCHAR(50) NOT NULL);

 

ALTER TABLE dbo.ReservationStatus ADD CONSTRAINT

    PK_ReservationStatus PRIMARY KEY CLUSTERED (ReservationStatusId);

CREATE TABLE dbo.PaymentType (

PaymentTypeId INT NOT NULL, 

PaymentTypeDesc NVARCHAR(50) NOT NULL); 

 

ALTER TABLE dbo.PaymentType ADD CONSTRAINT

    PK_PaymentType PRIMARY KEY CLUSTERED (PaymentTypeId);

 

CREATE TABLE dbo.CustomerPaymentType (

PaymentTypeId INT NOT NULL, 

CustomerId INT NOT NULL, 

PaymentNotes NVARCHAR(2000) NULL);

 

ALTER TABLE dbo.CustomerPaymentType ADD CONSTRAINT

    PK_CustomerPaymentType PRIMARY KEY CLUSTERED (PaymentTypeId, CustomerId);

4. 创建附加表和主键约束

在两个相互关联的表之间有外键的强制约束。表中的外键约束定义为参考表,需要另一个表中的相关记录,在参考表中任意时间可插入一行或更新。在图1中的关系模型中,这些外键关系用箭头表示。外键约束只在表的关系中定义。在我的图表中外键约束将在那些有箭头触及的地方定义。

在我的好关系模型中我将需要改变每个参考表来定义外键约束去添加约束。讲义5是我能用于在原有表中创建外键约束的T-SQL的代码。这个约束可以确保一天记录不被插入或上传到原有的表中除非在顾客表中找到一条相对应的记录。USE RoomReservation;

GO

ALTER TABLE dbo.Reservation

ADD CONSTRAINT FK_Reservation_CustomerPaymentType FOREIGN KEY (CustomerId)

    REFERENCES dbo.Customer (CustomerID);

5. 在原有的参考顾客表中创建外键约束

为了完成我的设计我需要事先其他所有外键约束在我的图1关系模型中。讲义6包含了在我的关系模型中创建附加项的更改表的语句。

USE RoomReservation;

GO

ALTER TABLE dbo.Reservation

ADD CONSTRAINT FK_Reservation_RoomType FOREIGN KEY (RoomTypeId)

    REFERENCES dbo.RoomType (RoomTypeId);

    

ALTER TABLE dbo.Reservation

ADD CONSTRAINT FK_Reservation_ReservationStatus FOREIGN KEY (ReservationStatusId)

    REFERENCES dbo.ReservationStatus (ReservationStatusId);    

    

ALTER TABLE dbo.CustomerPaymentType

ADD CONSTRAINT FK_CustomerPaymentType_PaymentType FOREIGN KEY (PaymentTypeId)

    REFERENCES dbo.PaymentType (PaymentTypeId);  

    

ALTER TABLE dbo.CustomerPaymentType

ADD CONSTRAINT FK_CustomerPaymentType_Customer FOREIGN KEY (CustomerId)

    REFERENCES dbo.Customer (CustomerId);   

6:创建额外的外键约束

验证数据库的绘制

一旦我从数据模型中构建数据库,我就应该验证已实现的设计,以确保它是正确的。
此验证过程旨在确保将我构建到物理数据库中的所有数据完整性规则正确地实现。
在我的设计中我需要验证的规则:

·插入或更新的所有行必须为任何定义为一个特定值不能是空值。

·作为主要的键的列不允许有一式两次的值。

·具有外键约束的列不允许在引用表中没有匹配记录的数据。

在我可以验证数据整数规则之前,我首先需要用一些有效的数据来验证引用的表,我将使用在清单7中的一些有数据代码来填充这些表。

USE RoomReservation;

GOSET NOCOUNT ON;-- Create PaymentType recordsINSERT INTO PaymentType VALUES(1,'Visa');INSERT INTO PaymentType VALUES(2,'MasterCard');INSERT INTO PaymentType VALUES(3,'American Express');-- Create Customer INSERT INTO Customer VALUES 

    (1,'Greg','Larsen','123 Some Place'

      ,NULL,'123-456-7890',Null,'MyCity','MA','12345');-- Create Reservation StatusINSERT INTO ReservationStatus VALUES (1,'Booked');INSERT INTO ReservationStatus VALUES (2,'Cancelled');-- Create Room TypeINSERT INTO RoomType VALUES (1,'Kingsize');INSERT INTO RoomType VALUES (2,'Queen');INSERT INTO RoomType VALUES (3,'Double');                            

7:插入初始数据

为了验证我在数据库中构建的数据完整性规则,我将运行清单8中的插入语句:

USE RoomReservation;

GO-- Violates NOT NULL constraintINSERT INTO Reservation VALUES(1,'2011-8-1 5:00 PM'

                                ,'2011-8-2 9:00 AM' 

                                , 150.99,NULL,1,1);                                                                                                                                                          -- Violates Primary Key ConstraintINSERT INTO RoomType VALUES (3,'Suite');  -- Violates Foreign Key ConstraintINSERT INTO CustomerPaymentType VALUES (1,2,'Will need an internet connection');

8:测试各种约束和插入语句

每个插入语句都应该失败,因为它们违反了内置房间预订数据库中的数据完整性规则,第一个插入语句违反了房间预订表非空值验证检查。

第二个插入语句违反了放置在房间类型表上的主键约束。此插入语句试图插入房间类型ID列的值。问题是房间类型表中已经有一个记录,其房间类型ID值为3。

最后一个插入语句违反了顾客付款类型表插入语句的外键约束,在顾客表中没有值为2的顾客ID。

要正确插入这些记录,需要清除插入的数据值。清理完数据后,我将能够将这些新数据插入到适当的表中。清单9包含已清除插入语句,这些语句将通过所有数据完整性检查,并成功地插入房间预订数据库中的适当表中:

USE RoomReservation;

GO-- Violates NOT NULL constraintINSERT INTO Reservation VALUES(1,'2011-8-1 5:00 PM'

                                ,'2011-8-2 9:00 AM' 

                                , 150.99,1,1,1);                                                                                                                                                          -- Violates Primary Key ConstraintINSERT INTO RoomType VALUES (4,'Suite');  -- Violates Foreign Key ConstraintINSERT INTO CustomerPaymentType VALUES (1,1,'Will need an internet connection');

9:附加约束测试

关系数据库设计

我预订的例子演示了如何把一个关系模型,并用它来利用非空主键实现SQLServer数据库的外键约束,并建立数据完整性规则,我在我的数据库设计,这让我在底层数据库定义执行这些规则,而不是编写代码在我的业务处理层来验证这些数据的规则。通过这样做,我允许SQL下水道数据库引擎为我执行这些数据完整性检查。

通过了解和创建围绕关系数据库模型的数据库设计,你将获得一个健壮和高效的数据库实现,在该实现中,你可以将数据完整性检查直接构建到数据库中。

这篇文章是通往T-sql dml的阶梯的一部分

注册我们的RSS提要,一旦我们在楼梯上发布一个新的级别,就会收到通知。


 

猜你喜欢

转载自blog.csdn.net/xtt_3170707038/article/details/79857113
今日推荐