Điều gì làm cho PostgreSQL hơn các CSDL SQL khác? - P1

Có vài sự lựa chọn các cơ sở dữ liệu mã nguồn mở ở ngoài kia (chúng ta thấy có MySQL, MariaDB và Firebird), nhưng cái gì PostgreSQL có mà những cái khác thì không?

Tag line của PostgreSQL tuyên bố rằng nó là: "Cơ sở dữ liệu mã nguồn mở tiên tiến nhất thế giới". Chúng tôi sẽ cung cấp cho bạn một vài lý do tại sao PostgreSQL tuyên bố như vậy.

Trong phần một của bài viết này, chúng ta sẽ xem lưu trữ dữ liệu - mô hình, các cấu trúc, các loại dữ liệu và giới hạn kích thước. Trong phần 2, chúng ta sẽ tập trung nhiều hơn vào truy xuất và thao tác dữ liệu.


Mô hình dữ liệu

PostgreSQL không chỉ là cơ sở dữ liệu quan hệ, nó là quan hệ hướng đối tượng. Điều này cung cấp cho nó một vài lợi thế so với các cơ sở dữ liệu SQL mã nguồn mở khác như MySQL, MariaDB và Firebird.

Một đặc điểm cơ bản của cơ sở dữ liệu quan hệ hướng đối tượng là hỗ trợ các đối tượng người dùng tự định nghĩa và các hành vi của chúng bao gồm các kiểu dữ liệu, các hàm, các thao tác, các tên miền và các chỉ mục. Điều này làm cho PostgreSQL cực kỳ mạnh và linh hoạt. Trong những cái khác, các cấu trúc dữ liệu phức tạp có thể được tạo ra, lưu trữ, và truy xuất. Trong một vài ví dụ ở bên dưới bạn sẽ nhìn thấy các cấu trúc hỗn hợp lồng nhau cái mà các hệ quản trị cơ sở dữ liệu chuẩn (RDBMS) không hỗ trợ.

Các kiểu dữ liệu và cấu trúc

Có một danh sách các kiểu dữ liệu PostgreSQL hỗ trợ. Bên cạnh kiểu số, floating-point, chuỗi, boolean, và các kiểu dữ liệu mà bạn mong muốn (và nhiều tùy chọn khác), PostgreSQL tự hào với uuid, tiền tệ, liệt kê (enumerated), hình học (geometric), nhị phân (binary), địa chỉ mạng, chuỗi bit, tìm kiếm văn bản, xml, json, mảng, hỗn hợp, và các loại khoảng (range types), cũng như một vài kiểu internal cho nhận biết đối tượng và vị trí đăng nhập. Để công bằng, MySQL, MariaDB và Firebird mỗi cái có một vài loại ở mức độ khác nhau, nhưng PostgreSQL hỗ trợ tất cả.

Chúng ta hãy xem xét một vài thứ:

Địa chỉ mạng

PostgreSQL cung cấp nhiều kiểu dữ liệu dành cho việc lưu trữ địa chỉ mạng. Kiểu dữ liệu CIDR (Classless Internet Domain Routing) theo quy ước cho địa chỉ mạng IPv4 và IPv6. Một vài ví dụ cho CIDR:

  • 92.168.100.128/25
  • 10.1.2.3/32
  • 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128
  • ::ffff:1.2.3.0/128

Cũng có sẵn cho việc lưu trữ địa chỉ mạng là kiểu dữ liệu INET, sử dụng cho lưu trữ IPv4 và IPv6 nơi subnet là không bắt buộc. Kiểu dữ liệu MACADDR có thể sử dụng lưu trữ địa chỉ MAC cho việc xác định phần cứng chẳng hạn như 08-00-2b-01-02-03.

MySQL và MariaDB có một vài hàm INET để chuyển đổi địa chỉ mạng, nhưng không cung cấp các kiểu dữ liệu cho việc lưu trữ các địa chỉ mạng. Firebird cũng không có kiểu địa chỉ mạng.

Mảng nhiều chiều

