国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

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

2024-07-21 02:31:30
字體:
供稿:網(wǎng)友

作為數(shù)據(jù)庫的開發(fā)者,我們經(jīng)常面臨著要找出及刪除數(shù)據(jù)庫中冗余數(shù)據(jù)的任務(wù),如果數(shù)據(jù)庫中有大量的冗余數(shù)據(jù)(占總數(shù)的百分比太多),數(shù)據(jù)的精確性和可靠性將受到影響,同時也影響著數(shù)據(jù)庫的性能,那么如何解決這個問題呢?下面我將探討關(guān)于這個問題的這個解決方案,Oracle也為我們提供了一個解決方案,但是Oracle提供的解決方案不夠完美,遇到大批量數(shù)據(jù)那個解決方案工作起來很慢

應該怎么刪除冗余數(shù)據(jù)呢?
在這里我們應用一個PL/SQl方案(一個自定義的存儲過程)或者一個SQL語句的解決方案(使用一個分析的函數(shù)RANK()和一個嵌套的子查詢)來消除冗余數(shù)據(jù)然后控制應該保留的記錄


什么是冗余數(shù)據(jù)?
冗余數(shù)據(jù)就是一個數(shù)據(jù)表中,這個表中的行包含了一些相同的值,這些值理論上來說應該是唯一的(這些值一般來說能確定一條記錄)例如,像社會保險號,姓與名的集合.那么我們把這么含有相同信息的行中包含的數(shù)據(jù)叫做冗余數(shù)據(jù),現(xiàn)在所有的數(shù)據(jù)庫表中都有主鍵約束,主鍵中記錄了一行記錄中的唯一值,從數(shù)據(jù)庫的角度來看,每一行都是唯一的,但是從我們用戶角度看來,這些記錄都是相同的記錄,因為它們都包含相同的鍵值(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

那么這些冗余數(shù)據(jù)是怎么出現(xiàn)的那?通常有兩種情況:1.從不同的表中加載或者合并數(shù)據(jù)

通過圖形化的用戶接口來輸入數(shù)據(jù),然后由計算機來生成一個唯一的鍵,并做為這一條記錄的主鍵

那么怎樣找到冗余數(shù)據(jù)呢?讓我們來創(chuàng)建一個叫作Customer 的表并向其中加入冗余數(shù)據(jù),看表1,正如你所看到的,我們并沒有在這個表上做什么限制來防止冗余數(shù)據(jù),下面這么代碼創(chuàng)建了一個唯一約束,來防止冗余數(shù)據(jù)的生成
SQL
Listing 1. 創(chuàng)建Customer表
這個表中我們故意加入了冗余數(shù)據(jù)
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.',
           'Pleasant Hill', 'CA', '95114', '9254247701',
           TO_DATE('14-APR-2001', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1005, 'Krieger', 'Jeff', '120 Mercury Rd.',
           'San Ramon', 'CA', '95114', '9252997100',
           TO_DATE('02-FEB-2001', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1006, 'Monroe', 'John', '122 West Ave.',
           'Phoenix', 'AZ', '85004', '9252997100',
           TO_DATE('02-OCT-2000', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1007, 'Lord', 'Don', '573 Hill View',
           'Atlanta', 'GA', '30303', '3036578900',
           TO_DATE('12-DEC-2000', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1008, 'Griffith', 'David', '10 Fulton Rd. Apt.4',
           'San Francisco', 'CA', '94121', '7236578900',
           TO_DATE('15-DEC-1999', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1009, 'Simon', 'Michael', '573 Hill View',
           'Santa Monica', 'CA', '90402', '8185689200',
           TO_DATE('22-MAY-1999', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1010, 'Simon', 'Michael', '573 Hill View',
           'Santa Monica', 'CA', '90402', '8185689200',
           TO_DATE('02-OCT-1999', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1011, 'Stone', 'Tony', '12 Main St. Apt. 3',
           'Oakland', 'CA', '94342', '5104562881',
           TO_DATE('07-DEC-1999', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1012, 'Krieger', 'Jeff', '120 Mercury Rd.',
           'San Ramon', 'CA', '95114', '9252997100',
           TO_DATE('15-JUN-1999', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1013, 'Blue', 'Don', '12250 Saturn Rd.',
           'Pleasanton', 'CA', '95434', '9252332400',
           TO_DATE('09-SEP-1999', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1014, 'Stone', 'Tony', '12 Main St. Apt. 3',
           'Oakland', 'CA', '94342', '5104562881',
           TO_DATE('11-APR-2000', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1015, 'Mason', 'Paul', '53 Orange Way',
           'Las Vegas', 'NV', '89101', '5104562881',
           TO_DATE('04-JUL-2000', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1016, 'Stone', 'Tony', '12 Main St. Apt. 3',
           'Oakland', 'CA', '94342', '5104562881',
           TO_DATE('30-DEC-2000', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1017, 'Krieger', 'Jeff', '120 Mercury Rd.',
           'San Ramon', 'CA', '95114', '9252997100',
           TO_DATE('11-JAN-2001', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1018, 'Blake', 'Becky', '1099 Venus St.',
           'Salt Lake City', 'UT', '84106', '8016543501',
           TO_DATE('12-JUN-2001', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1019, 'Stone', 'Tony', '12 Main St. Apt. 3',
           'Oakland', 'CA', '94342', '5104562881',
            TO_DATE('03-NOV-2000', 'DD-MON-YYYY'));

INSERT INTO Customers
   VALUES (1020, 'Hill', 'Larry', '2220 Bench St.',
           'Santa Rosa', 'CA', '94533', '7072279800',
            TO_DATE('24-AUG-2000', 'DD-MON-YYYY'));

COMMIT;
 看下面的代碼我在姓,和名這兩個字段上加上唯一約束,(當然你可以在創(chuàng)建表的時候加上這一約束,來防止冗余數(shù)據(jù))
ALTER TABLE Customers
   ADD CONSTRAINT Customers_LastFirst
   UNIQUE (LastName, FirstName);

Customer表中的冗余鍵是LastName和FirstName的集合,我們把含有冗余鍵的數(shù)據(jù)進行分組并進行統(tǒng)計.

SELECT LastName, FirstName, COUNT(*)   FROM Customers
   GROUP BY LastName, FirstName
   ORDER BY LastName, FirstName;

Listing 2顯示了這條語句的輸出,我們可以看到有三行的輸出大于1,這也就意味著表中含有3組冗余數(shù)據(jù).
Listing 2. 找出冗余

LASTNAME        FIRSTNAME    COUNT(*)
--------------- ---------- ----------
Blake           Becky               1
Blue            Don                 1
Bradley         Tom                 1
Chang           Jim                 1
Griffith        David               1
Hill            Larry               1
King            Chuck               1
Krieger         Jeff                3
Loney           Julie               1
Lord            Don                 1
Mason           Paul                1
Monroe          John                1
Simon           Michael             2
Stone           Tony                5

14 rows selected.

我們在語句中加入Having()語句來過濾出非冗余數(shù)據(jù).
SELECT LastName, FirstName, COUNT(*)
   FROM Customers
   GROUP BY LastName, FirstName
   HAVING COUNT(*) > 1;

SQL
Listing 3. 過濾冗余
加入Having()語句來過濾出非冗余數(shù)據(jù).
LASTNAME        FIRSTNAME    COUNT(*)
--------------- ---------- ----------
Krieger         Jeff                3
Simon           Michael             2
Stone           Tony                5

3 rows selected.
Listing 3顯示了以上代碼的輸入,盡管如此,這些查詢結(jié)果并沒有顯示出能標識每一行的字段,我們將上一語句做為一個嵌套查詢來顯示標識這些記錄的ID
SELECT ID, LastName, FirstName
   FROM Customers
   WHERE (LastName, FirstName) IN
   (SELECT LastName, FirstName
       FROM Customers
       GROUP BY LastName, FirstName
       HAVING COUNT(*) > 1)
   ORDER BY LastName, FirstName;

Listing 4顯示出了以上代碼的結(jié)果,這些查詢顯示了有三組冗余,共有十行,我們應該保留這些組中的1005,1009,1001這些記錄然后刪除1012,1017,1010,1011,1016,1019,1014這些冗余的條目.
SQL
Listing 4. 找出唯一的鍵
語句的輸出
ID LASTNAME        FIRSTNAME
----- --------------- ----------
 1005 Krieger         Jeff
 1012 Krieger         Jeff
 1017 Krieger         Jeff
 1009 Simon           Michael
 1010 Simon           Michael
 1001 Stone           Tony
 1011 Stone           Tony
 1016 Stone           Tony
 1019 Stone           Tony
 1014 Stone           Tony

10 rows selected.

Oracle公司給出的一個解決方案
Oracle 公司給我們提供一個見刪除冗余數(shù)據(jù)的一個方案,這個方案使用了Oracle公司自己的一個集合函數(shù)MIN()或者MAX()來解決這一問題MIN()函數(shù)可以得到每一組中(冗余的非冗余的),應保留的所有值.(正如我們所見,輸入出不包含那些大ID的冗余值

SELECT MIN(ID) AS ID, LastName, FirstName
   FROM Customers
   GROUP BY LastName, FirstName;
這一條命令的輸出
Listing 5. Output of MIN() query
這一條命令顯示了所有的非冗余的數(shù)據(jù),其它的行則應該被刪除
ID LASTNAME        FIRSTNAME
----- --------------- ----------
 1018 Blake           Becky
 1013 Blue            Don
 1000 Bradley         Tom
 1002 Chang           Jim
 1008 Griffith        David
 1020 Hill            Larry
 1004 King            Chuck
 1005 Krieger         Jeff
 1003 Loney           Julie
 1007 Lord            Don
 1015 Mason           Paul
 1006 Monroe          John
 1009 Simon           Michael
 1001 Stone           Tony

14 rows selected.


這樣你就可以刪除那些不在這個表中的所有的行,同樣將上一條語句作為一個子查詢,構(gòu)造一個語句

DELETE FROM Customers
   WHERE ID NOT IN
   (SELECT MIN(ID)
       FROM Customers
    GROUP BY LastName, FirstName);

盡管如此,理論是可行的,但是這個方案并不是那么有效,因為這樣一來,DBMS要完成兩個表的掃描來完成這項任務(wù),對于大量的數(shù)據(jù)來說,這簡直是不可行的,為了測試他的性能,我創(chuàng)建了Customer表,大約有5000,000行,45,000冗余行,(9%)以上這個命令運行了一個小時,沒有輸出結(jié)果,它耗盡了我的耐心,所以我殺死了這個進程
這個方案的令外這個方案還有一個缺點,你不能控制每一個組中你要保留的行


一種PL/SQl解決方案:使用存儲過程刪除冗余數(shù)據(jù),叫做DeleDuplicate的存儲過程,這個過程的結(jié)構(gòu)很清晰的.
SQL
Listing 6. The DeleteDuplicate stored procedure

它將這些冗余行選擇一到一個游標中,然后從表中取出每一個冗余行來進行與游標中的行進行比對,然后決定是否刪除
CREATE OR REPLACE PROCEDURE DeleteDuplicates(
   pCommitBatchSize IN INTEGER := 5000) IS

CURSOR csr_Duplicates IS
   SELECT ID, LastName, FirstName
   FROM Customers
   WHERE (LastName, FirstName) IN
   (SELECT LastName, FirstName
       FROM Customers
       GROUP BY LastName, FirstName
       HAVING COUNT(*) > 1)
   ORDER BY LastName, FirstName;

/*保存上一次的姓和名*/
vLastName Customers.LastName%TYPE := NULL;
vFirstName Customers.FirstName%TYPE := NULL;

vCounter INTEGER := 0;

BEGIN

   FOR vDuplicates IN csr_Duplicates
   LOOP
      IF vLastName IS NULL OR
      (vDuplicates.LastName != vLastName
       OR NVL(vDuplicates.FirstName, ' ') != NVL(vFirstName, ' '))
 THEN
 /*第一次取出行或者是一個新行
  保存它的姓和名的值*/
    vLastName := vDuplicates.LastName;
    vFirstName := vDuplicates.FirstName;

 ELSE
       /*冗余數(shù)據(jù),刪除它*/
    DELETE
            FROM Customers
       WHERE ID = vDuplicates.ID;

    vCounter := vCounter + 1;

/*提交結(jié)果*/
    /* Commit every pCommitBatchSize rows */
    IF MOD(vCounter, pCommitBatchSize) = 0
    THEN
       COMMIT;
    END IF;

      END IF;
   END LOOP;

   IF vCounter > 0
   THEN
      COMMIT;
   END IF;


   DBMS_OUTPUT.PUT_LINE(TO_CHAR(vCounter) ||
                        ' duplicates have been deleted.');

   EXCEPTION
      WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE('Error ' ||
                                TO_CHAR(SQLCODE) || ': ' || SQLERRM);
         ROLLBACK;

END DeleteDuplicates;

 

它將冗余數(shù)據(jù)選擇到一個游標中,并根據(jù)(LastName,FirstName)來分組(在我們這個方案中),然后打開游標然后循環(huán)地取出每一行,然后用與先前的取出的鍵值進行比較,如果這是第一次取出這個值,或者這個值不是冗余鍵,那么跳過這個記錄然后取下一個,不然的話,這就是這個組中的冗余記錄,所以刪掉它.
讓我們運行一下這個存儲過程
BEGIN
   DeleteDuplicates;
END;
/

SELECT LastName, FirstName, COUNT(*)
   FROM Customers
   GROUP BY LastName, FirstName
   HAVING COUNT(*) > 1;

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

二.SQL解決方案,使用RANK()刪除冗余數(shù)據(jù)
Oracle8i分析函數(shù)RANK()來枚舉每一個組中的元素,在我們的方案中, 我們應用這個方案,我們使用這個函數(shù)動態(tài)的把冗余數(shù)據(jù)連續(xù)的排列起來加上編號,組由Partintion by 這個語句來分開,然后用Order by 進行分組
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ù)的個數(shù)來顯示尤其對于冗余數(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號由小到大進行的排序,所有的冗余數(shù)據(jù)的SqlNumber都大于一,所有的非冗余數(shù)據(jù)都等于一,所以我們?nèi)∽约核瑁瑒h除那么沒用的
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.

這顯示有七行需要刪除,還是用上一個表我測試了一下這個代碼,它用了77秒種就刪除了所有的數(shù)據(jù)準備好了用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);
我們可以看到最后的兩行語句對表中的數(shù)據(jù)進行了排序,這不是有效的,所以我們來優(yōu)化一下最后一個查詢語句,把Rank()函數(shù)應用到只含有冗余數(shù)據(jù)的組,而不是所有的列
下面這個語句是比較有效率的,雖然它不像上一個查詢那樣精簡
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%的性能,這樣就提高
了將這個作為子查詢的刪除查詢的效率,
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ù),比起上一個136秒,這是一個很大的進步,相比之下,存儲過程用了56秒,這樣存儲過程有些慢了使用PL/SQL語句我們和我們以上的代碼,會得到更好的更精確的代碼,和提高你代碼的執(zhí)行效率,雖然對于從數(shù)據(jù)庫中枚舉數(shù)據(jù)PL/SQL對于Sql兩者沒有什么差別,但是對于數(shù)據(jù)的比較上,PL/SQL就比SQL要快很多,但是如果冗余數(shù)據(jù)量比較小的話,我們盡量使用SQL而不使用PL/SQL

如果你的數(shù)據(jù)表沒有主鍵的話,那么你可以參考其它技術(shù)

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


這是一種保留最大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ù)保證了你可以控制每一個表中的保留的組,假設(shè)你有一個數(shù)據(jù)庫,有一個促銷或者有一個折扣信息,比如一個團體可以使用這種促銷5次,或者個人可以使用這個折扣三次,為了指出要保留的組的個數(shù),你可以在where 和having子句中進行設(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ù)而且能給你很大的可伸展性


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 波密县| 云梦县| 海口市| 福建省| 平昌县| 尖扎县| 保山市| 巢湖市| 尉犁县| 秀山| 博客| 泗阳县| 湘乡市| 长寿区| 乌拉特后旗| 霍林郭勒市| 当涂县| 栾城县| 当雄县| 江阴市| 银川市| 余江县| 贵定县| 额尔古纳市| 郧西县| 八宿县| 绍兴市| 涟源市| 星座| 凯里市| 遵义县| 宝兴县| 沙雅县| 姚安县| 青田县| 克山县| 绥宁县| 会东县| 崇信县| 邯郸市| 香河县|