1、表的定义:
对于任何一种关系型数据库而言,表都是数据存储的最核心、最基础的对象单元。如今就让咱们从这里起步吧。
1. 建立表:
CREATE TABLE products (
product_no integer,
name text,
price numeric
);
2. 删除表:
DROP TABLE products;
3. 建立带有缺省值的表:
CREATE TABLE products (
product_no integer,
name text,
price numeric DEFAULT 9.99 --DEFAULT是关键字,其后的数值9.99是字段price的默认值。
);
CREATE TABLE products (
product_no SERIAL, --SERIAL类型的字段表示该字段为自增字段,彻底等同于Oracle中的Sequence。
name text,
price numeric DEFAULT 9.99
);
输出为:
NOTICE: CREATE TABLE will create implicit sequence "products_product_no_seq" for serial column "products.product_no"
4. 约束:
检查约束是表中最为常见的约束类型,它容许你声明在某个字段里的数值必须知足一个布尔表达式。不只如此,咱们也能够声明表级别的检查约束。
CREATE TABLE products (
product_no integer,
name text,
--price字段的值必须大于0,不然在插入或修改该字段值是,将引起违规错误。还须要说明的是,该检查约束
--是匿名约束,即在表定义时没有显示命名该约束,这样PostgreSQL将会根据当前的表名、字段名和约束类型,
--为该约束自动命名,如:products_price_check。
price numeric CHECK (price > 0)
);
CREATE TABLE products (
product_no integer,
name text,
--该字段的检查约束被显示命名为positive_price。这样作好处在于从此维护该约束时,能够根据该名进行直接操做。
price numeric CONSTRAINT positive_price CHECK (price > 0)
);
下面的约束是非空约束,即约束的字段不能插入空值,或者是将已有数据更新为空值。
CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric
);
若是一个字段中存在多个约束,在定义时能够不用考虑约束的声明顺序。
CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric NOT NULL CHECK (price > 0)
);
惟一性约束,即指定的字段不能插入重复值,或者是将某一记录的值更新为当前表中的已有值。
CREATE TABLE products (
product_no integer UNIQUE,
name text,
price numeric
);
CREATE TABLE products (
product_no integer,
name text,
price numeric,
UNIQUE (product_no)
);
为表中的多个字段定义联合惟一性。
CREATE TABLE example (
a integer,
b integer,
c integer,
UNIQUE (a, c)
);
为惟一性约束命名。
CREATE TABLE products (
product_no integer CONSTRAINT must_be_different UNIQUE,
name text,
price numeric
);
在插入数据时,空值(NULL)之间被视为不相等的数据,所以对于某一惟一性字段,能够屡次插入空值。然而须要注意的是,这一规则并非被全部数据库都遵照,所以在进行数据库移植时可能会形成必定的麻烦。
5. 主键和外键:
从技术上来说,主键约束只是惟一约束和非空约束的组合。
CREATE TABLE products (
product_no integer PRIMARY KEY, --字段product_no被定义为该表的惟一主键。
name text,
price numeric
);
和惟一性约束同样,主键能够同时做用于多个字段,造成联合主键:
CREATE TABLE example (
a integer,
b integer,
c integer,
PRIMARY KEY (b, c)
);
外键约束声明一个字段(或者一组字段)的数值必须匹配另一个表中某些行出现的数值。 咱们把这个行为称作两个相关表之间的参考完整性。
CREATE TABLE orders (
order_id integer PRIMARY KEY, --该表也能够有本身的主键。
--该表的product_no字段为上面products表主键(product_no)的外键。
product_no integer REFERENCES products(product_no),
quantity integer
);
CREATE TABLE t1 (
a integer PRIMARY KEY,
b integer,
c integer,
--该外键的字段数量和被引用表中主键的数量必须保持一致。
FOREIGN KEY (b, c) REFERENCES example (b, c)
);
当多个表之间存在了主外键的参考性约束关系时,若是想删除被应用表(主键表)中的某行记录,因为该行记录的主键字段值可能正在被其引用表(外键表)中某 条记录所关联,因此删除操做将会失败。若是想完成此操做,一个显而易见的方法是先删除引用表中和该记录关联的行,以后再删除被引用表中的该行记录。然而需 要说明的是,PostgreSQL为咱们提供了更为方便的方式完成此类操做。
CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
);
CREATE TABLE orders (
order_id integer PRIMARY KEY,
shipping_address text
);
CREATE TABLE order_items (
product_no integer REFERENCES products ON DELETE RESTRICT, --限制选项
order_id integer REFERENCES orders ON DELETE CASCADE, --级联删除选项
quantity integer,
PRIMARY KEY (product_no, order_id)
);
限制和级联删除是两种最多见的选项。RESTRICT 禁止删除被引用的行。 NO ACTION 的意思是若是在检查约束的时候,若是还存在任何引用行,则抛出错误; 若是你不声明任何东西,那么它就是缺省的行为。(这两个选择的实际区别是,NO ACTION 容许约束检查推迟到事务的晚些时候,而 RESTRICT 不行。) CASCADE声明在删除一个被引用的行的时候,引用它的行也会被自动删除掉。 在外键字段上的动做还有两个选项: SET NULL 和 SET DEFAULT。 这样会致使在被引用行删除的时候,引用它们的字段分别设置为空或者缺省值。 请注意这些选项并不能让你逃脱被观察和约束的境地。好比,若是一个动做声明 SET DEFAULT,可是缺省值并不能知足外键,那么动做就会失败。相似ON DELETE,还有ON UPDATE 选项,它是在被引用字段修改(更新)的时候调用的。可用的动做是同样的。
2、系统字段:
PostgreSQL的每一个数据表中都包含几个隐含定义的系统字段。所以,这些名字不能用于用户定义的字段名。这些系统字段的功能有些相似于Oracle中的rownum和rowid等。
oid: 行的对象标识符(对象ID)。这个字段只有在建立表的时候使用了WITH OIDS,或者是设置了配置参数default_with_oids时出现。这个字段的类型是oid(和字段同名)。
tableoid: 包含本行的表的OID。这个字段对那些从继承层次中选取的查询特别有用,由于若是没有它的话,咱们就很难说明一行来自哪一个独立的表。tableoid能够和pg_class的oid字段链接起来获取表名字。
xmin: 插入该行版本的事务的标识(事务ID)。
cmin: 在插入事务内部的命令标识(从零开始)。
xmax: 删除事务的标识(事务ID),若是不是被删除的行版本,那么是零。
cmax: 在删除事务内部的命令标识符,或者是零。
ctid: 一个行版本在它所处的表内的物理位置。请注意,尽管ctid能够用于很是快速地定位行版本,但每次VACUUM FULL以后,一个行的ctid都会被更新或者移动。所以ctid是不能做为长期的行标识符的。
OID是32位的量,是在同一个集群内通用的计数器上赋值的。对于一个大型或者长时间使用的数据库,这个计数器是有可能重叠的。所以,假设OID是惟一 的是很是错误的,除非你本身采起了措施来保证它们是惟一的。若是你须要标识表中的行,咱们强烈建议使用序列号生成器。
3、表的修改:
1. 增长字段:
ALTER TABLE products ADD COLUMN description text;
新增的字段对于表中已经存在的行而言最初将先填充所给出的缺省值(若是你没有声明DEFAULT子句,那么缺省是空值)。
在新增字段时,能够同时给该字段指定约束。
ALTER TABLE products ADD COLUMN description text CHECK(description <> '');
2. 删除字段:
ALTER TABLE products DROP COLUMN description;
若是该表为被引用表,该字段为被引用字段,那么上面的删除操做将会失败。若是要想在删除被引用字段的同时级联的删除其全部引用字段,能够采用下面的语法形式。
ALTER TABLE products DROP COLUMN description CASCADE;
3. 增长约束:
ALTER TABLE products ADD CHECK(name <> ''); --增长一个表级约束
ALTER TABLE products ADD CONSTRAINT some_name UNIQUE(product_no);--增长命名的惟一性约束。
ALTER TABLE products ADD FOREIGN KEY(pdt_grp_id) REFERENCES pdt_grps; --增长外键约束。
ALTER TABLE products ALTER COLUMN product_no SET NOT NULL; --增长一个非空约束。
4. 删除约束:
ALTER TABLE products DROP CONSTRAINT some_name;
对于显示命名的约束,能够根据其名称直接删除,对于隐式自动命名的约束,能够经过psql的\d tablename来获取该约束的名字。和删除字段同样,若是你想删除有着被依赖关系地约束,你须要用CASCADE。一个例子是某个外键约束依赖被引用 字段上的惟一约束或者主键约束。如:
MyTest=# \d products
Table "public.products"
Column | Type | Modifiers
------------+---------+-----------
product_no | integer |
name | text |
price | numeric |
Check constraints:
"positive_price" CHECK (price > 0::numeric)
和其余约束不一样的是,非空约束没有名字,所以只能经过下面的方式删除:
ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
5. 改变字段的缺省值:
在为已有字段添加缺省值时,不会影响任何表中现有的数据行, 它只是为未来INSERT命令改变缺省值。
ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;
下面为删除缺省值:
ALTER TABLE products ALTER COLUMN price DROP DEFAULT
6. 修改字段的数据类型:
只有在字段里现有的每一个项均可以用一个隐含的类型转换转换成新的类型时才可能成功。好比当前的数据都是整型,而转换的目标类型为numeric或 varchar,这样的转换通常均可以成功。与此同时,PostgreSQL还将试图把字段的缺省值(若是存在)转换成新的类型, 还有涉及该字段的任何约束。可是这些转换可能失败,或者可能生成奇怪的结果。 在修改某字段类型以前,你最好删除那些约束,而后再把本身手工修改过的添加上去。
ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);
7. 修改字段名:
ALTER TABLE products RENAME COLUMN product_no TO product_number;
8. 修改表名:
ALTER TABLE products RENAME TO items;
4、权限:
只有表的全部者才能修改或者删除表的权限。要赋予一个权限,咱们使用GRANT命令,要撤销一个权限,使用REVOKE命令。
须要指出的是,PUBLIC是特殊"用户"能够用于将权限赋予系统中的每个用户。在声明权限的位置写ALL则将全部的与该对象类型相关的权限都赋予出去。
GRANT UPDATE ON table_name TO user; --将表的更新权限赋予指定的user。
GRANT SELECT ON table_name TO GROUP group; --将表的select权限赋予指定的组。
REVOKE ALL ON table_name FROM PUBLIC; --将表的全部权限从Public撤销。
最初,只有对象全部者(或者超级用户)能够赋予或者撤销对象的权限。可是,咱们能够赋予一个"with grant option"权限,这样就给接授权限的人以授予该权限给其它人的权限。若是授予选项后来被撤销,那么全部那些从这个接受者接受了权限的用户(直接或者经过级连的受权)都将失去该权限。 sql
这里须要特别说明的是,该博客中的大部分案例和段落均取自于PostgreSQL中文文档,如转载本系列博客,请一样注明该出处。 数据库