数据库设计(4/9):创建架构

简介:

在第一篇,我们因它们是什么并区分它们命名数据元。在第二篇,我们用SQL里给我们的数据类型和简单的行或列约束来模型化数据元。在第三篇,我们把这些行放入表成为实体,关系和辅助数据。

现在我们有了基表,是时候把它们放一起作为数据库,增加其它的架构对象混合一起。这需要我们从比一次一个表或多个表更高的层级来看。对这个一个有用的工具是实体关系图(E-R (Entity-Relationship) diagram)。不好的消息是有很多风格的实体关系图,其中一些变得非常复杂。这个工具的第一个版本应归于Peter Chen在他1976年的论文里,它还是一个很好开始的地方。每个系统认同实体表表现为一个在它里面有表名的矩形。但一些系统会放入所有列名,对于主键标上特殊符号作为不同等等。

Chen最先使用方块牌(diamond)作为关系表。这是个很好的主意,在它里面很容易画n元关系,你可以快速看到交替的模式框和方块牌。如果一个表同时使用,会有一些结论。例如,婚姻是丈夫和妻子之间的关系,但也有婚姻日期的数据,登记号,证婚人(presiding official)等等。

接下来的系统放弃了方块牌,把关系表放入矩形,并使用只能显示二元关系的线,但线的末端有可选或必选成员关系的标志,0,1或更多成员关系级别,给它一些权利。这三个图形是条形作为1,圆形作为0,“鸡爪”作为多个。这个百闻不如一见。

我们可以认为讲师(lecturer)传授(teaches)课程(courses),因此课程是被讲师传授。

这很好理解,但我们应该表示更多的规则。例如,如果我们有一个策略,每个讲师必须刚好只传授一个课程?我们可以添加用最大1的条行标志和第二个执行中间线的条行来表示传授关系。这个逻辑适用于关系里涉及的课程。

现在,让我们放宽一些规则。我们认为保持一个讲师工作,即使他这次没传授任何东西,但换取这份工作安全,我们想让他有时候可以传授一个或更多的课程。圆形指向线中心,鸡爪在课程框旁。

这一切都很好,直到我们觉得多对多的关系,这会看起来像这样:

我们需要有一个明确的关系表,称它“教学任务(Teaching Assignments)”,在讲师和课程之间。实体关系图更容易看懂,不需要看很多的SQL DDL语句。还有其它突出的模式,例如扇形。

 

我不能把部门和人员正确匹配我们。假设常见的组织架构,这应该2个1:n分部(Divisions)的关系模型。

你可以用多个工具从SQL DDL里获得实体关系图,在更高级查看其它问题模式。这里我不会给ER模型和图的详细说明;现在我只想让你知道它们。接下来,你可以自己学习使用它们。

一旦你的表设计已经确定,就可以考虑数据访问了。这通常意味着你会加索引到表。有两类索引:主和从。主索引必须在表上执行唯一性约束,像PRIMARY KEY和UNIQUE约束,从索引添加是为了性能提升。

SQL引擎会自动为你创建主索引,但这个假设并不对你有好处。在SQL Server里,在一个表上你只能有一个聚集索引,因此小心用它。例如,不用聚集索引在customer_id列作为客户表的主键,你会使用它保持物理文件按部门编号排序,因为这是你的报表分组和汇总的样子。同时使用非聚集索引作为查找客户就可以了。

索引的树结构由在CREATE INDEX语句里的列顺序决定。这就是说:

1 CREATE INDEX Foobar ON Customers (state_code, city_name);

1 CREATE INDEX Barfoo ON Customers (city_name, state_code); 

逻辑上是一样的,但功能不同。

选择从索引是个非完全多项式(NP-Complete)问题,因此你不能用常规方法创建它们。最好你可以遵循一些简单的启发式。第一个启发式不要重叠索引(over-index)。初学者喜欢增加很多索引让它们的产寻更快。这并不都是对的:查询优化器会忽略用不到的索引,因此事实上它们变成了“无用代码”。但当基表修改的时候,每个插入,更新和删除语句会修改这些无用的索引。这会是很大的负担。

第二个启发式如果一列从不在查询条件里使用(意思是说在WHERE、ON或HAVING子句里),那它不应该在索引里出现。

第三个启发式你不应该有常见列前缀列表的索引。

这就是说如果你有个像这样的索引:

1 CREATE INDEX Floob ON ExampleTable (a, b, c, d); 

那实际上,下列这些索引是赠送的:

1 CREATE INDEX Floob_3 ON ExampleTable (a, b, c);
2 CREATE INDEX Floob_2 ON ExampleTable (a, b);
3 CREATE INDEX Floob_1 ON ExampleTable (a); 

