作者: Gregory Larsen, 2017/08/02 (第一次出版: 2011/11/09)

翻译:谢雪妮,许雅莉,赖慧芳,刘琼滨

译文:

系列

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

这个阶梯将为您提供一个基本的理解,即如何使用SQL Server的翻译 SQL(T- SQL)的方言和对SQL Server表格中的数据进行处理。DML是数据操纵语言,是处理数据的语言的方面。它包括语句选择、插入、更新和删除。这个阶梯也将提供一些SQL语言的历史和一些关于集合理论的一般概念。每一层都将建立在先前的水平之上,因此当您完成时,您将很好地了解如何从SQL Server中选择和修改数据。

在上一级的楼梯上,我提供了关于基本选择语句和SQL历史的信息,这些级别为理解如何检索数据以及SQL环境是如何演变的提供了基础,因为技术和技术解决方案已经改变了超时工作。在这个级别,我将探索如何实现基于关系模型的简单SQL Server数据库。在开始创建数据库之前,首先让我介绍一下关系模型的创建者的一些历史。

关系数据建模之父

关系数据库设计的概念首先由Edgar F提出。. 在1970年,Codd发表论文的标题为“大型共享数据银行的数据关系模型”。 Codd在IBM工作时开发了这种建模理论。BM在Codd的数据建模概念上跳得不够快,因此并不是第一个供应关系数据库引擎的供应商,它利用了Codd的新关系数据建模理论。Codd的关系建模概念现在是用来在SQL Server和其他关系数据库引擎中创建关系数据库的框架。Codd出生于英格兰的波特兰岛,在加入皇家空军之前学习了数学和化学,成为了第二次世界大战的飞行员1948年,他搬到纽约,开始在IBM工作,在那里他是一名数学程序员。他漂流了好几年,最终搬到加州,在IBM圣何塞研究实验室工作。直到20世纪90年代,当他的健康状况不佳迫使他退休时,Codd继续努力完善并证明了关系数据模型的合理性。2003年4月18日,Codd去世,享年79岁。

在SQL Server中实现关系模型

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

我的简单的关系模型将是一个简单的酒店预订系统。这个预订系统需要跟踪客户预订信息。图1说明了这个简单的关系模型,我将使用t - sql实现它:

通过回顾这个模型,您可以看到它包含许多实体(由方框表示)来跟踪预订相关信息。每个实体都由一些属性(列)组成,其中一个或多个属性被标识为主键(粗体和下划线的名称)。也表示实体之间的一些关系(以箭头表示),以显示不同的实体之间是如何相互关联的。我将使用实体、属性、主键和关系的模型,然后开发一个物理SQL Server数据库,它表示此关系模型的设计。要从这个模型构建物理数据库,我们需要在SQL Server中识别基于此模型定义的不同对象。对于图1中的每个实体或框,我将在SQL Server中创建一个表。对于每个实体的每个属性,我将在关联的表中创建一个列。对于每个主键,我将创建一个唯一的集群索引(注意,使用唯一的非聚集索引也可以创建主键)。有关索引的更多信息,请参见http://www .sqlservercentral.com/stairway/72399/).。最后,对于每个关系,我将创建一个外键约束。要开始构建我的数据库,我首先需要创建一个SQL Server数据库来保存我计划创建的所有新数据库对象。我的数据库将被称为房间预订。我将使用以下的t - sql代码创建我的数据库

CREATE DATABASE RoomReservation;

要从我的模型中开始构建我的房间预订数据库对象,我将创建表对象。要在sql server中创建一个表,我需要使用创建表语句。通过创建表语句,我将能够定义每个表中的每个表和所有列。下面是创建SQL Server表的简单语法

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

Where:

<table_name> = Name of table
<column_definition> = column_name data_type,[NULL | NOT NULL]

For complete syntax of the CREATE TABLE statement refer to SQL Server Books Online.

The first table I create will be the Customer table, created using the code in Listing 1.

USE RoomReservation;
GO
CREATE 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:创建Customer表

在这段代码中,当我创建我的Customer表时,我创建了我需要的所有列,但我还指定了在插入或更新记录时,该列是否需要一个值。我通过在某些列上指定非空值来实现这一点,而其他列则指定为空值。

如果一个列被定义为不为空,那意味着你不能创建一个记录,除非你用一个实际值填充这个列。而使用空值规范定义一个列意味着您可以创建一行,而不必为这个列指定一个值,或者另一种方法是,该列允许空值。我在创建表的语句上面我允许列地址2和邮箱地址支持空值,而所有其他的柱子需要值将提供创建一个行时。

