mysql怎么消除冗余,mysql數(shù)據(jù)冗余

SQL中的數(shù)據(jù)冗余的最佳解決方法是什么?

數(shù)據(jù)應(yīng)該盡可能少地冗余,這意味著重復(fù)數(shù)據(jù)應(yīng)該減少到最少。比如說,一個(gè)部門雇員的電話不應(yīng)該被存儲(chǔ)在不同的表中, 因?yàn)檫@里的電話號(hào)碼是雇員的一個(gè)屬性。如果存在過多的冗余數(shù)據(jù),這就意味著要占用了更多的物理空間,同時(shí)也對(duì)數(shù)據(jù)的維護(hù)和一致性檢查帶來了問題,當(dāng)這個(gè)員工的電話號(hào)碼變化時(shí),冗余數(shù)據(jù)會(huì)導(dǎo)致對(duì)多個(gè)表的更新動(dòng)作,如果有一個(gè)表不幸被忽略了,那么就可能導(dǎo)致數(shù)據(jù)的不一致性。 從一范式轉(zhuǎn)化到二范式根據(jù)第二范式的定義,轉(zhuǎn)化為二范式就是消除部分依賴??疾毂?-1,我們可以發(fā)現(xiàn),非主屬性Project Name部分依賴于主鍵中的Project Number; 非主屬性Employee Name,Salary Category和Salary package都部分依賴于主鍵中的Employee Number;表1-1的形式,存在著以下潛在問題:1. 數(shù)據(jù)冗余:每一個(gè)字段都有值重復(fù);2. 更新異常:比如Project Name字段的值,比如對(duì)值"TPMS"了修改,那么就要一次更新該字段的多個(gè)值;3. 插入異常:如果新建了一個(gè)Project,名字為TPT, 但是還沒有Employee加入,那么Employee Number將會(huì)空缺,而該字段是主鍵的一部分,因此將無法插入記錄;Insert into SAMPLE(PRJNUM, PRJNAME, EMYNUM, EMYNAME, SALCATEGORY, SALPACKAGE) values(100003, 'TPT', NULL, NULL, NULL, NULL)

創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站制作、網(wǎng)站建設(shè)與策劃設(shè)計(jì),正安網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:正安等地區(qū)。正安做網(wǎng)站價(jià)格咨詢:18982081108

4. 刪除異常:如果一個(gè)員工 200003, Kevin 離職了,要將該員工的記錄從表中刪除,而此時(shí)相關(guān)的Salary信息 C 也將丟失, 因?yàn)樵贈(zèng)]有別的行紀(jì)錄下 Salary C的信息。Delete from sample where EMYNUM = 200003

Select distinct SALCATEGORY, SALPACKAGE from SAMPLE因此,我們需要將存在部分依賴關(guān)系的主屬性和非主屬性從滿足第一范式的表中分離出來,形成一張新的表,而新表和舊表之間是一對(duì)多的關(guān)系。由此,我們得到:

CREATE TABLE "PROJECT" ( "PRJNUM" INTEGER NOT NULL, "PRJNAME" VARCHAR(200)) IN "USERSPACE1";ALTER TABLE "PROJECT" ADD PRIMARY KEY ("PRJNUM");Insert into PROJECT(PRJNUM, PRJNAME) values(100001, 'TPMS'), (100002, 'TCT');

表1-2

表 1-3

CREATE TABLE "EMPLOYEE" ( "EMYNUM" INTEGER NOT NULL, "EMYNAME" VARCHAR(200), "SALCATEGORY" CHAR(1), "SALPACKAGE" INTEGER) IN "USERSPACE1";ALTER TABLE "EMPLOYEE" ADD PRIMARY KEY ("EMYNUM");Insert into EMPLOYEE(EMYNUM, EMYNAME, SALCATEGORY, SALPACKAGE) values(200001,'Johnson', 'A', 2000), (200002, 'Christine', 'B', 3000), (200003, 'Kevin', 'C',4000), (200004, 'Apple', 'B', 3000);Employee Number Employee Name Salary Category Salary Package200001 Johnson A 2000200002 Christine B 3000200003 Kevin C 4000200004 Apple B 3000

