thắc mắc Chuẩn hóa cơ sở dữ liệu.

jiangcristian

Senior Member
Các bác ở đây cho em hỏi là chuẩn hóa csdl có phải là yêu cầu bắt buộc khi thiết kế csdl cho một hệ thống không ạ. Tại vì em thấy đôi khi tăng độ chuẩn hóa lên sẽ làm tăng tải hơn cho hệ thống.

Vd 1: Trong 1 db hệ thống quản lí cửa hàng, bảng lưu thông tin hóa đơn thường sẽ có thông tin về đơn giá mặt hàng, số lượng mặt hàng. Tổng giá của hóa đơn có thể được tính bằng đơn giá một mặt hàng x số lượng hàng. Đây có thể coi là 1 ví dụ kinh điển mà mỗi khi học về chuẩn hóa csdl ở trường đại học luôn được nhắc đến.
Nhưng nếu thay vì quản lí 1 cửa hàng nhỏ, hệ thống của chúng ta quản lí rất nhiều gian hàng, hoặc 1 sàn tmđt thì sao, bảng ghi hóa đơn có thể gồm hàng triệu record, và lúc này mỗi khi xem hóa đơn sẽ phải query trong 1 đống record đó và tính lại giá trị hóa đơn để hiển thị cho người dùng. Điều này liệu có thể khiến hệ thống chạy chậm hơn không?


Vd 2: Giả sử hệ thống quản lí điểm số của sinh viên trong 1 trường đại học, các thông tin cần lưu bao gồm điểm thành phần từng môn, số tín chỉ của từng môn. Như vậy điểm tổng kết của sinh viên là một thuộc tính có thể tính toán dựa trên điểm từng môn và số tín chỉ dựa trên công thức cho trước.

Tuy nhiên nếu k lưu lại giá trị điểm tổng kết này thì giả sử sau này công thức tính điểm cũ được thay = công thức tính điểm mới => điểm tổng kết của các sinh viên cũ có thể bị thay đổi.

Trong 2 ví dụ trên thậm chí csdl còn chưa đạt chuẩn 1, nếu chuẩn hóa lên các dạng cao hơn thậm chí có thể có nhiều vấn đề phát sinh hơn, các bác nghĩ sao ạ.
 
Các bác ở đây cho em hỏi là chuẩn hóa csdl có phải là yêu cầu bắt buộc khi thiết kế csdl cho một hệ thống không ạ. Tại vì em thấy đôi khi tăng độ chuẩn hóa lên sẽ làm tăng tải hơn cho hệ thống.

Vd 1: Trong 1 db hệ thống quản lí cửa hàng, bảng lưu thông tin hóa đơn thường sẽ có thông tin về đơn giá mặt hàng, số lượng mặt hàng. Tổng giá của hóa đơn có thể được tính bằng đơn giá một mặt hàng x số lượng hàng. Đây có thể coi là 1 ví dụ kinh điển mà mỗi khi học về chuẩn hóa csdl ở trường đại học luôn được nhắc đến.
Nhưng nếu thay vì quản lí 1 cửa hàng nhỏ, hệ thống của chúng ta quản lí rất nhiều gian hàng, hoặc 1 sàn tmđt thì sao, bảng ghi hóa đơn có thể gồm hàng triệu record, và lúc này mỗi khi xem hóa đơn sẽ phải query trong 1 đống record đó và tính lại giá trị hóa đơn để hiển thị cho người dùng. Điều này liệu có thể khiến hệ thống chạy chậm hơn không?


Vd 2: Giả sử hệ thống quản lí điểm số của sinh viên trong 1 trường đại học, các thông tin cần lưu bao gồm điểm thành phần từng môn, số tín chỉ của từng môn. Như vậy điểm tổng kết của sinh viên là một thuộc tính có thể tính toán dựa trên điểm từng môn và số tín chỉ dựa trên công thức cho trước.
Tuy nhiên nếu k lưu lại giá trị điểm tổng kết này thì giả sử sau này công thức tính điểm cũ được thay = công thức tính điểm mới => điểm tổng kết của các sinh viên cũ có thể bị thay đổi.

Trong 2 ví dụ trên thậm chí csdl còn chưa đạt chuẩn 1, nếu chuẩn hóa lên các dạng cao hơn thậm chí có thể có nhiều vấn đề phát sinh hơn, các bác nghĩ sao ạ.

Không bắt buộc chuẩn hoá hoàn toàn.

