表空间

 

编辑

表空间是数据库的逻辑划分,一个表空间只能属于一个数据库。所有的 数据库对象都存放在指定的表空间中。但主要存放的是表, 所以称作表空间。



Oracle数据库中至少存在一个表空间,即SYSTEM的表空间。



SQL Server数据库与Oracle数据库之间最大的区别要属表空间设计。Oracle数据库开创性地提出了表空间的设计理念,这为Oracle数据库的高性能做出了不可磨灭的贡献。可以这么说,Oracle中很多优化都是基于表空间的设计理念而实现的。




表空间 外文名  tablespaces 软件类型 数据库 Oracle数据库 优    势 表空间的设计理念 面向领域 服务器



目录



  1. 表空间的典型应用
  2. 建立表空间与建立用户的顺序关系





表空间的典型应用


编辑


典型应用一:控制用户所占用的表空间配额。



在一些大型的数据库应用中,我们需要控制某个用户或者某一组用户其所占用的磁盘空间。这就好像在文件 服务器中,需要为每个用户设置 磁盘配额一样,以防止硬盘空间耗竭。所以,在数据库中,我们也需要限制用户所可以使用的磁盘空间大小。为了达到这个目的,我们就可以通过表空间来实现。



我们可以在Oracle数据库中,建立不同的表空间,为其设置最大的存储容量,然后把用户归属于这个表空间。如此的话,这个用户的存储容量,就受到这个表空间大小的限制。



典型应用二:控制数据库所占用的磁盘空间。



有时候,在Oracle数据库 服务器运行过程中,可能运行不止一个服务。除了 数据库服务器外,可能还有 邮件服务器等应用系统服务器。为此,就需要先对Oracle数据库的磁盘空间作个规划,否则,当多个 应用程序服务所占用的磁盘空间都无限增加时,最后可能导致各个服务都因为硬盘空间的耗竭而停止。所以,在同一台服务器上使用多个应用程序服务时,我们需要先为各个应用服务规划分配磁盘空间,各服务的磁盘空间都不能够超过我们分配的最大限额,或者超过后及时地提醒我们。只有这样,才能够避免因为磁盘空间的耗竭而导致各种应用服务的崩溃。



典型应用三:灵活放置表空间,提高数据库的输入输出性能。



数据库管理员还可以将不同类型的数据放置到不同的表空间中,这样可以明显提高数据库输入输出性能,有利于数据的 备份与恢复等管理工作。因为我们数据库管理员在备份或者恢复数据的时候,可以按表空间来备份数据。如在设计一个大型的 分销系统 后台数据库的时候,我们可以按省份建立表空间。与浙江省相关的数据文件放置在浙江省的表空间中,北京发生业务记录,则记录在北京这个表空间中。如此,当浙江省的业务数据出现错误的时候,则直接还原浙江省的表空间即可。很明显,这样设计,当某个表空间中的数据出现错误需要恢复的时候,可以避免对其他表空间的影响。



另外,还可以对表空间进行独立备份。当数据库容量比较大的时候,若一下子对整个数据库进行 备份,显然会占用比较多的时间。虽然说Oracle数据库支持 热备份,但是在备份期间,会占用比较多的系统资源,从而造成数据库性能的下降。为此,当数据库容量比较大的时候,我们就需要进行设置多个表空间,然后规划各个表空间的备份时间,从而可以提高整个数据库的备份效率,降低备份对于数据库正常运行的影响。



典型应用四:大表的排序操作。



我们都知道,当表中的记录比较多的时候,对他们进行查询,速度会比较慢。第一次查询成功后,若再对其进行第二次重新排序,仍然需要这么多的时间。为此,我们在 数据库设计的时候,针对这种容量比较大的表对象,往往把它放在一个独立的表空间,以提高数据库的性能。



典型应用五:日志文件与数据文件分开放,提高数据库安全性。



默认情况下,日志文件与数据文件存放在同一表空间。但是,这对于 数据库安全方面来说,不是很好。所以,我们在数据库设计的过程中,往往喜欢把日志文件,特别是重要日志文件,放在一个独立的表空间中,然后把它存放在另外一块硬盘上。如此的话,当存放数据文件的硬盘出现故障时,能够马上通过存放在另一个表空间的重做日志文件,对数据库进行修复,以减少企业因为数据丢失所带来的损失。



当然,表空间的优势还不仅仅这些,企业对于数据库的性能要求越高,或者数据库容量越大,则表空间的优势就会越大。





