Datastore 1 Giới thiệu

Một phần của tài liệu THƯƠNG MẠI ĐIỆN TỬ TẠI VIỆT NAM (Trang 27 - 36)

2.2.3.1 Giới thiệu

Kho dữ liệu của App Engine đem lại khả năng lưu trữ mạnh mẽ cho ứng dụng web, và tốc độ khi truy cập dữ liệu. Ứng dụng tạo ra những thực thể (entity) và dữ liệu được chứa trong thuộc tính (property) của mỗi thực thể. Tất cả các câu truy vấn dữ liệu

đều đã được đánh chỉ mục từ trước để đem lại sự nhanh nhất khi truy vấn số lượng lớn dữ liệu.

App Engine cung cấp 2 sự lựa chọn cho chúng ta về kho dữ liệu, bạn chỉ có thể chọn lựa khi bạn là admin của hệ thống. Khi đó hãy vào Admin Console để tùy chỉnh:

- Kho dữ liệu Master/Slave: dựa theo mô hình hệ thống master-slave, hệ thống sẽ ghi lại dữ liệu một cách bất đồng bộ đối với trung tâm dữ liệu vật lý. Ở bất cứ thời điểm nào cũng chỉ có 1 trung tâm dữ liệu là chủ (master) mà thôi. Đảm bảo tính sẵn sàng cho việc đọc và truy vấn dữ liệu, nhưng phải mất một ít thời gian khi trung tâm dữ liệu gặp sự cố hoặc thời gian chết. Tùy chọn này cần lượng lưu trữ và CPU thấp nhất. Đây là tùy chọn mặc định.

- Kho dữ liệu High Replication: dựa theo giải thuật Paxos, cung cấp tính sẵn sàng cho việc đọc và ghi dữ liệu rất cao. Nhưng tùy chọn này cần lượng lưu trữ và CPU cao gấp 3 lần so với tùy chọn Master/Slave.

Hình 2.7: Màn hình thiết lập tuỳ chọn các lưu trữ của datastore GAE lưu trữ các object còn được biết đến là “thực thể”. Mỗi thực thể có nhiều thuộc tính. Mỗi thuộc tính có kiểu xác định.

Không giống như các hệ cơ sở dữ liệu truyền thống GAE sử dụng cấu trúc phân tán để tự động quản lý việc mở rộng cho một khối lượng dữ liệu rất lớn. Datastore của GAE khác so với cơ sở dữ liệu truyền thống ở việc miêu tả mối ràng buộc giữa các object. Chẳng hạn như 2 thực thể cùng loại nhưng có thuộc tính khác nhau. Những thực thể khác nhau có cùng tên thuộc tính nhưng khác nhau về kiểu giá trị. Tuy nhiên

interface giao tiếp với datastore có nhiều đặc điểm giống với cơ sở dữ liệu truyền thống, đặc điểm độc đáo của datastore ngụ ý rằng việc thiết kế và quản lý thì khác nhau nhằm tận dụng khả năng quy mô tự động.

Một số khái niệm trong datastore:

Entities

Một ứng dụng App Engine có thể chứa dữ liệu trong một hay nhiều thực thể datastore. Mỗi thực thể có một hay nhiều thuộc tính, mỗi thuộc tính đều có tên và giá trị. Mỗi thực thể đều được phân loại để tiện cho việc truy vấn.

Ở cái nhìn đầu tiên, chúng ta thấy thực thể có thể gần giống các hàng (row) trong một bảng trong cơ sở dữ liệu quan hệ. Và mỗi thuộc tính có thể giống với một cột. Tuy nhiên đối với các thực thể cùng loại với nhau có thể có các thuộc tính khác nhau. Thứ 2, các thực thể có thể có cùng thuộc tính với các thực thể cùng loại khác nhưng khác về kiểu dữ liệu. Một điểm khác nhau nữa giữa thực thể và các hàng (row) là các thực thể có thể có nhiều giá trị cho một thuộc tính đơn lẻ.

Mỗi thực thể có một khóa riêng (key) phân biệt lẫn nhau được cung cấp bởi ứng dụng hoặc do App Engine. Khác với CSDL quan hệ, khoá của thực thể không phải là thuộc tính, nó tồn tại độc lập với thực thể. Khoá của thực thể không được thay đổi khi thực thể đã được tạo ra.

Truy vấn(queries) và chỉ mục (indexes)

Một câu truy vấn trên datastore trả về không hoặc nhiều thực thể cùng loại với nhau. Nó cũng có thể trả về các khóa của thực thể. Câu truy vấn có thể dựa vào các giá trị thuộc tính của thực thể và được sắp xếp theo giá trị của thuộc tính. Câu truy vấn cũng có thể làm việc với các khóa của thực thể.

