2012-12-06 49 views
9

Tôi có 4 loại người dùng và mỗi người đều có dữ liệu cụ thể, nhưng họ cũng chia sẻ dữ liệu commun, như username, password ..thiết kế cơ sở dữ liệu quan hệ nhiều kiểu sử dụng

Suy nghĩ đầu tiên của tôi là để tạo ra một users bảng chính với user_type cột. Sau đó, khi truy vấn dữ liệu người dùng, tôi chỉ có thể chọn user_type và sau đó tùy thuộc vào việc output chạy truy vấn khác để lấy dữ liệu cụ thể "loại người dùng". Tôi không thích điều này vì tôi ước tôi có thể lấy tất cả dữ liệu liên quan đến người dùng bằng một truy vấn và lý tưởng sử dụng Khóa ngoại.

Ý tưởng thứ hai là không có cột user_type trong bảng users và thay vào đó sử dụng khóa ngoài từ bảng loại người dùng cụ thể sẽ trỏ đến một hàng bảng chính users. Tôi thích rằng tốt hơn một chút mặc dù tôi đoán tôi sẽ phải chạy N truy vấn, trong đó N là số lượng người dùng loại mỗi khi tôi cần phải lấy dữ liệu người dùng.

Có tùy chọn nào khác không? Điều gì sẽ là thực hành tốt trong trường hợp như vậy?

Rất cám ơn

+0

Nếu tôi hiểu bạn, bạn chỉ cần sử dụng một điều khoản JOIN trong câu lệnh SQL của bạn. Một cái gì đó giống như 'SELECT * FROM người dùng U LEFT JOIN user_details D ON U.id = D.user_id WHERE U.id =?' –

+0

Người dùng có thể có nhiều hơn một loại tại một thời điểm không? –

+0

@Catcall không có trong trường hợp này một người dùng chỉ có thể có một loại, mặc dù tôi tò mò về khả năng trong trường hợp là gì – silkAdmin

Trả lời

14

Trường hợp của bạn trông giống như một thể hiện của lớp/phân lớp.

Có hai cách cổ điển để thiết kế các bảng SQL để xử lý các lớp con. Mỗi người đều có những ưu điểm cũng như những khuyết điểm.

Một cách được gọi là "Thừa kế bảng đơn". Trong thiết kế này chỉ có một bảng cho tất cả các loại người dùng. Nếu một cột nhất định không liên quan đến một hàng nhất định, giao lộ được để lại NULL. Một cột có thể được thêm vào để cho biết loại người dùng.

Một cách khác được gọi là "Thừa kế bảng lớp". Điều này giống như câu trả lời của Nanego, với một vài thay đổi nhỏ. Có một bảng cho người dùng, với tất cả dữ liệu chung và trường id. Có một bảng cho mỗi phân lớp, với dữ liệu liên quan đến phân lớp đó. Trường id thường được thiết lập dưới dạng bản sao của trường id trong hàng phù hợp trở lại trong bảng người dùng.Bằng cách này, khóa lớp con có thể thực hiện nhiệm vụ kép, hoạt động như cả khóa chính lẫn khóa ngoài tham chiếu bảng người dùng. Kỹ thuật cuối cùng này được gọi là "Khóa chính được chia sẻ". Nó đòi hỏi một chút lập trình tại thời gian chèn, nhưng nó cũng có giá trị nó. Nó thực thi tính chất một-một của mối quan hệ, và nó tăng tốc độ tham gia cần thiết.

Bạn có thể tra cứu cả ba thiết kế này dưới dạng thẻ trong SO hoặc dưới dạng bài viết trên web.

+2

Cảm ơn bạn đã bỏ những điều khoản đó, googled họ và đã học được rất nhiều – silkAdmin

0

cách của tôi để làm nó đã có để tạo ra một bảng "Người" với các lĩnh vực phổ biến, và một bảng đối với từng loại người dùng với một chìa khóa nước ngoài "Person_Id".

Trong yêu cầu của bạn, bạn chỉ cần tham gia hai bảng có khóa nước ngoài để nhận tất cả dữ liệu cho một loại người dùng.

Bạn có bao nhiêu loại người dùng?

+0

ngay bây giờ 4 nhưng tôi muốn giữ linh hoạt .. Giải pháp thứ hai tôi đã đề cập thực sự là những gì bạn đang đề xuất . – silkAdmin

2

Mặc dù việc sử dụng không gian đĩa hiệu quả hơn, nhưng vấn đề chia tách thành các bảng riêng biệt là bạn yêu cầu có hiệu quả các kết nối có điều kiện - tham gia vào bảng cụ thể kiểu người dùng dựa trên user_type. Đây là một nỗi đau để mã như SQL, và những ngày này những người quan tâm về không gian đĩa?

Tùy chọn tốt hơn là có một bảng người dùng với đủ cột để lưu trữ thông tin về mọi loại người dùng, biết rằng một số cột sẽ không được sử dụng cho một số loại người dùng. "Không hiệu quả" của việc sử dụng các cột không sử dụng sẽ được bù đắp nhiều hơn trong tốc độ thực thi và sự đơn giản của truy vấn. Nó cũng dễ dàng mở rộng, trong trường hợp bạn có một kiểu người dùng khác - việc thêm các cột dễ dàng hơn là thêm bảng và khi bạn thêm nhiều loại người dùng hơn, yêu cầu cho các cột mới sẽ giảm đi (chỉ có aren '). t nhiều điều khác nhau về người dùng bạn cần lưu trữ)

+2

Tôi ghét phải upvote này vì nó chỉ cảm thấy cẩu thả, nhưng nó thực sự là sự thật. –

+0

Tôi đồng ý rằng sẽ làm cho mã sạch hơn rất nhiều để tránh tham gia nhưng tôi rất thích có bảng phù hợp với các lớp học PHP, Nó chỉ cảm thấy thanh lịch hơn – silkAdmin

+1

Ngoài ra tôi thấy một nhược điểm này là bảng toàn vẹn lỏng như tôi 'd phải làm cho tất cả các trường nullable có thể dẫn đến lỗi trong mã phụ trợ. – silkAdmin

Các vấn đề liên quan