[Cơ sở dữ liệu] Chuẩn hóa lược đồ quan hệ

Share:
First Normal Form (1NF) thiết lập các qui tắc cơ bản cho một Database đã được tổ chức:
  • Định nghĩa các cột dữ liệu cần thiết, bởi vì chúng trở thành các cột trong một bảng. Đặt các cột dữ liệu có liên quan với nhau trong một bảng.
  • Bảo đảm rằng không có việc lặp lại các nhóm dữ liệu nào.
  • Bảo đảm rằng có một Primary Key.

Qui tắc đầu tiên của 1NF

Bạn phải định nghĩa các cột dữ liệu. Nghĩa là kiểm tra dữ liệu để được lưu giữ, tổ chức dữ liệu vào trong các cột, định nghĩa kiểu dữ liệu của mỗi cột, và cuối cùng đặt các cột dữ liệu liên quan với nhau vào trong bảng riêng của chúng.
Ví dụ, bạn đặt tất cả cột liên quan tới vị trí trong bảng Location, liên quan tới thành viên trong bảng MemberDetail, …

Qui tắc thứ hai của 1NF:

Bước tiếp theo để bảo đảm rằng không có sự lặp lại các nhóm dữ liệu. Chúng ta xem xét bảng sau:
CREATE TABLE SINHVIEN(
       ID   INT              NOT NULL,
       TEN VARCHAR (20)     NOT NULL,
       TUOI  INT              NOT NULL,
       KHOAHOC  CHAR (25),
       TENSACH   VARCHAR(155)
);
Nếu hiển thị một sinh viên với nhiều lần mượn sách khác nhau khác nhau, thì nó sẽ cho:
IDTENTUOIKHOAHOCTENSACH
100Hoang19CNTTMang_May_Tinh
100Hoang19CNTTLap_Trinh_C
100Hoang19CNTTTu_Tuong_Ho_Chi_Minh
Nhưng theo 1NF, chúng ta cần bảo đảm rằng không có sự lặp lại các nhóm dữ liệu. Vì thế, chúng ta chia bảng trên thành 2 phần và kết hợp chúng bởi một key như sau:
Bảng SINHVIEN:
CREATE TABLE SINHVIEN(
       ID   INT              NOT NULL,
       TEN VARCHAR (20)     NOT NULL,
       TUOI  INT              NOT NULL,
       KHOAHOC  CHAR (25),
       PRIMARY KEY (ID)
);
Bảng này sẽ có các bản ghi sau:
IDTENTUOIKHOAHOC
100Hoang19CNTT
Bảng MUONSACH:
CREATE TABLE MUONSACH(
       ID   INT              NOT NULL,
       SINHVIEN_ID INT       NOT NULL,
       TENSACH   VARCHAR(155),
       PRIMARY KEY (ID)
);
Bảng này sẽ có các bản ghi sau:
IDSINHVIEN_IDTENSACH
10100Mang_May_Tinh
11100Lap_Trinh_C
12100Tu_Tuong_Ho_Chi_Minh

Qui tắc thứ ba của 1NF

