作为数据库的开发者,我们经常面临着要找出及删除数据库中冗余数据的任务,如果数据库中有大量的冗余数据(占总数的百分比太多),数据的精确性和可靠性将受到影响,同时也影响着数据库的性能,那么如何解决这个问题呢?下面我将探讨关于这个问题的这个解决方案,oracle也为我们提供了一个解决方案,但是Oracle提供的解决方案不够完美,遇到大批量数据那个解决方案工作起来很慢
应该怎么删除冗余数据呢?
在这里我们应用一个PL/SQl方案(一个自定义的存储过程)或者一个SQL语句的解决方案(使用一个分析的函数RANK()和一个嵌套的子查询)来消除冗余数据然后控制应该保留的记录
什么是冗余数据?
冗余数据就是一个数据表中,这个表中的行包含了一些相同的值,这些值理论上来说应该是唯一的(这些值一般来说能确定一条记录)例如,像社会保险号,姓与名的集合.那么我们把这么含有相同信息的行中包含的数据叫做冗余数据,现在所有的数据库表中都有主键约束,主键中记录了一行记录中的唯一值,从数据库的角度来看,每一行都是唯一的,但是从我们用户角度看来,这些记录都是相同的记录,因为它们都包含相同的键值(First Name + Last Name),即使他们有不同的主键
ID Last Name First Name City Phone
---- --------------- ---------- --------------- ----------
1005 Krieger Jeff San Ramon 9252997100
1012 Krieger Jeff San Ramon 9252997100
1017 Krieger Jeff San Ramon 9252997100
那么这些冗余数据是怎么出现的那?通常有两种情况:1.从不同的表中加载或者合并数据
通过图形化的用户接口来输入数据,然后由计算机来生成一个唯一的键,并做为这一条记录的主键
那么怎样找到冗余数据呢?让我们来创建一个叫作Customer 的表并向其中加入冗余数据,看表1,正如你所看到的,我们并没有在这个表上做什么限制来防止冗余数据,下面这么代码创建了一个唯一约束,来防止冗余数据的生成
SQL
Listing 1. 创建Customer表
这个表中我们故意加入了冗余数据
DROP TABLE Customers CASCADE CONSTRAINTS;
CREATE TABLE Customers(
Id INTEGER NOT NULL,
LastName VARCHAR2(15) NOT NULL,
FirstName VARCHAR2(10),
Address VARCHAR2(20),
City VARCHAR2(15),
State CHAR(2),
Zip VARCHAR2(10),
Phone VARCHAR2(10),
RecDate DATE,
CONSTRAINT Customers_PK
PRIMARY KEY (ID))
TABLESPACE TALLYDATA;
INSERT INTO Customers
VALUES (1000, 'Bradley', 'Tom', '2450 3rd Str. #12',
'San Francisco', 'CA', '94114', '4156679230',
TO_DATE('01-JAN-2000', 'DD-MON-YYYY'));
INSERT INTO Customers
VALUES (1001, 'Stone', 'Tony', '12 Main St. Apt. 3',
'Oakland', 'CA', '94342', '5104562881',
TO_DATE('12-MAR-2001', 'DD-MON-YYYY'));
INSERT INTO Customers
VALUES (1002, 'Chang', 'Jim', '425 26th Ave.',
'Seattle', 'WA', '98103', '8182454400',
TO_DATE('15-JUN-2000', 'DD-MON-YYYY'));
INSERT INTO Customers
VALUES (1003, 'Loney', 'Julie', '12 Keith St.',
'Castro Valley', 'CA', '94546', '5103300721',
TO_DATE('22-NOV-2000', 'DD-MON-YYYY'));
INSERT INTO Customers
VALUES (1004, 'King', 'Chuck', '100 Broadway St.',
&nb