Il tuo primo schema è la scelta migliore dei due. A questo punto, non dovresti preoccuparti di problemi di prestazioni. Preoccupati di creare un design buono, flessibile ed estensibile. Ci sono tutti i tipi di trucchi che puoi fare in seguito per memorizzare nella cache i dati ed eseguire query più velocemente. L'utilizzo di uno schema di database meno flessibile per risolvere un problema di prestazioni che potrebbe anche non materializzarsi è una decisione sbagliata.
Inoltre, molti (forse la maggior parte) risultati dei sondaggi vengono visualizzati solo periodicamente e da un numero limitato di persone (organizzatori di eventi, amministratori, ecc.), quindi non dovrai interrogare costantemente il database per tutti i risultati. E anche se lo fossi, la performance andrà bene. Probabilmente impaginare i risultati in qualche modo comunque.
Il primo schema è molto più flessibile. Puoi, per impostazione predefinita, includere domande come nome e indirizzo, ma per i sondaggi anonimi, semplicemente non puoi crearli. Se il creatore del sondaggio vuole visualizzare solo le risposte di tutti a tre domande su cinquecento, si tratta di una query SQL davvero semplice. Puoi impostare un'eliminazione a cascata per eliminare automaticamente le risposte e le domande quando un sondaggio viene eliminato. Anche la generazione di statistiche sarà molto più semplice con questo schema.
Ecco una versione leggermente modificata dello schema che hai fornito. Presumo che tu possa capire quali tipi di dati vanno dove :-)
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