Bạn nên thiết kế DAO theo nhu cầu ứng dụng của mình, chứ không phải bố cục cơ sở dữ liệu của bạn. Bắt đầu với một DAO, và nếu nó trở nên quá lớn, sau đó tái cấu trúc nó thành nhiều DAO theo cách có ý nghĩa với mã của bạn.
Toàn bộ điểm của DAO là ẩn bất kỳ khái niệm cơ sở dữ liệu nào (như bảng) từ ứng dụng của bạn. Ứng dụng của bạn chỉ nên xem nó như một dịch vụ với một số phương pháp hữu ích. Ví dụ, nếu ứng dụng của bạn cần một số dữ liệu người dùng đến từ cả bảng Người dùng và bảng EmailAddresses, mã ứng dụng của bạn không cần phải phối hợp hai DAO - nó sẽ gọi một phương thức DAO getUserDetails() và DAO sẽ ẩn thực tế là nhiều bảng cần phải được gọi.
Tôi đang đề xuất tùy chọn đầu tiên trong câu hỏi của bạn, nhưng tôi sẽ không hạn chế chính mình đối với quy tắc "một DAO cho mỗi lớp chứa".