Các Storage engine trong kiến trúc MySQL

Một phần của tài liệu Mở rộng truy vấn MySQL và ứng dụng chuyển đổi dữ liệu dạng bảng sang JSON (Trang 32)

2.4.1 Các Storage engine.

MySQL hỗ trợ các kỹ thuật lưu trữ khác nhau để điều khiển tạo ra các bảng phục vụ cho các mục đích ứng dụng khác nhau của người dùng. Với kiến trúc MySQL hoàn toàn độc lập với các ứng dụng và DBA ở tất cả các cấp độ thực thi và chi tiết ở mức độ lưu trữ, cung cấp một mô hình ứng dụng phù hợp và dễ dàng với các API.

Kiến trúc kỹ thuật lưu trữ trong MySQL có thể thêm các kỹ thuật lưu trữ khác được mô tả ở hình bên dưới.

Kiến trúc có thể gắn thêm được các kỹ thuật lưu trữ cung cấp một tập các chuẩn để quản lý và hỗ trợ các dịch vụ thông dụng ở tất cả các kỹ thuật. Chính các kỹ thuật lưu trữ là các thành phần của máy chủ cơ sở dữ liệu, thực thi các hành động trên các dữ liệu và được duy trì ở cấp độ máy chủ vật lý.

Kiến trúc này rất có hiệu quả và các mô đun cung cấp các lợi ích to lớn cho những người muốn nhắm đến mục tiêu cụ thể, chẳng hạn những ứng dụng về kho dữ liệu, xử lý giao dịch hoặc các ứng dụng có tính sẵn sàng cao.

Hình 2.2 Kiến trúc MySQL với các kỹ thuật lƣu trữ có thể gắn thêm3

3

Với phiên bản hiện tại MySQL 5.1 đã hỗ trợ các kỹ thuật lưu trữ sau:

- MyISAM: là kỹ thuật lưu trữ mặc định (trước phiên bản 5.1), và được sử dụng

ở hầu hết các ứng dụng web, ứng dụng kho dữ liệu và những môi trường ứng dụng ứng dụng khác.

- InnoDB: Một kỹ thuật lưu trữ an toàn trong trong giao dịch như commit,

rollback và khả năng phục hồi để bảo vệ dữ liệu người dùng. InnoDB cung cấp khóa hàng, và cũng cung cấp tính toàn vẹn dữ liệu bằng các ràng buộc toàn vẹn tham chiếu khóa ngoài.

- Infobright: Đây là một kỹ thuật mới nhất của cộng đồng mã nguồn mở, hoàn

toàn miễn phí. Với kỹ thuật này chúng ta có thể sử dụng vào nhiều ứng dụng khác nhau đặc biệt là ứng dụng trong kho dữ liệu. Vì không gian lưu trữ và hiệu năng của kỹ thuật này mang lại là vượt trội so với các kỹ thuật trước đó.

- Memory: Lưu trữ tất cả dữ liệu trong bộ nhở RAM để truy cập nhanh các ứng

dụng đòi hỏi cao về hiệu năng. Kỹ thuật này trước đây được biết đến như là kỹ thuật HEAP

- Merge: cho phép một DBA hoặc người phát triển nhóm một chuỗi các hoạt

động bảng MyISAM giống nhau và tham chiếu chúng như là những đối tượng. Kỹ thuật này tốt cho môi trường VLDB giống như kho dữ liệu.

- Archive: cung cấp giải pháp hoàn hảo để lưu trữ và lấy số lượng lớn

- Federated: cung cấp khả năng liên kết các máy chủ riêng biệt MySQL để tạo ra

một cơ sở dữ liệu logic từ các máy chủ vật lý.

- NDBCLUSTER (cũng được biết đến như NDB): đây là một kỹ thuật phân cụm

cơ sở dữ liệu đặc biệt phù hợp cho các ứng dụng đòi hỏi cao về thời gian hoạt động và tính sẵn dùng.