Cả 2 ví dụ trên, tổng giá hoá đơn và điểm tổng kết đều nên lưu vào database. Khoan nói chuyện về chuẩn hoá hay ko. Đây là vấn đề thiết kế database, những thông tin kiểu transaction như này phải lưu vì đơn giá, công thức tính sau này có thể thay đổi, hơn nữa đây là thông tin lịch sử và thường ko đổi nên lưu luôn.

Bạn cứ nghĩ nếu không sử dụng máy tính thì cái hoá đơn, sổ học bạ cũng phải tính rồi lưu hồ sơ bỏ tủ chứ có ai lưu mổi cái học bạ điểm từng môn rồi khi cần truy xuất thông tin lại lấy nó ra khỏi tủ, rồi tính lại cho mổi lần xem.

Việc thiết kế database tính sẵn các field cũng thường gặp để phục vụ làm report, data analysis. Thông thường dự án lớn sẽ có database riêng (google Multidimensional Database, OLAP, Data Cube...), dự án nhỏ thì thường nó dùng chung luôn với relational database (tạo 1 số table với các field tính sẵn làm report thôi).

Nguyên tắc là:
Cái gì mang tính chất transaction, lịch sử, ít thay đổi như hoá đơn, tổng điểm thì tính ra, lưu database luôn.

Ngược lại ko phải transaction, ko mang tính lịch sử, hay thay đổi thì tính lúc report: Ví dụ tổng số nhân viên, dynamic report doanh số sales hàng ngày xem cho vui. Nếu doanh số sales mà có report cuối tháng, quý để báo cáo thuế thì lại phải lưu vì con số tổng cuối tháng/quý là thông tin lịch sử và về mặt nghiệp vụ có lưu hồ sơ lại.
 
Các bác ở đây cho em hỏi là chuẩn hóa csdl có phải là yêu cầu bắt buộc khi thiết kế csdl cho một hệ thống không ạ. Tại vì em thấy đôi khi tăng độ chuẩn hóa lên sẽ làm tăng tải hơn cho hệ thống.

Vd 1: Trong 1 db hệ thống quản lí cửa hàng, bảng lưu thông tin hóa đơn thường sẽ có thông tin về đơn giá mặt hàng, số lượng mặt hàng. Tổng giá của hóa đơn có thể được tính bằng đơn giá một mặt hàng x số lượng hàng. Đây có thể coi là 1 ví dụ kinh điển mà mỗi khi học về chuẩn hóa csdl ở trường đại học luôn được nhắc đến.
Nhưng nếu thay vì quản lí 1 cửa hàng nhỏ, hệ thống của chúng ta quản lí rất nhiều gian hàng, hoặc 1 sàn tmđt thì sao, bảng ghi hóa đơn có thể gồm hàng triệu record, và lúc này mỗi khi xem hóa đơn sẽ phải query trong 1 đống record đó và tính lại giá trị hóa đơn để hiển thị cho người dùng. Điều này liệu có thể khiến hệ thống chạy chậm hơn không?


Vd 2: Giả sử hệ thống quản lí điểm số của sinh viên trong 1 trường đại học, các thông tin cần lưu bao gồm điểm thành phần từng môn, số tín chỉ của từng môn. Như vậy điểm tổng kết của sinh viên là một thuộc tính có thể tính toán dựa trên điểm từng môn và số tín chỉ dựa trên công thức cho trước.

Tuy nhiên nếu k lưu lại giá trị điểm tổng kết này thì giả sử sau này công thức tính điểm cũ được thay = công thức tính điểm mới => điểm tổng kết của các sinh viên cũ có thể bị thay đổi.

Trong 2 ví dụ trên thậm chí csdl còn chưa đạt chuẩn 1, nếu chuẩn hóa lên các dạng cao hơn thậm chí có thể có nhiều vấn đề phát sinh hơn, các bác nghĩ sao ạ.

Thực ra thì chuẩn hóa sẽ đảm bảo consistency của dữ liệu. Những gì mà có thể lấy được từ dữ liệu hiện có thì không lưu thêm nữa. Thường thì mọi người sẽ làm thêm 1 tầng cache cho những dữ liệu này (nếu hay cần dùng đến).
Tuy nhiên thì tùy vào nghiệp vụ và tốc độ hệ thống mà có thể lưu thêm các trường khác (dữ liệu bị lặp) trong db. Cái này thì lại gây tốn tài nguyên của tầng application là phải đảm bảo cho dữ liệu khớp với nhau.
 
Các bác ở đây cho em hỏi là chuẩn hóa csdl có phải là yêu cầu bắt buộc khi thiết kế csdl cho một hệ thống không ạ. Tại vì em thấy đôi khi tăng độ chuẩn hóa lên sẽ làm tăng tải hơn cho hệ thống.

