Android

Firebase, Bài 4.1: Hướng dẫn chuyển đổi sang Firebase Realtime Database từ SQL Database

Như tôi đã nói trong Bài mở đầu và Bài 2.1, Firebase Realtime Database (FRD) có cấu trúc khác với SQL Database (SQLD). Trong khi SQLD có cấu tạo dạng bảng gồm cột và hàng như một Excel Worksheet thì FRD lại có cấu tạo dạng tầng lớp. Mỗi cái đều có ưu điểm mà cái kia không hoàn toàn thay thế được. Tuy nhiên, tùy vào yêu cầu và mong muốn của bạn mà bạn vẫn có thể dùng tốt FRD cho một ý tưởng vốn thích hợp nhất với SQLD. Hôm nay chúng tôi sẽ đưa ra vài hướng dẫn cơ bản để giúp bạn có thể định hướng đi của mình. Các bài viết có dựa trên hướng dẫn “chính chủ” của anh David East, và nếu bạn đã đọc qua các bài hướng dẫn trước về Firebase của chúng tôi thì bạn đã biết anh ấy là ai rồi.

Xin lưu ý là các hướng dẫn của chúng tôi chỉ mang tính tham khảo dưới góc độ tổng quát. Không phải bất kì CSDL SQL nào cũng có thể được chuyển đổi thành CSDL Firebase theo các hướng mà chúng tôi đang và sẽ trình bày, cũng như việc vận dụng và tối ưu hóa CSDL còn phụ thuộc vào ý tưởng của bạn về cấu trúc tổ chức dữ liệu và mong muốn của bạn đối với cơ sở dữ liệu đó, và trình độ với kinh nghiệm của bạn về Firebase Realtime Database. Các bài viết sẽ không hề bàn tới tính Realtime của FRD mà chỉ nói về cấu trúc dữ liệu mà thôi.

FirebaseRealtimeDatabase

1. Ý tưởng chung:

Nếu bạn đã có thao tác với MS Excel/Apple Numbers/OpenOffice Calc hay Google Trang tính thì bạn sẽ không còn cảm thấy lạ lùng với SQLD vì chúng có cấu tạo như nhau, tức là dạng bảng với các cột chỉ các thuộc tính (properties) của một đối tượng và các hàng là mỗi đối tượng. Mỗi ô cố định sẽ là thuộc tính (property) của một đối tượng cụ thể. Ví dụ:

TABLE NAME: EXAMPLE_DB

 No Organisations Website_addresses Headquarter_location
 1 EITGUIDE http://eitguide.com  Vietnam
 2 GOOGLE http://www.google.com US
 3 APPLE http://www.apple.com US

Trong khi đó FRD được cấu tạo theo kiểu cây phân tầng, nói dân dã thì là “ông-cha-con-cháu-chắt”, các thuộc tính và các đối tượng không được bố trí cố định như SQLD. Và nếu tôi chuyển đổi bảng trên ra FRD thì tôi không chỉ có đúng một CSDL duy nhất, mà trái lại, có nhiều biến thể khác nhau, chẳng hạn:

Hoặc dưới góc độ khác:

Hoặc dưới một góc độ khác nữa:

Tóm lại là việc chuyển từ một SQLD sang FRD không chỉ có một hướng, và lựa chọn hướng nào là tùy vào, trước nhất là ý tưởng của bạn, sau là trình độ và kinh nghiệm của bạn. Vì vậy, vui lòng đừng để lại bình luận dạng “Em có cái bảng trong SQLD dư lầy, các anh hướng dẫn cho tôi chuyển sang FRD với!”. Đó là ý tưởng của bạn và chính bạn là người chịu trách nhiệm bảo trì CSDL đó. Do đó, bạn là người hiểu rõ nhất bản thân nên làm gì.

2. Lợi thế của FRD so với SQLD:

Nếu bạn đã có kinh nghiệm thao tác với SQLD (chí ít là với SQLite DB) và cũng có làm việc với FRD chút ít rồi thì bạn sẽ thấy, là việc đọc ghi dữ liệu trên FRD “chả có” một câu Schema nào. Chẳng hạn, với SQLD bên trên, bạn sẽ có câu “SELECT * FROM EXAMPLE_DB WHERE Organisations = ‘EITGUIDE’” để lấy các thông tin về đối tượng có tên EITGUIDE, chẳng hạn địa chỉ website. Rồi nếu làm Android thì bạn sẽ bỏ câu Schema đó vào Cursor rồi cho nó move sang cột nào đó. Tuy nhiên, với FRD thì bạn hoàn toàn thao tác với các hàm vô cùng quen thuộc đối với ngôn ngữ và nền tảng đích, thông qua bộ thư viện có sẵn cho Android, iOS và JS với Web. Chẳng hạn với FRD dưới đây và để lấy thông tin về đối tượng EITGUIDE trên Android:

Và code sẽ là

Đối với iOS và Web thì còn đơn giản hơn nữa. Bạn sẽ gặp các hàm được viết sẵn bằng ngôn ngữ của nền tảng, và tên các methods cũng được tùy biến cho phù hợp với phong cách của ngôn ngữ và nền tảng đó. Và đương nhiên, IDE cũng sẽ suggest bạn các hàm cũng như chỉ ra các lỗi cú pháp (syntax) do đánh phím sai. Còn đối với các câu Schema dạng String thì IDE sẽ “mặc kệ” bạn vì việc quan sát câu schema không phải là nhiệm vụ của nó.

Một điểm mạnh rất đáng chú ý nữa là đối với Firebase thì bạn sẽ thêm bớt các thuộc tính của đối tượng “dễ như trở bàn tay”, chỉ việc thêm thuộc tính trong struct, class hoặc định nghĩa của Object mà bạn thao tác là được. Chẳng hạn, đối với class Organisation, bấy giờ tôi muốn thêm 1 property mới là “CEO” thì tôi chỉ việc thêm trong class hay struct, chẳng hạn với JS:

Và như vậy là xong. Và mỗi lần bạn đưa một Object mới lên FRD thì FRD sẽ tự tạo thêm một trường mới trên đó mà bạn sẽ không cần làm gì khác. Và khi get dữ liệu về, các Organisation cũ chưa có thuộc tính là CEO thì đơn giản, bạn đem get ra thì kết quả sẽ là null/nil và bạn đưa ra code xử lí trên thiết bị khách mà thôi, còn trên CSDL gốc thì bạn đâu có gì để làm. Chẳng hạn với iOS-Swift:

Trong khi đó, đối với SQLD thì mấy câu Schema như ALTER TABLE, ADD COMLUMN và xử lí hàng loạt các Events trên server (nếu cần) là một công việc không hề dễ dàng và nhiều khi bạn “đỏ con mắt bên trái, xốn con mắt bên phải” vẫn chưa tìm ra được lỗi (nếu có). Và rõ ràng thì việc thao tác với FRD là dễ dàng hơn so với SQLD khi mọi hàm tỏ ra thân thuộc hơn hẳn.

3. Lợi thế của SQLD so với FRD

Nếu bạn là người thiết kế CSDL thì việc query các Object là điều không cần bàn cãi vì CSDL chính là “con đẻ” của bạn. Tuy nhiên nếu bạn là người được tuyển vào quản trị một CSDL có sẵn thì có lẽ mọi chuyện không được thoải mái như bạn nghĩ, nhất là ý tưởng tổ chức dữ liệu của bạn khác hẳn với người tiền nhiệm, hoặc bạn kế nhiệm vào chiếc ghế nóng trong tình huống “chưa biết ông-đơ” gì khi người tiền nhiệm dứt áo ra đi mà không thèm hướng dẫn bạn về cách họ thiết kế CSDL. Như tôi đã nói bên trên, việc thiết kế CSDL trên Firebase là vô cùng quan trọng, bởi lẽ thao tác query dữ liệu chỉ có thể làm được nếu bạn nắm rõ được cách tổ chức của các đối tượng và vị trí của chúng.

Đối với SQLD thì dễ hơn nhiều vì bạn có thể mặc kệ cái ông-bà tiền nhiệm kia nghĩ ngợi gì vì chỉ có mỗi cách bố trí bảng duy nhất. Có khác biệt chăng là bạn thích để cột Website thành cột cuối trong khi tôi thích để vị trí áp chót. Nhưng nhìn chung, là nếu bạn nhìn vào cái bảng “phong thần” mà tôi vẽ bên trên thì cỡ nào bạn cũng hiểu ý tôi là gì. Và việc query với câu Schema chả có gì khác biệt. Một khi bạn đã biết các thông tin thì việc lọc và khóa các đối tượng diễn ra dễ hơn bao giờ hết. Chẳng hạn, tôi “SELECT * FROM EXAMPLE_DB WHERE Organisation = ‘Google’” thì ngay lập tức tôi có tất cả các thông tin về Google. Và tôi chỉ việc lấy các thông tin đó ra mà thôi, bảo đảm chúng sẽ chính xác vì tôi đã khóa vào hàng có Organisation = Google rồi.

Tuy nhiên, với Firebase thì có thể khó khăn hơn. Vì nếu tôi chọn CSDL này trước khi bàn giao cho bạn thì bạn sẽ đỡ biết mấy:

Cái này cũng dễ dàng cho bạn, tuy nhiên nếu tôi đặt thêm 1 property khác như “ceo” và cho nó nằm chung tầng với “hq_location” thì sẽ gây cho bạn thêm một vài khó khăn nhỏ.

Còn nếu như cái dưới đây thì không ít bạn sẽ đổ mồ hôi hột.

Với CSDL mang tính “đánh đố” như vậy thì bạn chỉ có hướng làm như sau: Tìm trong các children của “organisation” coi tên nào có value là “google”. Tìm được nó rồi thì lấy key của nó ra và dùng key đó để tìm tiếp trong các trường còn lại.

Trong FRD, việc định vị các children cần tìm theo thuộc tính là vô cùng quan trọng. Bởi lẽ mỗi đối tượng cần có một vị trí xác định. Nếu bạn không tìm được cách cố định để lọc các đối tượng cần tìm ra thì nước biển sẽ vô cùng mặn mòi. Đối với CSDL minh họa của tôi thì nhìn có vẻ đơn giản, nhưng nếu là một CSDL phức tạp và người tiền nhiệm chọn cách thiết kế “trời ơi đất hỡi” chỉ có mỗi người đó hiểu được thì bạn sẽ mất không ít thời gian và công sức để “giải mã” cái “ẩn số” khó chịu đó.

Và không thể không nhắc tới sự liên kết giữa các đối tượng trong cùng một bảng trong SQLD. Nếu trước đây, bạn có làm một bảng Excel để tính tiền thuê nhà thì bạn sẽ áp dụng cái điều tương tự đó cho SQLD mà không hề gặp bất cứ rắc rối nào lớn. Vì đơn giản là tiền tháng mới sẽ được dựa trên các hiệu của các thông số mới và các thông số cũ tương ứng. Tuy nhiên, sẽ là khó khăn nếu bạn dùng FRD. Ừ thì trong phần snapshot có trả về key của Object liền trước đấy. Tuy nhiên, nếu bạn cần số liệu của tháng trước của tháng trước của tháng trước của tháng trước đứng dưới góc nhìn của tháng này thì e là mọi chuyện không dễ cho lắm, mặc dù điều này là hoàn toàn có thể.

4. “Tôi nên thiết kế CSDL theo hướng nào?”

Như bạn đã thấy, tôi đã đưa ra 3 FRD chỉ ứng với 1 bảng SQLD duy nhất. Bạn thấy cái số 1 là tốt nhất cho bạn? Có thể. Nhưng một người bạn của bạn lại thích cái số 2 với lí do riêng và nếu hai bạn tranh cãi thì chẳng khác nào cãi rằng thịt gà hay cá trê ngon hơn, bởi lẽ mỗi người có cái lí của mình, để cho phù hợp với mục đích của bản thân. Riêng tôi thì tôi chọn cái số 3, vì nó thích hợp cho tôi hơn.

Thiết kế kiểu nào thì tùy vào tính chất, mục đích và sự mong đợi của bạn đối với CSDL đó, cũng như tùy vào trình độ và kinh nghiệm của bạn nữa. Tuy nhiên, hãy đảm bảo là bạn biết cách để query dữ liệu, đúng hơn là cách trỏ vào (các) đối tượng mà bạn cần. Bởi không phải bạn chỉ có mỗi việc add, remove và get các đối tượng ra, mà còn là edit chúng khi cần thiết. Tốt nhất, bạn nên làm ít nhất 3 mô hình khác nhau, và chọn cái nào dễ dàng nhất, không chỉ cho hiện tại mà còn là cả về sau này, khi phát sinh ra nhiều vấn đề mà ở hiện tại bạn chưa lường tới.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.