Thứ Ba, 25 tháng 8, 2009

So sánh cách lấy dữ liệu tự động và lấy theo query trong cakephp

I. So sánh


Trong cakephp, có 2 cách lấy dữ liệu chính là lấy dự liệu tự động thông qua các hàm viết sẵn của cakephp và lấy dữ liệu từ câu lệnh query trực tiếp.


Ưu nhược điểm của 2 phương pháp trên:


1. Lấy dữ liệu tự động


a) Ưu điểm


- Lấy dữ liệu từ các bảng sẽ được thực hiện tự động thông qua khai báo quan hệ ở model


- Việc thêm quan hệ hoặc thay đổi quan hệ giữa các bảng sẽ được thực hiện ở model, vì vậy khi quan hệ với bảng khác hoặc thay đổi dữ liệu chỉ cần thay đổi quan hệ ở model.


- Dễ dàng hơn trong việc phân trang, phân trang tìm kiếm.


- Dữ liệu lấy ra đã được đưa theo cấu trúc mảng hình cây hợp lý, làm cho việc hiển thị dữ liệu trở lên đơn giản và dễ dàng hơn.


b) Nhược điểm


- Việc lấy dữ liệu sẽ trở lên vô cùng nhiều và chậm do lấy dữ liệu từ tẩt cả các bảng quan hệ nếu không sử dụng hợp lý recursive và bindModel (cách dùng sẽ có ở dưới).


c) Định dạng dữ liệu lấy ra


Dữ liệu lấy ra sẽ được hiển thị theo nhiều định dang, tùy theo từng mối quan hệ là một – một, một nhiều hay nhiều nhiều.


- Với quan hệ một - một:



Array

(

    [User] => Array

        (

            [id] => 121

            [name] => Gwoo the Kungwoo

            [created] => 2007-05-01 10:31:01

        )

    [Profile] => Array

        (

            [id] => 12

            [user_id] => 121

            [skill] => Baking Cakes

            [created] => 2007-05-01 10:31:01

        )

)


- Với quan hệ một nhiều:



Array

(  

    [User] => Array

        (

            [id] => 121

            [name] => Gwoo the Kungwoo

            [created] => 2007-05-01 10:31:01

        )

    [Comment] => Array

        (

            [0] => Array

                (

                    [id] => 123

                    [user_id] => 121

                    [title] => On Gwoo the Kungwoo

                    [body] => The Kungwooness is not so Gwooish

                    [created] => 2006-05-01 10:31:01

                )

            [1] => Array

                (

                    [id] => 124

                    [user_id] => 121

                    [title] => More on Gwoo

                    [body] => But what of the ‘Nut?

                    [created] => 2006-05-01 10:41:01

                )

        )

)


- Quan hệ nhiều – một



Array

(

   [Profile] => Array

        (

            [id] => 12

            [user_id] => 121

            [skill] => Baking Cakes

            [created] => 2007-05-01 10:31:01

        )    

    [User] => Array

        (

            [id] => 121

            [name] => Gwoo the Kungwoo

            [created] => 2007-05-01 10:31:01

        )

)

- Quan hệ nhiều nhiều
Array

(  

    [Recipe] => Array

        (

            [id] => 2745

            [name] => Chocolate Frosted Sugar Bombs

            [created] => 2007-05-01 10:31:01

            [user_id] => 2346

        )

    [Tag] => Array

        (

            [0] => Array

                (

                    [id] => 123

                    [name] => Breakfast

                )

           [1] => Array

                (

                    [id] => 124

                    [name] => Dessert

                )

           [2] => Array

                (

                    [id] => 125

                    [name] => Heart Disease

                )

        )

)


2. Lấy dữ liệu từ câu lệnh query


a) Ưu điểm


- Việc lấy dữ liệu sẽ không còn phụ thuộc vào quan hệ ở model, mà chỉ phụ thuộc vào quan hệ khi khai báo ở câu query


- Việc lấy dữ liệu sẽ thực hiện nhanh hơn, liên kết giữa các bảng sẽ rõ ràng hơn dựa vào câu lệnh liên kết ở query.


b) Nhược điểm


- Khi thay đổi quan hệ giữa các bảng, hoặc thêm quan hệ với một bảng mới, phải sửa lại câu query.


- Việc phân trang sẽ trở nên khó khăn phức tạp hơn


- Dữ liệu lấy ra dưới dạng mảng, nhưng chưa được sắp xếp lại theo cấu trúc.


- Khi sử dụng câu lệnh query, ta phải hiểu rất rõ quan hệ và sử dụng thành thao các lệnh trong query


c) Định dạng dữ liệu lấy ra


Khi lấy dữ liệu thông qua câu lệnh query, thì với tất cả các quan hệ dữ liệu dữ liệu lấy ra từ câu lệnh query đểu có định dạng như sau:


Array