建立表空间与建立用户的顺序关系


编辑


数据库设计的时候,我们建议 数据库管理员按如下顺序设置表空间。



第一步:建立表空间。



在设计数据库的时候,首先需要设计表空间。我们需要考虑,是只建立一个表空间呢,还是需要建立多个表空间,以及各个表空间的存放位置、 磁盘限额等等。



到底设计多少个表空间合理,没有统一的说法,这主要根据企业的实际需求去判断。如企业需要对用户进行磁盘限额控制的,则就需要根据用户的数量来设置表空间。当企业的数据容量比较大,而其又对数据库的性能有比较高的要求时,就需要根据不同类型的数据,设置不同的表空间,以提高其输入输出性能。



第二步:建立用户,并制定用户的默认表空间。



在建立用户的时候,我们建议 数据库管理员要指定用户的默认表空间。因为我们在利用CREATE语句创建 数据库对象,如数据库表的时候,其默认是存储在数据库的当前默认空间。若不指定用户默认表空间的话,则用户每次创建数据库对象的时候,都要指定表空间,显然,这不是很合理。



另外要注意,不同的表空间有不同的权限控制。用户对于表空间A具有完全控制权限,可能对于表空间B就只有查询权限,甚至连连接的权限的都没有。所以,合理为用户配置表空间的访问权限,也是提高数据库安全性的一个方法。



 

客户要求用pgsql,所在服务器装了一下pgsql,我出了一个pgsql的分类,看这篇文章前,把这个分类下的文章都可以看一下,这是我熟悉pgsql的一套流程。以前搞过一次pgsql,很早了。


1,查看数据库



查看 复制 打印 ?

1. playboy=> \l                       //\加上字母l,相当于mysql的,mysql> show databases;  
2.         List of databases  
3.    Name    |  Owner   | Encoding  
4. -----------+----------+----------  
5.  playboy   | postgres | UTF8  
6.  postgres  | postgres | UTF8  
7.  template0 | postgres | UTF8  
8.  template1 | postgres | UTF8  
9.   
10. playboy=> select pg_database_size('playboy');    //查看playboy数据库的大小  
11.  pg_database_size  
12. ------------------  
13.           3637896  
14. (1 row)  
15.   
16. playboy=> select pg_database.datname, pg_database_size(pg_database.datname) AS size from pg_database;    //查看所有数据库的大小  
17.   datname  |  size  
18. -----------+---------  
19.  postgres  | 3621512  
20.  playboy   | 3637896  
21.  template1 | 3563524  
22.  template0 | 3563524  
23. (4 rows)  
24.   
25. playboy=> select pg_size_pretty(pg_database_size('playboy'));      //以KB,MB,GB的方式来查看数据库大小  
26.  pg_size_pretty  
27. ----------------  
28.  3553 kB  
29. (1 row)


2,查看多表



查看 复制 打印 ?

1. playboy=> \dt                      //相当于mysql的,mysql> show tables;  
2.         List of relations  
3.  Schema | Name | Type  |  Owner  
4. --------+------+-------+---------  
5. public | test | table | playboy  
6. (1 row)


3,查看单表



查看 复制 打印 ?

1. playboy=> \d test;                 //相当于mysql的,mysql> desc test;  
2. "public.test"  
3.  Column |         Type          | Modifiers  
4. --------+-----------------------+-----------  
5.  id     | integer               | not null  
6.  name   | character varying(32) |  
7. Indexes: "playboy_id_pk" PRIMARY KEY, btree (id)  
8.   
9. playboy=> select pg_relation_size('test');   //查看表大小  
10.  pg_relation_size  
11. ------------------  
12.                 0  
13. (1 row)  
14.   
15. playboy=> select pg_size_pretty(pg_relation_size('test'));   //以KB,MB,GB的方式来查看表大小  
16.  pg_size_pretty  
17. ----------------  
18.  0 bytes  
19. (1 row)  
20.   
21. playboy=> select pg_size_pretty(pg_total_relation_size('test'));   //查看表的总大小,包括索引大小  
22.  pg_size_pretty  
23. ----------------  
24.  8192 bytes  
25. (1 row)


4,查看索引


查看 复制 打印 ?

1. playboy=> \di                      //相当于mysql的,mysql> show index from test;  
2.                 List of relations  
3.  Schema |     Name      | Type  |  Owner  | Table  
4. --------+---------------+-------+---------+-------  
5. public | playboy_id_pk | index | playboy | test  
6. (1 row)  
7.   
8. playboy=> select pg_size_pretty(pg_relation_size('playboy_id_pk'));    //查看索大小  
9.  pg_size_pretty  
10. ----------------  
11.  8192 bytes  
12. (1 row)