- CSV: là kỹ thuật lưu trữ dữ liệu trên file văn bản, sử dụng các giá trị định dạng

bằng dấu.

- Blackhole: Mục đích của kỹ thuật này phục vụ trong thiết kế cơ sở dữ liệu phân

tán.

2.4.2 Các điểm ƣu việt của Storage engine.

MySQL hỗ trợ rất nhiều các kỹ thuật lưu trữ cho các miền ứng dụng khác nhau. Ứng với mỗi kỹ thuật, chúng ta sẽ có nhiều những ưu điểm mà các kỹ thuật này mang lại, chúng ta có thể chia ra hai phần đó là kỹ thuật hỗ trợ giao dịch và kỹ thuật không hỗ trợ giao dịch để thấy được các ưu điểm mà các kỹ thuật này mang lại.

Các kỹ thuật hỗ trợ giao dịch

- An toàn hơn, ngay cả khi MySQL bị treo hoặc chúng ta gặp vấn đề ở phần cứng, chúng ta vẫn có thể nhận lại dữ liệu vì các kỹ thuật này sẽ tự động sửa lỗi hoặc sao lưu lại từ nhật ký giao dịch.

- Với cơ chế COMMIT và ROLLBACK trong kỹ thuật lưu trữ sẽ giúp cho các giao dịch trong thương mại, ngân hàng an toàn và tin cậy hơn.

- Chúng ta có thể kết hợp nhiều khối lệnh và chấp nhận chúng ở cùng một thời điểm với câu lệnh COMMIT.

- Chúng ta có thể thực hiện lệnh ROLLBACK để bỏ qua những thay đổi của chúng ta (nếu autocommit bị vô hiệu hóa).

- Nếu chúng ta cập nhật bị lỗi thì tất cả những thay đổi của chúng ta vẫn hoàn nguyên.

- Trong giao dịch việc cập nhật và đọc thường xảy ra đồng thời, các kỹ thuật lưu trữ đã giải quyết tốt vấn đề này bằng cách khóa hàng thay vì khóa bảng.

Các kỹ thuật không hỗ trợ giao dịch

- Các truy vấn trên các kỹ thuật này là rất nhanh vì không phải truy vấn trên các tham chiếu.

- Chi phí không gian lưu trữ là rất thấp.

- Yêu cầu ít bộ nhớ cho việc cập nhật.

Chúng ta không thể kết hợp các bảng có hỗ trợ giao dịch và không hỗ trợ giao dịch vì mỗi kỹ thuật lưu trữ có bản đều tự do chúng thực hiện giao dịch, nếu khi có vấn đề xay ra thì các bảng không hỗ trợ giao dịch sẽ không truy ngược lại và khó có thể phục hồi lỗi và trả lại toàn bộ các điểm giao dịch đang còn tranh luận.

CHƢƠNG 3: MỞ RỘNG TRUY VẤN CHUYỂN ĐỔI DỮ LIỆU SANG DẠNG JSON

Đối với những ứng dụng đặc thù chuyên biệt người ngoài những hàm sẵn có trong hệ quản trị cơ sở dữ liệu MySQL người sử dụng có thể tạo ra những hàm mới phù hợp với ứng dụng của họ. MySQL cung cấp 3 cách khác nhau để tạo ra những hàm mới :

Hàm do người dùng định nghĩa hàm này sẽ được biên dịch thành các file liên kết động và được đưa vào MySQL bằng cách sử dụng câu lệnh Create function, hàm này thường được viết bằng ngôn ngữ C hoặc C++.

Có thể xây dựng các hàm như các hàm được xây dựng sẵn trong MySQL các hàm này được biên dịch vào mysqld.

Các Strore Procedure các hàm này được xây dựng từ các hàm của MySQL tuy nhiên hàm này được viết bằng ngôn ngữ truy vấn SQL.