CREATE TABLE "PRJ_EMY" ( "PRJNUM" INTEGER NOT NULL, "EMYNUM" INTEGER NOT NULL) IN "USERSPACE1";ALTER TABLE "PRJ_EMY" ADD PRIMARY KEY ("PRJNUM", "EMYNUM");Insert into PRJ_EMY(PRJNUM, EMYNUM) values(100001, 200001), (100001, 200002),(100001, 200003), (100002, 200001), (100002, 200004);

同時(shí),我們把表1-1的主鍵,也就是表1-2和表1-3的各自的主鍵提取出來,單獨(dú)形成一張表,來表明表1-2和表1-3之間的關(guān)聯(lián)關(guān)系:

表 1-4

這時(shí)候我們仔細(xì)觀察一下表1-2, 1-3, 1-4, 我們發(fā)現(xiàn)插入異常已經(jīng)不存在了,當(dāng)我們引入一個(gè)新的項(xiàng)目 TPT 的時(shí)候,我們只需要向表1-2 中插入一條數(shù)據(jù)就可以了, 當(dāng)有新人加入項(xiàng)目 TPT 的時(shí)候,我們需要向表1-3, 1-4 中各插入一條數(shù)據(jù)就可以了。雖然我們解決了一個(gè)大問題,但是仔細(xì)觀察我們還是發(fā)現(xiàn)有問題存在。

回頁首

從二范式轉(zhuǎn)化到三范式考察表前面生成的三張表,我們發(fā)現(xiàn),表1-3存在傳遞依賴關(guān)系,即:關(guān)鍵字段 Employee Number -- 非關(guān)鍵字段 Salary Category --非關(guān)鍵字段 Salary Package 。而這是不滿足三范式的規(guī)則的,存在以下的不足:1、 數(shù)據(jù)冗余:Salary Category和Salary Package的值有重復(fù);2、 更新異常:有重復(fù)的冗余信息,修改時(shí)需要同時(shí)修改多條記錄,否則會(huì)出現(xiàn)數(shù)據(jù)不一致的情況;3、 刪除異常:同樣的,如果員工 200003 Kevin 離開了公司,會(huì)直接導(dǎo)致 Salary C 的信息的丟失。Delete from EMPLOYEE where EMYNUM = 200003

Select distinct SALCATEGORY, SALPACKAGE from EMPLOYEE因此,我們需要繼續(xù)進(jìn)行規(guī)范化的過程,把表1-3拆開,我們得到:

表 1-5

表 1-6

這時(shí)候如果 200003 Kevin 離開公司,我們只需要從表 1-5 中刪除他就可以了, 存在于表1-6中的Salary C信息并不會(huì)丟失。但是我們要注意到除了表 1-5 中存在 Kevin 的信息之外, 表1-4中也存在 Kevin 的信息, 這很容易理解, 因?yàn)?Kevin 參與了項(xiàng)目 100001, TPMS, 所以當(dāng)然也要從中刪除。 至此,我們將表1-1經(jīng)過規(guī)范化步驟,得到四張表,滿足了三范式的約束要求,數(shù)據(jù)冗余、更新異常、插入異常和刪除異常。在三范式之上,還存在著更為嚴(yán)格約束的BC范式和四范式,但是這兩種形式在商業(yè)應(yīng)用中很少用到,在絕大多數(shù)情況下,三范式已經(jīng)滿足了數(shù)據(jù)庫表規(guī)范化的要求,有效地解決了數(shù)據(jù)冗余和維護(hù)操作的異常問題。

什么是數(shù)據(jù)庫中的數(shù)據(jù)冗余?如何消除數(shù)據(jù)冗余?

學(xué)號(hào)

