数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
《SQL Story》摘录五——关系真相

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

 

关系的真相

长期以来,我们习惯了称关系型数据库中的表为二维表。因为它有行和列,很容易我们就可以把它同一个二维平面联系起来,但事实上,这并非关系型数据库的初衷,也并非符合关系模型的设计。其实长久以来,我对此也只有一个很模糊的概念,对平面表的观点虽有怀疑,却一直无从验证。直到有一天,翻出一本老书——《关系数据库》(石树刚、郑振楣编著,清华大学出版社,1993年),这本老书没有什么流行的新噱头,却满满当当地净是数学理论。这本书读起来并不是很诱人,不过的确很严谨,澄清了我的很多不明之处。也激励我找来各种权威材料重头学起。薄薄一本书,定价只有9.9元,想想这应当是我在上学时,从旧书摊上买的,可能当时只花了不到五元钱。这肯定是我买的性价比最高的一本书了。

在此,我不想从别人书中抄出大段原话,拼出一篇文字,有这工夫还不如上网回贴子更有成就感,我宁愿将我的心得,用并不严密,但尽可能易懂的语言写下。让朋友们先对关系模型有个基本概念,使众多像我这样非科班出身的读者多少了解一下事实真相,不至于在工作中有所不便。如果你想真正掌握关系型数据库的数学模型,请读一读这本不流行的老书《关系数据库》。当然,还有很多新近的正规教材也写得很不错,比如现在在我手边的《DATABASE SYSTEM CONCEPTS》(机械工业出版社)和《SQL-3 参考大全》(机械工业出版社)。前两本写得更严谨一些,后一本是译得不太好,有些关键地方读着莫名其妙,不过总得来说还是本难得的好书。

言归正传,现在我们说说关系型数据库到底是怎么一回事。我们先看一个表:

X Y Z

------------------

0 0 0

1 1 1

0 0 1

0 1 1

……

这个表存储一个三维空间内的一些点。我们可以很清楚地看到,每一个完整的行,才代表一个点。仅定位某行某列,它并不能表达这个表所定义的信息结构。当我们向这个表中插入或删除数据,它仍代表三维空间内的点集。但如果我们增加一列T(time)呢?那一切全变了,它不再是三维空间了,现在,这个表中存储的是四维的信息了(读过相对论的朋友应当了解,相对论中的时空就是一个四维坐标系)。删除一列呢?比如Z列,现在我们面对的就是X-Y 平面了,这是一个二维坐标系。也就是说,在表中删除或增加或修改若干列,并不会改变这个表所代表的意义。而修改或增删列,就会改变表的结构,表所代表的意义也就不同于以前了。表的行和列,并不是平等的!我们不能简单地把它理解为一个平面!相反,我认为,将表的结构理解为一个代数空间更合适,这样,表中的每一行是这个代数空间中的一个点,那么当前表中的信息就形成了这个空间中的一个点集。当然,这个集合还可有其它的约束条件,下面我们从关系模型说起。

在严格意义上的关系模型中,一个关系模式,包括关系名、有限属性集、属性值域、属性列到值域的映射、完整性约束和属性间依赖。对应数据库中的结构,通常一个关系模式对应一个或多个表和视图。这些表和视图有其各自包括的列,而列有列名、列的数据类型、表和视图的主键约束、外键约束、检查、断言、触发器(在SQL Server2000中,已可以在视图中定义索引和触发器,再加上视图本身的 SQL脚本,视图以可以定义为一个完整的关系模式)。一个简单的关系模式可以只由一个表构成,而多个元组(表或视图)组成的关系,其相互的关联由外键和触发器来完成。在这个定义中,关系中的各个列(也就是说关系的模式)可以有很强的依赖性。比如某些列有主键约束,另一些列有引用外键。而行与行之间(也就是说关系之间)的依赖只存在于两种情况——外键和触发器。其中外键可以表达为模式上的(也就是列之间的)依赖。例如以下订单系统,它由客户表,订单表和

CREATE TABLE CUSTOMERS(

CUSTOMERID INT NOT NULL,

FIRSTNAME CHAR(20),

LASTNAME CHAR(20),

CITY VARCHAR(30),

CONSTRAINT PK_CUSTOMER PRIMARY KEY(CUSTOMERID)

)

CREATE TABLE GOODS(

ID INT NOT NULL,

NAME CHAR(20) NOT NULL,

NUMBER INT,

PRICE MONEY,

CONSTRAINT PK_GOOD PRIMARY KEY(ID))

CREATE TABLE ORDERS(

ORDERID INT NOT NULL,

CUSTOMERID INT NOT NULL,

ORDERDATE DATETIME,

CONSTRAINT PK_ORDER PRIMARY KEY(ORDERID),

CONSTRAINT FK_CUSTOMER FOREIGN KEY (CUSTOMERID)

REFERENCES CUSTOMERS(CUSTOMERID))

CREATE TABLE ITEMS(

ITEMSID INT NOT NULL,

ORDERID INT NOT NULL,

NUMBER INT NOT NULL

CONSTRAINT PK_ITEM PRIMARY KEY(ITEMSID),

CONSTRAINT FK_GOOD FOREIGN KEY (ITEMSID)

REFERENCES GOODS(ID),

CONSTRAINT FK_ORDER FOREIGN KEY (ORDERID)

REFERENCES ORDERS(ORDERID)

)

以上一表中,一位客户可以有多张订单,订单的订户依赖客户表。一张订单可以有多个条目,明细条目又依赖于订单和商品的存在。这四个表就构成一个关系模式,四个表都有其主键,表中的其它列依赖于主键列。表之间的外键引用则构成了表之间的依赖关系。由此联接起了整个模式。每一个完整的订单,包括ORDERS表中的订购信息和ITEMS表中的明细,形成一个关系。而一个用户和他的订单,又可以形成一种新的关系,这些关系的模式,可以由SQL语句来表达,这里不详细讲了,朋友们可以试一下,很简单的联接查询而已。我们可以看到,这个典型的关系中,信息的内容之复杂,远远超出了“几个二维平面表”所能定义的。“带有强约束条件关联的若干代数空间点集”可能更好一些。甚至,我们还可以在其上定义更强的约束,比如用一个触发器保证用户的订购数在某一范围内。当我们增删订单,存货甚至客户时,由于强有力的约束存在,保证了每个关系仍是完整的。可列的定义本身就是关系模式的一部分,如果我们改变或增删了列,修改的是整个模式。至少一个代数空间,被我们改变了。这也就是行和列的区别。当然,只定义一个表,不给它加以任何约束,在技术上是允许的,但这样的表不能称为一个关系。它甚至不能保证最基本的关系完整性。如以前的文章所示,这样的表轻易就可以插入重复数据,而这些不能互相区别的数据并不能给我们更多的信息。这种没有约束的表在实用中应当严格限制于临时表,不应在其它任何场合出现。

希望读了这篇文章的朋友,能够不再犯我当初常初的错误,建立一个又一个没有任何约束的表,存入不可靠的数据。我们应当把信息的结构和关系模型直接表达在数据库的设计中,这才是关系型数据库的意义所在。这一次几乎没有可执行的代码,可能读者们会有意见。不过真心祝大家能理解我的意思,在关系型数据库的世界中更轻松自如地工作。如果您有批评、表扬、指导,我在这里专心地听取,谢谢您的支持。我在书中专注于SQL Server 和InterBase,希望有Oracle或DB2等其它数据库系统的高手与我合作,完成本书的不同版本内容,与我分享劳动的艰辛和成功的喜悦。




相关文章

相关软件