Oracle 11g Concepts 笔记2:什么是唯一、非唯一索引及索引分类

从Oracle索引的特征上,我们可以简单的把索引分为Unique Indexes and Nonunique Indexes,即唯一索引和非唯一索引。

1      对于唯一索引,唯一索引确保被索引的字段或多个联合字段在表中绝对不会有重复值;通常,我们在建表时,创建唯一约束或者主键约束,再或者建表以后给表添加唯一、主键约束时,Oracle会自动在主键、唯一约束的字段上创建唯一索引,并且索引的名字跟约束的名字一样,如:

SQL> create table tt(id1 number primary key,id2 number,id3 number);
Table created.
SQL> select index_name,table_name,uniqueness from user_indexes where table_name='TT';
INDEX_NAME                     TABLE_NAME                     UNIQUENESS
------------------------------ ------------------------------ ----------
SYS_C0015420                   TT                             UNIQUE
SQL> select table_name,constraint_name,index_name,constraint_type
2  from user_constraints
3  where table_name='TT';
TABLE_NAME     CONSTRAINT_NAME  INDEX_NAME    CONSTRAINT_TYPE
-------------- ---------------- ------------- ---------------
TT             SYS_C0015420     SYS_C0015420  P

我们在建测试表tt时在id1字段上创建了一个主键约束,当然该约束名字SYS_C0015420是Oracle自动分配给我们的,同时我们也看到tt表上有1个名为SYS_C0015420的索引。
接下来,在id2字段上添加一个唯一约束,并且手动指定名字:

SQL> alter table tt add constraint tt_id2_uk unique(id2);
Table altered.
SQL> select table_name,constraint_name,index_name,constraint_type
2  from user_constraints
3  where table_name='TT';
TABLE_NAME                     CONSTRAINT_NAME                INDEX_NAME                     C
------------------------------ ------------------------------ ------------------------------ -
TT                             SYS_C0015420                   SYS_C0015420                   P
TT                             TT_ID2_UK                      TT_ID2_UK                      U
SQL>  select index_name,table_name,uniqueness from user_indexes where table_name='TT';
INDEX_NAME                     TABLE_NAME                     UNIQUENES
------------------------------ ------------------------------ ---------
TT_ID2_UK                      TT                             UNIQUE
SYS_C0015420                   TT                             UNIQUE
SQL>

我们发现,这tt表上的两个索引都是唯一索引,且名字都等同于各自对应的约束名字。
然后,在该表上创建一个索引:

SQL> create index idx_tt_id3 on tt(id3);
Index created.
SQL> select index_name,table_name,uniqueness from user_indexes where table_name='TT';
INDEX_NAME                     TABLE_NAME                     UNIQUENES
------------------------------ ------------------------------ ---------
IDX_TT_ID3                     TT                             NONUNIQUE
TT_ID2_UK                      TT                             UNIQUE
SYS_C0015420                   TT                             UNIQUE
SQL>

此时,发现该索引IDX_TT_ID3是一个非唯一索引,我们也可以使用create unique index…语句显示创建一个唯一索引。
就唯一索引存储而言,每一个rowid会唯一对应表中的一条记录,在索引的叶子块儿中,数据按照索引字段升序存放。
2     对于非唯一索引,允许被索引的字段有重复值。并且,非唯一索引的存放有别于唯一索引,它的数据在索引叶子块儿中是按照索引字段和rowid进行升序存放的。
3    在Oracle数据库中,索引分类有以下几种:

  • B树索引 B-tree indexes;B树索引又可分为以下子类:
    • 索引组织表Index-organized tables
    • 反转索引Reverse key indexes
    • 降序索引Descending indexes
    • B树聚簇索引B-tree cluster indexes
  • 位图和位图联合索引Bitmap and bitmap join indexes
  • 基于函数的索引Function-based indexes
  • 应用域索引Application domain indexes

4    关于Oracle的索引还有更多知识需要了解和探索,下篇继续,To Be Continued…

WordPress恢复及建站记