姓名

課程名

成績

001

張三

數(shù)學(xué)

90

001

張三

語文

91

002

李四

數(shù)學(xué)

90

002

李四

語文

91

這樣的表稱為有數(shù)據(jù)冗余

我們常常把這樣的表分為兩個(gè)表,如:

表1

學(xué)號(hào)

姓名

001

張三

002

李四

表2

學(xué)號(hào)

課程名

成績

001

數(shù)學(xué)

90

001

語文

91

002

數(shù)學(xué)

90

002

語文

91

這樣處理后既可滿足數(shù)據(jù)的第二范式要求,當(dāng)然還不是最好的。通過關(guān)系模式的范式可以消除數(shù)據(jù)冗余,基本的數(shù)據(jù)庫應(yīng)滿足第三范式(3NF)。

看看數(shù)據(jù)庫的“范式”內(nèi)容

你就更好理解了。

數(shù)據(jù)庫冗余怎么辦

它將冗余數(shù)據(jù)選擇到一個(gè)游標(biāo)中,并根據(jù)(LastName,F(xiàn)irstName)來分組(在我們這個(gè)方案中),然后打開游標(biāo)然后循環(huán)地取出每一行,然后用與先前的取出的鍵值進(jìn)行比較,如果這是第一次取出這個(gè)值,或者這個(gè)值不是冗余鍵,那么跳過這個(gè)記錄然后取下一個(gè),不然的話,這就是這個(gè)組中的冗余記錄,所以刪掉它.

讓我們運(yùn)行一下這個(gè)存儲(chǔ)過程

BEGIN

DeleteDuplicates;

END;

/

SELECT LastName, FirstName, COUNT(*)

FROM Customers

GROUP BY LastName, FirstName

HAVING COUNT(*) 1;

最后一個(gè)查詢語句沒有返回值,所以冗余數(shù)據(jù)沒有了從表中取冗余數(shù)據(jù)的過程完全是由定義在csr_Duplicates 這個(gè)游標(biāo)中的SQL語句來實(shí)現(xiàn)的,PL/SQl只是用來實(shí)現(xiàn)刪除冗余數(shù),那么能不能完全用SQL語句來實(shí)現(xiàn)呢?

二.SQL解決方案,使用RANK()刪除冗余數(shù)據(jù)Oracle8i分析函數(shù)RANK()來枚舉每一個(gè)組中的元素,在我們的方案中, 我們應(yīng)用這個(gè)方案,我們使用這個(gè)函數(shù)動(dòng)態(tài)的把冗余數(shù)據(jù)連續(xù)的排列起來加上編號(hào),組由Partintion by 這個(gè)語句來分開,然后用Order by 進(jìn)行分組SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,

FirstName ORDER BY ID) SeqNumber

FROM Customers

ORDER BY LastName, FirstName;

SQL

Listing 7. Output of single SQL statement that uses RANK()

顯示的是根據(jù)記錄的條數(shù)的個(gè)數(shù)來顯示尤其對(duì)于冗余數(shù)據(jù)

ID LASTNAME FIRSTNAME SEQNUMBER

----- --------------- ---------- ----------

1018 Blake Becky 1

1013 Blue Don 1

1000 Bradley Tom 1

1002 Chang Jim 1

1008 Griffith David 1

1020 Hill Larry 1

1004 King Chuck 1

1005 Krieger Jeff 1

1012 Krieger Jeff 2

1017 Krieger Jeff 3

1003 Loney Julie 1

1007 Lord Don 1

1015 Mason Paul 1

1006 Monroe John 1

1009 Simon Michael 1

1010 Simon Michael 2

1001 Stone Tony 1

1011 Stone Tony 2

1014 Stone Tony 3

1016 Stone Tony 4

1019 Stone Tony 5

