Định nghĩa: Lược đồ quan hệ R với tập các phụ thuộc hàm được gọi là
ở dạng chuẩn Boye – Codd (Boye Codd Normal Form, BCNF) nếu X→ A thoả mãn trên R, A∉X thì X là một khoá của R.
Ví dụ: Cho quan hệ R(CSZ) với các phụ thuộc hàm CS→Z, Z→C. Ta thấy R không ở BCNF mà ở 3NF vì Z→C không phải là khoá của R.
Định lý: Nếu một lược đồ quan hệ R với tập phụ thuộc hàm F là ở
BCNF thì nó là ở 3NF (đã được chứng minh). Nhận xét: - Nếu R đạt chuẩn BC thì Q đạt chuẩn 3
- Một lược đồ quan hệ có thể ở 3NF nhưng chưa chắc ở BCNF
Ví dụ: Xác định dạng chuẩn của lược đồ quan hệ sau:
R(ACDEIB) với F = {ACD→EBI; CE→AD}.
R có hai khoá là ACD và CE, vậy R đạt chuẩn BC.
Thuật toán kiểm tra dạng chuẩn BC
Input: Lược đồ quan hệ Q, tập phụ thuộc hàm F
Output: Khẳng định Q đạt chuẩn BC hay không đạt chuẩn BC. Bước 1: Tìm tất cả khóa của Q
Bước 2: Từ F tạo tập phụ thuộc hàm tương đương F1tt có vế phải một thuộc tính
Bước 3: Nếu mọi phụ thuộc hàm X → A ∈ F1tt với A∉X đều có X là siêu khóa thì Q đạt chuẩn BC ngược lại Q không đạt chuẩn BC
5. Thuật toán kiểm tra dạng chuẩn của một lược đồ quan hệ.
Dạng chuẩn của một lược đồ cơ sở dữ liệu là dạng chuẩn thấp nhất trong các dạng chuẩn của các lược đồ quan hệ con.
Input: Lược đồ quan hệ Q, tập phụ thuộc hàm F Output: Khẳng định Q đạt chuẩn gì?
Bước 1: Tìm tất cả khóa của Q
Bước 2: Kiểm tra chuẩn BC nếu đúng thì Q đạt chuẩn BC, kết thúc thuật toán
Ngược lại qua bước 3
Bước 3: Kiểm tra chuẩn 3 nếu đúng thì Q đạt chuẩn 3, kết thúc thuật toán
Ngược lại qua bước 4
Bước 4: Kiểm tra chuẩn 2 nếu đúng thì Q đạt chuẩn 2, kết thúc thuật toán.
Ngược lại Q đạt chuẩn 1
IV. HƯỚNG DẨN CÀI ĐẶT VÀ SỬ DỤNG CHƯƠNG TRÌNH
1. Cài đặt chương trình
- Copy thư mục BORLANDC vào ổ đĩa hệ thống. Double Click tập tin
- Vào menu File/Open hay bấm phím F3 để mở tập tin
CSDL_PR1.CPP và bấm tiếp Ctrl – F9 để thực thi chương trình hay có
2. Các chức năng của chương trình
Chương trình “ỨNG DỤNG CÁC THUẬT TOÁN ĐỂ TÌM BAO ĐÓNG,
TÌM KHÓA, TÌM PHỦ TỐI TIỂU VÀ CHUẨN HÓA QUAN HỆ ĐẠT CHUẨN BOYE CODD” được viết bằng ngôn ngữ C++ gồm 7 menu tùy
chọn.
Sử dụng chương trình: Nhập số từ 1 đến 7 theo tùy chọn menu yêu cầu của người sử dụng. Để thoát chương trình nhập số 0. Muốn kết thúc một tùy chọn trước khi chuyển sang nhập số của menu tùy chọn khác, bấm một phím bất kỳ.
Code chương trình:
#include <iostream.h>
#include <iomanip.h>
#include <stdio.h> #include <ctype.h> #include <conio.h> #define MAX 20 typedef struct { int vt, vp; } pth; typedef struct { char an[MAX][20]; pth a[MAX];
int n, sott, sokhoa, khoa[MAX]; } quanhe;
void doi(char *s, int &k) { int i = 0; flushall(); gets(s); k = 0; while (s[i]) { k = k | (1<<(toupper(s[i])-'A')); i++; } }
void nhappth(quanhe &R) {
int k, kh; char s[20]; int nn = 0;
cout<<"\n\nNhap phu thuoc ham (nhap lien tuc cac ten thuoc tinh cua 2 ve, Enter de ngung)\n";
do {
cout<<"\nVe trai:"; doi(s, k);
if (k) {
R.a[nn].vt = k;
cout<<"\nVe phai:"; doi(s, k);
kh = R.a[nn].vt; R.a[nn].vt = kh & ~k;
if (R.a[nn].vt && R.a[nn].vt) R.a[nn++].vp = k & ~kh; }
} while (k); R.n = nn; }
void inthuoctinh(quanhe R, int m) { int j, k; for (j=0; j<R.sott; j++) { k = (1<<j) & m; if (k) cout<<R.an[j]; //char(j+'A'); } }
void in(quanhe R, int i) {
inthuoctinh(R, R.a[i].vt); cout<<" --> ";
inthuoctinh(R, R.a[i].vp); }
void baodong(quanhe R, int k, int &kc) {
int i, stop; kc = k; do {
stop = 1;
for (i=0; i<R.n; i++)
if ((R.a[i].vt & kc)==R.a[i].vt && (R.a[i].vp & kc)! =R.a[i].vp)
{
kc = kc | R.a[i].vp; stop = 0;
}
}
void phanrapth(quanhe &R) { int m, j, k; int i=0; while (i<R.n) { m = R.a[i].vp; for (j=0; j<R.sott; j++) if (m & (1<<j)) { R.a[i].vp = 1<<j; if (m!=(1<<j)) { for (k=R.n; k>i; k--) R.a[k] = R.a[k-1]; i++; R.n++; m = m-(1<<j); R.a[i].vp = m; } } i++; } }
int kiemtra(pth a[], int n, int k) { int i, kc, stop; char s[20]; kc = a[k].vt; do { stop = 0;
for (i=0; i<n; i++)
if (i!=k && (a[i].vt & kc)==a[i].vt && (a[i].vp & kc)! =a[i].vp)
{
kc = kc | a[i].vp; stop = 1;
} while (!stop && kc!=a[k].vt); return a[k].vp & kc;
}
void loaivp(quanhe &R) { int k, i=0; while (i<R.n) { if (kiemtra(R.a, R.n, i)) { R.n--; for (k=i; k<R.n; k++) R.a[k] = R.a[k+1]; } else i++; } }
void loaivt(quanhe &R) { int m, kc, k, j, i=0; while (i<R.n) { m = R.a[i].vt; for (j=0; j<R.sott; j++) if (m & (1<<j)) { k = m -(1<<j); if (k!=0) { baodong(R, k, kc); if ((1<<j) & kc) R.a[i].vt = m = k; } } i++; } }
void rutgon(quanhe &R) {
int i, j, k;
for (i=0; i<R.n; i++) {
j=i+1;
while (j<R.n)
if (R.a[i].vt==R.a[j].vt) {
R.a[i].vp = R.a[i].vp | R.a[j].vp; R.n--; for (k=j; k<R.n; k++) R.a[k] = R.a[k+1]; } else j++; } } void inpth(quanhe R) { int i;
cout<<" Tap phu thuoc ham F = {"; for (i=0; i<R.n; i++)
{ in(R, i); cout<<(i==R.n-1? "": ","); } cout<<"}"; }
void tapndtg(quanhe R, int &ng, int &di, int &tg ) {
int i, u, ing, idi; ing = idi = 0;
for (i=0; i<R.n; i++) {
ing = ing | R.a[i].vt; idi = idi | R.a[i].vp;
}
ng = ing & ~idi; di = idi & ~ing; tg = ing & idi; }
void nhaptt(quanhe &R) {
int i;
cout<<"\nNhap so thuoc tinh:"; cin>>R.sott;
cout<<"\nCac thuoc tinh duoc dat ten lan luot la:"; for (i=0; i<R.sott; i++)
{
R.an[i][0] = 'A'+i; R.an[i][1] = 0; cout<<R.an[i]; }
cout<<"\n\n\n"; }
void xoakhoa(int khoa[], int &sokhoa, int k) {
int i; sokhoa--;
for (i=k; i<sokhoa; i++) khoa[i] = khoa[i+1]; }
void timkhoa(quanhe &R) {
int i, j, k, kc, ng, di, tg, ki, kj, kk, tam ; tapndtg(R, ng, di, tg); tam = (1<<R.sott); if (R.n==0) { R.sokhoa = 1; R.khoa[0] = tam-1; return;
}
ng = (tam-1) & ~(tg | di); R.sokhoa = 0;
for (i=0; i<tam; i++) {
if (i==0 || ((i & tg) && (i &di)==0)) { k = ng+i; baodong(R, k, kc); if (kc==(1<<R.sott)-1) R.khoa[R.sokhoa++] = k; } } i=0; while (i<R.sokhoa) { j = 0; while (j<R.sokhoa) { ki = R.khoa[i]; kj = R.khoa[j]; kk = ki &kj; if (kk==kj && i!=j) { tam = R.khoa[i]; R.khoa[i] = R.khoa[j]; R.khoa[j] = tam; } else
if (kk==ki && i!=j)
xoakhoa(R.khoa, R.sokhoa, j); else j++; } i++; } } int tim1khoa(quanhe R) { int tam, i, t, t0, kc;
t = tam = (1<<R.sott)-1; if (R.n==0) return t; for (i=0; i<R.sott; i++) { t0 = t & ~(1<<i); baodong(R, t0, kc); if (kc==tam) t = t0; } return t; }
void phutoitieu(quanhe &R) { phanrapth(R); loaivp(R); loaivt(R); rutgon(R); }
int idx(char str[], char st[][20], int n) {
int i;
for (i=0; i<n; i++)
if (strcmp(str, st[i])==0) return i;
return n; }
void xoapth(pth ham[], int &n, int k) {
int i; n--;
for (i=k; i<n; i++)
ham[i] = ham[i+1]; }
void xoatentt(char ham[][20], int &n, int k) {
int i; n--;
for (i=k; i<n; i++)
strcpy(ham[i], ham[i+1]); }
void chenqh(quanhe R[], int &n, quanhe Rc, int k) {
int i;
for (i=n; i>k; i--) R[i] = R[i-1]; R[k] = Rc;
n++; }
int dangchuan(quanhe R[], int &soqh) {
quanhe Rc, Rm;
int is, i, i1, i2, tmp1, tmp2, j, k, kc, kd, m, chuan, tam, tt0khoa, cont, ttkhoa=0; soqh = 1; is = 0; phutoitieu(R[0]); while (is<soqh) { timkhoa(R[is]); tam = (1<<R[is].sott)-1; ttkhoa = 0;
for (i=0; i<R[is].sokhoa; i++)
ttkhoa = ttkhoa | R[is].khoa[i]; tt0khoa = tam & ~ttkhoa;
cont = 1; i=0;
Rc = R[is];
phanrapth(R[is]);
while (i<R[is].sott && cont) {
k = (1<<i); if (k & tt0khoa) {
while (j<R[is].n && cont) {
if (k & R[is].a[j].vp) //thuoc tinh
khong khoa trong ve phai {
m=0;
while (m<Rc.sokhoa && cont) {
if ((R[is].a[j].vt & R[is].khoa[m]) == R[is].a[j].vt && R[is].a[j].vt !=R[is].khoa[m])
{ cont = 0; baodong(R[is], R[is].a[j].vt, kc); kd = kc & ~R[is].a[j].vt; Rm.sott = 0; Rm.n = 0;
for (i1=0; i1<Rc.sott; i1++)
if ((1<<i1) & kc)
strcpy(Rm.an[Rm.sott++], R[is].an[i1]);
i2=0;
for (i1=0; i1<Rc.sott; i1++) if (((1<<i1) & kd) ==0) strcpy(R[is].an[i2++], Rc.an[i1]); R[is].sott = i2; i1=0; while (i1<R[is].n) if
((R[is].a[i1].vt & kc) ==R[is].a[i1].vt && (R[is].a[i1].vp & kc) ==R[is].a[i1].vp)
{ Rm.a[Rm.n++] = R[is].a[i1];
xoapth(R[is].a, R[is].n, i1); } else i1++; i1=0; while (i1<R[is].n) { for (i2=0; i2<Rm.n; i2++) if ((R[is].a[i1].vp & Rm.a[i2].vt)==Rm.a[i2].vt && (R[is].a[i1].vt & Rm.a[i2].vp)==Rm.a[i2].vp)
{ R[is].a[i1].vp = (R[is].a[i1].vp & ~Rm.a[i2].vt) | Rm.a[i2].vp;
if ((R[is].a[i1].vp & R[is].a[i1].vt)==R[is].a[i1].vp)
{ xoapth(R[is].a, R[is].n, i1);
i1--; break; } } i1++; }
for (i1=0; i1<R[is].n; i1++) { tmp1 = tmp2 = 0; for (i2=0; i2<Rc.sott; i2++) { if (1<<i2 & R[is].a[i1].vt)
tmp1 = tmp1 | (1<<idx( Rc.an[i2],R[is].an, R[is].sott));
if (1<<i2 & R[is].a[i1].vp)
tmp2 = tmp2 | (1<<idx( Rc.an[i2], R[is].an,R[is].sott)); } R[is].a[i1].vt = tmp1; R[is].a[i1].vp = tmp2; }
for (i1=0; i1<Rm.n; i1++) { tmp1 = tmp2 = 0; for (i2=0; i2<Rc.sott; i2++) { if (1<<i2 & Rm.a[i1].vt)
tmp1 = tmp1 | (1<<idx(Rc.an[i2], Rm.an, Rm.sott));
if (1<<i2 & Rm.a[i1].vp)
tmp2 = tmp2 | (1<<idx(Rc.an[i2], Rm.an, Rm.sott)); } Rm.a[i1].vt = tmp1; Rm.a[i1].vp = tmp2; } chenqh(R, soqh, Rm, is); chuan = 1; } m++; }
} j++; } } i++; } i=0;
while (i<Rc.sott && cont) {
k = (1<<i);
if (k & tt0khoa) //thuoc tinh khong
khoa
for (j=0; j<R[is].n; j++)
if (k & R[is].a[j].vp) //thuoc tinh
khong khoa trong ve phai
if (R[is].a[j].vt & tt0khoa) //thuoc tinh khong khoa trong ve trai
{ cont = 0; baodong(R[is], R[is].a[j].vt, kc); kd = kc & ~R[is].a[j].vt; Rm.sott = 0; Rm.n = 0;
for (i1=0; i1<Rc.sott; i1++) if ((1<<i1) & kc) strcpy(Rm.an[Rm.sott++], R[is].an[i1]);
for (i1=0; i1<Rc.sott; i1++) if ((1<<i1) & kd) xoatentt(R[is].an, R[is].sott, i1);
i1=0;
while (i1<R[is].n)
if ((R[is].a[i1].vt & kc) ==R[is].a[i1].vt && (R[is].a[i1].vp & kc) ==R[is].a[i1].vp)
{
Rm.a[Rm.n++] = R[is].a[i1];
xoapth(R[is].a, R[is].n, i1);
} else
i1++;
for (i1=0; i1<R[is].n; i1++) {
tmp1 = tmp2 = 0; for (i2=0; i2<Rc.sott; i2++)
{
if (1<<i2 & R[is].a[i1].vt)
tmp1 = tmp1 | (1<<idx( Rc.an[i2],R[is].an, Rc.sott));
if (1<<i2 & R[is].a[i1].vp)
tmp2 = tmp2 | (1<<idx( Rc.an[i2], R[is].an,Rc.sott));
}
R[is].a[i1].vt = tmp1; R[is].a[i1].vp = tmp2;
}
for (i1=0; i1<Rm.n; i1++) {
tmp1 = tmp2 = 0; for (i2=0; i2<Rc.sott; i2++)
{
if (1<<i2 & Rm.a[i1].vt)
tmp1 = tmp1 | (1<<idx(Rc.an[i2], Rm.an, Rc.sott));
if (1<<i2 & Rm.a[i1].vp)
tmp2 = tmp2 | (1<<idx(Rc.an[i2], Rm.an, Rc.sott));
}
Rm.a[i1].vt = tmp1; Rm.a[i1].vp = tmp2; }
chenqh(R, soqh, Rm, is); chuan = 2; ////////////////////////////////////////////////////// } i++; } i=0;
while (i<R[is].n && cont) {
j=0;
while (j<R[is].sokhoa && cont) { if (R[is].a[i].vt !=R[is].khoa[j]) { /////////////////////////////////////////////////////// cont = 0; baodong(R[is], R[is].a[j].vt, kc); kd = kc & ~R[is].a[j].vt; Rm.sott = 0; Rm.n = 0; Rc = R[is];
for (i1=0; i1<R[is].sott; i1++) if ((1<<i1) & kc)
strcpy(Rm.an[Rm.sott++], R[is].an[i1]);
i2=0;
for (i1=0; i1<R[is].sott; i1++) if (((1<<i1) & kd)==0) strcpy(R[is].an[i2++], Rc.an[i1]); R[is].sott = i2; i1=0; while (i1<R[is].n) if ((R[is].a[i1].vt & kc) ==R[is].a[i1].vt && (R[is].a[i1].vp & kc) ==R[is].a[i1].vp)
{
Rm.a[Rm.n++] = R[is].a[i1];
xoapth(R[is].a, R[is].n, i1); }
i1++; i1=0;
while (i1<R[is].n) {
for (i2=0; i2<Rm.n; i2++) if ((R[is].a[i1].vp & Rm.a[i2].vt)==Rm.a[i2].vt && (R[is].a[i1].vt &
Rm.a[i2].vp)==Rm.a[i2].vp)
{
R[is].a[i1].vp = (R[is].a[i1].vp & ~Rm.a[i2].vt) | Rm.a[i2].vp;
if ((R[is].a[i1].vp & R[is].a[i1].vt)==R[is].a[i1].vp) { xoapth(R[is].a, R[is].n, i1); i1--; break; } } i1++; }
for (i1=0; i1<R[is].n; i1++) {
tmp1 = tmp2 = 0;
for (i2=0; i2<Rc.sott; i2++) {
if (1<<i2 & R[is].a[i1].vt) tmp1 = tmp1 | (1<<idx( Rc.an[i2],R[is].an, Rc.sott));
if (1<<i2 & R[is].a[i1].vp) tmp2 = tmp2 | (1<<idx( Rc.an[i2], R[is].an,Rc.sott));
}
R[is].a[i1].vt = tmp1; R[is].a[i1].vp = tmp2; }
{
tmp1 = tmp2 = 0;
for (i2=0; i2<Rc.sott; i2++) {
if (1<<i2 & Rm.a[i1].vt) tmp1 = tmp1 | (1<<idx(Rc.an[i2], Rm.an, Rc.sott));
if (1<<i2 & Rm.a[i1].vp) tmp2 = tmp2 | (1<<idx(Rc.an[i2], Rm.an, Rc.sott));
}
Rm.a[i1].vt = tmp1; Rm.a[i1].vp = tmp2; }
chenqh(R, soqh, Rm, is); chuan = 3; } j++; } i++; } if (cont) is++; } return chuan; } void main() { quanhe R[20], RR; char s[20];
int i, chon, j, k, kc, kh, soqh; do {
clrscr();
cout<<"\nUNG DUNG CAC THUAT TOAN DE TIM KHOA, TIM PHU TOI THIEU VA CHUAN HOA QUAN HE DAT CHUAN BC\n";
cout<<"\n1. Nhap luoc do quan he"; cout<<"\n2. In tap phu thuoc ham";
cout<<"\n3. Tim bao dong tap thuoc tinh"; cout<<"\n4. Phu toi tieu";
cout<<"\n5. Tim 1 khoa cua luoc do quan he";
cout<<"\n6. Tim tat ca cac khoa cua luoc do quan he"; cout<<"\n7. Phan ra luoc do de dat chuan BC";
cout<<"\nChon (Nhap so 1 den so 7 theo menu tuy chon - Nhap so 0 de thoat):";
cin>>chon; switch (chon) { case 1: nhaptt(RR); nhappth(RR); break; case 2: inpth(RR); break; case 3:
cout<<"\nNhap tap hop cac thuoc tinh:"; doi(s, k);
baodong(RR, k, kc); cout<<"Bao dong :"; inthuoctinh(RR, kc); break;
case 4:
R[0] = RR;
phutoitieu(R[0]);
cout<<"\nPhu toi tieu:\n"; inpth(R[0]);
break; case 5:
kh = tim1khoa(R[0]);
cout<<"\nKet qua tim 1 khoa cua luoc do la:";
inthuoctinh(R[0], kh); break;
case 6:
cout<<"\nKet qua tim tat ca cac khoa cua luoc do la:";
timkhoa(R[0]);
for (i=0; i<R[0].sokhoa; i++) { cout<<endl; inthuoctinh(R[0], R[0].khoa[i]); } break; case 7: R[0] = RR; dangchuan(R, soqh);
cout<<"\nQuan he duoc phan ra dat chuan BC\n";
for (i=0; i<soqh; i++) { rutgon(R[i]); cout<<endl<<"Qh R"<<i+1<<"("; for (j=0; j<R[i].sott; j++) cout<<R[i].an[j]; cout<<")\n"; inpth(R[i]); cout<<endl<<" Khoa:"; for (j=0; j<R[i].sokhoa; j++) { inthuoctinh(R[i], R[i].khoa[j]); cout<<" "; } cout<<"\n"; } break; } if (chon>0) {
cout<<"\n\n\nNhan phim bat ky de tiep tuc"; getch();
}
} while (chon>0); }
Menu 1: Nhập lược đồ quan hệ
Bấm phím số 1 và bấm Enter để chọn menu Nhập lược đồ quan
hệ. Nhập dữ liệu theo yêu cầu.
Ví dụ: LĐQH r(R) với R = {A, B, C, D, E, F) và tập PTH F như sau:
F={ ABC-> DEF, BC DF, CE -> AD}
- Nhập số thuộc tính của quan hệ là 6
- Lần lượt nhập vế trái của phụ thuộc hàm 1 là ABC (bấm Enter) - Nhập tiếp vế phải của phụ thuộc hàm 1 là DEF (bấm Enter) - Nhập vế trái của phụ thuộc hàm 2 là BC (bấm Enter)
- Nhập tiếp vế phải của phụ thuộc hàm 2 là DF (bấm Enter). - Nhập vế trái của phụ thuộc hàm 3 là CE (bấm Enter)
- Bấm phím Enter lần nữa khi đã nhập đủ tập phụ thuộc hàm. (để kết thúc menu 1)
Bấm phím Enter để kết thúc menu 1 và bấm tiếp thêm một phím bất kỳ. Bấm phím số 2 để chọn In ra lược đồ quan hệ vừa nhập.
Menu 3: Tìm bao đóng tập thuộc tính
Bấm một phím bất kỳ, bấm tiếp phím số 3 để chọn Tìm bao đóng
của tập thuộc tính
Menu 4: Phủ tối tiểu
Bấm một phím bất kỳ, bấm tiếp phím số 4 để chọn tìm phủ tối
tiểu.
Bấm một phím bất kỳ, bấm tiếp phím số 5 để chọn tìm nhanh một
khóa của lược đồ quan hệ.
Menu 6: Tìm tất cả khóa của lược đồ quan hệ
Bấm một phím bất kỳ, bấm tiếp phím số 6 để chọn tìm tất cả khóa
Menu 7: Phân rã lược đồ để đạt dạng chuẩn Boye Codd (BC)
Bấm một phím bất kỳ, bấm tiếp phím số 7 để chọn menu phân rã
- Nhấn phím bất kỳ để tiếp tục nhập số menu tùy chọn theo yêu cầu. Khi muốn thoát chương trình, bấm phím số 0.
KẾT LUẬN ------
Thực tế, cho đến nay các hệ CSDL quan hệ cũng đã thu được những thành tựu to lớn không những về phương diện lý thuyết mà còn trong ứng dụng thực tế.
Sự tiến bộ nhanh chóng của công nghệ truyền thông và sự phát triển vượt bậc của mạng Internet, hòa cùng với xu thế toàn cầu hoá trong mọi lĩnh vực, đặc biệt là về thương mại đã dẫn đến việc phân bố ngày càng rộng rãi của tổng công ty - công ty con, xí nghiệp - phân xưởng phụ ở khắp nơi. Điều tất yếu xảy ra là dữ liệu thông tin cần cập nhật và xử lý rất lớn và không thể quản lý tập trung. Các hệ CSDL quan hệ (RDBM) hiện tại sẽ bộc lộ những yếu kém trong những tác vụ như tạo chỉ mục một lượng lớn dữ liệu, phân trang, hoặc phân phối luồng dữ liệu media (phim, ảnh, nhạc, ...). Thêm vào đó, ngữ nghĩa của mô hình quan hệ chưa đủ phong phú, việc quản lý các dữ liệu động và phức tạp kém hiệu quả,... Do đó, một số hướng nghiên cứu mở rộng
được đề xuất: CSDL suy diễn, CSDL hướng đối tượng, CSDL phân tán.
Thế hệ CSDL mới ra đời đã giảm thiểu tối đa các phép tính toán, tác vụ đọc-ghi liên quan kết hợp với xử lý theo lô (batch processing), đảm bảo được yêu cầu xử lý dữ liệu của các dịch vụ mạng xã hội nhưng chỉ đòi hỏi về tài nguyên phần cứng thấp.
Một số đặc điểm của thế hệ CSDL mới:
- Thế hệ CSDL mới là phi quan hệ (không ràng buộc): Non-relational là khái niệm không sử dụng các ràng buộc dữ liệu cho nhất quán dữ liệu. Khác với relational - ràng buộc - thuật ngữ sử dụng đến các mối quan hệ giữa các bảng trong cơ sở dữ liệu quan hệ (RDBM) sử dụng
mô hình gồm 2 loại khóa: khóa chính và khóa phụ (primary key + foreign key) để ràng buộc dữ liệu nhằm thể hiện tính nhất quán dữ liệu từ các bảng khác nhau.
- Lưu trữ phân tán: mô hình lưu trữ phân tán các tập tin hoặc dữ liệu ra nhiều máy khác nhau trong mạng LAN hoặc Internet dưới sự kiểm soát của phần mềm.
- Nhất quán cuối: tính nhất quán của dữ liệu không cần phải đảm bảo