直接创建隐含的索引是多余的。

下一个你经常会用的添加到架构的东西是视图。很多程序员认为视图可以帮助用户减少重复代码的编写。那是对的,但视图的最大优点是它每次用同样的方式做同样的事,对每个人。人总不会一致的。不抱怨的话,相比另一个程序员,程序员不会实现不同的业务规则。Fred读到的规格是(shipping_qty > 100))和Sam读到的规格(shipping_qty >= 100);如果他们使用视图的话,业务规则适用一个且只有一个方式。

通常来讲,视同扮演2个方式。或者他们是本地的语句(通常一个SELECT)和扩展为内嵌的文本,它们的定义保持在架构里。另一个做法是从它们的定义以物理表实现它们的定义。一般而言,当多个会话同时使用它们的时候,一个好的SQL引擎会实现视图,这样的话虚拟表可以在主存里共享,一个会话可以多次使用同样的视图。在SQL Server,你可以在视图上创建索引提高性能。

即使有经验的SQL人员也不知道视图的另一部分; WITH CHECK OPTION子句。如果指定了WITH CHECK OPTION,视图表必须可更新。这个做法是阻止通过WHERE子句的违反。我们用例子解释下:

复制代码
1 CREATE VIEW NYC_Personnel
2 AS
3 SELECT *
4 FROM Personnel
5 WHERE city_name = 'New York'; 
复制代码

现在我们用下列语句UPDATE:

1 UPDATE NYC_Personnel
2 SET city_name = 'Birmingham'; –- everyone moved!! 

UPDATE会执行,没有任何问题,但我们再次使用NYC_Personnel时,刚才看到的记录现在都消失了。这已不再符合WHERE子句的条件!同样,一个有(col1 = 'B')的INSERT INTO语句没有问题,但在这个视图里从不会看到。

WITH CHECK OPTION会让系统会在INSERT或UPDATE上检查WHERE子句。如果新的或修改的行测试失败,修改会被拒绝,视图还是一样。那么,刚才的UPDATE语句会收到错误信息,你不能在特定方式里修改特定列。

WITH CHECK OPTION可以作为架构级别的CHECK()子句。例如,假设有规则的酒店预定,你不能添加客人到另一个客人已或会占用的房间。不用直接写约束,像这样:

复制代码
 1 CREATE TABLE Hotel
 2 (room_nbr INTEGER NOT NULL,
 3 arrival_date DATE NOT NULL,
 4 departure_date DATE NOT NULL,
 5 guest_name CHAR(30) NOT NULL,
 6 CONSTRAINT schedule_right
 7 CHECK (H1.arrival_date <= H1.departure_date),
 8- valid Standard SQL, but going to to work!!
 9 CONSTRAINT no_overlaps
10 CHECK (NOT EXISTS
11 (SELECT *
12 FROM Hotel AS H1, Hotel AS H2
13 WHERE H1.room_nbr = H2.room_nbr
14 AND H2.arrival_date < H1.arrival_date
15 AND H1.arrival_date < H2.departure_date))); 
复制代码

schedule_right约束没有问题,因为它没有子查询,但很多产品会检查overlaps约束。我们可以不用表上的no_overlaps约束,我们可以在Hotel表上所有行列上构建一个视图,并增加执行WITH CHECK OPTION的WHERE子句。

复制代码
 1 CREATE VIEW Valid_Hotel_Stays (room_nbr, arrival_date, departure_date, guest_name)
 2 AS
 3 SELECT H1.room_nbr, H1.arrival_date, H1.departure_date, H1.guest_name
 4 FROM Hotel AS H1
 5 WHERE NOT EXISTS
 6 (SELECT *
 7 FROM Hotel AS H2
 8 WHERE H1.room_nbr = H2.room_nbr
 9 AND H2.arrival_date < H1.arrival_date
10 AND H1.arrival_date < H2.departure_date)
11 AND H1.arrival_date <= H1.departure_date
12 WITH CHECK OPTION; 
复制代码

例如:

1 INSERT INTO Valid_Hotel_Stays
2 VALUES (1, '2011-01-01', '2011-01-03', 'Ron Coe'); 

随后:

1 INSERT INTO Valid_Hotel_Stays
2 VALUES (1, '2011-01-03', '2011-01-05', 'John Doe'); 

在第2个INSERT INTO语句上,会给我们想要的违反了WITH CHECK OPTION子句。

真正的好处是,这让约束在声明代码(declarative code)里了,且查询优化器可以使用。

视图可以通过隔离让用户看不到未授权或不需要的数据。理想地,你想为每个用户创建一系列的视图,让他们觉得数据库就像专门为它们设计的一样。这会花点时间,你需要知道如何使用SQL的第三(最被忽略的)子语言——数据控制语言(the DCL (Data Control Language))。