我們可以看一到,SeqNumber這一列中的數(shù)值,冗余數(shù)據(jù)是根據(jù)ID號(hào)由小到大進(jìn)行的排序,所有的冗余數(shù)據(jù)的SqlNumber都大于一,所有的非冗余數(shù)據(jù)都等于一,所以我們?nèi)∽约核?,刪除那么沒用的SELECT ID, LastName, FirstName

FROM

(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,

FirstName ORDER BY ID) AS SeqNumber

FROM Customers)

WHERE SeqNumber 1;

SQL

Listing 8. 冗余鍵的鍵值

有七行必須被刪除

ID LASTNAME FIRSTNAME

----- --------------- ----------

1012 Krieger Jeff

1017 Krieger Jeff

1010 Simon Michael

1011 Stone Tony

1014 Stone Tony

1016 Stone Tony

1019 Stone Tony

7 rows selected.這顯示有七行需要?jiǎng)h除,還是用上一個(gè)表我測試了一下這個(gè)代碼,它用了77秒種就刪除了所有的數(shù)據(jù)準(zhǔn)備好了用Sql語句來刪除冗余數(shù)據(jù),版本一它執(zhí)行了135秒

DELETE

FROM CUSTOMERS

WHERE ID IN

(SELECT ID

FROM

(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,

FirstName ORDER BY ID) AS SeqNumber

FROM Customers)

WHERE SeqNumber 1);

我們可以看到最后的兩行語句對(duì)表中的數(shù)據(jù)進(jìn)行了排序,這不是有效的,所以我們來優(yōu)化一下最后一個(gè)查詢語句,把Rank()函數(shù)應(yīng)用到只含有冗余數(shù)據(jù)的組,而不是所有的列下面這個(gè)語句是比較有效率的,雖然它不像上一個(gè)查詢那樣精簡SELECT ID, LastName, FirstName

FROM

(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,

FirstName ORDER BY ID) AS SeqNumber

FROM

(SELECT ID, LastName, FirstName

FROM Customers

WHERE (LastName, FirstName) IN (SELECT LastName, FirstName

FROM Customers

GROUP BY LastName, FirstName

HAVING COUNT(*) 1)))

WHERE SeqNumber 1;

選擇冗余數(shù)據(jù)只用了26秒鐘,這樣就提高了67%的性能,這樣就提高了將這個(gè)作為子查詢的刪除查詢的效率,

DELETE

FROM Customers

WHERE ID IN

(SELECT ID

FROM

(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,

FirstName ORDER BY ID) AS SeqNumber

FROM

(SELECT ID, LastName, FirstName

FROM Customers

WHERE (LastName, FirstName) IN (SELECT LastName, FirstName

FROM Customers

GROUP BY LastName, FirstName

HAVING COUNT(*) 1)))

WHERE SeqNumber 1);

現(xiàn)在只用了47秒鐘的就完成的上面的任務(wù),比起上一個(gè)136秒,這是一個(gè)很大的進(jìn)步,相比之下,存儲(chǔ)過程用了56秒,這樣存儲(chǔ)過程有些慢了使用PL/SQL語句我們和我們以上的代碼,會(huì)得到更好的更精確的代碼,和提高你代碼的執(zhí)行效率,雖然對(duì)于從數(shù)據(jù)庫中枚舉數(shù)據(jù)PL/SQL對(duì)于Sql兩者沒有什么差別,但是對(duì)于數(shù)據(jù)的比較上,PL/SQL就比SQL要快很多,但是如果冗余數(shù)據(jù)量比較小的話,我們盡量使用SQL而不使用PL/SQL如果你的數(shù)據(jù)表沒有主鍵的話,那么你可以參考其它技術(shù)

Rank()其它的方法