Vd 1: Trong 1 db hệ thống quản lí cửa hàng, bảng lưu thông tin hóa đơn thường sẽ có thông tin về đơn giá mặt hàng, số lượng mặt hàng. Tổng giá của hóa đơn có thể được tính bằng đơn giá một mặt hàng x số lượng hàng. Đây có thể coi là 1 ví dụ kinh điển mà mỗi khi học về chuẩn hóa csdl ở trường đại học luôn được nhắc đến.
Nhưng nếu thay vì quản lí 1 cửa hàng nhỏ, hệ thống của chúng ta quản lí rất nhiều gian hàng, hoặc 1 sàn tmđt thì sao, bảng ghi hóa đơn có thể gồm hàng triệu record, và lúc này mỗi khi xem hóa đơn sẽ phải query trong 1 đống record đó và tính lại giá trị hóa đơn để hiển thị cho người dùng. Điều này liệu có thể khiến hệ thống chạy chậm hơn không?


Vd 2: Giả sử hệ thống quản lí điểm số của sinh viên trong 1 trường đại học, các thông tin cần lưu bao gồm điểm thành phần từng môn, số tín chỉ của từng môn. Như vậy điểm tổng kết của sinh viên là một thuộc tính có thể tính toán dựa trên điểm từng môn và số tín chỉ dựa trên công thức cho trước.
Tuy nhiên nếu k lưu lại giá trị điểm tổng kết này thì giả sử sau này công thức tính điểm cũ được thay = công thức tính điểm mới => điểm tổng kết của các sinh viên cũ có thể bị thay đổi.

Trong 2 ví dụ trên thậm chí csdl còn chưa đạt chuẩn 1, nếu chuẩn hóa lên các dạng cao hơn thậm chí có thể có nhiều vấn đề phát sinh hơn, các bác nghĩ sao ạ.

Về việc chuẩn hóa dữ liệu, thực tế khi đi làm thì thiết kế db mình vẫn sẽ chuẩn hóa, sau đó tùy tình huống mà có thể để dư thừa dữ liệu nhằm giảm tính toán ở phía app, hoặc giảm số lượt query vào db, giảm việc phải join nhiều bảng dữ liệu.

Về ví dụ của bạn, thì do các dữ liệu như tổng giá trị đơn hàng, hay điểm tổng kết của sinh viên nó mang tính thời điểm (do giá sản phẩm có thể sau này sẽ đổi, hoặc công thức tính điểm tổng kết sẽ đổi) nên là chắc chắn bạn cần lưu lại rồi (để cho chắc có khi cần lưu lại cả version của sản phẩm trong order đó).
 
Thực ra thì chuẩn hóa sẽ đảm bảo consistency của dữ liệu. Những gì mà có thể lấy được từ dữ liệu hiện có thì không lưu thêm nữa. Thường thì mọi người sẽ làm thêm 1 tầng cache cho những dữ liệu này (nếu hay cần dùng đến).
Tuy nhiên thì tùy vào nghiệp vụ và tốc độ hệ thống mà có thể lưu thêm các trường khác (dữ liệu bị lặp) trong db. Cái này thì lại gây tốn tài nguyên của tầng application là phải đảm bảo cho dữ liệu khớp với nhau.
Phần caching này chỉ là việc thêm layer để hạn chế truy xuất dữ liệu từ DB thôi bác, như #2 nói chuẩn đấy, nó liên quan đến việc thiết kế data và database ngay từ đầu.
 
Vậy tóm lại là chuẩn hóa ở công ty là cần hay không vậy các Bác. Công ty lớn? Công ty nhỏ? Công ty vừa?.... Và chuẩn hóa tới BCNF là ok phải không ạ ?
 
Tại sao trong 2 ví dụ trên DB lại chưa đạt chuẩn 1 ?

Ví dụ 1:
Mình ví dụ có các bảng
User (id,name)
Item (id, tên, ... )
Order( id, buy_time, user_id <FK>)
OrderItem (id, order_id<FK>, item_id <FK>, item_price, quantity)

Khi tính tổng thì query các orderItem có cùng order id. Tùy vào định nghĩa của bạn. nếu bạn quy định giá item là cố định không bao giờ thay đổi thì có thể bỏ cột item_price. Đôi khi nó bằng nhau nhưng không phải là 1

Ví dụ 2
Order chính là điểm tổng kết kỳ,
Order Item chính là môn học đi kèm với điểm
 
Back
Top