2010-09-08 25 views
7

Ứng dụng của tôi cần thăm dò cơ sở dữ liệu MySQL cho các hàng mới. Mỗi khi hàng mới được thêm vào, chúng sẽ được lấy ra. Tôi đã nghĩ đến việc tạo trình kích hoạt để đặt tham chiếu đến các hàng mới trên một bảng riêng biệt. Bảng gốc có hơn 300.000 hàng.Cách nhanh nhất để thăm dò ý kiến ​​một bảng MySQL cho các hàng mới là gì?

Ứng dụng được xây dựng bằng PHP.

Một số câu trả lời hay, tôi nghĩ câu hỏi xứng đáng là tiền thưởng.

+2

IMO, nếu có thể, bất kỳ lớp nào bạn sử dụng để chèn, tức là các dịch vụ bao gồm các hoạt động CRUD, phải 'thông báo' cho ứng dụng của bạn sau khi chèn. Bằng cách này bạn không thường xuyên bỏ phiếu. – Alex

+0

@ Alex: Chúng là hai ứng dụng độc lập khác nhau. Ứng dụng thứ hai chỉ đọc từ cơ sở dữ liệu. – HyderA

+1

Tôi muốn nói trình kích hoạt INSERT SAU sẽ là điểm trên, thực hiện ở cấp MySQL, và để cho các cuộc thăm dò kịch bản và làm sạch các mục mới trong bảng khác. Bằng cách đó, ngay cả việc buộc một id khác (không tự động) sẽ vẫn hoạt động. – Wrikken

Trả lời

7

Đối với các ứng dụng bên ngoài tôi thấy sử dụng một cột dấu thời gian là một phương pháp mạnh mẽ hơn mà không phụ thuộc vào id tự động và các vấn đề khóa chính khác

Thêm cột vào bảng như:

insertedOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP 

hoặc theo dõi các lần chèn và cập nhật

updatedOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 

Trong externa l ứng dụng tất cả các bạn cần làm là theo dõi dấu thời gian cuối cùng khi bạn đã làm một cuộc thăm dò ý kiến. Sau đó chọn từ dấu thời gian đó về phía trước trên tất cả các bảng có liên quan. Trong các bảng lớn, bạn có thể cần lập chỉ mục cột dấu thời gian

+0

Lập chỉ mục trường như vậy sẽ * luôn * có lợi, không chỉ trong trường hợp các bảng lớn. +1 anyway. –

+0

Lập chỉ mục thường có lợi. Có rất nhiều trường hợp sử dụng khi chỉ mục trên không đáng giá. Thông thường một bảng có nhiều chèn và xóa giữa mỗi lần chọn dựa trên TIMESTAMP, và chọn dựa trên TIMESTAMP được thực hiện không thường xuyên – TFD

+1

Điều gì đó phải cẩn thận với giải pháp này: nếu ứng dụng thực hiện bỏ phiếu đang nhận các thay đổi theo lô (ví dụ: 'SELECT * FROM TABLE WHERE updatedOn>: LAST_TIMESTAMP ORDER BY updateOn LIMIT 100') và có khả năng nhiều hơn kích thước lô có thể được cập nhật cùng một lúc (ví dụ: 'CẬP NHẬT TABLE SET COLUMN = 'VALUE' WHERE OTHER_COLUMN = 'SOMETHING R WNG CHỌN HUNDREDS OF ROWS'') sau đó bạn sẽ bỏ lỡ hàng. – ICR

3

Bạn có thể sử dụng câu lệnh sau để tìm hiểu xem một kỷ lục mới đã được chèn vào trong bảng:

select max(id) from table_name 

thay thế tên của khóa chính và tên bảng trong tuyên bố trên. Giữ giá trị tối đa (id) trong một biến tạm thời và lấy tất cả các bản ghi mới giữa giá trị này và giá trị tối đa (id) đã lưu cuối cùng. Sau khi tìm nạp bản ghi mới, hãy đặt giá trị tối đa (id) thành giá trị bạn nhận được từ truy vấn.

+1

Tại sao không chọn * từ tên_bảng nơi id>: tối đa –

0

giả sử bạn có một số nhận dạng hoặc một số dữ liệu khác luôn phát triển, bạn nên theo dõi ứng dụng php của bạn của id cuối cùng được truy xuất.

sẽ hoạt động với hầu hết các trường hợp. Trừ khi bạn vào trại thời gian thực, tôi không nghĩ bạn cần nhiều hơn thế.