这个创建表语句并没有完全定义我的客户表,因为它是在我上面的关系数据库模型中表示的。我还需要创建一个主键约束的列ID。这个主键约束将确保该表中没有两个记录具有相同的客户编号码的值。这个主键约束将确保该表中没有两个记录具有相同的客户编号码的值。创建主键的代码如清单2所示

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); 清单2:向客户表添加主键约束
此表语句向客户表添加了主键约束。该主键将在聚集索引命名pk_customer窗体的创建。在翻译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_CustomerPaymentType FOREIGN KEY (CustomerId)
REFERENCES dbo.Customer (CustomerID);
清单6:创建额外的外键限制

验证数据库的设计

一旦我完成了从数据模型构建数据库的工作,我应该验证所实现的设计,以确保它是正确的。这个验证过程是确保我在物理数据库中构建的所有数据完整性规则都正确地实现了。在我的设计中,我需要验证这些规则。

所有插入或更新的行必须对定义为非空值的列有一个特定的值。

主键的列不允许重复的值。

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

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

SET NOCOUNT ON;
-- Create PaymentType records
INSERT 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 Status
INSERT INTO ReservationStatus VALUES (1,'Booked');
INSERT INTO ReservationStatus VALUES (2,'Cancelled');
-- Create Room Type
INSERT INTO RoomType VALUES (1,'Kingsize');
INSERT INTO RoomType VALUES (2,'Queen');
INSERT INTO RoomType VALUES
清单7:插入初始数据

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

USE RoomReservation;
GO
-- Violates NOT NULL constraint
INSERT INTO Reservation VALUES(1,'2011-8-1 5:00 PM'
,'2011-8-2 9:00 AM'
, 150.99,1,1,1);
-- Violates Primary Key Constraint
INSERT INTO RoomType VALUES (4,'Suite');
-- Violates Foreign Key Constraint
INSERT INTO CustomerPaymentType VALUES (1,1,'Will need an internet connection');
清单8:用INSERT语句测试各种约束

这些INSERT语句中的每一个都应该失败,因为它们违反了构建在订房数据库中的数据完整性规则。第一个INSERT语句违反了预订规则列的非空验证检查。

第二个INSERT语句违反了放在房间类型表上的主键约束。这个INSERT语句试图为房间类型编号的列插入3的值。问题是在房间类型值为3的房间类型表中已经有了记录。

最后一个INSERT语句违反了顾客缴费方式表的外键约束。在这个特殊的INSERT语句中,顾客表中没有客户编号值为2的值。

要正确地插入这些记录,插入的数据值需要清理。一旦数据被清理干净,我就可以将这些新数据插入到合适的表中。清单9包含清除所有数据完整性检查并成功插入到房间预订数据库中的适当表的清理INSERT语句:

USE RoomReservation;
GO
-- Violates NOT NULL constraint
INSERT INTO Reservation VALUES(1,'2011-8-1 5:00 PM'
,'2011-8-2 9:00 AM'
, 150.99,1,1,1);
-- Violates Primary Key Constraint
INSERT INTO RoomType VALUES (4,'Suite');
-- Violates Foreign Key Constraint
INSERT INTO CustomerPaymentType 清单9:附加约束测试
 

关系数据库设计

我的预订示例演示了如何使用关系模型并使用它来实现SQL Server数据库。通过使用非空值、主键和外键完整性约束,我将数据完整性规则构建到数据库设计中。这允许我在底层数据库定义中执行这些规则,而不必在业务处理层中编写代码来验证这些数据规则。通过这样做,我允许SQL Server数据库引擎为我执行这些数据完整性检查。

通过了解并在关系数据库模型周围创建数据库设计,您将构建一个健壮且高效的数据库实现,您可以在数据库中构建数据完整性检查。

