25/12/2018, 21:41

Đa hình trong sql

Đầu tiên ta sẽ nhắc lại một chút về đa hình trong lập trình hướng đối tượng? Tính đa hình là hiện tượng các đối tượng thuộc các lớp khác nhau có thể hiểu cùng 1 thông điệp theo các cách khác nhau. Trong bài viết này chúng ta sẽ cùng xem xét cách sử dụng sql để hỗ trợ các tính chất của đa hình. ...

Đầu tiên ta sẽ nhắc lại một chút về đa hình trong lập trình hướng đối tượng? Tính đa hình là hiện tượng các đối tượng thuộc các lớp khác nhau có thể hiểu cùng 1 thông điệp theo các cách khác nhau. Trong bài viết này chúng ta sẽ cùng xem xét cách sử dụng sql để hỗ trợ các tính chất của đa hình.

Đặt tình huống

Một ví dụ về đa hình trong thực tế. Ta có 3 địa điểm như: Sân bay, nhà hàng, khách sạn. Cả 3 đều là 1 vị trí sẽ có các trường chung như là id, tên, thành phố.. . và các trường riêng như khách sạn (số sao, số phòng...) Cách thông thường trong lập trình hướng đối tượng ta sẽ tạo ra class chung ( class cha) cho cả 3 như ở đây ta tạm gọi class Location (Chứa các điểm chung) sau đó tạo các lớp con thêm thông tin bổ sung đối với mỗi loại. Mặt khác, cách sử dụng SQL mà chúng ta hay mắc phải là tạo 3 bảng riêng biệt với các thông tin lặp lại nhau dẫn đến khi truy vấn đến thông tin chung trên các bảng ta sẽ phải thực hiện lặp lại các câu lệnh truy vấn đến từng bảng riêng.

The base table

Chúng ta hoàn toàn có thể xử lý tình huống trên bằng 1 cách khác hay được gọi là “disjoint subtypes”

  • Ta sẽ tạo bảng Locations như sau
create table Locations (
  id bigint primary key auto_increment,
  type enum ('Restaurant', 'Airpot', 'Hotel') not null,
  city string not null,
  description text not null,
);

The subtype tables

Tiếp theo chúng ta sẽ tạo tiếp các bảng con cho mỗi loại với khóa chính id cũng là khóa ngoại trỏ đến bảng Locations ví dụ: create table Hotel ( id int primary key, star int not null, foreign key id references Animals(id) ); Sử dụng chung 1 key (id) để đảm bảo rằng mỗi đối tượng sẽ chỉ có 1 id duy nhất trong các bảng con.

Đa hình

  • Bây giờ khi bạn muốn xử lý tất cả các location mà không quan tâm nó thuộc kiểu nào chỉ việc truy vấn đến bảng vị trí.
  • Ví dụ:
select L.* from Locations L where city = "Ho Chi Minh";

Hoặc chúng ta có thể sửa đổi thông tin chung mà không cần biết nó thuộc loại nào:

update Locations set city="Ha Noi" where id=111;

Khi bạn muốn lấy ra 1 loại cụ thể ta có thể sử dụng join đơn giản:

select L.*, A.* from Locations L 
join Airports A on L.id=A.id
where A.city="HaNoi";

Views

Ta có thể định nghĩa sẵn các view để truy vấn đến bảng con dễ dàng hơn như:

drop view if exists AirportsView;
create view AirportsView as
select * from Locations L 
join Airports A on L.id=A.id;

Sau đó có thể dễ dàng truy vấn đến sân bay bằng cách:

select * from AirportsView where city="Ho Chi Minh";

Thêm và xóa

  • Đối với việc thêm ta cần thực hiện 2 bước, đầu tiên tạo Location sau đó tạo loại con. tương tự để xóa ta sẽ xóa ở bản con và xóa ở bảng cha tiếp theo.

Tổng kết

  • Đây chỉ là 1 trong số rất nhiều cách giúp ta xử lý vấn đề đa hình ngăn gọn hơn khi thực hiện truy vấn, việc thiết kế db còn tùy thuộc vào mục đích và yêu cầu của từng trường hợp khác nhau, Nếu bạn có ý tưởng khác tốt hơn xin hảy để lại comment để cùng chia sẽ với mọi người.
0