Non è che siano poi totalmente distinti, anzi.
L'approccio canonico, poco sicuro, è il 2). In questa ipotesi è la tua applicazione a controllare se l'utente (dell'applicazione) tizio può fare o non fare qualcosa.
Per le situazioni a maggior sicurezza si adottano entrambi, 1 e 2.
Ovvero gli utenti dell'applicazione (2) vengono fatti corrispondere a utenti DIVERSI del RDBMS (1).
Ciò può avvenire per gruppo o per singolo, a seconda della granularità richiesta.
Questo al fine di aggiungere un livello ulteriore di sicurezza, soprattutto avendo utenti che sono tutti limitati (nessun utente amministratore può usare l'applicazione).
Operativamente (parliamo ad esempio di mysql) è prassi comune creare delle viste delle tabelle che sono legate agli utenti del database secondo una qualche regola.
Poi avrai i singoli GRANT anche a livello addirittura di singolo campo, ottenendo quindi una combinazione di selezione e proiezione sui campi medesimi.
---
Facciamo qualche esempio: supponiamo di avere una tabella importante (es. esami medici) composta da 1000 righe e 10 campi.
Supponiamo che alcuni di questi campi possano essere visibili ad utenti diversi, ad esempio i medici vedono tutti e 10, gli specialisti ne vedono 5 e magari le segretarie 3.
Puoi creare delle viste del tipo
select campo1,campo2,campo3 from tabella where gruppo_utente="segreteria"
oppure
select campo1,campo2,campo3,campo4,campo5 from tabella where gruppo_utente="specialista"
e
select * from tabella where gruppo_utente="medico"
magari
select * from tabella where utente="superman"
Al login mantenendo allineato utenti DB ed applicazioni avrai tante viste diverse quanti utenti (o gruppi di utenti), pertanto l'applicazione utilizzerà ad esempio l'utente TIZIO del database, il quale opererà su una vista delle tabelle.