DCL不是个安全系统;它是SQL数据库的简单的控制工具。它让数据不在安全级别外暴露。

在一个安全的系统里,在最小的安全级别,我们被告知超人是来自外星球的奇怪访客,有常人不及的能力和技能。但我们需要更高的级别来知道他是伪装的Clark Kent,伟大都市报纸的温顺记者~~~


本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/5595792.html,如需转载请自行联系原作者

相关文章
|
17天前
|
NoSQL 关系型数据库 MySQL
微服务架构下的数据库选择:MySQL、PostgreSQL 还是 NoSQL?
在微服务架构中,数据库的选择至关重要。不同类型的数据库适用于不同的需求和场景。在本文章中,我们将深入探讨传统的关系型数据库(如 MySQL 和 PostgreSQL)与现代 NoSQL 数据库的优劣势,并分析在微服务架构下的最佳实践。
|
17天前
|
设计模式 缓存 关系型数据库
探索微服务架构中的数据库设计挑战
微服务架构因其模块化和高扩展性被广泛应用于现代软件开发。然而,这种架构模式也带来了数据库设计上的独特挑战。本文探讨了在微服务架构中实现数据库设计时面临的问题,如数据一致性、服务间的数据共享和分布式事务处理。通过分析实际案例和提出解决方案,旨在为开发人员提供有效的数据库设计策略,以应对微服务架构下的复杂性。
|
17天前
|
消息中间件 缓存 监控
优化微服务架构中的数据库访问:策略与最佳实践
在微服务架构中,数据库访问的效率直接影响到系统的性能和可扩展性。本文探讨了优化微服务架构中数据库访问的策略与最佳实践,包括数据分片、缓存策略、异步处理和服务间通信优化。通过具体的技术方案和实例分析,提供了一系列实用的建议,以帮助开发团队提升微服务系统的响应速度和稳定性。
|
17天前
|
消息中间件 缓存 监控
优化微服务架构中的数据库访问:策略与实践
随着微服务架构的普及,如何高效管理和优化数据库访问成为了关键挑战。本文探讨了在微服务环境中优化数据库访问的策略,包括数据库分片、缓存机制、异步处理等技术手段。通过深入分析实际案例和最佳实践,本文旨在为开发者提供实际可行的解决方案,以提升系统性能和可扩展性。
|
21天前
|
存储 负载均衡 数据库
探索后端技术:从服务器架构到数据库优化的实践之旅
在当今数字化时代,后端技术作为支撑网站和应用运行的核心,扮演着至关重要的角色。本文将带领读者深入后端技术的两大关键领域——服务器架构和数据库优化,通过实践案例揭示其背后的原理与技巧。无论是对于初学者还是经验丰富的开发者,这篇文章都将提供宝贵的见解和实用的知识,帮助读者在后端开发的道路上更进一步。
|
2月前
|
存储 缓存 关系型数据库
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
36 0
|
2月前
|
XML 分布式数据库 数据库
【计算机三级数据库技术】第13章 大规模数据库架构--附思维导图
文章概述了分布式数据库、并行数据库、云计算数据库架构和XML数据库的基本概念、目标、体系结构以及与传统数据库的比较,旨在提供对这些数据库技术的全面理解。
30 1
|
2月前
|
存储 前端开发 关系型数据库
Linux 技术架构:前端、后端与数据库的完美融合
【8月更文挑战第25天】本文深入剖析了Linux操作系统的技术架构,重点介绍了前端、后端及数据库三大核心组成部分。Linux前端技术不仅涵盖了图形用户界面(GUI),包括GNOME、KDE等桌面环境,还涉及HTML、CSS、JavaScript等Web前端技术及其相关框架。后端技术则聚焦于Python、Java等多种编程语言、Apache和Nginx等Web服务器以及MySQL、PostgreSQL等数据库管理系统。Linux数据库技术覆盖了关系型和非关系型数据库,如MySQL、MongoDB等,并提供了多种数据库管理工具。
61 0
|
2月前
|
存储 Serverless API
Serverless 架构实现弹幕场景问题之在initializer方法中初始化数据库实例如何解决
Serverless 架构实现弹幕场景问题之在initializer方法中初始化数据库实例如何解决
16 0
|
2月前
|
SQL 数据库
拒绝了对对象 ‘GetTips‘ (数据库 ‘vipsoft‘,架构 ‘dbo‘)的 EXECUTE 权限
拒绝了对对象 ‘GetTips‘ (数据库 ‘vipsoft‘,架构 ‘dbo‘)的 EXECUTE 权限
33 0
下一篇
无影云桌面