Bởi vì PostgreSQL là một cơ sở dữ liệu quan hệ hướng đối tượng, mảng các giá trị có thể lưu trữ hầu hết các kiểu dữ liệu có sẵn. Làm điều này bằng cách thêm cặp ngoặc [ ] vào sau kiểu dữ liệu chỉ định cho cột hoặc sử dụng ARRAY. Kích thước của mảng có thể chỉ định cụ thể, nhưng không bắt buộc. Hãy xem thực đơn của một kỳ nghỉ dã ngoại để minh họa cho việc sử dụng mảng:

-- create a table where the values are arrays

CREATE TABLE holiday_picnic ( 

     holiday varchar(50) -- single value

     sandwich text[], -- array

     side text[] [], -- multi-dimensional array

     dessert text ARRAY, -- array

     beverage text ARRAY[4] -- array of 4 items

);

 -- insert array values into the table

INSERT INTO holiday_picnic VALUES 

     ('Labor Day',

     '{"roast beef","veggie","turkey"}',

     '{

        {"potato salad","green salad","macaroni salad"},

        {"chips","crackers"}

     }',

     '{"fruit cocktail","berry pie","ice cream"}',

     '{"soda","juice","beer","water"}'

     );

MySQL, MariaDB, và Firebird không có khả năng này. Để lưu trữ mảng các giá trị như thế này trong một cơ sở dữ liệu truyền thống, một bảng riêng với một dòng cho mỗi giá trị mảng có thể được tạo ra như một cách giải quyết.

Dữ liệu hình học

Dữ liệu hình học nhanh chóng trở thành một yêu cầu cốt lõi cho nhiều ứng dụng.  PostgreSQL từ lâu đã hỗ trợ một loạt kiểu dữ liệu hình học như points, lines, circles, và polygons. Kiểu dữ liệu PATH là một trong số đó. Một path bao gồm nhiều điểm trong một chuỗi và có thể là mở (điểm đầu và điểm cuối không nối với nhau) hoặc đóng (điểm đầu và điểm cuối nối với nhau). Hãy sử dụng một ví dụ đường mòn đi bộ đường dài như là một path. Trong trường hợp này, đường mòn đi bộ đường dài của tôi là một vòng lặp vì thế điểm bắt đầu và điểm kết thúc của tôi được nối với nhau, và vì vậy path của tôi là đóng. Cặp ngoặc đơn xung quanh tập các tọa độ báo hiệu một path đóng trong khi một cặp ngoặc [ ] báo hiệu path mở.

-- create a table for trails

CREATE TABLE trails ( 

     trail_name varchar(250),

     trail_path path

);

 -- insert a trail into the table

 -- where the path is defined by lat-long coordinates

INSERT INTO trails VALUES 

     ('Dool Trail - Creeping Forest Trail Loop',

     ((37.172,-122.22261666667),

     (37.171616666667,-122.22385),

     (37.1735,-122.2236),

     (37.175416666667,-122.223),

     (37.1758,-122.22378333333),

     (37.179466666667,-122.22866666667),

     (37.18395,-122.22675),

     (37.180783333333,-122.22466666667),

     (37.176116666667,-122.2222),

     (37.1753,-122.22293333333),

     (37.173116666667,-122.22281666667)));

Phần mở rộng PostGIS có sẵn cho PostgreSQL tăng các tính năng dữ liệu hình học có sẵn với việc thêm các kiểu không gian, các hàm, các thao tác và các chỉ mục. Nó là vị trí nhận biết và hỗ trợ cả dữ liệu raster và vector. Nó cũng cung cấp khả năng tương tác với một loạt mã nguồn mở của bên thứ 3 và các công cụ không gian địa lý độc quyền để làm việc, lập bản đồ và vẽ các dữ liệu. 

Chú ý rằng MySQL 5.7.8 và từ MariaDB 5.3.3, phần mở rộng kiểu dữ liệu đã được thêm vào để hỗ trợ tiêu chuẩn OpenGIS cho thông tin địa lý. Phiên bản này của MySQL và các phiên bản tiếp theo của MariaDB cung cấp lưu trữ kiểu dữ liệu tương tự các kiểu dữ liệu hình học. Tuy nhiên, trong MySQL và MariaDB, các giá trị dữ liệu trước tiên phải chuyển đổi thành định dạng hình học sử dụng các lệnh đơn giản trước khi chèn vào các bảng. Firebird hiện tại không cung cấp các kiểu dữ liệu hình học.