Với App Engine, mỗi câu truy vấn sẽ có một chỉ mục trong datastore. Khi ứng dụng cần thực hiên một câu truy vấn, thì datastore sẽ tìm chỉ mục của câu truy vấn đó. Khi chúng ta tạo mới một thực thể và cập nhật cái cũ thì datastore cũng sẽ cập nhật lại chỉ mục. Điều này giúp cho câu truy vấn được nhanh hơn.

Phiên giao dịch (Transaction)

Khi một ứng dụng có quá nhiều client liên tục đọc hay ghi cùng một dữ liệu ở cùng một thời điểm, thì phiên giao dịch rất cần thiết để dữ liệu không bị đọc sai. Mỗi phiên giao dịch là đơn vị nhỏ nhất và chỉ có hai trạng thái là thành công hoặc thất bại.

Một ứng dụng đọc hay cập nhật nhiều thực thể trong một phiên giao dịch, nhưng nó phải nói cho App Engine biết những thực thể nào sẽ được cập nhật khi nó tạo ra nhiều thực thể. Ứng dụng làm được điều này bởi việc tạo ra nhóm thực thể. Nhờ nhóm thực thể, App Engine sẽ biết được các thực thể sẽ phân tán như thế nào qua các server, vì thế nó có thể khẳng định chắc chắn là phiên giao dịch thành công hay thất bại. App Engine cũng hỗ trợ những phiên giao dịch nội bộ (local transaction).

Nếu một người dùng cố gắng cập nhật một thực thể trong khi người khác đang cập nhật thực thể đó thì datastore sẽ ngay lập tức trả về một biệt lệ báo lỗi. Trong thuật ngữ database, thì ta nói App Engine sử dụng “optimistic concurrency control”. Với chỉ mục và “optimistic concurrency control”, App Engine được thiết kế giúp cho ứng dụng có thể đọc dữ liệu nhanh hơn và đảm bảo hơn.

2.2.3.2 JDO

GAE cung cấp một số API để làm việc với datastore như : JDO, JPA, Low-API; trong phạm vi khóa luận chúng em sử dụng JDO.

a. Khái niệm

JDO là một interface chuẩn cho việc lưu trữ đối tượng chứa dữ liệu vào cơ sơ dữ liệu. Tiêu chuẩn này định nghĩa các giao diện cho các chú thích đối tượng Java, trích rút các đối tượng với các truy vấn, và tương tác với một cơ sở dữ liệu bằng cách sử dụng transaction. Một ứng dụng có sử dụng giao diện JDO có thể làm việc với các loại cơ sở dữ liệu mà không cần sử dụng bất kỳ mã cơ sở dữ liệu cụ thể, bao gồm cả cơ sở dữ liệu quan hệ, cơ sở dữ liệu phân cấp, và cơ sở dữ liệu đối tượng. Như các tiêu chuẩn giao diện khác, JDO làm đơn việc lưu trữ khác nhau trong ứng dụng của bạn.

Các App Engine Java SDK bao gồm thực hiện JDO 2,3 cho kho dữ liệu App Engine. Thực hiện dựa trên DataNucleus Access Platform, các mã nguồn mở tham khảo thực hiện cho JDO 2.3.

Hình 2.8: Hoạt động của JDO

b. Xác định lớp dữ liệu với JDO

Bạn có thể sử dụng JDO để lưu đối tượng dữ liệu Java( POJOs) trong datastore. Mỗi đối tượng được persistent với PersistenceManager trở thành một thực thể trong datastore. Chúng ta sử dụng chú thích( annotation) để nói với JDO cách lưu trữ và tạo ra đối tượng của lớp dữ liệu.

Ví dụ:

@PersistenceCapable public class FoodStatus { /**ID . */

@PrimaryKey

@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private String foodStatusId;

/** Name . */ @Persistent

private String foodStatusName; /**

* Get value of foodStatusId. * @return the foodStatusId */

public String getFoodStatusId() { return foodStatusId;

} /** /**

* @param foodStatusId the foodStatusId to set */

public void setFoodStatusId(String foodStatusId) { this.foodStatusId = foodStatusId;

} /** /**

* Get value of foodStatusName. * @return the foodStatusName */

public String getFoodStatusName() { return foodStatusName;

} /** /**

* Set the value for foodStatusName.

* @param foodStatusName the foodStatusName to set */

public void setFoodStatusName(String foodStatusName) { this.foodStatusName = foodStatusName;

}} }

Tương ứng 1 Object được lưu bởi JDO sẽ trở thành một thực thể trong App Engine datastore. Khi đó loại thực thể sẽ là tên của class và tên của thuộc tính class là tên thuộc tính của thực thể.

c. Khóa chính:

Mỗi thực thể có một key nhằm xác định tính duy nhất trong GAE. Một key hoàn chỉnh bao gồm Application ID, loại và ID của thực thể( Key cũng chứa thông tin về nhóm thực thể).

Đối tượng key được lưu trữ là một trường của đối tượng, ta xác định khóa chính bằng khai báo @PrimaryKey.

Phân loại:

