2012-04-10 12 views
12

Tôi đang cố triển khai một bài trắc nghiệm trắc nghiệm và sẽ lưu trữ tất cả các câu hỏi và câu trả lời của mình trong cơ sở dữ liệu SQLite. Tôi sẽ có nhiều câu hỏi, và đối với mỗi câu hỏi sẽ có 2 hoặc nhiều câu trả lời có thể hiển thị.Lưu trữ một bài kiểm tra trắc nghiệm trong cơ sở dữ liệu - quyết định lược đồ

Câu hỏi của tôi là, làm cách nào để lưu trữ các câu hỏi và câu trả lời trong cơ sở dữ liệu? Tôi có hai ý tưởng cho một schema (khóa chính in đậm)

  1. như (nhiều nhiều)

câu hỏi (questionID: int, questionString: String, correctAnswerID: int)

câu trả lời (answerID: int, answerString: string)

questions_and_answers (questionID, answerID)

2.

câu hỏi (questionID: int, questionString: String, correctAnswerID: int)

câu trả lời (answerID: int, answerString: String, questionID: int khóa ngoài)

Tôi không chắc cái nào tốt hơn, hoặc nếu có cách nào khác?

Có lẽ questions_and_answers sẽ rất lớn và gây ra thời gian truy xuất và sự cố bộ nhớ lâu? Sau đó, một lần nữa, tôi giả định question_and_answers sẽ được lập chỉ mục trên các khóa chính. Trong lược đồ thứ hai, answers sẽ được lập chỉ mục trên answerID và không phải là questionID? có nghĩa là thời gian tìm kiếm sẽ tăng lên khi toàn bộ bảng sẽ phải được tìm kiếm?

Có thể có ~ 10.000 - 20.000 câu trả lời. (bài kiểm tra có thể chạy trên thiết bị di động và các câu hỏi sẽ cần phải được hiển thị "ngay lập tức")

Lưu ý: Tôi không mong đợi có nhiều câu trả lời trùng lặp giữa các câu hỏi. Tôi sẽ không nghĩ rằng số lượng chồng chéo sẽ có nghĩa là ít dữ liệu được lưu trữ, xem xét thêm không gian được yêu cầu bởi questions_and_answers bảng

+0

Câu trả lời của bạn có thực sự có khả năng được sao chép qua nhiều câu hỏi không? – Tenner

+0

Tại một dự đoán thô, tôi có thể nói rằng 30% câu trả lời sẽ xuất hiện trong nhiều câu hỏi –

Trả lời

7

Bạn là lược đồ thứ hai tốt hơn vì nó mô hình miền thực tế: mỗi câu hỏi có thiết lập các câu trả lời. Ngay cả khi bạn có thể "nén" dữ liệu bằng cách lưu trữ các câu trả lời trùng lặp một lần, nó không khớp với tên miền thực tế.

Xuống đường bạn sẽ muốn chỉnh sửa câu trả lời. Với lược đồ 1, điều đó có nghĩa là tìm kiếm đầu tiên nếu câu trả lời đó đã tồn tại. Nếu nó tồn tại, bạn sẽ phải kiểm tra xem có câu hỏi nào vẫn dựa vào câu trả lời cũ không. Nếu nó không tồn tại, bạn sẽ vẫn phải kiểm tra xem có câu hỏi nào khác dựa vào câu trả lời đó không, và sau đó chỉnh sửa câu trả lời đó hoặc tạo câu trả lời mới.

Giản đồ 1 chỉ làm cho cuộc sống thực sự khó khăn.

Để trả lời các câu hỏi chỉ mục của bạn, bạn sẽ cần thêm chỉ mục trên questionId.Khi bạn có chỉ mục đó, tìm kiếm câu trả lời cho một câu hỏi sẽ được mở rộng.

Bây giờ, trên một lưu ý hoàn toàn khác, tại sao lại sử dụng cơ sở dữ liệu cho điều này? Cân nhắc lưu trữ chúng dưới dạng tài liệu đơn giản ở định dạng chuẩn như json. Bất cứ lúc nào bạn truy vấn một câu hỏi, bạn sẽ hầu như luôn luôn muốn câu trả lời, và ngược lại. Thay vì thực hiện nhiều truy vấn, bạn có thể tải toàn bộ tài liệu trong một bước.

Nếu sau đó bạn tìm thấy bạn cần bộ nhớ nâng cao hơn (truy vấn, dự phòng, v.v.), bạn có thể chuyển sang cơ sở dữ liệu tài liệu như MongoDB hoặc CouchDB.

+0

Tôi vừa mới nghĩ về cách tôi sẽ đi về việc xóa một câu hỏi và nhận ra rằng sẽ khó khăn hơn nhiều trên lược đồ. cảm giác với tôi ngay bây giờ! Tôi nghĩ rằng tôi muốn sử dụng một cơ sở dữ liệu bởi vì tôi nghĩ rằng nó sẽ dễ dàng hơn để tìm kiếm/quản lý/lưu trữ/chỉnh sửa các câu hỏi. Nó không bao giờ xảy ra với tôi để lưu trữ chúng như là tài liệu - bạn có nghĩ rằng nó sẽ cung cấp hiệu suất tốt hơn đáng kể? Cảm ơn câu trả lời của bạn –

+1

Nếu việc sử dụng dữ liệu của bạn giống như tôi mong đợi, thì giải pháp dựa trên tài liệu có thể dễ dàng thực hiện tốt hơn. Một giải pháp tài liệu sẽ chỉ có 1 tra cứu (tài liệu), so với (câu hỏi + câu trả lời). –

-1

Có vẻ như bế tắc (vòng tròn) như questionID cột được gọi là khóa ngoại trong trả lời bảng và correctAnswerID cột được gọi là khóa ngoại trong câu hỏi bảng.

Tốt hơn nên tạo một cột loại bit trong bảng câu trả lời để đánh dấu câu trả lời đúng và loại bỏ cột correctAnswerID.