Chapter 2. 数据定义

Table of Contents
2.1. 表的基本概念
2.2. 系统字段
2.3. 缺省值
2.4. 约束
2.4.1. 检查约束
2.4.2. 非空约束
2.4.3. 唯一约束
2.4.4. 主键
2.4.5. 外键
2.5. 继承
2.6. 修改表
2.6.1. 增加字段
2.6.2. 删除字段
2.6.3. 增加约束
2.6.4. 删除约束
2.6.5. 改变缺省值
2.6.6. 给字段改名字
2.6.7. 给表改名字
2.7. 权限
2.8. 模式
2.8.1. 创建一个模式
2.8.2. Public 模式
2.8.3. 模式搜索路径
2.8.4. 模式和权限
2.8.5. 系统表模式
2.8.6. 使用方式
2.8.7. 移植性
2.9. 其它数据库对象
2.10. 依赖性追踪

本章介绍我们如何创建一个保存我们的数据的数据库结构。 在关系型数据库里,裸数据是存储在表中的,因此本章的大部分 内容都将用于介绍如何创建表以及如何修改和我们在控制表中 存储的数据上有什么可以获得的特性。随后,我们讨论表是如何 能组织成模式的,以及如何给表赋予权限。最后,我们将简单查看 一下影响数据存储的其他因素,比如视图,函数,和触发器。这个 主题的详细信息将在 PostgreSQL 7.3.3 程序员手册 中找到。

2.1. 表的基本概念

关系型数据库中的表非常类似纸面上的一张表:它由行和列组成。 字段的数目是固定的,每个字段都有一个名字。行的数目是变化的 -- 它反映在任意时刻里存储的数据量。SQL 对表中的行的顺序没有任何 承诺---除非你要求明确地进行排序。这些内容在 Chapter 4 里介绍。另外,SQL 并不给行赋予唯一的标识,因此我们很可能在一个 表中有好几个完全相同的行。这是作为SQL的基础的下层数学模型的 必然结果,但是通常是我们不愿意看到的。本章稍后的部分将讨论 如何处理这个问题。

每个字段都有一个数据类型。数据类型约束可以赋予一个字段的 可能数值的集合,并且约束存储在字段里的数据的赋值语义,这样 它就可以用于计算。比如,一个声明为一个数值类型的字段将不会 接受任意文本字串,而存储在这样的字段里的数据可以用于数学计算。 相比之下,一个声明为字符字串类型的字段将接受几乎任意类型的数据, 但是它们自身是不能进行数学计算的,不过我们可以进行其他象字串 连接这样的操作。

PostgreSQL 包含一套可剪裁的内置 数据类型,这些类型可以适用于许多应用。用户也可以定义它们自己 的数据类型。大多数内置的数据类型有显而易见的名字和语义,因此 我们把详细的解释放在了 Chapter 5。有些常用的 数据类型是用于整数的 integer,用于可能为分数的 numeric,用于字符串的 text,用于日期 的 date,用于时间的 time,以及用于 包含日期和时间的数值的 timestamp

要创建一个表,你使用一个命名合适的 CREATE TABLE 命令。在这个命令里,你至少为新表声明一个名字,字段的名字以及字段的 数据类型。比如:

CREATE TABLE my_first_table (
    first_column text,
    second_column integer
);

这样就创建了一个有两个字段的叫做 my_first_table 的表。第一个字段的名字是 first_column,数据类型为 text;第二个字段的名字是 second_column, 数据类型是 integer。表和字段的名字遵循我们在 Section 1.1.1 里面解释的标识符语法。 类型名通常也是标识符,但是有一些例外。请注意字段列表是逗号分隔的, 并且用圆括弧包围。

当然,前面的例子做了极大的变化。通常,你会给你的表和字段名字, 这些字段里存储它们保存的数据。所以还是让我们给一个比较现实的 例子:

CREATE TABLE products (
    product_no integer,
    name text,
    price numeric
);

numeric 类型可以存储分数部分,金额很可能有 这样的分数部分。)

窍门: 如果你创建了许多相互关联的表,那么最好选择一种一致的命名模式 来为你的表和字段命名。比如,表名字可以选择单数或者复数, 两种选择都有这样那样的理论家支持。

有一个小限制:一个表能包含的字段数目。 根据字段类型的不同,这个数目可能在250到1600之间。 不过,不管是那一端的数字,如果你设计的表包含那么多的字段好象都很不可能发生, 否则是设计上有问题的表现。

如果你不再需要这个表,那么你可以用 DROP TABLE 命令删除它。象这样:

DROP TABLE my_first_table;
DROP TABLE products;

试图删除一个不存在的表是一个错误。不过,在 SQL 脚本文件里, 我们常见在创建表之前试图无条件删除它,忽略错误信息。

如果你需要修改一个已经存在的表,那么可以看看本章稍后的 Section 2.6

使用到目前为止讨论的工具我们可以创建功能完整的表。 本章剩下的部分是有关向表定义中增加特性,保证数据完整性,安全性或者便利性的内容。 如果你急于给你的表填充数据,那么你可以忽略余下的部分直接到 Chapter 3,然后在稍后的时候再阅读本章。