Qui tắc cuối cùng của 1NF là tạo một Primary Key cho mỗi bảng mà chúng ta đã tạo.
Second Normal Form (2NF) nói rằng nó nên theo tất cả qui tắc trong 1NF và phải là không có bất kỳ sự phụ thuộc cục bộ nào của bất kỳ cột nào vào Primary Key.
Giả sử có mối quan hệ khách hàng-đơn đặt hàng, và bạn muốn lưu ID của khách hàng, tên khách hàng, ID của đơn đặt hàng và chi tiết mua hàng và ngày mua:
CREATE TABLE KHACHHANG(
       KH_ID    INT              NOT NULL,
       KT_TEN VARCHAR (20)      NOT NULL,
       DD_ID   INT              NOT NULL,
       DD_CHI_TIET VARCHAR (20)  NOT NULL,
       NGAY_BAN  DATETIME,
       PRIMARY KEY (KH_ID, DD_ID)
);
Bảng này tuân theo các qui tắc trong 1NF. Trong bảng này, Primary Key gồm KH_ID và DD_ID. Giả sử, chúng là duy nhất khi cùng một khách hàng hiếm khi order cùng một thứ hàng.
Tuy nhiên, bảng này không tuân theo Second Normal Form (2NF) bởi vì có các sự phụ thuộc cục bộ của các Primary Key và các cột. KH_TEN là phụ thuộc vào KH_ID và không có liên kết thực sự nào giữa một TEN của khách hàng và những gì anh ta mua. Chi tiết đặt hàng DD_CHITIET và ngày mua cũng phụ thuộc vào DD_ID, nhưng chúng không phụ thuộc vào KH_ID, bởi vì không có liên kết nào giữa một KH_ID và một DD_ID hoặc NGAY_BAN của họ.
Để làm cho bảng này tuân theo Second Normal Form (2NF), bạn cần chia các cột thành 3 bảng:
Đầu tiên, tạo một bảng để lưu chi tiết về khác hàng như sau:
CREATE TABLE KHACHHANG(
       KH_ID    INT              NOT NULL,
       KT_TEN VARCHAR (20)      NOT NULL,
       PRIMARY KEY (KH_ID)
);
Sau đó, tạo một bảng để lưu chi tiết về mỗi đơn đặt hàng:
CREATE TABLE DONDATHANG(
       DD_ID   INT              NOT NULL,
       DD_CHI_TIET VARCHAR (20)  NOT NULL,
       PRIMARY KEY (KH_ID)
);
Cuối cùng, tạo một bảng thứ ba để lưu giữ KH_ID và DD_ID để theo dõi tất cả đơn đặt hàng của một khách:
CREATE TABLE CHITIET(
       KH_ID    INT              NOT NULL,
       DD_ID   INT              NOT NULL,
       NGAY_BAN  DATETIME,
       PRIMARY KEY (KH_ID, DD_ID)
);
Một bảng là theo Third Normal Form (3NF) khi nó thỏa mãn các điều kiện sau:
  • Nó là một bảng theo Second Normal Form (2NF).
  • Tất cả các trường mà không phải là primary là phụ thuộc vào primary key.
