2013-03-10 55 views
0

我有这样的:检查创建表

create table airport 
(idairport varchar(1), 
name varchar(1), 
city varchar(1), 
primary key(idairport)); 

是否可以检查一个城市没有超过3个机场?

编辑:

的运动是:

转换关系模型的概念架构。我们想知道,每个机场,已经有飞机和可能的目的地。如果模型未标准化,则将其归一化,避免存在空值。

约束:

  • 没有任何航班准点起飞机场和降落在同一机场 。
  • 一个城市最多有三个机场。

该解决方案必须是一组“CREATE TABLE”句子。尽你所能表达尽可能多的完整性约束。由于关系翻译而只指定所有“NOT NULL”。此外,你不应该忘记定义必要的外键和替代键(UNIQUE + NOT NULL)。

翻译后(如果我没看错):

create table aircraft 
(idaircraft varchar(1), 
seating varchar(1), 
primary key(idaircraft)); 

create table destination 
(idairportorigin varchar(1) references airport(idairport), 
idairportdestination varchar(1) references airport(idairport), 
idaircraft varchar(1), 
check(idairportorigin <> idairportdestination), 
primary key(idairportorigin, idairportdestination, idaircraft), 
foreign key (idaircraft) references aircraft(idaircraft)); 
+0

您可以使用插入/更新触发器添加检查插入或更新的数据 – 2013-03-10 15:43:59

+0

'创建表'是可能的? – David 2013-03-10 15:46:10

+0

所有的varchar(1)只是因为这是一个例子,对吧? – 2013-03-10 15:46:59

回答

0

像这样的事情会告诉你。

select city, count(city) citycount 
from airport 
group by city 
having count(city) >=3 
+0

这是一个查询,我需要在'创建表'中执行此操作,如果可能的话... – David 2013-03-10 16:05:31

+0

当您创建表时,它没有任何记录要检查。 – 2013-03-10 16:11:11

+1

@Dan Bracuk - 当你创建一个表并指定(比方说)'NOT NULL'时,仍然没有要检查的记录,但是无论如何可以设置限制。 – 2013-03-10 17:11:02

-2

如果您在DB写入触发那么下面的SQL将会给你算的机场 -

select count(idairport) from airport where city = 'entered city'

,然后你可以放弃添加任何机场距市区在预插入或更新前触发器。

而且,如果你使用一些编程API如JDBC等 -

然后也通过上面的SQL,你将有机场的计数输入/更新任何数据之前,然后你可以从这个角度丢弃添加/更新用编码。

+1

-1不会停止两个会话同时添加#3和#4。每个会话将看到两个现有的,然后添加更新。 – 2013-03-10 16:59:16

+0

@ShannonSeverance是正确的 - 读一致性防止触发器是一个强制约束的安全方法。 – 2013-03-10 18:36:08

0

“是否有可能检查一个城市没有超过3个机场?”

不适用于规范化的数据模型,只使用create table语句。

即使使用触发器单独不足以因读一致性防止交易从看到其他未提交的事务。

这样做的唯一安全的方法是使用上提交物化视图,存储计数,与放置在MV表的数列上的约束,以防止其超过3

+0

那么,你可以在触发器内部加锁。阅读(好)书:“为数据库专业应用数学” – Plouf 2013-03-10 19:42:25

+0

你必须锁定整个friggin表来使触发器工作。这会杀死并发。有趣的是,我怀疑任何真正的应用程序都会对机场和城市地图做出很多改变。 – 2013-03-11 04:45:10

+0

Welllllll,您可以使用DBMS_Lock仅在城市中对更改进行序列化,但这仍然超出了问题的局限性。此外,它不能在触发器内完成 - 序列化必须在事务中进行控制,以便其他会话无法读取有意进行更改的表。 – 2013-03-11 07:14:58