Votre premier schéma est le meilleur choix des deux. À ce stade, vous ne devriez pas vous soucier des problèmes de performances. Souciez-vous de faire une bonne conception flexible et extensible. Il existe toutes sortes d'astuces que vous pouvez utiliser ultérieurement pour mettre en cache les données et accélérer les requêtes. L'utilisation d'un schéma de base de données moins flexible pour résoudre un problème de performances qui peut même ne pas se matérialiser est une mauvaise décision.
En outre, de nombreux (peut-être la plupart) des résultats d'enquête ne sont consultés que périodiquement et par un petit nombre de personnes (organisateurs d'événements, administrateurs, etc.), de sorte que vous n'interrogerez pas constamment la base de données pour tous les résultats. Et même si vous l'étiez, la performance sera bonne. Vous auriez probablement paginé les résultats d'une manière ou d'une autre.
Le premier schéma est beaucoup plus souple. Vous pouvez, par défaut, inclure des questions telles que le nom et l'adresse, mais pour les sondages anonymes, vous ne pouvez tout simplement pas les créer. Si le créateur de l'enquête souhaite uniquement afficher les réponses de chacun à trois questions sur cinq cents, il s'agit d'une requête SQL très simple. Vous pouvez configurer une suppression en cascade pour supprimer automatiquement les réponses et les questions lorsqu'une enquête est supprimée. La génération de statistiques sera également beaucoup plus facile avec ce schéma.
Voici une version légèrement modifiée du schéma que vous avez fourni. Je suppose que vous pouvez déterminer quels types de données vont où :-)
surveys survey_id (index) title questions question_id (index, auto increment) survey_id (link to surveys->survey_id) question responses response_id (index, auto increment) survey_id (link to surveys->survey_id) submit_time answers answer_id (index, auto increment) question_id (link to questions-question_id) answer