使用Rank()函數(shù)你可以對(duì)選擇你所保留的數(shù)據(jù),(或者是小ID的或者是大ID 的,就由RECDate這個(gè)列來決定這種情況下,你可以把REcdate加入到(Orderby )子句中,倒序或者正序

這是一種保留最大Id的一種解決方案

DELETE

FROM Customers

WHERE ID IN

(SELECT ID

FROM

(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName, FirstName ORDER BY RecDate DESC, ID) AS SeqNumber

FROM

(SELECT ID, LastName, FirstName, RecDate

FROM Customers

WHERE (LastName, FirstName) IN (SELECT LastName, FirstName

FROM Customers

GROUP BY LastName, FirstName

HAVING COUNT(*) 1)))

WHERE SeqNumber 1);

這種技術(shù)保證了你可以控制每一個(gè)表中的保留的組,假設(shè)你有一個(gè)數(shù)據(jù)庫,有一個(gè)促銷或者有一個(gè)折扣信息,比如一個(gè)團(tuán)體可以使用這種促銷5次,或者個(gè)人可以使用這個(gè)折扣三次,為了指出要保留的組的個(gè)數(shù),你可以在where 和having子句中進(jìn)行設(shè)置,那么你將刪除所有大于你

設(shè)置有數(shù)的冗余組

DELETE

FROM Customers

WHERE ID IN

(SELECT ID

FROM

(SELECT ID, LastName, FirstName, RANK() OVER (PARTITION BY LastName,

FirstName ORDER BY ID) AS SeqNumber

FROM

(SELECT ID, LastName, FirstName

FROM Customers

WHERE (LastName, FirstName) IN (SELECT LastName, FirstName

FROM Customers

GROUP BY LastName, FirstName

HAVING COUNT(*) 3)))

WHERE SeqNumber 3);

As you can see, using the RANK() function allows you to eliminate duplicates in a

single SQL statement and gives you more capabilities by extending the power of

your

queries.

正如你所見使用Rank()可以消除冗余數(shù)據(jù)而且能給你很大的可伸展性

求助,千萬級(jí)MySQL去冗余數(shù)據(jù)

求助,千萬級(jí)MySQL去冗余數(shù)據(jù)

查詢指定的記錄最好通過Id進(jìn)行in查詢來獲得真實(shí)的數(shù)據(jù).其實(shí)不是最好而是必須,也就是你應(yīng)該先查詢出復(fù)合的ID列表,通過in查詢來獲得數(shù)據(jù)

MySQL數(shù)據(jù)庫遇到字段冗余怎么辦

刪除重復(fù)的記錄(重復(fù)記錄保留1條),可以按以下方法刪除

seleet distinct * into #Tmp from TableName

drop table TableName

select * into TableName from #Tmp

drop table #Tmp

數(shù)據(jù)部分字段重復(fù),ID不重復(fù)

delete 表 where id not in(

SELECT MAX(id) AS id FROM 表 GROUP BY rows) --- 刪除重復(fù)行

select * from 表 where id in(

SELECT MAX(id) AS id FROM 表 GROUP BY rows) --重復(fù)行只查詢一條

如何刪除數(shù)據(jù)庫中的冗余數(shù)據(jù)

數(shù)據(jù)冗余會(huì)導(dǎo)致數(shù)據(jù)庫中數(shù)據(jù)的重復(fù)出現(xiàn),占用大量的存儲(chǔ)空間,在使用中導(dǎo)致不 便。

數(shù)據(jù)庫設(shè)計(jì)中,要盡可能降低數(shù)據(jù)冗余,達(dá)到數(shù)據(jù)的簡潔,易用

為了達(dá)到最低冗余,在設(shè)計(jì)中進(jìn)行模式的規(guī)范化,一般達(dá)到BC范式的情況下,就可以大幅度第降低數(shù)據(jù)冗余。

數(shù)據(jù)冗余決不能完全消除,除非只有一個(gè)表。

新聞名稱:mysql怎么消除冗余,mysql數(shù)據(jù)冗余
網(wǎng)站網(wǎng)址:http://www.muchs.cn/article34/phjgse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、外貿(mào)建站、動(dòng)態(tài)網(wǎng)站電子商務(wù)、做網(wǎng)站、企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管