前段时间,经过几番折腾终于将个人Blog,OracleOnLinux.cn从以前的备份数据中完全恢复过来,历经将长达半年的临时无法访问后,终于可以正常访问了。 工作之余,抽点儿时间简单记录这次恢复经过及Blog建站过程。 首先记录建站过程: 2008年10月3日花1元RMB,以个人名义成功在紫田网络注册域名 www.OracleOnLinux.cn,至今一直生效,并准备长期使用下去; 2009年10月9日,在好友Jia GuoQing免费提供空间及相关技术的大力支持下,成功搭建WordPress个人Blog,第一篇系统日志Hello World面世,此时离域名生效日期已经1年有余; 期间,由于个人懒惰+不勤奋+不坚持等种种原因,博客更新频率颇低,站点流量徘徊不前; 2011年5月25日,在空间服务器崩溃前发表最后一篇博文:记一次10g RAC收缩表空间; 之后的某一天,国庆兄告之我,空间服务器硬盘故障,导致数据丢失,好在之前用PHPMyAdmin对后台的MySQL数据库做了一次完全备份,生成了一份SQL的dump文件,身为Oracle DBA的我想,只要有有效的备份,恢复起来应该不难; 2011年6月,忙碌,顾不得恢复博客,博客无法访问; 2011年7月,兼职,依然没心思恢复,继续无法访问; 2011年8月,懒惰,更懒得理博客,还是无法访问; 2011年9月,借口,不想恢复,博客访问不了; 2011年10月,NND,还有什么借口和推辞,实在说不下去忍不下去看不过去了,就向国庆兄拿到了当初备份的文件,是一份采用gzip压缩过的压缩包文件alldata.sql.gz,使用gunzip alldata.sql.gz 解压缩该备份文件,并尝试单独恢复数据库; 然后,分享这次恢复过程中遇到的问题及解决方法: 1备份文件过大,包含当时所有后台其它数据库,gunzip解压之后的alldata.sql SQL文本文件信息如下:

[root@oracle11g ~]# ll -h

total 1.2G

drwxr-xr-x 4 root root 4.0K Aug 18 09:42 10gRAC_Media

drwxr-xr-x 7 root root 4.0K Sep 30 15:57 11gRAC_Media

-rw-r--r-- 1 root root 1.2G Oct 18 13:38 alldata.sql

-rw------- 1 root root 1.4K Jan 27  2011 anaconda-ks.cfg

drwxr-xr-x 3 root root 4.0K Jan 29  2011 asm

drwxr-xr-x 2 root root 4.0K Jan 27  2011 Desktop

-rw-r--r-- 1 root root  37K Jan 27  2011 install.log

-rw-r--r-- 1 root root 3.6K Jan 27  2011 install.log.syslog

drwxr-xr-x 3 root root 4.0K Jan 29  2011 linux_image

[root@oracle11g ~]# wc -l alldata.sql

2930681 alldata.sql

[root@oracle11g ~]# wc alldata.sql

2930681   86537367 1194843806 alldata.sql

[root@oracle11g ~]#

备份文件达到1.2GB,计2930681行,要从一个这样的将近300万行的文件中恢复数据,让我何从下手,情何以堪呢?

[root@oracle11g ~]# ll -h
total 1.2G
drwxr-xr-x 4 root root 4.0K Aug 18 09:42 10gRAC_Media
drwxr-xr-x 7 root root 4.0K Sep 30 15:57 11gRAC_Media
-rw-r–r– 1 root root 1.2G Oct 18 13:38 alldata.sql
-rw——- 1 root root 1.4K Jan 27  2011 anaconda-ks.cfg
drwxr-xr-x 3 root root 4.0K Jan 29  2011 asm
drwxr-xr-x 2 root root 4.0K Jan 27  2011 Desktop
-rw-r–r– 1 root root  37K Jan 27  2011 install.log
-rw-r–r– 1 root root 3.6K Jan 27  2011 install.log.syslog
drwxr-xr-x 3 root root 4.0K Jan 29  2011 linux_image
[root@oracle11g ~]# wc -l alldata.sql
2930681 alldata.sql

2考虑采用SQLyog Enterprise这个MySQL GUI工具直接在本地恢复数据库,因为该图形工具提供一个直接从SQL Dump文件中恢复数据库的功能,的确好用; 3上述工作进行的还算顺利,可是恢复到MySQL自带的系统数据库information_schema时就报错,最为要命的是我blog用到的名为linuxor这个数据库还没恢复出来,该怎么办呢? 4怎么才能让MySQL GUI工具跳过系统自带的数据库information_schema,或者直接让MySQL GUI工具只恢复我所需要的linuxor这个数据库岂不更简单?于是,欲用Vim直接编辑这个大文件…… 5尝试使用Vim编辑器或其它文本编辑器编辑这个硕大的近300万行的文件时均无任何结果时,不得已,见招拆招考虑通过从解压缩出来的原始备份文件alldata.sql中抽取linuxor这个数据库相关的备份信息,如果能顺利抽取出来的话,那么我想,单独恢复linuxor这个数据库就不成问题了; 6接下来,使用split命令在Unix、Linux平台下拆分alldata.sql文件,我当时使用的命令如下,具体用法可自行Google之:

