Hoan nghênh bạn nhận ra đây là một vấn đề không tầm thường. Tôi đã viết một thư viện để thực hiện điều này cho một ứng dụng thương mại vào năm ngoái và mất khoảng 6 tháng để đưa nó đến nơi tôi hài lòng với nó.
Bỏ qua tranh luận về việc sử dụng cổng 80 và HTTP (TCP / IP) để tránh các vấn đề về tường lửa và hỗ trợ, bạn cần thiết kế một giao thức. Vì dự án của tôi rất phức tạp về dữ liệu nên tôi đã sử dụng một giao thức nhị phân (thay vì xml cồng kềnh) có thể xử lý bất kỳ dữ liệu nào. Tôi cũng muốn nó có tính năng hai chiều để tôi có thể CHÈN dữ liệu cũng như thực thi các yêu cầu. Tôi đã sử dụng CGI / FastCGI trên máy chủ.
Giao thức nhị phân mà tôi đã thiết kế khá đơn giản (luôn tốt hơn) và chia nhỏ các chuyển khoản lớn thành nhiều phần có kích thước do người dùng xác định (khoảng 600k có vẻ là tốt). Mỗi đoạn có một tiêu đề theo sau là dữ liệu.
Mặc dù giao thức này có thể được sử dụng để truyền bất kỳ loại dữ liệu nào, nhưng thông thường nó được sử dụng cho dữ liệu kiểu cơ sở dữ liệu như câu hỏi của bạn gợi ý. Để giải quyết vấn đề này, tôi quyết định sử dụng phương pháp tiếp cận hàng / cột cho thiết kế. Dữ liệu được lưu trữ từng hàng một nghĩa là, mỗi cột được lưu trữ cho hàng một, sau đó tất cả các cột cho hàng 2 ... hàng n.
Định dạng của dữ liệu một cột là:
' Col1Type 1Bytes - BYTE ' Data Type (REMSQL_TEXT etc)
' Col1Len 4Bytes - DWORD ' Length in bytes the Column Data - up to 4.2GB
' Col1Data nBytes - BYTE ' String data
(trong C, BYTE là CHAR)
Điều này có nghĩa là mỗi cột có một bộ mô tả kiểu dữ liệu. Tất cả các kiểu dữ liệu có thể được biểu diễn bằng:
REMSQL_NONE = 0 ' DataType undefined
REMSQL_QUAD = 1 ' 64-bit signed integer
REMSQL_DBLE = 2 ' 64-bit IEEE floating point number
REMSQL_TEXT = 3 ' STRING - (CHAR) string of Ascii Bytes
REMSQL_BLOB = 4 ' BLOB - (CHAR) string of Binary Bytes
REMSQL_NULL = 5 ' NULL - Empty Column
Các kiểu dữ liệu này đồng nhất với các kiểu dữ liệu cơ bản của SQLite và tương đương về mặt số học với kiểu liệt kê Kiểu dữ liệu cơ bản của SQL3.
Trong thiết kế này, nếu một trường trống (NULL) thì bạn chỉ lấy 5 byte để lưu trữ nó. Ví dụ:nếu một trường có 200 byte văn bản, thì chỉ cần 205 byte để lưu trữ nó. Lợi ích lớn hơn là phân tích cú pháp dữ liệu vì việc bỏ qua các cột có thể được thực hiện mà không cần đọc hết 200 byte để tìm một số ký tự kết thúc.
Tiêu đề Chunk phải chứa những thứ như, số hàng, số cột, tổng số byte, v.v. Nếu bạn sử dụng DWORD (số nguyên 64 bit không dấu) thì giới hạn lý thuyết cho một đoạn là 4,2gigs đủ để truyền mạng cục bộ.
Việc triển khai yêu cầu viết các trình bao bọc SQLite / MYSQL cho chức năng này. Tôi sử dụng riêng giao thức BINARY, điều này sẽ mất một chút thời gian, nhưng về cơ bản bạn cần các chức năng sau:Phía máy khách:SendRequest () - Gửi yêu cầu, chờ phản hồi
Phía máy chủ:ProcessRequest () - Nhận Yêu cầu, xử lý nó và trả về phản hồi
Trong trường hợp của tôi, phản hồi có thể là! 00MB dữ liệu hoặc hơn. Tôi lấy toàn bộ tập dữ liệu từ MySQL và lưu vào đĩa trên máy chủ. Sau đó, tôi trả về một đoạn trống chứa các chỉ số của tập dữ liệu. Sau đó, khách hàng yêu cầu tập dữ liệu với số lượng 600k, từng phần một. Nếu kết nối bị mất, nó chỉ bắt đầu từ nơi nó dừng lại.
Cuối cùng, tập dữ liệu chủ yếu là văn bản (địa chỉ tên, v.v.) nên đã chín muồi để nén. Bảo mật là một vấn đề rất lớn trong trường hợp này vì vậy mã hóa là điều cần thiết. Điều này thực sự phức tạp hơn một chút để thực hiện, nhưng về cơ bản bạn nén toàn bộ đoạn, đệm đến độ dài bằng bội số của mật mã khối BLOCKSIZE và mã hóa nó.
Trong quá trình này, tôi viết một lớp xây dựng chuỗi rất nhanh, triển khai mã hóa AES trong ASM và toàn bộ thư viện FastCGI (www.coastrd.com)
Vì vậy, như tôi đã nói, không tầm thường. Tôi sẽ sớm cung cấp thư viện này. Nếu bạn muốn kiểm tra, hãy gửi email cho tôi.
Khi bạn đã viết thông tin liên lạc thì bạn có thể bắt đầu thiết kế đồng bộ hóa. Tôi sẽ sử dụng một hàm băm cho mỗi bản ghi hoặc một cờ boolean đơn giản. Nếu có bất kỳ điều gì thay đổi trên máy chủ, chỉ cần gửi toàn bộ bản ghi và ghi đè lên phía máy khách (giả sử bạn đang cố gắng giữ cho các máy khách được đồng bộ hóa ...)
Nếu bạn viết bài của riêng mình, vui lòng đăng lại ở đây về trải nghiệm của bạn!
Tái bút. Cân nhắc việc thay đổi tiêu đề để thân thiện với tìm kiếm hơn .. Có lẽ như sau:
"Đồng bộ hóa cơ sở dữ liệu máy khách SQLite với cơ sở dữ liệu máy chủ MySQL"