0

Tôi sẽ làm một việc như thế này. Tất nhiên, đây là giả định rằng ID là một số ID gia tăng. Và cách bạn lưu trữ "vị trí hiện tại" trong cơ sở dữ liệu là tùy thuộc vào bạn.

<? 
$idFile = 'lastID.dat'; 

if(is_file($idFile)){ 
    $lastSelectedId = (int)file_get_contents($idFile); 
} else { 
    $lastSelectedId = 0; 
} 

$res = mysql_query("select * from table_name where id > {$lastSelectedId}"); 

while($row = mysql_fetch_assoc($res)){ 
    // Do something with the new rows 

    if($row['id']>$lastSelectedId){ 
     $lastSelectedId = $row['id']; 
    } 
} 

file_put_contents($idFile,$lastSelectedId); 

?> 
0

Tôi đồng ý với câu trả lời của TFD về việc theo dõi dấu thời gian trong một tệp/bảng riêng biệt và sau đó tìm nạp tất cả các hàng mới hơn. Đó là cách tôi làm điều đó cho một ứng dụng tương tự.

Ứng dụng của bạn truy vấn một bảng (hoặc tệp) hàng đơn để xem liệu dấu thời gian đã thay đổi từ bộ nhớ cục bộ có phải là số lần truy cập hiệu suất không. Sau đó, tìm nạp các hàng mới từ bảng hàng 300k dựa trên dấu thời gian một lần nữa sẽ ổn, giả sử dấu thời gian được lập chỉ mục đúng.

Tuy nhiên, đọc câu hỏi của bạn tôi đã tò mò nếu kích hoạt Mysql có thể thực hiện cuộc gọi hệ thống, nói một tập lệnh php có thể thực hiện một số thao tác nâng hạng nặng. Hãy tắt they can bằng cách sử dụng sys_exec()User-Defined Function. Bạn có thể sử dụng điều này để thực hiện tất cả các loại xử lý bằng cách chuyển nó vào dữ liệu hàng được chèn vào, về cơ bản có thông báo chèn ngay lập tức.

Cuối cùng, a word of caution về cách sử dụng trình kích hoạt để gọi các ứng dụng bên ngoài.

0

Một tùy chọn có thể là sử dụng câu lệnh INSERT INTO SELECT. Lấy từ những gợi ý sử dụng timestamps để kéo hàng mới nhất, bạn có thể làm một cái gì đó giống như ...

INSERT INTO t2 (
    SELECT * 
    FROM t1 
    WHERE createdts > DATE_SUB(NOW(), INTERVAL 1 HOUR) 
); 

này sẽ mất tất cả các hàng chèn trong một giờ trước và chèn chúng trong bảng 2. Bạn có thể có một tập lệnh chạy truy vấn này và chạy nó mỗi giờ (hoặc bất kỳ khoảng thời gian nào bạn cần).

Điều này sẽ đơn giản hóa kịch bản PHP của bạn để kéo các hàng vì bạn không cần phải lặp qua bất kỳ hàng nào. Nó cũng được thoát khỏi việc phải theo dõi id chèn cuối cùng.

Các giải pháp Fanis purposed cũng có vẻ như nó có thể là thú vị là tốt.

Lưu ý, truy vấn chọn trong phần chèn ở trên có thể được điều chỉnh để chỉ chèn một số trường nhất định. Nếu bạn chỉ cần một số trường nhất định, bạn sẽ cần chỉ định chúng trong phần chèn như vậy ...

INSERT INTO t2 (field1, field2) (
    SELECT field1, field2 
    FROM t1 
    WHERE createdts > DATE_SUB(NOW(), INTERVAL 1 HOUR) 
); 
1

Tạo một Daemon PHP để theo dõi bảng MySQL Kích thước tệp, nếu thay đổi truy vấn cho bản ghi mới, nếu mới các bản ghi được tìm thấy chạy quá trình tiếp theo.

Tôi nghĩ rằng có một trình tiện ích PEAR đang hoạt động, bạn có thể dễ dàng định cấu hình để theo dõi kích thước tệp Bảng MySQL và khởi chạy tập lệnh của bạn.

+1

Tôi không chắc chắn về MySQL, nhưng thường không gian bảng được phân bổ theo khối, do đó khi phân bổ đã được thực hiện, một số hàng có thể được thêm vào trước khi cần phân bổ khác. – pascal

+0

Nhiều bảng nằm trong cùng một tệp nếu sử dụng innodb. – frodeborli

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