[root@oracle11g ~]# split -500000 alldata.sql

[root@oracle11g ~]# ll -h

total 1.8G

drwxr-xr-x 4 root root 4.0K Aug 18 09:42 10gRAC_Media

drwxr-xr-x 7 root root 4.0K Sep 30 15:57 11gRAC_Media

-rw-r--r-- 1 root root 1.2G Oct 18 13:38 alldata.sql

-rw------- 1 root root 1.4K Jan 27  2011 anaconda-ks.cfg

drwxr-xr-x 3 root root 4.0K Jan 29  2011 asm

drwxr-xr-x 2 root root 4.0K Jan 27  2011 Desktop

-rw-r--r-- 1 root root  37K Jan 27  2011 install.log

-rw-r--r-- 1 root root 3.6K Jan 27  2011 install.log.syslog

drwxr-xr-x 3 root root 4.0K Jan 29  2011 linux_image

-rw-r--r-- 1 root root 111M Nov  1 16:36 xaa

-rw-r--r-- 1 root root 107M Nov  1 16:37 xab

-rw-r--r-- 1 root root 454M Nov  1 16:44 xac

-rw-r--r-- 1 root root  90M Nov  1 16:45 xad

-rw-r--r-- 1 root root 227M Nov  1 16:47 xae

-rw-r--r-- 1 root root 153M Nov  1 16:47 xaf

[root@oracle11g ~]#

该命令可将alldata.sql文本文件拆分成每个500000行的小文本文件,考虑到备份文件接近300万行,这样,就会生成6个xaa、xab、xac、xad、xae、xaf相对较小的文件。 7然后,使用grep命令从每个拆分出来的小文件中过滤'CREATE DATABASE `linuxor`',前提是我的确知道该备份文件中,肯定只有一个名为linuxor的数据库;

[root@oracle11g ~]# grep 'CREATE DATABASE `linuxor`' xaa

[root@oracle11g ~]# grep 'CREATE DATABASE `linuxor`' xab

[root@oracle11g ~]# grep 'CREATE DATABASE `linuxor`' xac

[root@oracle11g ~]# grep 'CREATE DATABASE `linuxor`' xad

[root@oracle11g ~]# grep 'CREATE DATABASE `linuxor`' xae

CREATE DATABASE `linuxor` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

[root@oracle11g ~]# grep 'CREATE DATABASE `linuxor`' xaf

8定位到xae这个拆分文件里包含'CREATE DATABASE `linuxor`'关键字且其它几个拆分文件xaa、xab、xac、xad、xaf中均无'CREATE DATABASE `linuxor`'关键字相关信息后,就基本可以断定出我需要的linuxor的数据库信息就只位于xae该文件中了; 9在确定了xae文件后,就可以直接使用Vim编辑器编辑这个文件了,掐头去尾一番后,xae这个文件中只剩下linuxor这个数据库的备份信息了;

[root@oracle11g ~]# wc -l xae

4954 xae

正是这个仅仅只有4954行的文件才是我真正想要的啊!!! 10最后重命名xae为xae.sql文件,在MySQL GUI工具中,导入我的xae.sql文件,并且无任何错误后,至此,后台数据库完全恢复成功!!!!

Enter password: ******

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 14

Server version: 5.1.58-community MySQL Community Server (GPL)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

This software comes with ABSOLUTELY NO WARRANTY. This is free software,

and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| linuxor            |

| mysql              |

| test               |

+--------------------+

4 rows in set (0.00 sec)

mysql>

11接下来,做一些收尾工作,将xae.sql上传到空间服务器。创建MySQL数据库,安装配置WordPress,然后在PHPMyAdmin中删除WordPress数据库中的所有表,并重新将xae.sql中的数据导入数据库中。这样一来,我所有以前的blog内容尽收眼底全部找回,万岁! 后记: 1当初注册OracleOnLinux.cn这个域名时,是希望通过写Blog的形式督促自己把学习、工作中遇到的关于Linux上的Oracle相关的案例记录下来,一来可以鞭策自己,二来可以同大家分享知识,分享快乐。现在,看来自己做得不够好,需要戒除懒惰的恶习,勤能补拙,多读书多写多思考,最重要的是要分享; 2从这次Blog数据库的恢复经历可以看出来,对于任何情况下的重要数据库都应该备份,否则无从恢复,没有有效的备份,任何DBA都只能有心无力回天乏术了; 3如果广大网友对WordPress搭建博客有兴趣或需要帮助的话,可及时回复评论与我沟通,具体联系方式可以查看About页面,同时感谢大家光临本站点;