Tìm kiếm hiệu quả không phân biệt dạng chữ với pureXML DB2 Tìm kiếm và sắp xếp dữ liệu XML theo cách không phân biệt dạng chữ Matthias Nicola ([email protected]) Chuyên gia về hiệu năng CSDL IBM Silicon Valley Laboratory 23 10 2009 Các giá trị của các phần tử và các thuộc tính XML, theo định nghĩa, là phân biệt dạng chữ. Ví dụ, nếu bạn tìm kiếm các phần tử <city> cho giá trị "Paris", bạn sẽ không tìm thấy "PARIS" hoặc "paris". Điều này có thể được giải quyết bằng các hàm XQuery như fn:upper-case(), nhưng hiệu năng sẽ không phải luôn luôn tối ưu do việc sử dụng các hàm như vậy cản trở việc sử dụng các chỉ số XML. Bài viết này giải thích cách tạo ra một cơ sở dữ liệu không phân biệt dạng chữ khi sử dụng DB2® pureXML™ và hành vi hay xảy ra trong truy vấn XML và các chỉ mục XML. Tìm kiếm không phân biệt dạng chữ với các hàm chữ hoa và chữ thường Ví dụ sau sẽ cho bạn một sự hiểu biết rõ ràng hơn về tìm kiếm không phân biệt dạng chữ. Liệt kê 1 định nghĩa một bảng có một cột số nguyên (INTEGER) và một cột XML và chèn 7 hàng vào trong bảng đó. Mỗi hàng có chứa một tài liệu khách hàng nhỏ có chứa một phần tử XML <city>. Các giá trị trong phần tử này khác nhau về chữ hoa và chữ thường. Một số giá trị tất cả là chữ hoa, một số giá trị tất cả là chữ thường và một số trường hợp trộn lẫn ("ký tự chữ hoa đầu tiên"). Điều này có thể xảy ra khi dữ liệu này đã đến từ một loạt các ứng dụng có sử dụng các quy tắc khác nhau để nhập vào dữ liệu chữ hoa và chữ thường. Liệt kê 1. Bảng và dữ liệu mẫu CREATE TABLE customer (id INTEGER, xmldoc XML); INSERT INTO customer (2,'<Customer (3,'<Customer (4,'<Customer (5,'<Customer (6,'<Customer (7,'<Customer (id, xmldoc) VALUES (1,'<Customer id="1"><city>PARIS</city></Customer>'), id="2"><city>Tokyo</city></Customer>'), id="3"><city>tokyo</city></Customer>'), id="4"><city>PARIS</city></Customer>'), id="5"><city>paris</city></Customer>'), id="6"><city>Delhi</city></Customer>'), id="7"><city>Paris</city></Customer>'); © Copyright IBM Corporation 2009 Tìm kiếm hiệu quả không phân biệt dạng chữ với pureXML DB2 Nhẫn hiệu đăng ký Trang 1 của 7 developerWorks® ibm.com/developerWorks/vn/ Một ứng dụng truy vấn các tài liệu XML này để tìm kiếm các khách hàng với một thành phố cụ thể hầu như đòi hỏi tìm kiếm không phân biệt dạng chữ. Ví dụ, bạn có thể muốn tìm tất cả các khách hàng ở Paris và hy vọng sẽ lấy ra hàng 1, 4, 5 và 7. Tuy nhiên, nếu bạn tìm kiếm giá trị "Paris", thì chỉ có hàng 7 được trả về. Để tóm lấy tất cả bốn hàng mà bạn cần, bạn có thể sử dụng hàm XQuery fn:upper-case() để biến đổi các giá trị phần tử thành phố thành dạng chữ hoa và so sánh chúng với ""PARIS". Điều này được chỉ ra trong truy vấn trong Liệt kê 2 nó trả về tất cả bốn khách hàng ở Paris. Liệt kê 2. Chọn các khách hàng ở Paris SELECT id, XMLCAST( XMLQUERY('$XMLDOC/Customer/city') AS VARCHAR(15)) AS city FROM customer WHERE XMLEXISTS('$XMLDOC/Customer[fn:upper-case(city) = "PARIS"]'); Nếu truy vấn của bạn sử dụng một dấu tham số cho giá trị tìm kiếm, rồi tham số này cũng sẽ được biến đổi sang dạng chữ hoa. Điều này được thể hiện trong Liệt kê 3. Dấu tham số ("?") được gõ vào là VARCHAR(15) và được chuyển vào vị từ XQuery như là biến "c". Liệt kê 3. Chọn các khách hàng khi sử dụng một dấu tham số SELECT id, XMLCAST( XMLQUERY('$XMLDOC/Customer/city') AS VARCHAR(15)) AS city FROM customer WHERE XMLEXISTS('$XMLDOC/Customer[fn:upper-case(city) = fn:upper-case($c)]' PASSING CAST(? AS VARCHAR(15)) AS "c"); Hình 1 cho thấy kết quả đầu ra của các truy vấn thí dụ ở trên. Hình 1. Kết quả của truy vấn thí dụ Tất cả điều này thực hiện tốt nếu bạn đang truy vấn chỉ một số lượng nhỏ dữ liệu hoặc nếu các truy vấn của bạn cũng chứa các vị từ chọn như là vị từ dạng chữ hoa được áp dụng chỉ cho một tập kết quả trung gian nhỏ. Vấn đề là vị từ có hàm fn:upper-case() ngăn cản sử dụng các chỉ mục XML trong DB2. Do đó, cách tiếp cận này không thích hợp với số lượng lớn dữ liệu. Để tránh việc sử dụng hàm fn:upper-case() và lợi dụng các lợi ích của các chỉ mục XML, cần thiết tạo ra một cơ sở dữ liệu không phân biệt dạng chữ. Tạo một cơ sở dữ liệu không phân biệt dạng chữ trong DB2 DB2 hỗ trợ phép đối chiếu Unicode nhận biết-cục bộ kể từ Phiên bản 9.5 Bản sửa lỗi 1. Điều này cho phép bạn bỏ qua dạng chữ và/hoặc các dấu. Để tạo một cơ sở dữ liệu không phân biệt dạng chữ cho tất cả các phép so sánh chuỗi, cần thiết sử dụng đối chiếu UCA500R1 như trong Liệt kê 4. Tìm kiếm hiệu quả không phân biệt dạng chữ với pureXML DB2 Trang 2 của 7 ibm.com/developerWorks/vn/ developerWorks® Liệt kê 4. Tạo một cơ sở dữ liệu không phân biệt dạng chữ CREATE DATABASE testdb USING CODESET UTF-8 TERRITORY US COLLATE USING UCA500R1_LEN_S2; Điều chuỗi UCA500R1_LEN_S2 có nghĩa chính xác gì? UCA500R1 UCA500R1 xác định rằng Unicode Collation Algorithm (UCA –Thuật toán phép đối chiếu Unicode) mặc định dựa trên phiên bản 5.0.0 chuẩn Unicode được sử dụng trong cơ sở dữ liệu này. Do UCA mặc định không thể kiểm soát đối chiếu chuỗi của mỗi ngôn ngữ được Unicode hỗ trợ cùng một lúc, việc bố trí các ký tự có thể được tùy chỉnh bằng cách sử dụng các thuộc tính tùy chọn. Các thuộc tính này được phân tách bằng một dấu gạch dưới (_). Từ khóa UCA500R1 cùng với các thuộc tính bất kỳ tạo nên một tên đối chiếu UCA. Tên đối chiếu được sử dụng trong Liệt kê 4 chứa hai thuộc tính: LEN và S2. LEN là của L (ngôn ngữ) và EN (mã ngôn ngữ ISO 639-1 cho tiếng Anh). Thuộc tính thứ hai S2 xác định mức độ mạnh mà nó quyết định có tính đến hay không dạng chữ hay trọng âm khi sắp xếp hoặc so sánh các chuỗi. Trong Liệt kê 4 mức độ mạnh 2 được sử dụng để cho "PARIS" và "paris" là như nhau. Sau đây là các ví dụ về các giá trị khác có thể có: • UCA500R1_LEN_S1 sẽ đối chiếu "cliche" = "Cliche" = "cliché" • UCA500R1_LEN_S2 sẽ đối chiếu "cliche" = "Cliche" < "cliché" • UCA500R1_LEN_S3 sẽ đối chiếu "cliche" < "Cliche" < "cliché" Có thể tìm thấy trong Trung tâm Thông tin DB2 (xem Tài nguyên) một danh sách tất cả các cách kết hợp có khả năng để sử dụng như một tên đối chiếu UCA. Truy vấn dữ liệu XML trong cơ sở dữ liệu không phân biệt dạng chữ Do cơ sở dữ liệu đã được tạo ra bằng cách sử dụng tên đối chiếu UCA500R1 với mức độ mạnh 2, các truy vấn trước đó bây giờ có thể được viết đơn giản như khi tất cả các dữ liệu thực sự sẽ là chữ hoa, mà không dùng hàm fn:upper-case() (Liệt kê 5). Nó thậm chí không quan trọng cho dù chuỗi tìm kiếm là "Paris" hoặc "PARIS" hoặc sự kết hợp nào khác của chữ hoa hay chữ thường. Liệt kê 5. Chọn các khách hàng ở Paris SELECT id, XMLCAST( XMLQUERY('$XMLDOC/Customer/city') AS VARCHAR(15)) AS city FROM customer WHERE XMLEXISTS('$XMLDOC/Customer[city = "PARIS"]'); Hình 2. Kết quả truy vấn thí dụ Tìm kiếm hiệu quả không phân biệt dạng chữ với pureXML DB2 Trang 3 của 7 developerWorks® ibm.com/developerWorks/vn/ Nếu bạn thêm một mệnh đề ORDER BY để sắp xếp theo giá trị thành phố được trích ra, tập kết quả vẫn duy trì như nhau: PARIS, paris và Paris được coi như là cùng giá trị. Để truy vấn dữ liệu này một cách hiệu quả, đặc biệt là nếu số hàng trong bảng lớn, bạn nên tạo một chỉ mục XML trên XPath là /Customer/city, như Liệt kê 6 cho thấy: Liệt kê 6. Tạo một chỉ mục XML CREATE INDEX customer_lang_idx ON test (xmldoc) GENERATE KEY USING XMLPATTERN '/Customer/city' AS SQL VARCHAR(15); giải thích truy vấn (bằng Visual Explain hoặc db2exfmt), bạn thấy rằng chỉ số được sử dụng để tìm kiếm không phân biệt dạng chữ: Hình 3. Kế hoạch giải thích để truy vấn tất cả các khách hàng ở Paris trong một cơ sở dữ liệu không phân biệt dạng chữ Mặt hạn chế tiềm ẩn của cách tiếp cận đã mô tả trong phần này là tất cả các dữ liệu trong tất cả các cột trong tất cả các bảng trong toàn thể cơ sở dữ liệu được xử lý theo cách không phân biệt dạng chữ. Không thể hạn chế không phân biệt dạng chữ cho các bảng hay các cột cụ thể. Đó là tất cả hoặc không. Lưu ý rằng không phân biệt dạng chữ chỉ áp dụng cho các giá trị phần tử và thuộc tính, chứ không phải tên thẻ của chúng. Các thẻ và biểu thức đường dẫn XML vẫn còn phân biệt dạng chữ. Ví dụ, Tìm kiếm hiệu quả không phân biệt dạng chữ với pureXML DB2 Trang 4 của 7 ibm.com/developerWorks/vn/ developerWorks® hai biểu thức XPath là /Customer/city (chữ "c" viết thường) và /Customer/City (chữ "C" viết hoa) là khác nhau. Cái sau sẽ không tìm thấy bất kỳ phần tử nào trong dữ liệu mẫu của chúng tôi bởi vì các phần tử <city> trong dữ liệu mẫu của chúng tôi được viết theo chữ thường. Hiệu năng Sử dụng một phép đối chiếu tùy chỉnh cho cơ sở dữ liệu có thể tác động đến hiệu năng truy vấn do số lượng của lần khớp các chuỗi có thể sẽ tăng lên khi bạn chọn một giá trị thiết lập UCA lỏng hơn. Nói cách khác, các phép so sánh chuỗi có thể tốn kém hơn trong cơ sở dữ liệu không phân biệt dạng chữ. Để kiểm tra sự khác biệt hiệu năng giữa các truy vấn các cơ sở dữ liệu phân biệt dạng chữ và không phân biệt dạng chữ, chúng tôi đã tạo ra một cơ sở dữ liệu thông thường (phân biệt dạng chữ) và một cơ sở dữ liệu không phân biệt dạng chữ. Chúng tôi đưa vào 20.000 tài liệu CustAcc từ khung chuẩn TPoX và đo một loạt các truy vấn trong cả hai cơ sở dữ liệu. Đối với các truy vấn chỉ có một số hàng nhỏ đến trung bình, sự khác biệt hiệu năng giữa hai cơ sở dữ liệu kiểm tra không đáng kể. Chúng tôi đã thấy một sự khác biệt lớn hơn đối với các truy vấn có một số lượng lớn các hàng, chẳng hạn như một hoạt động quét bảng qua tất cả 20.000 tài liệu XML so với phép so sánh chuỗi trên mỗi tài liệu. Các truy vấn như vậy đã lâu hơn 5% đến 8% trong cơ sở dữ liệu không phân biệt dạng chữ. Một chi phí nhỏ phải trả cho tìm kiếm phân biệt dạng chữ. Tóm tắt Có một số phương pháp để tìm kiếm dữ liệu DB2 theo cách không phân biệt dạng chữ như việc sử dụng các cột đã tạo ra (xem Tài nguyên). Trong khi các phương pháp này có thể làm việc tốt với dữ liệu quan hệ, nhưng chúng không phù hợp với truy vấn dữ liệu XML. Việc tạo ra một cơ sở dữ liệu với đối chiếu Unicode tùy chỉnh là cách tốt nhất để đạt được xử lý dữ liệu XML không phân biệt dạng chữ. Điều này làm cho mọi sự so sánh giá trị chuỗi trong cơ sở dữ liệu là không phân biệt dạng chữ và cho phép sử dụng các chỉ mục XML và các chỉ số quan hệ như bình thường. Chi phí hoạt động của việc tăng các mẫu tìm kiếm (liên quan đến dạng chữ hoặc dấu) đã chứng tỏ là rất thấp. Tìm kiếm hiệu quả không phân biệt dạng chữ với pureXML DB2 Trang 5 của 7 developerWorks® ibm.com/developerWorks/vn/ Tài nguyên • Đọc XML Support in DB2 Universal Database (PDF), của Matthias Nicola và Bert van der Linden, để tìm hiểu về các việc nâng cao hỗ trợ XML tự nhiên có sẵn trong DB2 Universal Database (Cơ sở dữ liệu đa năng DB2). • Đọc pureXML trong DB2 9: Dùng cách nào để truy vấn dữ liệu XML của bạn?, của Matthias Nicola và Fatma Özcan, để nhận được thông tin về cách truy vấn dữ liệu XML của bạn. • Trong Making DB2 Case-Insensitive, của Blair Adamache, xem các lời khuyên về cách bạn có thể dễ dàng cho phép những người dùng của bạn tìm kiếm dữ liệu quan hệ mà không phải băn khoăn về phân biệt dạng chữ. • Khám phá Một hàm do người dùng định nghĩa cho đối chiếu đúng văn hóa trong UDB DB2, của Doug Doole, để tìm hiểu về hàm do người dùng định nghĩa SORTKEY, đảm bảo đối chiếu đúng văn hóa cho cơ sở dữ liệu Unicode. • Trong Các phép so sánh chuỗi phân biệt dạng chữ với DB2 cho Linux, UNIX và Windows, của Knut Stolze, đọc về các kỹ thuật có thể được dùng để triển khai thực hiện các phép so sánh chuỗi phân biệt dạng chữ trong SQL. Các cột được tạo ra, các chỉ mục mở rộng và các chuỗi đối chiếu do người dùng định nghĩa được mô tả chi tiết. • Tìm các thuộc tính của tất cả đối chiếu dựa vào Unicode Collation Algorithm (Thuật toán đối chiếu Unicode), các giá trị của chúng và các ví dụ tiêu biểu về cách sử dụng trong Trung tâm Thông tin DB2. • Truy cập DB2 pureXML Wiki để theo sát tiến bộ về công nghệ XML của DB2. Tìm kiếm hiệu quả không phân biệt dạng chữ với pureXML DB2 Trang 6 của 7 ibm.com/developerWorks/vn/ developerWorks® Đôi nét về tác giả Matthias Nicola Matthias Nicola người lãnh đạo kỹ thuật về hiệu năng cơ sở dữ liệu XML tại Silicon Valley Lab của IBM. Công việc của ông tập trung vào tất cả các lĩnh vực về hiệu năng XML trong DB2, bao gồm XQuery, SQL/XML và tất cả các tính năng XML nguyên sơ trong DB2. Matthias Nicola cộng tác chặt chẽ với các đội phát triển XML DB2 cũng như với các khách hàng và các đối tác kinh doanh, là những người đang sử dụng XML, hỗ trợ họ trong việc thiết kế, triển khai thực hiện và tối ưu hóa các giải pháp XML. Trước khi gia nhập IBM, Matthias làm việc với hiệu năng kho dữ liệu cho Informix Software. Ông cũng đã có bốn năm làm việc trong các dự án nghiên cứu và các dự án công nghiệp trên cơ sở dữ liệu phân tán và nhân bản. Ông nhận bằng tiến sĩ khoa học máy tính vào năm 1999 ở Đại học Kỹ thuật Aachen, Đức. © Copyright IBM Corporation 2009 (www.ibm.com/legal/copytrade.shtml) Nhẫn hiệu đăng ký (www.ibm.com/developerworks/vn/ibm/trademarks/) Tìm kiếm hiệu quả không phân biệt dạng chữ với pureXML DB2 Trang 7 của 7