2010-07-19 56 views
5

Ok, vì vậy câu chuyện là như thế này:phát hiện khi dữ liệu đã thay đổi

- Tôi gặp rất nhiều tác phẩm (khá lớn, khoảng 25GB) mà đang ở trong một định dạng đặc biệt và cần phải được nhập khẩu trong một kho dữ liệu

- những tập tin này được cập nhật liên tục với các dữ liệu, thỉnh thoảng mới, đôi khi cùng một dữ liệu

- tôi đang cố gắng tìm ra một thuật toán trên làm thế nào tôi có thể phát hiện nếu một cái gì đó đã thay đổi cho một dòng cụ thể trong một tệp, để giảm thiểu thời gian cập nhật cơ sở dữ liệu

- cách nó hiện đang hoạt động bây giờ là tôi đang bỏ tất cả dữ liệu trong cơ sở dữ liệu mỗi lần và sau đó nhập lại, nhưng điều này sẽ không hoạt động nữa vì tôi sẽ cần một dấu thời gian cho thời điểm một mục đã thay đổi.

- các tập tin chứa chuỗi và số (tiêu đề, đơn đặt hàng, giá, vv)

Các giải pháp duy nhất tôi có thể nghĩ đến là:

- tính toán một hash cho mỗi hàng từ cơ sở dữ liệu, rằng nó được so sánh với giá trị băm của hàng từ tệp và nếu chúng khác nhau thì việc cập nhật cơ sở dữ liệu

- giữ 2 bản sao của tệp đó, trước đó và những tệp hiện tại nhanh hơn cập nhật db) và dựa trên các bản cập nhật đó.

Vì số lượng dữ liệu rất lớn đến rất lớn, tôi không còn lựa chọn nào khác. Về lâu dài, tôi sẽ loại bỏ các tập tin và dữ liệu sẽ được đẩy thẳng vào cơ sở dữ liệu, nhưng vấn đề vẫn còn.

Bất kỳ lời khuyên nào, sẽ được đánh giá cao.

Trả lời

1

Thay vì tính toán giá trị băm cho mỗi hàng từ cơ sở dữ liệu theo yêu cầu, tại sao bạn không lưu giá trị băm thay thế?

Sau đó, bạn chỉ có thể tính giá trị băm của tệp được đề cập và so sánh nó với cơ sở dữ liệu được lưu trữ.

Cập nhật:

Một lựa chọn khác mà đến tâm trí của tôi là để lưu trữ các thông tin ngày/giờ thay đổi lần cuối vào cơ sở dữ liệu và sau đó so sánh nó so với các tập tin trong câu hỏi. Điều này sẽ có tác dụng, miễn là thông tin không thể thay đổi một cách có chủ đích hoặc vô tình.

+0

Nếu bạn đang nói để tính toán giá trị băm của toàn bộ tệp so với băm của toàn bộ cơ sở dữ liệu sẽ không giúp tôi. Nhưng nếu bạn đang nói để lưu trữ các hash mỗi hàng trong cơ sở dữ liệu, có, đó là một trong những giải pháp tôi nghĩ đến. Tôi chỉ tự hỏi liệu điều đó có nhanh hơn là chỉ tìm ra liệu dữ liệu có thay đổi hay không bằng cách chỉ so sánh phần tử với phần tử. – hyperboreean

+0

+1 để đề xuất lưu trữ ngày và giờ sửa đổi lần cuối –

+0

Tôi không có bất kỳ dấu thời gian nào trong tệp đó. – hyperboreean

1

Vâng bất kể bạn sử dụng trường hợp xấu nhất của bạn sẽ là O (n), mà trên n ~ 25GB dữ liệu không phải là quá đẹp.

Trừ khi bạn có thể sửa đổi quy trình ghi vào tệp.

Vì bạn không cập nhật tất cả 25 GB mọi lúc, đó là tiềm năng lớn nhất của bạn để tiết kiệm chu kỳ.

1. Không viết ngẫu nhiên
Tại sao bạn không thực hiện quá trình ghi dữ liệu? Bằng cách này bạn sẽ có nhiều dữ liệu hơn, nhưng bạn sẽ có toàn bộ lịch sử và bạn có thể theo dõi dữ liệu nào bạn đã xử lý (những gì bạn đã đưa vào kho dữ liệu).

2.Giữ một danh sách các thay đổi nếu bạn phải viết ngẫu nhiên
Hoặc nếu bạn thực sự phải viết ngẫu nhiên, bạn có thể giữ một danh sách các hàng được cập nhật. Danh sách này có thể được xử lý như trong # 1 và bạn có thể theo dõi những thay đổi nào bạn đã xử lý. Nếu bạn muốn tiết kiệm một số không gian, bạn có thể giữ một danh sách các khối trong đó dữ liệu thay đổi (nơi khối là một đơn vị mà bạn xác định).