(



   [0] => Array
      (

[Category] => Array


(


[id] => 1


[name] => Thông tin thị trường


[alias] => tin_tuc


[parent_id] =>


[root_path] =>


[level] => 0


[order] =>


[lang] =>


[represent] =>


[is_hyperlink] => 0


[active] => 0


[layout] => 0


[created] => 0000-00-00 00:00:00


)



[NewsCategory] => Array


(


[id] => 16


[news_id] => 4


[category_id] => 1


)



)



[1] => Array


(


[Category] => Array


(


[id] => 2


[name] => Phân tích thị trường


[alias] =>


[parent_id] =>


[root_path] =>


[level] => 0


[order] =>


[lang] =>


[represent] =>


[is_hyperlink] => 0


[active] => 0


[layout] => 0


[created] => 0000-00-00 00:00:00


)



[NewsCategory] => Array


(


[id] => 17


[news_id] => 4


[category_id] => 2


)



)


...



)


3. So sánh tốc độ


Thực tế, cách sử dụng query và cách sử dụng lấy dữ liệu tự động thông qua các hàm find, findAll… sẽ không khác nhau là mấy hay nói đúng hơn là không khác gì nhau khi ta xác định rõ ràng recursive trong từng trường hơp cụ thể, kết hợp với sự dụng bindModel và unbindModel để xác định số lượng các bảng tham gia inner join.


II. Tối ưu dữ liệu theo cách lấy tự động


1. Sử dụng Recursive


Recursive trong cakephp thể hiện mức tham chiếu quan hệ nông, sâu giữa các bảng với nhau, trong cakephp có 4 mức thể hiện tham chiếu được thể hiện qua ví dụ sau đây:


Giả sử ta có tất cả 4 bảng bao gồm: domains, groups, users và news. Và mối quan hệ giữa các bảng như sau: Một domain có rất nhiều group, trong mỗi một group lại có rất nhiều user. Một user lại có thể đăng lên rất nhiều bài viết khác nhau. Vậy là ta có thể xác định các bảng có quan hệ tham chiếu đến nhau.


Ta có thể hình dung như sau:









































table



domains



groups



users



News



domains





hasMany







groups



belongsTo





hasMany





users





belongsTo





hasMany



news







belongsTo






Giả sử ta muốn lấy dữ liệu ở bảng group theo câu lệnh $this->Group->find(‘all’). Việc sử dụng giá trị recursive sẽ cho phép ta lấy dữ liệu khác nhau.


Cú pháp sử dụng recursive trong trường hợp này là:


$this->Group->recursive = 1


























Deapth



Mô tả



-1



Lấy dữ liệu ở bảng Group, không lấy thêm bất cứ bảng nào khác



0



Lấy dữ liệu ở bảng Group và dữ liệu domain tương ứng



1



Lấy dữ liệu ở bảng Group, Domain và dữ liệu ở bảng User tương ứng



2



Lấy dữ liệu ở bảng Group, Domain, User và dữ liệu ở bảng News tương ứng




Nhìn qua bảng trên ta thấy tùy từng giá trị recursive khác nhau mà cakephp thực hiện liên kết với (inner join) thích hợp. Giả sử như ta cho recursive bằng 2, có nghĩa là ta lấy ra dữ liệu của các group, dữ liệu domain tương ứng với mỗi group đó, đồng thời là một danh sách các user nằm trong từng group, trong mỗi user đấy lại lấy ra các tin tức do các user ấy đăng. Vậy có nghĩa là sẽ có 4 bảng liên kết với nhau. Với recursive là 1 thì chỉ có 3 bảng thôi.


Như vậy là tùy tường trường hợp cụ thể mà ta có thể khai báo giá trị recursive khác nhau. Trong trường hợp ta chỉ cần lấy dữ liệu từ mỗi bảng group thì ta chỉ cần khai báo giá trị recursive là -1. Nếu muốn lấy thêm dữ liệu ở bảng domain thì khai báo recursive = 0…. Việc khai báo recursive cho từng trường hợp sẽ làm tăng tốc độ query vì ta sẽ kiểm soát được số lượng các bảng liên kết với nhau.


2. Sử dụng bindModel và unbindModel


Trong một số trường hợp, với cùng một model chúng ta sẽ phải khai báo thêm một số quan hệ hoặc bỏ bớt một số quan hệ với các bảng khác, điều này xảy ra khi:


- Bạn cần giảm bớ số lượng dữ liệu và mối quan hệ của các bảng lien quan cần lấy đến, trong khi khởi tạo ở model ta đã khai báo tất cả các quan hệ ấy rồi. (ví dụ như trong model group ở trên, ta chỉ muốn lấy dữ liệu từ 2 bảng là group và user, trong khi đó theo quan hệ ta sẽ phải join đồng thời cả 3 bảng user, group và domain. Như vậy việc truy xuất dữ liệu sẽ chậm hơn)


- Bạn muốn thay đổi cách liên kết của một model xác định để sẵp xếp hoặc lọc dữ liệu liên quan.


Khi muốn thêm một liên kết ta sẽ dùng đến bindModel và khi muốn xóa một liên kết ta sẽ sử dụng unbindModel. (Cách sử dụng bindModel va unbindMode sẽ được bàn sau)

Không có nhận xét nào:

Đăng nhận xét