thắc mắc Cách thiết kế Database trong SQL

teeeeeeeee

Senior Member
Hi mấy thím,
Em đang có một thắc mắc nhỏ trong thiết kế các bảng của SQL, cụ thể là thiết kế các bảng user(sẽ có hai loại là normal_user và admin_user).
Tuy nhiên, em google thì có hai cách như thế này:
Một là sẽ gộp chung tất cả các User vào chung một bảng và tạo hai bảng riêng để lấy role(Như hình dưới)
Screen Shot 2020-05-02 at 10.50.06.png


CÒn cách 2 thì em đọc được trên stackoverflow thì sẽ tạo một bảng user gồm các thuộc tính chung và tạo hai bảng con normal với admin giống như kiểu kế thừa trong OOP. Link stackoverflow

Các thím cho em hỏi là cách nào sẽ tối ưu hơn ạ? Với lại trong thực tế thì cách nào được sử dụng nhiều hơn
Q8sGcLO.png

Em cảm ơn mấy thím
MjfezZB.png
 
Bạn đọc ở đây nhé link
Nó còn tùy vào cấu trúc dự án của bạn và hướng bạn muốn phân quyền như thế nào để đưa ra được cấu trúc phân quyền phù hơp nhất. Vd như cty mình thì đang xài phân quyền theo chức năng như trong bài viết. Nhưng thiết kế không giống trong bài viết đâu.
Pm9YP1O.png
vì cách trong bài viết performance không tốt. chỉ là các hoạt động giống thôi
5nansbY.png
 
Kiểu nào chả đc. Thường thì làm table user và role rồi n-n với nhau với các app có nhiều role.
Còn app chỉ có 2 role thì làm 1 cái flag isAdmin cũng chả sao, hoặc là 1 col chứa user type.
Nếu 2 function của user và admin tách biệt thì làm 2 table riêng cũng đc.
 
Tùy theo yêu cầu thực tế mà chọn. Ví dụ như loại 2 của chủ thớt sẽ khó mở rộng và chỉ có 2 loại. Giờ giả sử thêm loại thứ 3 thì sẽ phải tạo thêm 1 bảng. Còn như loại 1 thì không cần tạo thêm bảng
 
Ý bạn muốn hỏi là bạn muốn làm sao để biết user này thuộc role nào, có 2 cách đang làm bạn phân vân, hoặc là kiểu bảng bridge, 2 là mỗi kiểu user bạn tạo bảng riêng đúng không?

- Với cái việc bạn có cái bảng User_Role, bạn có thể phân quyền 1 user có thể có nhiều role.
- Khi thêm kiểu role mới, nếu bạn dùng cách User_Role, bạn sẽ không phải tạo bảng mới.
- Nếu bạn thực sự muốn 1 user nhiều role, nếu bạn dùng cách từng bảng cho mỗi role, bạn phải seek n bảng cho từng kiểu role, mỗi khi có kiểu role mới thì bạn phải seek thêm bảng mới -> Càng nhiều kiểu role càng giảm performance, cũng không biết viết code kiểu gì (mỗi lần thêm role là phải sửa code). Nếu bạn dùng User_Role, bạn chỉ phải seek đúng cái bảng này.
- ... và có thể còn những cái mình chưa nghĩ ra.

Mình thấy cái link stackoverflow nó hướng đến cái mục đích chính là do 2 kiểu user kia nó có 1 số field khác nhau, phải lưu data thế nào, thì người ta mới nghĩ đến cách làm đó. Chứ nếu bạn hướng đến chỉ là để biết user kia có role gì, đặc biệt là nếu 1 user có thể có nhiều role, thì mình ko bao giờ làm theo kiểu cách dưới.

Cái dưới là kiểu vertical partitioning, nghĩa là bạn tách data ra lưu trong 2 bảng. Mục đích của nó thường là thế này:

- Giảm độ lớn của 1 row. -> Giảm IO. Chỉ khi cần đến các thông tin kia thì mới join vào để lấy. Nếu bạn nói bạn có thể dùng covering index để giảm read IO, thì thêm index cũng đồng nghĩa với việc giảm performance của write.
- Có thể là giữ được versioning của data của user đó đó. VD bạn 1 user có 2 row trong UserDetail, chỉ có 1 row được đánh là hiện tại, còn lại, bị đề là deleted, nhưng bạn sẽ vẫn có được data đó trong tay chứ ko phải ghi đè nếu bạn dùng bảng đơn.
- Bạn có thể có được data flexible hơn. VD Bạn có thể có UserDetail và SpecialUserDetail, trong mỗi bảng có key để gắn với bảng user, để đạt được mục đích như trong cái link stackoverflow kia chẳng hạn.
- ... và có thể còn những cái mình chưa nghĩ ra.

Nói chung mình thấy cái bài viết trong stackoverflow đang nói về vấn đề làm sao để model userdetail khi có 1 số kiểu user có 1 số field khác trong khi 1 số kiểu user lại có 1 số field khác, chứ không phải là cách model làm sao để biết user x là user role kiểu a hay là user role kiểu b. Bạn thử đọc lại xem.

Góc nhìn trên là góc nhìn của một thằng chuyên đi model hệ thống analytic chứ không phải OLTP. Bạn có thể cân nhắc.
 
Last edited:
User - > junction table ( many-many) <= role => junction table (many- many ) <= rights

Bên trong cái rights có thể là :api right hay table right, hoặc cả 2 , tuỳ .
 
1716017022270.png

Mọi người cứu em với.
Em làm cái erd đơn giản mô phỏng ứng dụng shopee food, hiện tại gặp vấn đề ở cái đơn hàng.
Đối với việc tài khoản người dùng thì ban đầu em gộp tất cả người dùng vào 1 bảng USER rồi có các Role như trên, nhưng database phức tạp quá
Trong bảng đơn hàng:
-Khách hàng thì sẽ đặt món ăn, thông tin sẽ lưu vào bảng này.
-Chủ quán ăn sẽ xác nhận đơn hàng ("Xác nhận", "Hủy") với trường trangThaiDonHang.
-Người giao hàng thì cũng phải cập nhật trạng thái vận chuyển.
Em thấy sai ở chỗ: làm sao để thằng shipper biết đơn hàng nào mà xác nhận. (Bình thường việc shipper nhận đơn hàng nào thì thông qua vị trí shipper gần nhất với nhà hàng, cái này thì em làm k được).
 
Bạn đọc ở đây nhé link
Nó còn tùy vào cấu trúc dự án của bạn và hướng bạn muốn phân quyền như thế nào để đưa ra được cấu trúc phân quyền phù hơp nhất
 
Back
Top