Mặc dù trong một cơ sở dữ liệu XML nguyên gốc thì chưa bao giờ có hiệu quả nếu thực hiện một phép toán nối để chọn các bản ghi, thường rất tốt nếu tìm nạp dữ liệu từ nhiều loại tài liệu
Trang 16 lời khuyên để tối ưu hóa một cơ sở dữ liệu XML nguyên gốc
Các hướng dẫn thông dụng cho việc sử dụng XQuery với các cơ sở dữ liệu XML nguyên gốc
Donnie Cameron, Nhà phân tích lập trình viên cao cấp, R.R Bowker, LLC
Tóm tắt: RSS, Atom, các ứng dụng (mashup), các yêu cầu tìm kiếm đặc biệt và
các sự phát triển khác đang làm cho các cơ sở dữ liệu XML nguyên gốc cho một
hệ điều hành nào đó trở thành một phần quan trọng trong các ứng dụng và các dịch
vụ tìm kiếm Các loại cơ sở dữ liệu này vượt trội về hiệu quả tìm kiếm thông qua các bộ sưu tập lớn của dữ liệu bán cấu trúc Trong bài này, bạn sẽ tìm thấy một số hướng dẫn thông dụng để đạt hiệu năng tối đa cho các ứng dụng sử dụng XQuery
và các cơ sở dữ liệu XML nguyên gốc
Các cơ sở dữ liệu XQuery và cơ sở dữ liệu XML nguyên gốc
Các từ viết tắt thường dùng
RAM: Random-access memory - Bộ nhớ truy cập ngẫu nhiên
RSS: Really Simple Syndication - Tập hợp dữ liệu đơn giản
XML: Extensible Markup Language - Ngôn ngữ đánh dấu mở rộng
XSLT: Extensible Stylesheet Language Transformations - Các chuyển đổi ngôn ngữ bảng định kiểu mở rộng
Việc sử dụng XQuery (một ngôn ngữ chức năng được thiết kế để truy vấn các bộ sưu tập dữ liệu XML) với các hệ thống cơ sở dữ liệu XML nguyên gốc có thể vô cùng có ích trong một số tình huống Khi dùng cho các truy vấn phức tạp và chủ yếu là chỉ đọc, được so sánh với các cơ sở dữ liệu quan hệ chuẩn, các cơ sở dữ liệu
Trang 2XML nguyên gốc cung cấp các thời gian đáp ứng nhanh hơn và các thời gian phát triển nhanh hơn Với hệ thống chuyển đổi-dữ liệu mạnh nhất, đơn giản nhất có sẵn hiện nay được xây dựng ngay trong ngôn ngữ truy vấn, bạn đạt được các thời gian phát triển nhanh hơn vì bạn không cần phải thiết kế một hệ thống lập chỉ mục toàn-văn bản riêng biệt hay lắp ghép nhiều dữ liệu cho người dùng
Với cái giá chèn và cập nhật chậm hơn, các cơ sở dữ liệu XML nguyên gốc có thể cung cấp các thời gian đáp ứng ngoài hộp tốt hơn hẳn vì chúng giữ cho dữ liệu của mình phần lớn không được tiêu chuẩn hóa, cung cấp các chỉ mục mặc định và làm cho việc sử dụng bộ nhớ RAM có sẵn tốt hơn nhiều Tuy nhiên, khi xử lý các tập hợp dữ liệu rất lớn, bạn có thể cải thiện hơn nữa các thời gian đáp ứng truy vấn của một cơ sở dữ liệu XML nguyên gốc bằng cách làm theo một vài hướng dẫn thông dụng chung sau:
Tránh tiêu chuẩn hóa
Sử dụng các tên phần tử duy nhất
Ước tính trước các giá trị
Chuyển đổi dữ liệu theo các truy vấn của bạn
Mô tả sơ lược mã Xquery
Giữ một danh sách tối ưu hóa
Các hướng dẫn này là phổ biến và thích hợp cho nhiều cơ sở dữ liệu XML nguyên gốc đang có sẵn hiện nay, bao gồm cả DB2® Express-C của IBM, Mark Logic Server, eXist và thậm chí cả XML của Berkeley DB Oracle (xem Tài nguyên để
có các liên kết) Bây giờ chúng ta hãy xem xét chi tiết các hướng dẫn tối ưu hóa
Trang 3
Tránh tiêu chuẩn hóa
Điều quan trọng nhất mà bạn có thể làm khi bạn thiết kế một lược đồ cơ sở dữ liệu XML nguyên gốc là tránh sự cám dỗ về tiêu chuẩn hóa dữ liệu theo cùng một cách
mà bạn làm khi bạn thiết kế một cơ sở dữ liệu quan hệ
Việc tiêu chuẩn hóa dữ liệu cho một cơ sở dữ liệu XML nguyên gốc bao gồm việc thiết kế nhiều loại tài liệu XML liên kết với nhau theo những cách tương tự như những cách mà các bảng mô hình-quan hệ liên kết với nhau Tuy nhiên, trong hầu hết các trường hợp, bạn sẽ cần phải tiêu chẩn hóa một chút nếu có bất kỳ dữ liệu nào cho một cơ sở dữ liệu XML nguyên gốc Thường khá phổ biến là đặt các dữ liệu trong hàng chục bảng mô hình-quan hệ vào trong một loại tài liệu XML đơn
Hầu hết các việc hiện thực của XQuery hiện có ngày nay thực hiện các kết nối kém đến mức ngay cả một truy vấn đơn giản bao gồm một vài nghìn bản ghi có thể mất một khoảng thời gian xử lý không thể chấp nhận được Điều này tạo ra tiêu chí để quyết định xem bạn có nên tiêu chuẩn hóa dữ liệu đơn giản không: Đừng bao giờ tiêu chuẩn hóa dữ liệu đến mức mà một truy vấn được hỗ trợ sẽ cần phải thực hiện một phép toán nối để chọn các bản ghi
Một truy vấn được hỗ trợ là một truy vấn mà bạn có thể mong đợi những người sử dụng tạo dữ liệu của bạn Ví dụ, nếu bạn xây dựng một ứng dụng để bán các băng video, bạn có thể mong đợi một người dùng truy vấn đến tất cả các băng video có một từ khoá nào đó trong phần tiêu đề và do một người cụ thể làm đạo diễn Vì điều này, bạn chắc chắn muốn các tài liệu XML mô tả băng video có chứa tiêu đề của băng video và tên đạo diễn của nó Mặt khác, với ứng dụng cụ thể này, bạn có thể không muốn hỗ trợ một truy vấn cho tất cả các băng video có một từ khoá cụ thể trong tiêu đề và do một người sinh ở New York làm đạo diễn Nói cách khác,
Trang 4với ví dụ ứng dụng video, nếu bạn có thông tin chi tiết về đạo diễn (ngoài tên của đạo diễn), thì thật tốt là xem xét việc giữ nó trong một tài liệu XML riêng biệt
Hãy tưởng tượng một cơ sở dữ liệu có hai loại tài liệu XML liên kết, video-rec và director-rec, cái trước mang thông tin chi tiết về các băng video bao gồm một trình định danh director-rec, cái sau mang thông tin chi tiết về các đạo diễn Truy vấn với một bản ghi có một từ khóa trong tiêu đề và một đạo diễn sinh ở New York là một truy vấn phải thực hiện một phép toán nối để chọn các bản ghi Như nói ở trên, có lẽ là không tốt để hỗ trợ cho loại truy vấn này vì nó còn hơn một truy vấn khai phá-dữ liệu, không thực sự là loại truy vấn mà hầu hết những người dùng đang duyệt web một loại cửa hàng video trực tuyến Tuy nhiên, trừ khi bạn có các
lý do cụ thể để di chuyển các thông tin chi tiết về đạo diễn tới một loại tài liệu riêng biệt, bạn nên giữ nó trong tài liệu video-rec
Mặc dù trong một cơ sở dữ liệu XML nguyên gốc thì chưa bao giờ có hiệu quả nếu thực hiện một phép toán nối để chọn các bản ghi, thường rất tốt nếu tìm nạp
dữ liệu từ nhiều loại tài liệu XML khi chuyển đổi dữ liệu từ các kết quả tìm kiếm Cửa hàng video mà tôi đã mô tả có thể đưa ra các kết quả một cách dễ dàng và có hiệu quả bao gồm nơi sinh của đạo diễn, dù cần đến vị trí yêu cầu tìm nạp dữ liệu
từ một tài liệu không thuộc các kết quả tìm kiếm ban đầu Các hoạt động cần thiết
để lắp ghép các kết quả theo cách này bị hạn chế trong một vài bản ghi mà ứng dụng đó đã chọn và nó lên kế hoạch để hiển thị các bản ghi đó; đó là tính toán và các yêu cầu bộ nhớ là không đáng kể so với những gì cần thiết để kết nối nhiều loại tài liệu trong một truy vấn tìm kiếm chung
Sử dụng các tên phần tử duy nhất
Trang 5Các phần tử duy nhất là các phần tử luôn luôn tham chiếu đến một phần tử tương đương trong một tài liệu XML Các phần tử không duy nhất là các phần tử có thể
xuất hiện ở bất cứ đâu trong tài liệu XML và cần phải đặt trước một đường dẫn có nghĩa Ví dụ, nếu một tài liệu XML có chứa 10 loại nút hoàn toàn khác nhau và mỗi loại bao gồm một phần tử ngày làm phần tử con cháu, thì phần tử ngày là một tên của phần tử không duy nhất Việc sử dụng các tên phần tử không duy nhất có thể cản trở khả năng của bạn để đánh giá hoặc mô tả một số lựa chọn thay thế XQuery hoặc XPath cho việc định vị dữ liệu của bạn Ví dụ, các tên phần tử không duy nhất có thể khiến bạn không đánh giá đúng mã thực hiện tìm kiếm chỉ mục ít hơn Ngoài ra, các tên phần tử không duy nhất có thể thu nhận các cách hỗ trợ mới nổi cho các kết quả tìm kiếm nhiều nhánh
Những phần sau sẽ đưa ra các ví dụ về các loại tối ưu hóa mà bạn có thể hỗ trợ bằng cách thay đổi thiết kế của một tài liệu giống như trong Liệt kê 1 để cho nó sử dụng các tên phần tử khác nhau
Liệt kê 1 Tài liệu cơ bản với các tên phần tử không duy nhất
Trang 9Thực hiện tìm kiếm chỉ mục ít hơn
Để có được những cái tên đầu tiên của các sinh viên có họ là Silver, bạn có thể sử dụng một biểu thức XPath như trong Liệt kê 2
Liệt kê 2 Biểu thức Xpath tìm họ Silver
: /class-info/students/student/name[last = "Silver"]/first
Nếu bạn đã hạn chế dữ liệu để dữ liệu hiển thị trong một tài liệu duy nhất trong Liệt kê 1, thì việc đánh giá biểu thức XPath trong Liệt kê 2 luôn luôn trả về kết quả phù hợp trong Liệt kê 3
Liệt kê 3 Kết quả của XPath
<first>Andrew</first>
<first>Bruce</first>
Trang 10Nếu dữ liệu không được đánh chỉ mục, thì Liệt kê 2 luôn luôn là cách nhanh nhất
để nhận được các kết quả đó Biểu thức này giới hạn số lượng các nhánh mà cơ sở
dữ liệu phải tìm kiếm để tìm các phần tử liên quan
Tuy nhiên, nếu dữ liệu được đánh chỉ mục, thì tùy thuộc vào việc thực hiện cơ sở
dữ liệu cụ thể mà bạn sử dụng và miễn là bạn có một tập hợp dữ liệu rất lớn, một biểu thức giống như biểu thức trong Liệt kê 4 thường có thể giải quyết nhanh hơn
Liệt kê 4 Biểu thức Xpath để sử dụng khi dữ liệu được đánh chỉ mục
: //name[last = "Silver"]/first
Lý do của việc cải thiện tiềm năng là hệ thống phải xem xét các phần tử ít hơn trong chỉ mục Tuy nhiên, do thiết kế của tài liệu trong Liệt kê 1, trong đó sử dụng các tên phần tử không duy nhất, nên XPath trong Liệt kê 4 trả về các kết quả
không đúng; các kết quả đó bao gồm tên của giáo viên, Dan Thiết kế này ngăn cản bạn khỏi mô tả các truy vấn sử dụng các chỉ mục ít hơn Một thiết kế tốt hơn là thay thế các tên phần tử không duy nhất trong Liệt kê 1 bằng các tên phần tử duy nhất, như Liệt kê 5 mô tả
Liệt kê 5 Thay thế các tên phần tử không duy nhất trong Liệt kê 1 bằng các tên phần tử duy nhất
Trang 11Hỗ trợ các kết quả tìm kiếm nhiều nhánh
Mục tiêu của việc tìm kiếm nhiều nhánh là để hiển thị các liên kết cho phép người dùng thu hẹp nhanh chóng và trực quan các kết quả tìm kiếm theo các trục khác nhau Trong một ứng dụng có hỗ trợ các kết quả tìm kiếm nhiều nhánh, một truy vấn liệt kê tất cả các giáo viên trong cơ sở dữ liệu có thể trả về thông tin như thế trong giao diện người dùng (xem Liệt kê 6)
Liệt kê 6 Tìm kiếm nhiều nhánh
•Tabor, Gavin
Trang 12•Lusher Elementary School (35)
•Academy of the Sacred Heart (34)
•Isidore Newman School (32)
•Audubon Charter School (28)
•Benjamin Franklin Elementary Math-Science Magnet (25)
•Grades
Trang 13số giáo viên mà bạn sẽ kết thúc với số lượng đó nếu bạn nhấn vào liên kết đó Các kết quả tìm kiếm nhiều nhánh thường chỉ hiển thị một vài giá trị có thể cho từng nhánh Khi số lượng các giá trị riêng biệt cho một nhánh là nhỏ, như là trường hợp của nhánh Grades, ứng dụng thường hiển thị tất cả các nhánh theo thứ tự trong đó chúng có nghĩa nhất Tuy nhiên, khi một nhánh bao gồm nhiều giá trị có thể, thì ứng dụng đó thường chỉ hiển thị các giá trị sẽ trả về nhiều kết quả nhất và thường hiển thị các giá trị đó theo thứ tự số lượng các kết quả giảm dần
Một số cơ sở dữ liệu XML nguyên gốc đang kết hợp hỗ trợ cho các tìm kiếm nhiều nhánh, nhưng chúng yêu cầu các chỉ mục đặc biệt để cung cấp hiệu năng tốt nhất Một thuật toán XQuery điển hình để thu thập các giá trị hiển thị cho một nhánh nhanh chóng trở thành một nút cổ chai khi số lượng các bản ghi trong cơ sở
dữ liệu tăng lên và khi số lượng các giá trị có thể cho một nhánh tăng lên Đối với một cơ sở dữ liệu lớn có hàng nghìn giá trị nhánh, thì đúng là một thuật toán như vậy không thể thực hiện được Để cung cấp sức mạnh tìm kiếm nhiều nhánh, các máy XML nguyên gốc cần có khả năng xây dựng các từ vựng từ các giá trị mà
Trang 14một phần tử nhận trong cơ sở dữ liệu Các từ vựng này có thể được triển khai thực hiện từ các chỉ mục đặc biệt, lần lượt có thể yêu cầu các tên phần tử duy nhất
Nếu bạn có một cơ sở dữ liệu XML nguyên gốc tương đối nhỏ không hỗ trợ tìm kiếm nhiều nhánh và bạn cần phải viết mã riêng của mình để hỗ trợ chức năng như vậy, bạn sẽ thấy tên phần tử duy nhất là cần thiết như thế nào đối với mã của bạn cũng như chúng hướng tới mã hỗ trợ tìm kiếm nhiều nhánh đã tồn tại trong các cơ
sở dữ liệu cao cấp hơn
Ước tính trước các giá trị
Ý định thêm dữ liệu dư thừa vào một tài liệu XML là ý định dị thường với một người quản trị cơ sở dữ liệu quan hệ dày dạn Tuy nhiên, khi mối quan tâm chính của bạn là hiệu năng — ví dụ, khi bạn phải trả về các kết quả tìm kiếm nhiều nhánh với các truy vấn chạy dựa vào hàng chục triệu bản ghi — việc ước tính trước một số giá trị dựa trên dữ liệu hiện có trong tài liệu XML và sau đó thêm các kết quả vào tài liệu XML có thể giúp cải thiện đáng kể các thời gian đáp ứng Các
cơ sở dữ liệu XML nguyên gốc là tất cả về việc hy sinh bộ nhớ và chấp nhận dư thừa để đổi lấy hiệu năng
Giả sử bạn có một bộ các tài liệu XML siêu dữ liệu hình ảnh Mỗi tài liệu trong các tài liệu XML này có một hoặc nhiều phần tử trong các phần tử camera (máy ảnh), device (thiết bị) và scanner (máy quét), tất cả lưu giữ thông tin về thiết bị đã tạo nên hình ảnh Phần tử device biểu diễn một nút phức tạp bao gồm một phần tử với tên của thiết bị và một số các phần tử khác với thông tin bổ sung Trong ví dụ này, tất cả các phần tử device cần thiết trong các phần khác của ứng dụng và do đó không thể bị loại bỏ Ứng dụng này triển khai thực hiện các tìm kiếm nhiều nhánh
Trang 15và đòi hỏi một nhánh có tên là scanning device (thiết bị quét) để chỉ ra tên của thiết bị đã tạo nên hình ảnh
Tương tự, các tài liệu siêu dữ liệu hình ảnh có các phần tử chiều cao và chiều rộng, trừ khi ứng dụng đòi hỏi một nhánh gọi là size (kích thước), có thể bắt nguồn dễ dàng từ các phần tử height (chiều cao) và width (chiều rộng)
Trang 16</device>
<width>1200</width>
<height>1024</height>
</image>
Liệt kê 8 là ví dụ thứ hai
Liệt kê 8 Ví dụ về tài liệu siêu dữ liệu hình ảnh thứ hai
<image>
<id>123456788</id>
<date>2009-11-16T03:14:42</date>
<description>Empire State Building</description>
<scanner>Pixel Maker LS</scanner>
<width>800</width>
<height>600</height>
</image>
Trang 17Bây giờ hãy hình dung một cơ sở dữ liệu có đủ các bản ghi này mà một truy vấn
về các hình ảnh đã nhận được vào 16.11.2009 trả về 5.000 hình ảnh Trong số này, ứng dụng hiển thị 30 hình ảnh Khung nhìn các kết quả-tìm kiếm hiển thị các nhánh khác nhau, bao gồm cả scanning device và size, cung cấp một danh sách ngắn của các giá trị với mỗi nhánh Các giá trị của nhánh scanning device bao gồm Scanmelter 2000 (1202) và Pixel Maker LS (207) Các giá trị của nhánh size bao gồm 1200x1024 (2302) và 800x600 (113)
Hãy nghĩ về đoạn mã mà bạn có thể viết để đáp ứng các yêu cầu này Thật khá dễ dàng để viết đoạn mã này, nhưng nó không mở rộng tốt do số lượng công việc mà
nó phải làm để đếm số lượng các bản ghi thỏa mãn truy vấn mà mỗi giá trị nhánh đại diện Có thể có hàng trăm các giá trị nhánh; đoạn mã này cần tính toán tổng số kết quả cho mỗi một trong số chúng để xác định năm giá trị nhánh nào cần liệt kê cho nhánh này Tình hình xấu đi nhanh chóng với số lượng các bản ghi trong cơ sở
dữ liệu, với số nhánh mà ứng dụng của bạn đang hiển thị và với số các giá trị nhánh có thể cho mỗi nhánh Nếu ứng dụng của bạn đang hiển thị 50 nhánh và xử
lý hàng triệu bản ghi, thì bạn thực sự không có một tùy chọn nào cả, nhưng cần ước tính trước các giá trị nhánh và đưa chúng vào trong bản ghi đó
Các tài liệu XML trong Liệt kê 7 và Liệt kê 8 sẽ nhận hai phần tử mới: name và size Sự thay đổi đơn giản đó sẽ cho phép thực hiện với quy mô tốt hơn nhiều
Chuyển đổi dữ liệu theo các truy vấn của bạn