Row Store vs Column Store
Bài đăng này đã không được cập nhật trong 8 năm
Column Store và Row Store, 2 cách lưu dữ liệu trong database management system (DBMS), mỗi cách có điểm mạnh cũng như hạn chế riêng, vì thế mà mỗi cách lại được áp dụng vào một hệ thống cụ thể. Trong bài viết này mình sẽ giới thiệu với các bạn về 2 cách lưu trữ dữ liệu này.
Mình sẽ minh họa dựa trên bảng dưới đây.
id | user | project | address | Tel |
---|---|---|---|---|
1 | Trung | A | Thái Nguyên | 123 |
2 | Nghĩa | A | Thanh Hóa | 345 |
3 | Tùng | B | Hà Nội | 789 |
4 | Hiếu | C | Hà Nội | 012 |
Row Store
Row Store là lưu dữ liệu theo row - theo hàng. Với bảng bên trên thì dữ liệu được ghi sẽ có dạng:
1: Trung, A, Thái Nguyên, 123
2: Nghĩa, A, Thanh Hóa, 345
3: Tùng, B, Hà Nội, 789
4: Hiếu, C, Hà Nội, 012
Nhìn vào cách lưu dễ thấy là row store sẽ rất có lợi khi mà phải trả về dữ liệu của 1 row cụ thể nào đó. Như ở trên thì để tìm địa chỉ của user Tùng thì chỉ cần tìm đến nơi lưu user Tùng, sau đó lấy ra address một cách đơn giản khi mà dữ liệu được lưu trên cùng 1 block. Khi mà số lượng row cần phải đọc càng tăng lên thì tốc độ sẽ càng chậm lại, và chậm nhất khi mà phải lấy dữ liệu trên toàn bộ các bản ghi vì khi đó cần phải đọc toàn bộ bảng để lấy dữ liệu.
Để tăng tốc cho câu query thì hẳn các bạn cũng đá biết với việc đánh index. Việc đánh index thực chất là tạo 1 bảng con lưu id và trường được chon làm index đã được sort. Dữ liệu được lưu dưới dạng:
4: Hiếu
2: Nghĩa
1: Trung
3: Tùng
Ví dụ cần tìm user Hiếu thì sẽ query vào bảng con để lấy ra id là 1, rồi sẽ query tiếp vào bảng chính theo id là 4 để lấy dữ liệu. Việc query vào bảng con có 2 lý do giúp tăng tốc độ query:
- Bảng con có ít dữ liệu hơn nên query nhanh hơn
- Bảng con được sort theo trường đánh index nên sẽ query theo trường đó nhanh hơn
Column Store
Trái ngược với Row Store là Column Store. Dữ liệu được lưu sẽ có dạng như sau:
1: Trung, 2: Nghĩa, 3: Tùng, 4: Hiếu
1, 2: A, 3: B, 4: C
1: Thái Nguyên, 2: Thanh Hóa, 3, 4: Hà Nội
1: 123, 2: 456, 3: 789, 4: 012
Dữ liệu sẽ được lưu theo column - theo cột. Mỗi cột dữ liệu của 1 row khi được lưu sẽ được lưu thêm id của row đó, để khi query lấy dữ liệu có thể biết được dữ liệu nào của row nào.
Ngoài ra với cột có dữ liệu như nhau, thay vì lưu là 1: A, 2: A
thì chỉ cần lưu là 1, 2: A
, qua đó giảm được lượng dữ liệu phải lưu.
Query vào DB được lưu theo kiểu Column Store sẽ chậm khi mà câu query lấy ra tất cả các giá trị của row. Khi đó thì cẩn phải đọc rất nhiều trên ổ đĩa để lấy ra được kết quả.
Việc đánh index ở trong Column Store thì không cần phải tạo thêm bảng con như Row Store vì dữ liệu được lưu theo cột nên chỉ việc sort dữ liệu trên cột đó là xong (do đó mà ở Redshift không có đánh index cho bảng mà chỉ có sort. Vì thực chất đơn thuần chỉ là sort dữ liệu trên cột). Chẳng hạn khi sort theo trường user ở bảng trên:
4: Hiếu, 2: Nghĩa, 1: Trung, 3: Tùng,
4: C, 1, 2: A, 3: B
3, 4: Hà Nội, 1: Thái Nguyên, 2: Thanh Hóa
4: 012, 2: 456, 1: 123, 3: 789
Điểm mạnh và yếu
Row Store và Column Store như 2 thái cực trái ngược nhau. Điểm mạnh của cái này cũng là điểm yếu của cái kia và ngược lại. Sau đây sẽ là những điểm mạnh yếu của cả 2 cách lưu dữ liệu:
-
Query SELECT: Hiển nhiên là với dữ liệu lớn thì Column Store sẽ nhanh hơn nhờ vào cách lưu dữ liệu. Row Store sẽ chỉ nhanh nếu như thoả mãn các điều kiện:
- Bảng có ít dữ liệu
- Trả về dữ liệu của một hay một vài row cụ thể
- Trả về toàn bộ dữ liệu của toàn bộ row (kiểu select * ...)
-
Khả năng nén dữ liệu: Column Store sẽ có khả năng nén dữ liệu dễ dàng vì được lưu theo cột, các cột thì lại chỉ theo một kiểu dữ liệu cụ thể như char, int, bigint,... Tùy vào định dạng mà sẽ có kiểu nén thích hợp. Row Store thì khó nén dữ liệu hơn do trên 1 block lại lưu nhiều kiểu dữ liệu.
-
Query Insert/Update: Hiển nhiên là Row Store sẽ cho khả năng insert/update mạnh mẽ hơn. Insert/Update càng nhiều row hay càng nhiều column trên 1 row thì sự khác biệt về tốc độ càng rõ ràng. Lý do là Column Store thì khi dữ liệu thay đổi ở 1 cột thì thứ tự sort thay đổi theo, do đó cũng phải thay đổi thứ tự sort ở các cột khác => ảnh hưởng toàn bộ dữ liệu. Chảng hạn ví dụ trên nếu như update user Tùng thành user tên là An thì thứ tự lưu DB sẽ trở thành
-
Parallel Processing: Column Store hỗ trợ, hay nói cách khác là rất thích hợp với việc query song song, hay là nhiều process cũng thực hiện query. Ví dụ như khi bạn cần đưa ra tel và address của user Hiếu. Khi bạn đã biết id là 1 thì bạn có 1 process chạy song song query trên 2 block, 1 trên block lưu tel và 1 trên block lưu address. Thời gian query giảm xuống còn 1 nửa. Với Parallel Processing thì điểm yếu khi mà phải query trên nhiều column của column store có thể hoàn toàn được loại bỏ. Tất nhiên để làm được điều đó còn cần rất nhiều yếu tố đi kèm như: tốc độ đọc của ổ đĩa, cách thức lưu dữ liệu trển block, trên điã để chạy đc Parallel Processing...
3: An, 4: Hiếu, 2: Nghĩa, 1: Trung
3: B, 4: C, 1, 2: A
3, 4: Hà Nội, 1: Thái Nguyên, 2: Thanh Hóa
3: 789, 4: 012, 2: 456, 1: 123
Ứng dụng
MySQL và PostgreSQL gốc cũng chỉ đơn thuần là row store. Bởi vì row store rất dễ dàng để xây dựng. Nó chỉ như là lưu text đơn thuần vào ổ đĩa vậy.
Việc xây dụng được column store là khó hơn rất nhiều vì để tận dụng được điểm mạnh của column store thì các hệ thống phải xây dựng rất nhiều việc liên quan như: khả năng nén dữ liệu, phân chia dữ liệu, query song song, hệ thống ổ cứng... Vì chỉ có như vậy mới phát huy được hết sức mạng của column store.
Bạn sẽ nên sử dụng row store với những trường hợp:
- Khi cần chú trọng ở tốc độ insert/update, hoặc cần sự cân bằng giữa insert/update và select
- Khi không cần phải query nhanh trên dữ liệu lớn
Còn bạn sẽ sử dụng column store với những trường hợp sau:
- Query trên dữ liệu lớn
- Cần tốc độ select và aggregation cao
Tùy vào yêu cầu của dự án mà bạn có thể chọn cho mình hệ thống lưu DB với cách lưu phù hợp.
Tham khảo:
https://en.wikipedia.org/wiki/Column-oriented_DBMShttps://en.wikipedia.org/wiki/Column-oriented_DBMS http://saphanatutorial.com/column-data-storage-and-row-data-storage-sap-hana/ http://docs.aws.amazon.com/redshift/latest/dg/c_columnar_storage_disk_mem_mgmnt.html
All rights reserved