Grain, fact và dimension
Bài này hữu ích khi tổng trên báo cáo tăng gấp đôi sau khi thêm một cột thông tin.
Đọc xong bạn hiểu gì
- Nói rõ mỗi dòng của bảng đại diện cho việc gì và cách nhận diện dòng đó
- Phân biệt bảng ghi sự kiện để tính với bảng cung cấp thông tin mô tả
- Nhận ra vì sao ghép theo mã hoá đơn có thể làm tiền hàng và tiền thanh toán bị cộng lặp
- Chọn cách tổng hợp hoặc giữ riêng hai bảng theo câu hỏi báo cáo cần trả lời
Khoảng 13 phút đọc.
Bối cảnh
Sao Mai là một chuỗi cửa hàng tạp hoá và đồ gia dụng. Chuỗi bắt đầu từ một cửa hàng và đang mở thêm cửa hàng mới. Mỗi cửa hàng bán hàng qua máy tính tiền; dữ liệu bán hàng được gửi về văn phòng để các phòng ban làm báo cáo. Tên chuỗi và mọi số liệu trong bài là giả lập.
Ngày 14/09/2026, cửa hàng CH01 bán các món trên hoá đơn HD3001. Tiền hàng cộng lại là 300.000 đ. Khách trả một phần bằng tiền mặt, phần còn lại bằng thẻ. Người lập báo cáo muốn thêm cách thanh toán vào bảng tiền hàng nên ghép các dòng hàng với các lần thanh toán theo mã hoá đơn. Sau khi ghép, tổng tiền hàng thành 600.000 đ.
Cửa hàng không bán thêm và khách cũng không trả thêm tiền. Tổng tăng lên vì cách ghép bảng. Để tìm chỗ sai, cần nhìn vào từng dòng trước khi nhìn tổng: dòng này đang ghi một món hàng, một lần trả tiền hay một cặp gồm cả hai?
Ví dụ xét hoá đơn đã trả đủ, không có giảm giá, hàng trả lại hay khoản điều chỉnh. Tiền hàng ở đây không thay cho định nghĩa doanh thu của từng báo cáo.
Mỗi dòng đại diện cho việc gì
Hoá đơn HD3001 có 2 dòng hàng và 2 lần thanh toán. Cùng một mã hoá đơn, nhưng hai bảng ghi những việc khác nhau.
Mức chi tiết (grain) cho biết mỗi dòng của một bảng đại diện cho việc gì. Chẳng hạn, “một dòng hàng trên một hoá đơn” khác với “một lần thanh toán của một hoá đơn”. Mô tả này giúp biết khoản tiền thuộc về đâu và cộng thế nào.
| Bảng | Mỗi dòng đại diện cho | Cách nhận diện trong ví dụ |
|---|---|---|
| Dòng hàng | Một dòng hàng trên hoá đơn | Mã hoá đơn và số thứ tự dòng |
| Thanh toán | Một lần trả tiền cho hoá đơn | Mã lần thanh toán |
| Tổng hợp theo hoá đơn | Toàn bộ tiền của một hoá đơn | Mã hoá đơn |
Khoá nhận diện là cột hoặc nhóm cột dùng để phân biệt từng dòng theo mức chi tiết đã nêu. Dòng hàng cần cả mã hoá đơn và số thứ tự dòng. Nếu các cửa hàng dùng trùng mã hoá đơn, khoá còn cần phân biệt cửa hàng; HD3001 là mã riêng trong ví dụ này.
Một dòng hàng cũng không nhất thiết là một đơn vị hàng. Khách mua nhiều gói gạo cùng loại có thể được ghi trên cùng một dòng, với số lượng và đơn giá. Vì vậy, đếm dòng hàng không thay được việc cộng số lượng hàng.
Khi nhận bảng để lập báo cáo, hãy nhờ người cung cấp ghi “Mỗi dòng là…” và khoá nhận diện. Tệp nhỏ dùng một lần có thể chỉ cần ghi chú trên tệp; bảng dùng lại nên giữ mô tả cùng bảng.
Fact và dimension
Fact (bảng sự kiện) ghi các sự kiện hoặc kết quả đo ở mức chi tiết đã chọn, kèm những giá trị dùng để tính. Trong ví dụ, bảng dòng hàng ghi việc bán hàng; bảng thanh toán ghi việc nhận tiền. Cả hai đều có thể là fact, dù chúng không ghi cùng một việc.
Tiền hàng của một dòng bằng số lượng nhân đơn giá; tiền thanh toán ghi khoản trả trong một lần. Tổng hai bên bằng nhau với hoá đơn đã trả đủ như HD3001, nhưng không thể dùng thay nhau: tiền trả cho cả hoá đơn chưa cho biết khoản trả riêng cho từng món.
Dimension (bảng chiều) cung cấp thông tin mô tả để đọc, lọc hoặc gom nhóm dữ liệu của fact. Chẳng hạn, bảng cửa hàng giúp đổi mã CH01 trên dòng bán hàng thành tên cửa hàng dễ đọc. Bảng cửa hàng có dòng mô tả CH01 như sau:
| Mã cửa hàng | Tên cửa hàng |
|---|---|
| CH01 | Cửa hàng số 1 |
Nếu mỗi mã khớp đúng một dòng mô tả cửa hàng, ghép thêm tên giữ nguyên mức chi tiết dòng hàng. Nếu nhiều dòng mô tả cùng khớp một mã, tiền hàng có thể bị cộng lặp.
Fact và dimension phân biệt theo vai trò, không theo cột số hay chữ. Bảng cửa hàng có thể có số thứ tự; fact vẫn cần mã và ngày để hiểu sự kiện thuộc về đâu.
Ghép bảng làm đổi mức chi tiết thế nào
Ghép bảng trong ví dụ nghĩa là tìm các dòng có cùng mã hoá đơn ở hai bảng và đặt chúng cạnh nhau. Với mỗi dòng hàng, cách ghép này lấy mọi lần thanh toán có mã HD3001. Kết quả không còn là một dòng cho mỗi dòng hàng: mỗi dòng mới là một cặp dòng hàng và lần thanh toán.
Vì HD3001 có 2 lần thanh toán, tiền của mỗi dòng hàng xuất hiện 2 lần trong bảng ghép. Ngược lại, tiền của mỗi lần thanh toán xuất hiện 2 lần, vì hoá đơn có từng ấy dòng hàng. Cộng tiền như khi hai bảng còn riêng sẽ làm cả hai tổng tăng lên.
Khác mức chi tiết chưa có nghĩa là mọi phép ghép đều sai. Dòng hàng và bảng cửa hàng cũng khác mức chi tiết. Cần xét mỗi dòng khớp bao nhiêu dòng bên kia và tiền xuất hiện bao nhiêu lần. HD3001 bị lặp vì nhiều dòng hàng cùng khớp nhiều lần thanh toán.
Nếu chỉ cần tổng tiền hàng, không cần ghép bảng thanh toán. Nếu cần so tổng tiền hàng với tổng khách đã trả, có thể cộng riêng từng bảng theo hoá đơn rồi mới ghép. Còn tiền hàng theo cách thanh toán cần dữ liệu hoặc quy tắc chia tiền cho từng món.
Ví dụ giải sẵn
Hai bảng nguồn đều đúng
Các dòng dưới thuộc HD3001, bán ở CH01 lúc 10:00 ngày 14/09/2026. D1 và D2 là mã ngắn để dễ theo dõi trong bài; số thứ tự dòng nằm trong bảng nguồn.
| Dòng hàng | Món hàng | Tiền hàng (đ) |
|---|---|---|
| D1 | Quạt bàn | 200.000 |
| D2 | Gạo 5 kg | 100.000 |
Tiền hàng mỗi dòng bằng số lượng nhân đơn giá. Có thể xem cách tính ngay từ các cột này:
| Dòng hàng | Số lượng | Đơn giá (đ) |
|---|---|---|
| D1 | 1 | 200.000 |
| D2 | 2 | 50.000 |
Khách thanh toán bằng tiền mặt lúc 10:01, rồi bằng thẻ lúc 10:02 cùng ngày. TT01 và TT02 là mã nhận diện các lần thanh toán.
| Lần trả | Cách trả | Số tiền (đ) |
|---|---|---|
| TT01 | Tiền mặt | 100.000 |
| TT02 | Thẻ | 200.000 |
Tổng tiền hàng là 300.000 đ; tổng khách trả là 300.000 đ. Không có dòng nguồn nào bị gửi lặp trong tình huống này.
Ghép trực tiếp theo mã hoá đơn
Người lập báo cáo ghép mọi dòng có mã HD3001. Bảng dưới chỉ hiện cặp mã và tiền hàng để thấy rõ khoản nào xuất hiện thêm lần nữa:
| Dòng hàng | Lần trả | Tiền hàng (đ) |
|---|---|---|
| D1 | TT01 | 200.000 |
| D1 | TT02 | 200.000 |
| D2 | TT01 | 100.000 |
| D2 | TT02 | 100.000 |
D1 khớp TT01 và cũng khớp TT02; D2 cũng vậy. Bảng ghép có 4 dòng. Nếu cộng cột tiền hàng, tổng thành 600.000 đ, thay vì 300.000 đ. Đây là tổng bị cộng lặp sau ghép, không phải tiền hàng mới bán.
Cặp D1–TT01 chỉ ghi hai dòng cùng thuộc HD3001, không cho biết tiền mặt của TT01 trả riêng cho món D1. Các cặp này do phép ghép tạo ra.
Cộng riêng theo hoá đơn rồi mới đối chiếu
Với câu hỏi “Hoá đơn này có bao nhiêu tiền hàng và khách đã trả bao nhiêu?”, nhóm làm như sau:
- Cộng tiền các dòng hàng theo mã hoá đơn, tạo bảng tổng tiền hàng của từng hoá đơn.
- Cộng tiền các lần thanh toán theo mã hoá đơn, tạo bảng tổng tiền đã trả của từng hoá đơn.
- Ghép các bảng tổng theo mã hoá đơn và kiểm mỗi mã chỉ có một dòng ở mỗi bên.
Mỗi bảng tổng có mức chi tiết là một hoá đơn. Ghép chúng cho kết quả đối chiếu:
| Hoá đơn | Tiền hàng (đ) | Đã trả (đ) |
|---|---|---|
| HD3001 | 300.000 | 300.000 |
Tiền hàng giữ đúng 300.000 đ và tiền đã trả giữ đúng 300.000 đ. Bảng này không còn chi tiết từng món hay từng cách trả. Nếu báo cáo vẫn cần những chi tiết đó, giữ các bảng riêng để xem bên cạnh bảng tổng.
Nếu hoá đơn chưa có thanh toán, chỉ lấy mã có ở cả hai bên sẽ bỏ mất hoá đơn đó. Báo cáo cần đủ hoá đơn bán ra phải giữ danh sách trong phạm vi và ghi rõ phần thiếu thanh toán. Lấy phần chung phù hợp khi chỉ đối chiếu hoá đơn có dữ liệu ở cả hai bên; cần nêu phạm vi này.
Phiếu kiểm trước khi ghép bảng đã điền
Phiếu dưới dành cho câu hỏi đối chiếu tổng của HD3001.
| Mục | Nội dung |
|---|---|
| Câu hỏi báo cáo | HD3001 có bao nhiêu tiền hàng và khách đã trả bao nhiêu? |
| Bảng bên dòng hàng | Bảng dòng hàng: mỗi dòng là một dòng hàng; nhận diện bằng mã hoá đơn và số thứ tự dòng |
| Bảng bên thanh toán | Bảng thanh toán: mỗi dòng là một lần trả tiền; nhận diện bằng mã lần thanh toán |
| Mã định dùng để ghép | Mã hoá đơn; mã này lặp ở cả hai bảng nguồn |
| Nếu ghép ngay | Mỗi dòng mới là một cặp dòng hàng và lần trả; cả tiền hàng lẫn tiền thanh toán bị lặp |
| Cách làm cho nhu cầu này | Cộng riêng từng bảng theo hoá đơn, kiểm mỗi mã chỉ có một dòng rồi mới ghép |
| Tổng dùng để đối chiếu | Tiền hàng 300.000 đ; đã trả 300.000 đ |
| Chi tiết không còn trong bảng tổng | Từng món hàng và từng cách thanh toán; giữ bảng nguồn để xem khi cần |
| Điều chưa suy ra được | Tiền của từng món chia cho tiền mặt và thẻ thế nào |
| Phần cần trao đổi | Người dùng báo cáo xác nhận câu hỏi; người lập báo cáo và người phụ trách kỹ thuật kiểm cách ghép |
Đổi từ tổng theo hoá đơn sang tiền hàng theo cách trả là đổi câu hỏi, nên phải xét lại cách làm trước khi thêm cột.
Khi nào nên làm, khi nào chưa cần
Nên ghi mức chi tiết và kiểm trước, sau ghép khi báo cáo kết hợp nhiều bảng, khi thêm thông tin làm tổng đổi bất thường, hoặc khi nhiều người dùng lại bảng ghép. Có thể kiểm một hoá đơn để tìm chỗ lặp, rồi kiểm toàn bộ phạm vi báo cáo.
Có cách khác: nếu chỉ cần tiền hàng, dùng bảng dòng hàng và bỏ bước ghép thanh toán. Nếu cần tổng theo hoá đơn, cộng riêng như ví dụ. Nếu cần xem từng món và từng lần trả, hiện hai bảng cạnh nhau thay vì ép chúng thành một bảng có tổng chung. Muốn chia tiền thanh toán cho từng món, cần dữ liệu ghi rõ hoặc quy tắc nghiệp vụ đã được người có quyền chốt; ví dụ này chưa có quy tắc ấy.
Chưa cần dựng riêng hệ thống fact và dimension khi một tệp nhỏ đã trả lời được câu hỏi và không cần dùng lại rộng rãi. Nếu nhóm vẫn quản lý được nội dung, có thể ghi tên cửa hàng ngay trong tệp, ghi chú mức chi tiết và kiểm tổng bằng tay. Khi nhiều báo cáo dùng chung thông tin mô tả và cập nhật trong nhiều tệp gây nhầm, mới cân nhắc tổ chức các bảng dùng chung.
Tự làm
Đồng nghiệp đổi bảng ghép sang các cột dưới đây để cộng tiền khách đã trả. Khoản nào bị lặp, và tổng đúng cần lấy từ đâu?
| Lần trả | Dòng hàng | Tiền đã trả (đ) |
|---|---|---|
| TT01 | D1 | 100.000 |
| TT02 | D1 | 200.000 |
| TT01 | D2 | 100.000 |
| TT02 | D2 | 200.000 |
Gợi ý
Xem đáp án
Tiền của từng lần trả bị lặp theo các dòng hàng. Cộng cột này được 600.000 đ, còn tổng đúng từ bảng thanh toán là 300.000 đ. Đổi thứ tự cột không đổi mức chi tiết của bảng ghép.
Nếu chỉ cần xem tiền đã trả theo cách thanh toán, cộng từ bảng thanh toán, chưa cần ghép dòng hàng. Nếu cần đối chiếu với tiền hàng theo hoá đơn, cộng riêng hai bên theo hoá đơn rồi ghép. Không dùng bảng các cặp để cộng như bảng ghi từng lần trả ban đầu.
Báo cáo cần thêm tên cửa hàng cho các dòng hàng. Bảng mô tả đang dùng có đúng một dòng khớp mỗi mã cửa hàng. Có cần cộng dòng hàng theo hoá đơn trước khi ghép không?
Gợi ý
Xem đáp án
Không cần cộng theo hoá đơn chỉ để thêm tên. Trong điều kiện đã nêu, mỗi dòng hàng nhận đúng một tên cửa hàng và vẫn giữ mức chi tiết cũ. Với HD3001, tiền hàng vẫn là 300.000 đ. Cộng trước có thể làm mất chi tiết món mà báo cáo cần.
Nếu bảng mô tả có nhiều dòng cùng khớp một mã, phải làm rõ dòng nào phù hợp trước khi ghép. Nếu thiếu mã khớp, cần kiểm cách báo cáo giữ phần chưa có tên để tránh bỏ mất tiền hàng. Với tệp nhỏ đã ghi tên rõ và chỉ dùng một lần, có thể chưa cần ghép thêm bảng mô tả riêng.
Quản lý muốn xem tiền hàng của từng món chia theo tiền mặt và thẻ. Đồng nghiệp đề nghị dùng ngay bảng ghép của HD3001 vì đã có món hàng và lần trả. Dữ liệu đã đủ chưa?
Gợi ý
Xem đáp án
Chưa đủ. Bảng thanh toán ghi tiền trả cho cả hoá đơn, không ghi trả cho từng món. Cộng tiền hàng theo cách trả từ bảng ghép sẽ đưa cùng một khoản vào nhiều nhóm.
Cần hỏi người dùng muốn chia tiền theo nghĩa nào, rồi tìm dữ liệu hoặc xin chốt quy tắc chia có điều kiện rõ. Nếu chỉ cần biết khách dùng cách trả nào, hiện danh sách bên cạnh các món là đủ. Nếu cần tổng đã trả theo từng cách, dùng riêng bảng thanh toán, chưa cần quy tắc chia tiền cho từng món.
Hiểu nhầm thường gặp
“Cùng mã hoá đơn thì ghép xong cứ cộng như cũ.” Mã hoá đơn có thể lặp ở cả hai bảng. Cần biết mỗi dòng sau ghép là gì và khoản tiền đã xuất hiện bao nhiêu lần.
“Hai bảng khác mức chi tiết thì không được ghép.” Dòng hàng vẫn có thể nhận tên từ bảng cửa hàng mà không tăng tổng, khi mỗi mã khớp đúng một dòng mô tả. Khác mức chi tiết là điều cần xét, còn cách khớp mới cho thấy có lặp hay mất dòng không.
“Tổng tăng gấp đôi thì chia đôi là xong.” Cách sửa này chỉ tình cờ khớp với HD3001. Hoá đơn khác có thể có cách trả khác hoặc thiếu dữ liệu. Cần sửa cách ghép và cộng theo nhu cầu, thay vì chia tổng theo tỷ lệ đoán.
“Xoá các khoản tiền giống nhau sẽ bỏ được phần lặp.” Hai lần trả khác nhau có thể có cùng số tiền mà đều là thật. Nhận diện bằng sự kiện và khoá của nó, không chỉ bằng giá trị tiền. Với ví dụ này, giữ nguồn đúng và sửa cách lập báo cáo, thay vì xoá giao dịch nguồn.
Tóm tắt
- Mức chi tiết nói mỗi dòng đại diện cho việc gì. Khoá nhận diện giúp phân biệt các dòng ở mức đó; mã hoá đơn chưa đủ để phân biệt từng dòng hàng hay lần trả.
- Fact ghi việc xảy ra và giá trị để tính; dimension cung cấp thông tin mô tả. Cả bảng dòng hàng và bảng thanh toán đều có thể là fact.
- Ghép theo hoá đơn có thể tạo từng cặp dòng hàng và lần trả. Khi đó, cả tiền hàng và tiền thanh toán có thể bị cộng lặp, dù hai bảng nguồn đều đúng.
- Chọn cách làm theo câu hỏi: dùng một bảng, cộng riêng theo hoá đơn rồi ghép, hoặc giữ hai bảng chi tiết cạnh nhau. Chưa suy ra được tiền theo từng món và cách trả nếu thiếu dữ liệu hoặc quy tắc chia phù hợp.
Thuật ngữ trong bài
| Tiếng Việt | Tiếng Anh |
|---|---|
| Mức chi tiết | Grain |
| Bảng sự kiện | fact |
| Bảng chiều | dimension |
Mẫu tải về: Phiếu kiểm trước khi ghép bảng (Word). Nội dung giống bảng đã điền ở mục Ví dụ giải sẵn, để trống cho bạn điền.
Bài liên quan: “OLTP và OLAP”, “Thuật ngữ và metadata”, “Chất lượng dữ liệu”.