Mỗi một cách thêm mới hàm trong MySQL đều có những ưu nhược điểm riêng : Đối với các hàm do người dùng định nghĩa chúng ta phải biên dịch ra thành các file thư viện ở trên máy của chúng ta sau đó đưa lên máy chủ cài MySQL đối với các hàm do MySQL xây dựng sẵn thì không cần cài đặt.

Đối với các hàm do MySQL xây dựng sẵn muốn chỉnh sửa chúng ta phải truy xuất vào mã nguồn của MySQL còn các hàm UDF chỉ cần cài bản đóng gói của MySQL là được.

Trong khuôn khổ của luận văn này chúng tôi chỉ tập trung nghiên cứu cách xây dựng hàm do người sử dụng định nghĩa để ứng dụng xây dựng các hàm chuyển dữ liệu truy vấn sang dạng JSON.

3.1 Hàm do ngƣời dùng định nghĩa (UDF)

Một trong những ưu điểm của hệ quản trị CSDL MySQL so với những hệ quản trị CSDL khác là khả năng linh hoạt có nghĩa là MySQL cho phép người sử dụng có thể định nghĩa các hàm phù hợp với ứng dụng của người dùng sau đó thêm vào MySQL và sử dụng như các hàm được xây dựng sẵn bởi MySQL.

Các hàm do người dùng định nghĩa phải được viết bằng ngôn ngữ lập trình C hoặc C++ và hệ điều hành phải hỗ trợ chức năng tải các thư viện động. Bản phân phối mã nguồn của MySQL có một file sql/udf_example.c file này định nghĩa 5 hàm mới của MySQL xem file này chúng ta có thể biết được một hàm UDF làm việc như thế nào file thư viện include/mysql_com.h định nghĩa về cấu trúc dữ liệu. Các hàm UDF bao gồm các đoạn mã sẽ trở thành một phần của máy chủ vì vậy khi chúng ta viết các hàm UDF sẽ phải chịu sự ràng buộc bởi bất kỳ các ràng buộc nào trên máy chủ. Ví dụ

khi chúng ta sử dụng các hàm trong thư viện libstdc++ các ràng buộc này có thể thay đổi theo phiên bản của máy chủ CSDL vì vậy chúng ta có thể nâng cấp phiên bản của máy chủ để phù hợp với những thay đổi trong hàm UDF

Các hàm do người dùng định nghĩa cung cấp các tính năng như sau:

 Hàm có thể trả về kiểu số nguyên, kiểu chuỗi, kiểu số thực cũng như chấp nhận nhiều tham số đầu vào cùng kiểu dữ liệu

 Chúng ta có thể tạo ra một hàm đơn giản để điều khiển một dòng tại một thời điểm hoặc hàm tổng hợp để điều khiển một nhóm dòng.

 Thông tin cung cấp trong các hàm cho phép kiểm tra số lượng, kiểu tham số và tên của các tham số của hàm.

 Giá trị trả về của hàm có thể là Null hoặc thông báo lỗi xảy ra.

Với mỗi hàm nếu chúng ta muốn sử dụng trong câu lệnh SQL chúng ta nên định nghĩa tương ứng trong C hoặc C++. Ví dụ tên “xxx” được sử dụng cho tên một hàm để phân biệt giữa SQL và C (C++) XXX() viết hoa là một hàm trong SQL còn xxx() là một hàm trong C/C++

Khi sử dụng C++ chúng ta có thể đóng gói hàm trong C với từ khóa extern "C" { ... } điều này sẽ bảo đảm rằng tên của hàm trong C++ có thể đọc được khi hoàn thành hàm UDF.

Hàm trong C/C++ mà chúng ta phải viết để thực thi giao diện XXX() là xxx()

Các kiểu dữ liệu của SQL tương ứng với kiểu giá trị trả về trong C/C++ theo bảng 3.1

SQL Type C/C++ Type

STRING char *

INTEGER long long

REAL double

