为每个基表选择一个语句
您只想拥有一张桌子的愿望是不知情和不明智的。
每张表都有关于应用情况的基本说明。使语句为真的行进入表中。
ivoice(i,c,...) // invoice [i] is to company [c] with ...
company(c,n,a,...) // company [c] has name [n] and address [a] ...
receiver(r,...) // receiver [r] ...
因此,每一个存在的行都做出了一个真实的陈述(或者它会不存在),而每一个不存在的行都会做出一个错误的陈述(或者它会存在)。因此,您可以将表视为从当前行生成语句加上不存在行中的语句的非。基表一起描述了您的应用情况。
在基表语句中限制“AND”
基本思想是从您的语句中删除大部分 AND。如果一个表语句是较小语句的与,那么它们应该总是像这样:
(1) something AND-free about [k1],...
其中 k1,... 列上的每个子行在表中都是唯一的,并且没有包含的较小子行是或类似的:
(2) [c]=some_function_of_all_of(k1,...)
(这称为“第五范式”。)
为什么要限制“与”?
因为否则您的表格会出现由其中一个更简单的语句组成的有问题的语句,例如:
blah [k1] blah [k2] AND blub [j1]
当 "blah ZZ blah 88" 为真或假时,根据 "blub [j1]" 的真实性,您通常不仅要在此表中放入一行,而且要放入一堆行每个可能的 j1 值。 (这称为更新异常。)
此外,您很可能想说“blah VV blah 999”是真还是假(在表内或表外),而不会对 j1s 哭诉。但你选择的桌子不会让你。 (这就是所谓的错误设计。)
PS:每个查询都有一个语句
每个查询表达式也有一个语句。查询的值是使其语句为真的行。通过关系运算符组合表以进行查询,通过逻辑运算符组合语句以进行语句。表的 JOIN、ON 和 WHERE 执行语句的 AND,表的 UNION 执行语句的 OR,SELECT 执行 THERE IS 等。因此,当您查询时,您正在从基表语句构建更复杂的语句。
// there is a name n,... where:
// invoice [i] is to company [c] and ...
// AND company [c] has name [n] and address [a] ...
SELECT i,c,a FROM company JOIN invoice ON company.c=invoice.c