Ngoài ra, bạn có thể giữ tổng kiểm tra/băm của khối/đường đã thay đổi. Tuy nhiên điều này có thể không thú vị - nó không quá rẻ để tính toán và so sánh trực tiếp có thể rẻ hơn (nếu bạn có chu kỳ CPU miễn phí trong khi viết nó có thể giúp bạn tiết kiệm thời gian đọc sau, YMMV).

Note (s)

  • Cả # 1 và # 2 là chỉ thú vị nếu bạn có thể làm điều chỉnh các quá trình đó ghi dữ liệu vào đĩa
  • Nếu bạn không thể sửa đổi quy trình viết trong dữ liệu 25GB sau đó tôi không thấy cách kiểm tra/băm có thể giúp - bạn phải đọc tất cả dữ liệu để tính toán băm (vì bạn không biết điều gì đã thay đổi) để bạn có thể so sánh trực tiếp trong khi đọc và đưa ra danh sách các hàng để cập nhật/thêm (hoặc cập nhật/thêm trực tiếp)
  • Sử dụng các thuật toán khác có thể là suboptimal, thuật toán khác sẽ không chỉ tìm kiếm các dòng đã thay đổi mà còn kiểm tra khoảng cách chỉnh sửa tối thiểu giữa hai tệp văn bản được cung cấp tùy chọn định dạng nhất định. (trong diff, điều này có thể được điều khiển bằng -H hoặc --minimal để làm việc chậm hơn hoặc nhanh hơn, tức là tìm kiếm giải pháp tối thiểu chính xác hoặc sử dụng thuật toán heuristic nếu iirc thuật toán này trở thành O (n log n); nhưng vẫn chậm hơn sau đó O (n) có sẵn cho bạn nếu bạn so sánh trực tiếp từng dòng)
3

Định nghĩa sự cố được hiểu là.

Giả sử các tệp của bạn có chứa

ID,Name,Age 
1,Jim,20 
2,Tim,30 
3,Kim,40 

Như bạn nói Row có thể được thêm/cập nhật, do đó các tập tin trở nên

ID,Name,Age 
1,Jim,20 -- to be discarded 
2,Tim,35 -- to be updated 
3,Kim,40 -- to be discarded 
4,Zim,30 -- to be inserted 

Bây giờ yêu cầu là để cập nhật cơ sở dữ liệu bằng cách chèn/chỉ cập nhật trên 2 bản ghi trong hai truy vấn sql hoặc 1 truy vấn theo lô chứa hai câu lệnh sql.

Tôi đang làm cho sau giả định đây

  • Bạn không thể sửa đổi các quy trình hiện có để tạo ra tập tin.
  • Bạn đang sử dụng một số xử lý theo lô [Đọc từ tệp - Xử lý trong bộ nhớ- Viết bằng DB] để tải lên dữ liệu trong cơ sở dữ liệu.

Lưu giá trị băm của Bản ghi [Tên, tuổi] vào ID trong bản đồ trong bộ nhớ trong đó ID là khóa và giá trị băm [Nếu bạn yêu cầu khả năng mở rộng hazelcast].

Khung Batch của bạn để tải dữ liệu [Một lần nữa giả định xử lý một dòng tệp dưới dạng một bản ghi], cần kiểm tra giá trị băm được tính toán với ID trong bộ nhớ trong Map.First time creation cũng có thể được thực hiện bằng cách sử dụng hàng loạt của bạn khuôn khổ để đọc tệp.

If (ID present) 
--- compare hash 
---found same then discard it 
—found different create an update sql 
In case ID not present in in-memory hash,create an insert sql and insert the hashvalue 

Bạn có thể xử lý song song, xử lý đoạn và phân vùng dữ liệu trong bộ nhớ bằng cách sử dụng đợt phát sóng và luồng mờ.

http://www.hazelcast.com/

http://static.springframework.org/spring-batch/

Hope this helps.

0

thực tế đó là loại vấn đề cần được giải quyết bằng phần mềm sao lưu, vậy tại sao không sử dụng một số giải pháp tiêu chuẩn của họ? cách tốt nhất là móc các cuộc gọi WriteFile để bạn sẽ nhận được các cuộc gọi lại trên mỗi lần cập nhật. Điều này sẽ làm việc khá tốt với các bản ghi nhị phân.

Điều gì đó mà tôi không thể hiểu được: tệp thực sự là tệp văn bản không chỉ được thêm vào, mà còn được cập nhật? điều này là rất không hiệu quả (cùng với ý tưởng giữ 2 bản sao của các tập tin, bởi vì nó sẽ làm cho bộ nhớ đệm tập tin làm việc thậm chí còn tồi tệ hơn).

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