• Long : có kiểu là long, là id của thực thể được sinh ra tự động bởi datastore. Sử dụng loại này cho đối tượng mà không ở trong một nhóm

thực thể có key của thực thể cha mẹ được sinh ra ngẫu nhiên bởi datastore. Giá trị của key được tạo ra khi đối tượng được lưu.

• Unencoded String : là một chuỗi được cung cấp bởi ứng dụng khi đối tượng được tạo ra. Đối với những đối tượng trong một nhóm mà khóa của thực thể cha mẹ được cung cấp bởi ứng dụng sẽ không sử dụng loại này.

• Key : là đối tượng của com.google.appengine.api.datastore.Key. Giá trị của Key bao gồm : khóa của bố mẹ( nếu có), chuỗi do ứng dụng tạo ra hoặc là ID do hệ thống tự sinh ra.

Ví dụ : import javax.jdo.annotations.IdGeneratorStrategy; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; import com.google.appengine.api.datastore.Key; // ... @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key;

public void setKey(Key key) { this.key = key;

}

Ứng dụng có thể tạo ra một thể hiện của Key sử dụng lớp KeyFactory.

import com.google.appengine.api.datastore.Key;

import com.google.appengine.api.datastore.KeyFactory; // ...

Key key = KeyFactory.createKey(Employee.class.getSimpleName(), "Alfred.Smith@example.com");

Employee e = new Employee(); e.setKey(key);

pm.makePersistent(e);

• Key as Encoded String : tương tự như Key, nhưng giá trị là chuỗi đã được mã hóa.

import javax.jdo.annotations.Extension; import javax.jdo.annotations.IdGeneratorStrategy; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; // ... @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)

@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") private String encodedKey;

Khi sử dụng Key as Encoded String, ta cần cung cấp cách tiếp cận chuỗi hoặc ID của đối tượng với một trường bổ xung như sau:

d. Các thao tác dữ liệu với JDO:

Tạo :

Để lưu trữ một đối tượng dữ liệu đơn giản trong datastore, chúng ta gọi phương thức makePersistent() :

PersistenceManager pm = PMF.get().getPersistenceManager(); import javax.jdo.JDOHelper;

import javax.jdo.PersistenceManagerFactory; public final class PMF {

private static final PersistenceManagerFactory pmfInstance =

JDOHelper.getPersistenceManagerFactory("transactions-optional"); private PMF() {}

public static PersistenceManagerFactory get() { return pmfInstance;

}} }

Phương thức makePersistent() được gọi một cách đồng bộ , nó sẽ không trả về kết quả cho tới khi đối tượng được lưu và chỉ số được cập nhật.

Để lưu nhiều đối tượng trong JDO, ta dùng phương thức makePersistentAll (Collection of objects). Phương pháp này hiệu quả hơn là dùng một loạt lời gọi makePersistent() đơn lẻ.

Xóa:

pm.deletePersistent(e); deletePersistentAll(...)

Lấy dữ liệu : sử dụng Key để truy xuất đối tượng

Key k = KeyFactory.createKey(Employee.class.getSimpleName(), "Alfred.Smith@example.com");

Employee e = pm.getObjectById(Employee.class, k);

Nếu lớp sử dụng trường key là unencoded string ID (String) hoặc numeric ID (Long):

Employee e = pm.getObjectById(Employee.class, "Alfred.Smith@example.com");

Ngoài key, chúng ta có thể truy vấn để trích rút đối tượng.

Thay đổi dữ liệu:

public void updateEmployeeTitle(User user, String newTitle) { PersistenceManager pm = PMF.get().getPersistenceManager(); try {

Employee e = pm.getObjectById(Employee.class, user.getEmail()); if (titleChangeIsAuthorized(e, newTitle) {

e.setTitle(newTitle); } else {

throw new UnauthorizedTitleChangeException(e, newTitle); }

} finally { pm.close(); }

Mọi thao tác cho đối tượng đều được cập nhật tự động vào cơ sở dữ liệu cho đến khi đóng PersistenceManager pm.close();

Chúng ta có thể chỉnh sửa đối tượng để khi đóng PersistenceManager pm.close(); cần khai báo @PersistenceCapable(detachable="true").

e. JDOQL

JDO bao gồm một tập cáo câu truy vấn cho việc trích rút các đối tượng theo một tập các tiêu chí , gọi là JDOQL. Nó không những tham chiếu đến dữ liệu và thuộc tính các lớp một cách trực tiếp mà còn bao gồm việc kiểm tra kiểu dữ liệu cho các tham số và kết quả trả về. JDOQL thì tương tự như SQL, nhưng JDOQL thích hợp hơn cho các cơ sở dữ liệu kiểu hướng đối tượng như datastore của GAE.

Một phần của tài liệu THƯƠNG MẠI ĐIỆN TỬ TẠI VIỆT NAM (Trang 27 - 36)

Tải bản đầy đủ (DOC)

(121 trang)
w