2010-11-11 41 views
6

Đây có thể là một tình huống phổ biến, nhưng tôi không thể tìm thấy câu trả lời cụ thể trên SO hoặc Google.Duy trì một bảng lớn các giá trị duy nhất trong MySQL

Tôi có một bảng lớn (> 10 triệu hàng) mối quan hệ bạn bè trên cơ sở dữ liệu MySQL rất quan trọng và cần được duy trì sao cho không có hàng trùng lặp. Bảng lưu trữ các uids của người dùng. SQL cho bảng là:

CREATE TABLE possiblefriends(
id INT NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(id), 
user INT, 
possiblefriend INT) 

Cách bàn hoạt động là mỗi người dùng có khoảng 1000 hoặc lâu hơn "có thể bạn bè" được phát hiện và cần phải được lưu trữ, nhưng lặp lại "bạn bè tốt" cần phải được tránh.

Vấn đề là do thiết kế chương trình, trong suốt một ngày, tôi cần thêm 1 triệu hàng hoặc nhiều hơn vào bảng có thể hoặc không trùng lặp mục nhập hàng. Câu trả lời đơn giản có vẻ là kiểm tra mỗi hàng để xem nó có phải là một bản sao không, và nếu không, sau đó chèn nó vào bảng. Nhưng kỹ thuật này có thể sẽ rất chậm khi kích thước bảng tăng lên 100 triệu hàng, 1 tỷ hàng hoặc cao hơn (mà tôi mong đợi nó sẽ sớm).

Cách tốt nhất (tức là nhanh nhất) để duy trì bảng duy nhất này là gì?

Tôi không cần phải có bảng chỉ có giá trị duy nhất luôn sẵn có. Tôi chỉ cần nó một lần một ngày cho công việc hàng loạt. Trong trường hợp này, tôi có nên tạo một bảng riêng mà chỉ chèn tất cả các hàng có thể (chứa các hàng trùng lặp và tất cả), và sau đó vào cuối ngày, tạo bảng thứ hai tính tất cả các hàng duy nhất trong bảng đầu tiên?

Nếu không, cách tốt nhất cho bảng này là gì?

(Nếu chỉ là giải pháp lâu dài tốt nhất, xin vui lòng cho tôi biết là chỉ số để sử dụng)

+0

câu hỏi, do u cần truy vấn tới bảng 'possiblefriends'? tôi chỉ nghĩ rằng u có thể chia bảng theo người dùng, nó sẽ có lợi khi truy vấn u, tuy nhiên nó có thể biến thành một thảm họa bảo trì trong dài hạn – ajreal

+0

@ajreal: bạn có nghĩa là mỗi người dùng có bảng riêng của mình? sẽ có gần một triệu người dùng, vì vậy điều đó có thể làm mọi thứ trở nên phức tạp. – eric

+0

có, đó là y tôi đã đề cập nó có thể biến thành một thảm họa bảo trì, làm thế nào về sử dụng 1k người dùng cho mỗi bảng hay như vậy? tưởng tượng u đặt tất cả các dữ liệu vào một bảng, và xảy ra bảng bị rơi và không thể phục hồi, hoặc thậm chí là phục hồi, bao lâu u có thể chịu với thời gian xuống? – ajreal

Trả lời

7

Thêm một chỉ số duy nhất trên (user, possiblefriend) sau đó sử dụng một trong số:

to vi chắc chắn rằng bạn không nhận được lỗi khi bạn cố gắng chèn một hàng trùng lặp.

Bạn cũng có thể muốn cân nhắc xem bạn có thể thả khóa chính tăng tự động và sử dụng (user, possiblefriend) làm khóa chính hay không. Điều này sẽ làm giảm kích thước của bảng của bạn và cũng là khóa chính sẽ hoạt động như chỉ mục, giúp bạn không phải tạo thêm chỉ mục.

Xem thêm:

+1

Tôi đã đọc câu hỏi đó. Có phải INSERT IGNORE hoặc INSERT ... ON UPPLATE KHU VỰC TUYÊN BỐ hiệu quả cho một bảng với hàng trăm triệu hàng nói chung? – eric

+1

@eric: Tôi tưởng tượng rằng 'INSERT IGNORE' là nhanh nhất, nhưng tôi đoán là vậy. Để chắc chắn bạn có thể chạy thử nghiệm hiệu suất trên cả ba phương pháp. Câu trả lời được bình chọn hàng đầu cho câu hỏi mà tôi đã liên kết để đề xuất sử dụng 'INSERT ... ON UPDATE DUPLICATE KEY UPDATE'. –

+1

NB - nó phải là một chỉ số duy nhất! – symcbean

2

Một chỉ số duy nhất sẽ cho phép bạn chắc chắn rằng lĩnh vực này thực sự là duy nhất, bạn có thể thêm một chỉ số duy nhất như vậy:

CREATE TABLE possiblefriends( 
id INT NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(id), 
user INT, 
possiblefriend INT, 
PRIMARY KEY (id), 
UNIQUE INDEX DefUserID_UNIQUE (user ASC, possiblefriend ASC)) 

Điều này cũng sẽ giúp bạn truy cập bảng đáng kể.

vấn đề khác của bạn với chèn hàng loạt là một chút khó khăn hơn, bạn có thể sử dụng trong xây dựng ON DUPLICATE chức năng KEY CẬP NHẬT dưới đây:

INSERT INTO table (a,b,c) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE c=c+1; 

UPDATE table SET c=c+1 WHERE a=1; 
+0

cảm ơn. sử dụng chỉ mục có tốt hơn không? sẽ có bất kỳ chi phí để sử dụng một chỉ số cho các bảng lớn hơn mà tôi nên xem xét? – eric

Các vấn đề liên quan