5,查看表空间,以及大小


查看 复制 打印 ?


1. playboy=> select spcname from pg_tablespace;         //查看所有表空间  
2.   spcname  
3. ------------  
4.  pg_default  
5.  pg_global  
6. (2 rows)  
7.   
8. playboy=> select pg_size_pretty(pg_tablespace_size('pg_default'));   //查看表空间大小  
9.  pg_size_pretty  
10. ----------------  
11.  14 MB  
12. (1 row)

在数据库运维工作中,经常会有数据目录使用率较高需要调整的情况,通常会给数据库建立多个表空间,
并分别位于不同的盘上,这时需要做的工作就是调整库中现有表和索引的表空间,下面简单总结下这块维护
工作的内容,以下都是基于 PostgreSQL 9.0.1 做的测试。

一  查询某个表所在表空间的简单方法   
     PostgreSQL 提供类似" \ "命令很方便得到相关信息,命令如下:

skytf=> \d test_2
             Table "skytf.test_2"
  Column |         Type          | Modifiers 
 --------+-----------------------+-----------
  id     | integer               | 
  obj_id | integer               | not null
  name   | character varying(64) | 
 Indexes:
     "idx_hash_name" hash (name)
     "idx_test_2" btree (id, obj_id)
Tablespace: "tbs_skytf_idx"

   备注:如果这个表的表空间为当前数据库的默认表空间,那么上面则不会显示 Tablespace 信息,
             相反,则会显示这张有的表空间,例如上面的表 test_2 的表空间为 tbs_skytf_idx,而
            表空间 "tbs_skytf_idx" 不是数据库 skytf 的默认表空间, 那么如何查询数据库的默认
             表空间呢,可以通过以下命令查询。
         
         
--1.1 查询数据库的默认表空间         

skytf=> select datname,dattablespace from pg_database where datname='skytf';
  datname | dattablespace 
 ---------+---------------
  skytf   |      14203070
 (1 row)skytf=> select oid,spcname from pg_tablespace where oid=14203070;
    oid    |  spcname  
 ----------+-----------
  14203070 | tbs_skytf
 (1 row)

     

   备注:通过以上查出数据库 skytf 的默认表空间为  tbs_skytf。

    
二 批量查询数据库表和索引的表空间--2.1 查询表和索引所在的表空间select relname, relkind, relpages,pg_size_pretty(pg_relation_size(a.oid)), tb.spcname

from pg_class a, pg_tablespace tb
  where a.reltablespace = tb.oid
    and a.relkind in ('r', 'i')
  order by a.relpages desc;




 
  
 备注:上面只取了部分结果,这个查询能够查询表和索引所处的表空间,但是有一点需要注意,这个查询
           仅显示表空间不是数据库默认表空间的数据库对像,而我们通常需要查出位于数据库默认表空间的
           对像,显然上面的查询不是我们想要的,接下来看另一个查询。

--2.2 查询位于默认数据库表空间的对像select relname, relkind, relpages,pg_size_pretty(pg_relation_size(a.oid)),reltablespace,relowner

from pg_class a
 where a.relkind in ('r', 'i')
and reltablespace='0' order by a.relpages desc;

                   

   备注:这个查询加入限制条件 reltablespace='0',即可查找出位于当前数据库默认表空间的

             数据库表和索引。 通常这才是我们想要的结果,接下来可以把部分表转移到其它表空间上去,转移

             的方法可以用 " ALTER TABLE table name move tablespace   tablespace_name"或者重建索引移表空间等方法,这里不详细介绍。

 


--2.3 查询在某个表空间上的对像

select relname, relkind, relpages,pg_size_pretty(pg_relation_size(a.oid)),reltablespace,relowner
 from pg_class a, pg_tablespace tb 
 where a.relkind in ('r', 'i')
 and a.reltablespace=tb.oid
 and tb.spcname='tablespace_name'
 order by a.relpages desc;

 

--2.4 手册上对于 pgclass 视图的 reltablespace 字段解释     The tablespace in which this relation is stored. If zero, the database is default tablespace is 

implied. (Not meaningful if the relation has no on-disk file.) 

 

select pg_database.datname, pg_database_size(pg_database.datname) AS size from pg_database;    //查看所有数据库的大小