Sự phụ thuộc của các trường không phải là primary là sự phụ thuộc giữa dữ liệu. Ví dụ, trong bảng dưới đây, tên Phường, Quận, và Thành phố là được kết nối (mà không thể phá vỡ) tới một zip code.
CREATE TABLE KHACHHANG(
       KH_ID       INT              NOT NULL,
       KH_TEN     VARCHAR (20)      NOT NULL,
       DOB           DATE,
       PHUONG        VARCHAR(200),
       QUAN          VARCHAR(100),
       THANHPHO         VARCHAR(100),
       ZIP           VARCHAR(12),
       EMAIL_ID      VARCHAR(256),
       PRIMARY KEY (KH_ID)
);
Sự phụ thuộc giữa các zip code và DIACHI được gọi là phụ thuộc có tính bắc cầu. Để tuân theo Third Normal Form (3NF), điều bạn cần làm là di chuyển các trường PHUONG, QUAN, THANHPHO vào trong bảng riêng của chúng, mà bạn có thể gọi là bảng Zip Code.
CREATE TABLE DIACHI(
       ZIP           VARCHAR(12),
       PHUONG        VARCHAR(200),
       QUAN          VARCHAR(100),
       THANHPHO         VARCHAR(100),
       PRIMARY KEY (ZIP)
);
Bây giờ, biến đổi bảng KHACHHANG như sau:
CREATE TABLE KHACHHANG(
       KH_ID       INT              NOT NULL,
       KH_TEN     VARCHAR (20)      NOT NULL,
       DOB           DATE,
       ZIP           VARCHAR(12),
       EMAIL_ID      VARCHAR(256),
       PRIMARY KEY (KH_ID)
);
Việc gỡ bỏ các phụ thuộc có tính bắc cầu đem lại cho ta hai lợi thế. Đầu tiên, lượng bản sao dữ liệu bị giảm xuống và vì thế Database của bạn trở nên nhỏ hơn.
Lợi thế thứ hai là toàn vẹn dữ liệu. Khi dữ liệu bị sao thay đổi, có một rủi ro lớn xảy ra khi chỉ cập nhật một số dữ liệu nào đó, đặc biệt kh nếu nó trải dài rộng một số vị trí khác nhau trong Database. Ví dụ, nếu dữ liệu address và zip code được lưu giữ trong 3 hoặc 4 bảng khác nhau, thì bất kỳ thay đổi nào trong zip code sẽ tác động đến mỗi bản ghi trong 3 hay 4 bảng đó.
Để trở thành một Database Expert hay một Database Administrator, bạn phải trả qua một khoảng thời gian học tập và làm việc khá dài. Điều này đòi hỏi kinh nghiệm trong các Database Design đa dạng và các khóa đào tạo tốt.
Với người mới bắt đầu, các hướng dẫn được liệt kê dưới đây sẽ giúp bạn cải thiện hiệu suất cơ sở dữ liệu (Database Performance).
  • Sử dụng 3BNF Database Design đã được giải thích trong chương Các khái niệm về RDBMS.
  • Tránh chuyển đổi số-thành-ký tự bởi vì các số và ký tự là khác nhau và điều này làm giảm hiệu suất cơ sở dữ liệu.
  • Trong khi sử dụng lệnh SELECT, chỉ lấy thông tin nào cần thiết và tránh sử dụng * trong các truy vấn SELECT bởi vì nó sẽ tải hệ thống một cách không cần thiết.
  • Tạo các chỉ mục (index) một cách cẩn thận trên tất cả các bảng, là nơi bạn thường có các hoạt động tìm kiếm. Tránh sử dụng chỉ mục trên các bảng mà bạn ít sử dụng hoạt động tìm kiếm và sử dụng nhiều hoạt động chèn và cập nhật.
  • Một Full-table Scan xuất hiện khi các cột trong mệnh đề WHERE không có một chỉ mục được liên kết với chúng. Bạn có thể tránh một full-table scan bằng việc tạo một chỉ mục trên các cột mà được sử dụng như là các điều kiện trong mệnh đề WHERE của một lệnh SQL.
  • Cẩn thận với các toán tử ngang bằng với các số thực và các giá trị date/time. Cả hai loại này có thể có một sự khác nhau rất nhỏ nhưng không rõ ràng để nhìn thấy, và để tạo một so khớp chính xác là điều không thể.
  • Sử dụng Pattern Matching (so khớp mẫu) một cách thận trọng. LIKE COL% là một điều kiện WHERE hợp lệ, giảm tập hợp được trả về, và chỉ có các bản ghi với dữ liệu bắt đầu với chuỗi COL được trả về. Tuy nhiên, COL%Y lại không giảm tập hợp kết quả được trả về, bởi vì %Y không thể được ước lượng một cách hiệu quả. Nỗ lực để thực hiện việc ước lượng là quá lớn và cần được xem xét lại. Trong trường hợp này, COL% được sử dụng, và %Y bị bỏ.
  • Tinh chỉnh các truy vấn SQL của bạn bằng việc kiểm tra cấu trúc của các truy vấn (và truy vấn phụ), cú pháp SQL, để phát hiện xét xem bạn đã thiết kế bảng để hỗ trợ cho thao tác dữ liệu nhanh và các truy vấn đã viết có theo phương thức tối ưu để cho phép DBMS của bạn thao tác dữ liệu một cách hiệu quả không.
  • Với các truy vấn mà được thực thi trên một nền tảng thông thường, bạn sử dụng các thủ tục. Một thủ tục là một nhóm các lệnh SQL. Thủ tục có thể được biên dịch bởi Database Engine và sau đó được thực thi. Không giống một lệnh SQL, Database Engine không cần tối ưu hóa thủ tục trước khi nó được thực thi.
  • Bạn có thể tối ưu hóa việc có một lượng dữ liệu lớn phải tải bằng việc xóa các chỉ mục. Tưởng tượng về bảng với hàng nghìn hàng.
  • Khi thực hiện Batch transaction, thực hiện COMMIT ngay sau khi một số lượng bản ghi được tạo thay vì tạo chúng sau mỗi lần tạo bản ghi.
  • Sử dụng Defragment với Database trên một nền tảng thông thường.

Tuning Tool có sẵn

Oracle có nhiều Tool để quản lý hiệu suất lệnh SQL, trong đó có hai tool khá phổ biến, đó là:
  • Explain plan − tool xác định Access path mà sẽ được lấy khi lệnh SQL được thực thi.


  • tkprof − đánh giá hiệu suất bằng thời gian trôi qua trong suốt mỗi giai đoạn xử lý của lệnh SQL.
Nếu bạn muốn đánh giá đơn giản thời gian đã trôi qua của một truy vấn trong Oracle, bạn có thể sử dụng lệnh SET TIMING ON trong SQL*Plus.
Kiểm tra RDBMS Documentation để biết thêm chi tiết về các Tool và Defragment trên.