Hỗ trợ JSON

Hỗ trợ JSON của PostgreSQL cho phép bạn ít sơ đồ (schema-less) trong một cơ sở dữ liệu SQL. Điều này có thể hữu ích khi cấu trúc dữ liệu yêu cầu phải có sự linh hoạt bởi vì nó vẫn thay đổi trong phát triển hoặc khi nó không biết các trường dữ liệu mà đối tượng dữ liệu sẽ chứa.

Kiểu dữ liệu JSON tuân theo JSON hợp lệ cái cho phép bạn sử dụng các thao tác và các hàm xây dựng trong PostgreSQL để truy vấn và thao tác dữ liệu. Cũng có sẵn kiểu JSONB - một dạng nhị phân của JSON nơi các khoảng trắng được loại bỏ, thứ tự đối tượng không được bảo quản nhưng thay vào đó là lưu trữ tối ưu, và chỉ giá trị cuối cùng cho các khóa trùng lặp được giữ lại. JSONB thường là định dạng được ưa thích khi nó yêu cầu ít khoảng trống cho đối tượng, có thể đánh chỉ mục và có thể xử lý nhanh hơn vì nó không đòi hỏi parsing lại. 

Trong MySQL 5.7.8 và MariaDB 10.0.1 hỗ trợ sẵn cho các đối tượng JSON đã được giới thiệu ở trên. Trong khi có rất nhiều hàm và thao tác cho JSON có sẵn trong các cơ sở dữ liệu này, chúng lại không có khả năng đánh chỉ mục theo cách của JSONB trong PostgreSQL. Firebird chưa tham gia câu lạc bộ này và chỉ hỗ trợ đối tượng JSON như văn bản.

Tạo một kiểu mới

Và nếu danh sách các loại dữ liệu mở rộng có sẵn của PostgreSQL là không đủ, bạn có thể sử dụng lệnh CREATE TYPE để tạo ra các kiểu dữ liệu mới như hỗn hợp (composite), liệt kê (enumerated), khoảng (range) và base. Đây là một ví dụ của việc tạo và truy vấn một kiểu dữ liệu mới:

-- create a new composite type called "wine"

CREATE TYPE wine AS ( 

     wine_vineyard varchar(50),

     wine_type varchar(50),

     wine_year int

);

 -- create a table that uses the composite type "wine"

CREATE TABLE pairings ( 

     menu_entree varchar(50),

     wine_pairing wine

);

 -- insert data into the table using the ROW expression

INSERT INTO pairings VALUES 

     ('Lobster Tail',ROW('Stag''s Leap','Chardonnay', 2012)),

     ('Elk Medallions',ROW('Rombauer','Cabernet Sauvignon',2012));

 /*

   query from the table using the table column name

   (use parentheses followed by a period

   then the name of the field from the composite type)

 */

SELECT (wine_pairing).wine_vineyard, (wine_pairing).wine_type 

FROM pairings 

WHERE menu_entree = 'Elk Medallions';

Bởi vì không phải là cơ sở dữ liệu quan hệ hướng đối tượng, MySQL, MariaDB và Firebird không cung cấp các chức năng mạnh mẽ này.

Kích thước dữ liệu

PostgreSQL có thể xử lý một lượng lớn dữ liệu. Các giới hạn về kích thước gửi được liệt kê dưới đây:

Giới hạn

Giá trị

Kích thước tối đa của cơ sở dữ liệu

Không giới hạn

Kích thước tối đa của table

32 TB

Kích thước tối đa của hàng (row)

1.6 TB

Kích thước tối đa của trường (field)

1 GB

Số hàng tối đa trên mỗi bảng

Không giới hạn

Số cột tối đa trên mỗi bảng

250 - 1600 phụ thuộc vào kiểu cột

Số lượng index tối đa trên mỗi bảng

Không giới hạn