到T-SQL DML 三级的阶梯:在SQL server中实现关系模型的更多相关文章

  1. 在SQL Server中实现关系模型的阶梯到级别3的t -SQL DML

    在SQL Server中实现关系模型的阶梯到级别3的t -SQL DML 格雷戈里·拉森(Gregory Larsen),2017/08/02(第一次出版:2011 /11/09) 原文链接:http ...

  2. 在SQL Server中实现关系模型

    使用SQL Server的Transact-SQL(T-SQL)方言,此楼梯将为您提供如何使用SQL Server表中的数据的基本了解. DML是数据操作语言,是处理数据的语言的一个方面.它包括SEL ...

  3. SQL DML 和 DDL

    数据库表 一个数据库通常包含一个或多个表.每个表由一个名字标识(例如“客户”或者“订单”).表包含带有数据的记录(行). 下面的例子是一个名为 "Persons" 的表: Id L ...

  4. SQL语句的使用,SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中的数据 DELETE - 从数据库表中删除数据 INSERT INTO - 向数据库表中插入数据

    SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法. 但是 SQL 语言也包含用于更新. ...

  5. 转:如何学习SQL(第三部分:SQL数据类型与三值逻辑)

    转自:http://blog.163.com/mig3719@126/blog/static/285720652010950921286/ 7. 数据类型 在数据库理论中,关系模型和数据类型这两部分内 ...

  6. 第十七周翻译-SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志

    SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志 作者:Tony Davis,2012/01/27 翻译:赖慧芳 译文: 该系列   本文是Stairway系列的一部分:SQL ...

  7. 第17周翻译:SQL Server中的事务日志管理的阶梯:第5级:在完全恢复模式下管理日志

    来源:http://www.sqlservercentral.com/articles/Stairway+Series/73785/ 作者:Tony Davis, 2012/01/27 翻译:刘琼滨. ...

  8. SQL Server中的事务日志管理的阶梯,级别1:事务日志概述

    SQL Server中的事务日志管理的阶梯,级别1:事务日志概述 翻译:刘琼滨 谢雪妮 许雅莉 赖慧芳 级别1:事务日志概述 事务日志是一个文件,其中SQL服务器存储了所有与日志文件关联的数据库执行的 ...

  9. SQL Server中的Merge关键字

    本文转载地址:http://www.cnblogs.com/CareySon/archive/2012/03/07/2383690.html 简介 Merge关键字是一个神奇的DML关键字.它在SQL ...

随机推荐

  1. 2015/12/25 ① 图灵测试 ② 安装jdk出现的问题 ③ 配置环境变量

    ①图灵测试 1,解释 图灵测试一词来源于计算机科学和密码学的先驱阿兰·麦席森·图灵写于1950年的一篇论文<计算机器与智能>.阿兰·麦席森·图灵1950年设计出这个测试,其内容是,如果电脑 ...

  2. Hackrank Kingdom Division 树形DP

    题目链接:传送门 题意: 给你一棵树,n个点 每个点可以染成红色和蓝色 但是红色的点与其相邻的点中必须有红色节点,蓝色也是 问你有多少种染色的方案 题解: 树形dp 先转化为有根树,取1为根 设定dp ...

  3. Android应用基础学习记录

    01_前言 前言,了解了Android的情况.这里也介绍一下本文.本文是记录学习Android应用程序开发过程,视频中使用的Android2.2版本号,我以4.2版本号为基础,找出当中的差异并记录下来 ...

  4. Evernote相关技术介绍——mysql+lucene+tomcat

    Evernote服务 我们的服务由以下几个组件组成. 分片(NoteStore)   分片是Evernote服务的核心单元,用于存储用户的笔记.每个分片最多可以支撑30万个Evernote用户,并包含 ...

  5. Java简单的加密解密算法,使用异或运算

    package cn.std.util; import java.nio.charset.Charset; public class DeEnCode { private static final S ...

  6. Iphone 启动图的尺寸

    APP图标设置 - 取Images.xcassets中的AppIcon, 图标尺寸 29pt * 2x => 58 * 5829pt * 3x => 87 * 8740pt * 2x =& ...

  7. saltstack源码-启动2-parsers.py选项初始化1

    class MasterOptionParser(OptionParser, ConfigDirMixIn, MergeConfigMixIn, LogLevelMixIn, RunUserMixin ...

  8. ChartCtrl源码剖析之——CChartScrollBar类

    CChartScrollBar类用来针对每个轴的数据进行滚动,将那些不在当前区域内的数据通过滚动展示出来. CChartScrollBar类的头文件. #pragma once class CChar ...

  9. Tomcat相关的LNMT和LAMT

    Tomcat相关的LNMT和LAMT LNMT:Linux Nginx MySQL Tomcat Client (http) --> nginx (reverse proxy)(http) -- ...

  10. apicloud踩坑集锦

    最近在用apicloud开发,这里录入一些踩坑的地方,从头到尾,要多尴尬有多尴尬,新入app开发,记录一些心得,和遇到的坑以及解决办法. 1,apicloud 打包的Android app ,打开fr ...