Bảng 3.1 Kiểu dữ liệu của C,C++ tƣơng ứng với kiểu dữ liệu trong MySQL

3.1.1 Hàm UDF đơn giản

Trong phần này sẽ mô tả các hàm khác nhau cần định nghĩa khi tạo các hàm UDF đơn giản. Khi tạo ra một hàm UDF đơn giản cần phải tạo ra ba hàm, hai trong số ba hàm đó có thể tùy chọn.

Hàm xxx_init(): Hàm tùy chọn. Khi một truy vấn SQL gọi hàm UDF thì hàm

init sẽ được gọi đầu tiên nếu nó tồn tại. Hàm này có nhiệm vụ sau đây: o Kiểm tra số tham số trong hàm xxx().

o Kiểm tra tham số nào là bắt buộc phải có, tham số nào là tùy chọn để chỉ cho Mysql buộc phải có đối số đó khi hàm chính được gọi. o Phân bổ bộ nhớ theo yêu cầu của hàm chính.

o Xác định độ dài tối đa của kết quả.

o Xác định số chữ số thập phân sau dấu phẩy. o Xác định xem kết quả trả về có thể là Null

Hàm xxx(): Hàm chính (hàm bắt buộc) sau khi hàm khởi tạo xxx_init() được

gọi thì hàm xxx() sẽ được gọi hàm này có trách nhiệm xử lý dữ liệu và trả về kết quả.

Hàm xxx_denit(): Hàm tùy chọn Khi hàm chính kết thúc và trả về kết quả hàm

hủy xxx_denit() sẽ được gọi nếu nó tồn tại. Hàm này có chức năng hủy giá trị khởi tạo cho hàm xxx() nó sẽ giải phóng bộ nhớ được tạo ra bởi chức năng khởi tạo. Khi 1 câu lệnh SQL XXX() được gọi, MySQL gọi hàm khởi tạo xxx_init() để nó thực thi các thiết lập cần thiết chẳng hạn như kiểm tra đối số hoặc cấp phát bộ nhớ nếu nó trả về lỗi MySQL hủy bỏ câu lệnh SQL và thông báo lỗi và không gọi hàm hủy nếu không lỗi MySQL gọi hàm chính XXX() cho mỗi hàng sau khi tất cả các hàng được xử lý xong MySQL gọi hàm xxx_deinit() chức năng hủy được gọi để dọn dẹp bộ nhớ.

Khi một hàm UDF đơn giản được gọi thứ tự gọi các hàm sẽ như sau:

MySQL gọi hàm xxx() cho mỗi dòng trả về của truy vấn SQL. Kết quả trả về của hàm xxx sẽ là kết quả trả về của hàm UDF.

Hàm xxx_init

Hàm xxx_init được khai báo như sau

my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); xxx_init() xxx() xxx() ……. xxx_denit()

Các tham số của hàm khỏi tạo xxx_init()

initid

Tham số initid có mặt ở cả ba hàm nó có kiểu dữ liệu là kiểu cấu trúc UDF_INIT

để trao đổi thông tin giữa các hàm. Các biến thành viên trong cấu trúc của UDF_INIT

được mô tả như dưới đây. Hàm khởi tạo phải cần phải điền giá trị vào bất kỳ thành viên nào muốn nó muốn thay đổi.

o my_bool maybe_null

Hàm xxx_init() thiết lập maybe_null là 1 nếu xxx() trả về giá trị NULL. Giá trị mặc định là 1 nếu bất kỳ tham số được khai báo là maybe_null

o unsigned int decimals :

Biến này chỉ số lượng số các số thập phân sau dấu chấm thập phân. Giá trị mặc định số lượng tối đa của số chữ số thập phân trong các đối số được truyền vào trong hàm chính ví dụ có 3 đối số có giá trị là 1,34, 1,345, và 1.3 thì decimals mặc định sẽ là 3, bởi vì 1,345 có 3 chữ số thập phân.