Mọi nhà quản trị cơ sở dữ liệu (DBA) đều biết, cần phải thận trọng về các khả năng không giới hạn và cực lớn. Chúng tôi đề nghị bạn hãy hiểu rõ hướng dẫn của mình khi tạo các bảng và thực hiện lập chỉ mục.

Hãy so sánh, MySQL và MariaDB  được biết đến với giới hạn kích thước dòng là 65,535 byte. Firebird cũng chỉ có kích thước tối đa cho một dòng là 64KB. Thông thường kích thước dữ liệu được giới hạn bởi giới hạn kích thước file của hệ điều hành. Bởi vì PostgreSQL có thể lưu trữ bảng dữ liệu trong nhiều file nhỏ hơn, nên nó có thể khắc phục được hạn chế này - mặc dù, điều quan trọng cần lưu ý là quá nhiều file có thể tác động tiêu cực đến hiệu năng. MySQL và MariaDB cũng làm được, tuy nhiên chúng hỗ trợ nhiều cột trên một bảng (lên tới 4,096 phụ thuộc vào kiểu dữ liệu) và kích thước mỗi bảng lớn hơn PostgreSQL, nhưng rất hiếm các điều kiện mà bạn cần thực hiện vượt quá các giới hạn của PostgreSQL.

Toàn vẹn dữ liệu

PostgreSQL phấn đấu để phù hợp với chuẩn ANSI-SQL:2008, tuân thủ đầy đủ ACID (Atomicity, Consitency, Isolation và Durability), và cũng được biết đến các tham chiếu vững chắc của nó (rock-solid referential) và toàn vẹn giao dịch (transactional integrity). Các khóa chính, hạn chế và các tầng khóa ngoài, các ràng buộc duy nhất, các ràng buộc not null, kiểm tra các ràng buộc và các tính năng toàn vẹn dữ liệu khác để chắc chắn chỉ dữ liệu hợp lệ mới được lưu trữ.

MySQL và MariaDB đang làm nhiều hơn việc tuân thủ các chuẩn SQL với các cỗ máy lưu trữ InnoDB/XtraDB. Chúng cung cấp một tùy chọn STRICT sử dụng các phương thức SQL,  nó xác định các cách kiểm tra sự hợp lệ của dữ liệu được sử dụng. Tuy nhiên, phụ thuộc vào phương thức bạn sử dụng, dữ liệu không hợp lệ và đôi khi âm thầm bị cắt ngắn (silently-truncated) có thể được chèn hoặc được tạo khi cập nhật. Hiện tại cũng không có cơ sở dữ liệu nào hỗ trợ kiểm tra các ràng buộc và cũng có một số khó khăn cho việc ràng buộc các khóa ngoài. Ngoài ra, toàn vẹn dữ liệu có thể phụ thuộc đáng kể và cỗ máy lưu trữ được lựa chọn. MySQL (và MariaDB fork) không giấu giếm rằng đã từ lâu họ cân bằng giữa tốc độ và hiệu suất hơn là tuân thủ tính toàn vẹn.

Tổng kết

PostgreSQL có rất nhiều khả năng. Được xây dựng bằng cách sử dụng mô hình quan hệ hướng đối tượng, nó hỗ trợ các cấu trúc phức tạp và rất nhiều các kiểu dữ liệu được xây dựng sẵn và do người dùng tự định nghĩa. Nó cung cấp khả năng mở rộng dữ liệu và đáng tin cậy cho tính toàn vẹn dữ liệu. Bạn có thể không cần tất cả các tính năng tiên tiến chúng ta đã đề cập cho việc lưu trữ dữ liệu, nhưng khi nhu cầu dữ liệu phát triển nhanh, chắc chắn lợi ích rõ ràng đó là tất cả đã ở trong tầm tay của bạn.

Bạn đã sẵn sàng tìm hiểu nhiều hơn về PostgreSQL? Trong phần 2 chúng ta sẽ xem thao tác và truy vấn dữ liệu trong PostgreSQL, bao gồm các tính năng bảng ảo, các khả năng truy vấn, đánh chỉ mục và các mở rộng ngôn ngữ.

Tags: