2011-10-02 43 views
9

Tôi cần tạo ứng dụng web HTML5 ngoại tuyến cho thiết bị iPad/máy tính bảng nơi người dùng có thể tải xuống tập dữ liệu (bảng dữ liệu) từ máy chủ và lưu trữ trên thiết bị. Sau đó, người dùng có thể ngắt kết nối khỏi máy chủ và xem/chỉnh sửa dữ liệu cục bộ trên thiết bị. Điều này dành cho những người làm việc ở những vùng xa xôi, nơi không có vùng phủ sóng di động và cần thu thập/cập nhật dữ liệu. Khi họ quay trở lại văn phòng, họ có thể đồng bộ/tải dữ liệu lên máy chủ. Lý do nó cần phải là HTML5 vì vậy nó là nền tảng bất khả tri, tức là có thể chạy nó trên iOS, Android vv miễn là nó có một trình duyệt web hiện đại hỗ trợ HTML5.Chức năng trình bao bọc cho IndexedDB

Bây giờ tôi đã xây dựng hệ thống bằng cách sử dụng bộ nhớ cục bộ HTML5 (cho dữ liệu) và bộ nhớ cache ứng dụng ngoại tuyến HTML5 (cho các trang/css/js/images) và nó hoạt động hợp lý với bộ dữ liệu nhỏ (tôi có thể xem , chỉnh sửa và lưu trong khi ngoại tuyến và tải/đồng bộ hóa khi trực tuyến). Bây giờ tôi cần phải mở rộng lên tới 10.000 hàng dữ liệu. Nó hoạt động nhưng nó khá chậm và treo trình duyệt trong 10 giây khi đang tải trên một máy tính 8 GB lõi tứ của Intel.

Vì vậy, tôi đã nghiên cứu một vài lựa chọn thay thế tốt hơn so với lưu trữ địa phương:

1) WebSQL: Sẽ là khả năng truy vấn dữ liệu bằng ngôn ngữ SQL và làm tham gia, vv Vấn đề là nó bây giờ bị phản một sẽ không được hỗ trợ lâu hơn vì vậy tôi không muốn đầu tư thời gian xây dựng một cái gì đó cho nó.

2) IndexedDB: Sử dụng kho lưu trữ đối tượng (về mặt kỹ thuật tôi đã lưu trữ các đối tượng bằng cách sử dụng API lưu trữ cục bộ và lưu trữ bằng JSON). Có khả năng nhanh hơn vì nó sử dụng các chỉ mục với phần phụ trợ SQL lite. Có rất nhiều mã soạn sẵn để thực hiện các tác vụ đơn giản như tạo cơ sở dữ liệu, thêm vào đó, đọc từ nó, lặp lại nó. Tôi chỉ muốn thực hiện một truy vấn đơn giản như select(xyc, abc).where(abc = 123).limit(20) nhưng thay vào đó phải viết rất nhiều mã JavaScript để làm điều đó. Làm thế nào để viết mã riêng của họ để thực hiện các phép nối giữa các bảng, bất kỳ ví dụ nào ở bất kỳ đâu?

Tôi đã tìm thấy một jQuery plugin có thể làm cho cuộc sống trở nên đơn giản hơn. Có những thứ khác xung quanh hoặc các thư viện khác làm giảm bớt nỗi đau khi sử dụng IndexedDB không?

Rất cám ơn!

+1

Tôi tin rằng WebSQL đã bị bỏ rơi ủng hộ IndexedDB ... –

+1

Xem ra cho WebSQL, Apple 5.0.1 không còn tồn tại dữ liệu WebSQL nữa. Nói cách khác, điều này sẽ làm tê liệt cơ sở dữ liệu cục bộ của ứng dụng của bạn. Phonegap có một giải pháp thay thế. https://issues.apache.org/jira/browse/CB-330 – Wytze

Trả lời

1

Bạn đã xem [Lawnchair] [1] chưa? Nó cung cấp một trừu tượng tốt đẹp từ kho lưu trữ cơ bản, cũng có các bổ sung cho truy vấn, tổng hợp và phân trang dữ liệu. Như một ví dụ về truy vấn:

// basic searching 
    this.where('record.name === "brian"', 'console.log(records)') 
    this.where('record.name != ?', username, 'console.log(records)') 

    // sorting results 
    this.where('name === "brian"').asc('active', 'console.log(records)') 

Hạn chế tiềm năng duy nhất tôi có thể thấy là nó không xuất hiện để xử lý di cư và là generic không xuất hiện để có một cách để tạo chỉ số vv

Liên quan đến các phép nối, IndexedDB được thiết kế để lưu trữ tài liệu không phải là một cơ sở dữ liệu quan hệ, tuy nhiên đây là một kịch bản phổ biến xuất hiện có hai lựa chọn:

1) Con trỏ lặp qua các mục dữ liệu 2) Nếu ở trên quá chậm, bạn cũng có thể tạo một cửa hàng đối tượng giá trị khóa chuyên dụng có thể n được sử dụng để thực hiện tìm kiếm được lập chỉ mục trong cửa hàng có liên quan. Tùy thuộc vào số lượng yêu cầu tham gia bạn có, đây có thể là một việc vặt.

+0

Cảm ơn @Sidebp Tôi đã xem xét nó. Dường như nó hỗ trợ lưu trữ cục bộ theo mặc định. Trong khi đó tôi thích nếu nó đã làm WebSQL theo mặc định vì nó nhanh hơn rất nhiều nhưng tôi không nghĩ rằng có một tùy chọn để thay đổi thứ tự của bộ điều hợp. WebSQL có thể truy vấn 200.000 hàng trong chưa đầy 2 giây. IndexedDB mất 15 giây. Bộ nhớ cục bộ bị treo sau khoảng 10.000 hàng. – zuallauz

4

Tôi có một mã nguồn mở web database wrapper hỗ trợ cả IndexedDB và WebSql.

Di chuyển phiên bản được xử lý theo nghĩa. Mã sau di chuyển (hoặc khởi tạo) sang phiên bản 2.

schema_ver2 = { 
    version: 2, 
    size: 2 * 1024 * 1024, // 2 MB 
    stores: [{ 
     name: 'ydn_obj', 
     keyPath: 'id.value', 
     indexes: [{ 
      name: 'age', 
      type: 'INTEGER' // type is require for WebSql 
     }] 
    }] 
} 
db = new ydn.db.Storage('db name', schema_ver2) 

Query rất linh hoạt và mạnh mẽ.Ví dụ:

q = db.query('customer').when('age', '>=', 18 , '<', 25).where('sex', '=', 'FEMALE') 
young_girls = q.fetch(10, 2); // limit and offset 

Một lần nữa với hiệu quả hơn truy vấn tầm quan trọng nếu tuổi được lập chỉ mục:

q = db.query('customer', 'age').bound(18, 25, true).where('sex', '=', 'FEMALE') 

Nó cũng hỗ trợ transaction.

p123 = db.tkey('player', 123); 
db.runInTransaction(function() { 
    p123.get().success(function(p123_obj) { 
     p123_obj.health += 10; 
     p123.put(p123_obj); 
    }); 
}, [p123]); 
0

Tôi nghĩ rằng JsStore sẽ hoạt động cho bạn.

phép nói rằng truy vấn của bạn trông giống như thế này trong sql -

select * from table_name nơi column1 = giới hạn 'abc' 20

Trong JsStore - Nó sẽ là

var Connection = new JsStore.Instance("YourDbName"); 
Connection.select({ 
    From: "table_name" 
    Where: { 
     Column1: 'abc', 
    }, 
    Limit:20, 
    OnSuccess:function (results){ 
     console.log(results); 
    }, 
    OnError:function (error) { 
     console.log(error); 
    } 
}); 

Vì vậy, bạn có thể viết sql như truy vấn bằng cách sử dụng JsStore.

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