Đối với các đối số không thiết lập số chữ số thập phân thì giá trị này được thiết lập là 31 nhiều hơn số chữ số thập phân tối đa của các kiểu dữ liệu DECIMAL, FLOAT và DOUBLE.

Giá trị số chữ số thập phân được khởi tạo là một giá trị mặc định nó có thể được thay đổi trong hàm đề phù hợp với các tính toán mặc định là số chữ số thập phân lớn nhất trong các đối số.

o Unsigned int max_length

Biến này chỉ chiều dài tối đa của kết quả. Giá trị mặc định của max_length khác nhau tùy thuộc vào loại kết quả của hàm. Đối với hàm trả về kết quả là chuỗi thì

max_length mặc định là chiều dài của đối số có độ dài dài nhất. Đối với số nguyên mặc định là 21 chữ số. Đối với các hàm trả về số thực mặc định là 13 cộng với số lượng chữ số thập phân được xác định bởi initid-> decimals. (Đối với các hàm trả về kết quả là số chiều dài bao gồm cả dấu hoặc các ký tự dấu thập phân.)

Nếu chúng ta muốn thiết lập giá trị trả về là một giá trị blob ta có thể thiết lập max_length 65KB hoặc 16MB. Bộ nhớ này không được phân bổ.

o char *ptr

Một con trỏ mà hàm có thể sử dụng cho mục đích riêng ví dụ hàm có thể sử dụng initid->ptr để giao tiếp giữa các bộ nhớ được cấp phát. Hàm xxx_init() có thể cấp phát bộ nhớ sau đó gán vào con trỏ này.

Trong hàm xxx() và xxx_deinit(), con trỏ initid->ptr được sử dụng để giải phóng bộ nhớ.

o my_bool const_item

Hàm xxx_init() thiết lập const_item là 1 nếu xxx() luôn trả về giá trị giống nhau ngược lại được thiết lập là 0.

args

Đây là một mảng bao gồm các tham số đầu vào. Tham số này sẽ được trình bày kỹ hơn ở phần xử lý tham số.

message

Đây là một con trỏ kiểu ký tự lưu trữ các thông báo khi có bất kỳ lỗi nào xảy ra trong quá trình thực hiện. Bộ nhớ cho con trỏ này mặc định là 200 ký tự.

Hàm xxx_init trả về kết quả là kiểu Boolean nếu hàm này thực hiện thành công nó sẽ trả về kết quả là 1 (true). Nếu có lỗi xảy ra trong quá trình thực hiện nó sẽ trả về kết quả là 0(false) và đưa ra thông báo lỗi tại tham số message.

Hàm xxx()

Hàm chính xxx() cần phải được khai báo như các ví dụ dưới đây kiểu dữ liệu trả về và các tham số khác nhau phụ thuộc vào kết quả trả về. Kết quả trả về có thể là một trong những kiểu dữ liệu sau STRING, INTEGER, REAL.

Đối với hàm trả về kết quả là chuỗi ký tự (String) được khai báo như sau:

char *xxx(UDF_INIT *initid, UDF_ARGS *args,char *result, unsigned long *length,char *is_null, char *error);

Với hàm trả về kết quả là số nguyên (INTEGER) được khai báo như sau:

long long xxx(UDF_INIT *initid, UDF_ARGS *args,char *is_null, char *error);

Với hàm trả về kết quả là số thực (REAL) được khai báo như sau:

double xxx(UDF_INIT *initid,UDF_ARGS *args,char *is_null, char *error);

Hàm trả về kết quả DECIMAL được khai báo tương tự như hàm trả về kiếu chuỗi

Các tham số trong hàm chính xxx()

Initid

Tham số này tương tự tham số initid của hàm xxx_init()

is_null

Một phần của tài liệu Mở rộng truy vấn MySQL và ứng dụng chuyển đổi dữ liệu dạng bảng sang JSON (Trang 32)

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

(63 trang)